Support single Java source files in kotlinc arguments
E.g. "kotlinc foo.kt test/Bar.java" will compile foo.kt, and declarations from Bar.java will be accessible to Kotlin code in foo.kt. The change in AbstractTopLevelMembersInvocationTest is needed because an incorrect configuration was created in that test where a library jar was also a Java source root (the compiler is never configured this way in production), which led to an exception in JavaCoreProjectEnvironment#addSourcesToClasspath #KT-17697 Fixed
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.cli.jvm
|
package org.jetbrains.kotlin.cli.jvm
|
||||||
|
|
||||||
|
import com.intellij.ide.highlighter.JavaFileType
|
||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
import org.jetbrains.kotlin.cli.common.CLICompiler
|
import org.jetbrains.kotlin.cli.common.CLICompiler
|
||||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||||
@@ -94,11 +95,16 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
}
|
}
|
||||||
else if (arguments.module == null) {
|
else if (arguments.module == null) {
|
||||||
for (arg in arguments.freeArgs) {
|
for (arg in arguments.freeArgs) {
|
||||||
configuration.addKotlinSourceRoot(arg)
|
|
||||||
val file = File(arg)
|
val file = File(arg)
|
||||||
if (file.isDirectory) {
|
if (file.extension == JavaFileType.DEFAULT_EXTENSION) {
|
||||||
configuration.addJavaSourceRoot(file)
|
configuration.addJavaSourceRoot(file)
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
configuration.addKotlinSourceRoot(arg)
|
||||||
|
if (file.isDirectory) {
|
||||||
|
configuration.addJavaSourceRoot(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
-7
@@ -26,6 +26,7 @@ import com.intellij.psi.search.GlobalSearchScope
|
|||||||
import gnu.trove.THashMap
|
import gnu.trove.THashMap
|
||||||
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
||||||
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndex
|
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndex
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.index.SingleJavaFileRootsIndex
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
||||||
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryClassSignatureParser
|
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryClassSignatureParser
|
||||||
@@ -36,21 +37,23 @@ import org.jetbrains.kotlin.name.ClassId
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.jvm.KotlinCliJavaFileManager
|
import org.jetbrains.kotlin.resolve.jvm.KotlinCliJavaFileManager
|
||||||
import org.jetbrains.kotlin.util.PerformanceCounter
|
import org.jetbrains.kotlin.util.PerformanceCounter
|
||||||
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.properties.Delegates
|
|
||||||
|
|
||||||
// TODO: do not inherit from CoreJavaFileManager to avoid accidental usage of its methods which do not use caches/indices
|
// TODO: do not inherit from CoreJavaFileManager to avoid accidental usage of its methods which do not use caches/indices
|
||||||
// Currently, the only relevant usage of this class as CoreJavaFileManager is at CoreJavaDirectoryService.getPackage,
|
// Currently, the only relevant usage of this class as CoreJavaFileManager is at CoreJavaDirectoryService.getPackage,
|
||||||
// which is indirectly invoked from PsiPackage.getSubPackages
|
// which is indirectly invoked from PsiPackage.getSubPackages
|
||||||
class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJavaFileManager(myPsiManager), KotlinCliJavaFileManager {
|
class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJavaFileManager(myPsiManager), KotlinCliJavaFileManager {
|
||||||
private val perfCounter = PerformanceCounter.create("Find Java class")
|
private val perfCounter = PerformanceCounter.create("Find Java class")
|
||||||
private var index: JvmDependenciesIndex by Delegates.notNull()
|
private lateinit var index: JvmDependenciesIndex
|
||||||
|
private lateinit var singleJavaFileRootsIndex: SingleJavaFileRootsIndex
|
||||||
private val topLevelClassesCache: MutableMap<FqName, VirtualFile?> = THashMap()
|
private val topLevelClassesCache: MutableMap<FqName, VirtualFile?> = THashMap()
|
||||||
private val allScope = GlobalSearchScope.allScope(myPsiManager.project)
|
private val allScope = GlobalSearchScope.allScope(myPsiManager.project)
|
||||||
private var useFastClassFilesReading = false
|
private var useFastClassFilesReading = false
|
||||||
|
|
||||||
fun initialize(packagesCache: JvmDependenciesIndex, useFastClassFilesReading: Boolean) {
|
fun initialize(index: JvmDependenciesIndex, singleJavaFileRootsIndex: SingleJavaFileRootsIndex, useFastClassFilesReading: Boolean) {
|
||||||
this.index = packagesCache
|
this.index = index
|
||||||
|
this.singleJavaFileRootsIndex = singleJavaFileRootsIndex
|
||||||
this.useFastClassFilesReading = useFastClassFilesReading
|
this.useFastClassFilesReading = useFastClassFilesReading
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,6 +67,7 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
index.findClass(classId) { dir, type ->
|
index.findClass(classId) { dir, type ->
|
||||||
findVirtualFileGivenPackage(dir, relativeClassName, type)
|
findVirtualFileGivenPackage(dir, relativeClassName, type)
|
||||||
}
|
}
|
||||||
|
?: singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
||||||
}?.takeIf { it in searchScope }
|
}?.takeIf { it in searchScope }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,6 +157,13 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
// traverse all
|
// traverse all
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.addIfNotNull(
|
||||||
|
singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
||||||
|
?.takeIf { it in scope }
|
||||||
|
?.findPsiClassInVirtualFile(relativeClassName)
|
||||||
|
)
|
||||||
|
|
||||||
if (result.isNotEmpty()) {
|
if (result.isNotEmpty()) {
|
||||||
return@time result.toTypedArray()
|
return@time result.toTypedArray()
|
||||||
}
|
}
|
||||||
@@ -169,10 +180,10 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
//abort on first found
|
//abort on first found
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
if (found) {
|
if (!found) {
|
||||||
return PsiPackageImpl(myPsiManager, packageName)
|
found = singleJavaFileRootsIndex.findJavaSourceClasses(packageFqName).isNotEmpty()
|
||||||
}
|
}
|
||||||
return null
|
return if (found) PsiPackageImpl(myPsiManager, packageName) else null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findVirtualFileGivenPackage(
|
private fun findVirtualFileGivenPackage(
|
||||||
@@ -216,6 +227,11 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
true
|
true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
for (classId in singleJavaFileRootsIndex.findJavaSourceClasses(packageFqName)) {
|
||||||
|
assert(!classId.isNestedClass) { "ClassId of a single .java source class should not be nested: $classId" }
|
||||||
|
result.add(classId.shortClassName.asString())
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,10 +72,7 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
|||||||
import org.jetbrains.kotlin.cli.common.toBooleanLenient
|
import org.jetbrains.kotlin.cli.common.toBooleanLenient
|
||||||
import org.jetbrains.kotlin.cli.jvm.JvmRuntimeVersionsConsistencyChecker
|
import org.jetbrains.kotlin.cli.jvm.JvmRuntimeVersionsConsistencyChecker
|
||||||
import org.jetbrains.kotlin.cli.jvm.config.*
|
import org.jetbrains.kotlin.cli.jvm.config.*
|
||||||
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
import org.jetbrains.kotlin.cli.jvm.index.*
|
||||||
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesDynamicCompoundIndex
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndex
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.index.JvmUpdateableDependenciesIndexFactory
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem
|
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem
|
||||||
import org.jetbrains.kotlin.cli.jvm.modules.JavaModuleInfo
|
import org.jetbrains.kotlin.cli.jvm.modules.JavaModuleInfo
|
||||||
import org.jetbrains.kotlin.cli.jvm.modules.ModuleGraph
|
import org.jetbrains.kotlin.cli.jvm.modules.ModuleGraph
|
||||||
@@ -207,11 +204,16 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
// REPL and kapt2 update classpath dynamically
|
// REPL and kapt2 update classpath dynamically
|
||||||
val indexFactory = JvmUpdateableDependenciesIndexFactory()
|
val indexFactory = JvmUpdateableDependenciesIndexFactory()
|
||||||
|
|
||||||
rootsIndex = indexFactory.makeIndexFor(initialRoots)
|
val (roots, singleJavaFileRoots) =
|
||||||
|
initialRoots.partition { (file) -> file.isDirectory || file.extension != JavaFileType.DEFAULT_EXTENSION }
|
||||||
|
rootsIndex = indexFactory.makeIndexFor(roots)
|
||||||
updateClasspathFromRootsIndex(rootsIndex)
|
updateClasspathFromRootsIndex(rootsIndex)
|
||||||
|
|
||||||
(ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl)
|
(ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl).initialize(
|
||||||
.initialize(rootsIndex, configuration.getBoolean(JVMConfigurationKeys.USE_FAST_CLASS_FILES_READING))
|
rootsIndex,
|
||||||
|
SingleJavaFileRootsIndex(singleJavaFileRoots),
|
||||||
|
configuration.getBoolean(JVMConfigurationKeys.USE_FAST_CLASS_FILES_READING)
|
||||||
|
)
|
||||||
|
|
||||||
val finderFactory = CliVirtualFileFinderFactory(rootsIndex)
|
val finderFactory = CliVirtualFileFinderFactory(rootsIndex)
|
||||||
project.registerService(MetadataFinderFactory::class.java, finderFactory)
|
project.registerService(MetadataFinderFactory::class.java, finderFactory)
|
||||||
@@ -230,7 +232,7 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
|
|
||||||
private val allJavaFiles: List<File>
|
private val allJavaFiles: List<File>
|
||||||
get() = configuration.javaSourceRoots
|
get() = configuration.javaSourceRoots
|
||||||
.mapNotNull(this::findLocalDirectory)
|
.mapNotNull(this::findLocalFile)
|
||||||
.flatMap { it.javaFiles }
|
.flatMap { it.javaFiles }
|
||||||
.map { File(it.canonicalPath) }
|
.map { File(it.canonicalPath) }
|
||||||
|
|
||||||
@@ -337,13 +339,9 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
fun tryUpdateClasspath(files: Iterable<File>): List<File>? = updateClasspath(files.map(::JvmClasspathRoot))
|
fun tryUpdateClasspath(files: Iterable<File>): List<File>? = updateClasspath(files.map(::JvmClasspathRoot))
|
||||||
|
|
||||||
fun contentRootToVirtualFile(root: JvmContentRoot): VirtualFile? {
|
fun contentRootToVirtualFile(root: JvmContentRoot): VirtualFile? {
|
||||||
when (root) {
|
return when (root) {
|
||||||
is JvmClasspathRoot -> {
|
is JvmClasspathRoot -> if (root.file.isFile) findJarRoot(root) else findLocalFile(root)
|
||||||
return if (root.file.isFile) findJarRoot(root) else findLocalDirectory(root)
|
is JavaSourceRoot -> findLocalFile(root)
|
||||||
}
|
|
||||||
is JavaSourceRoot -> {
|
|
||||||
return if (root.file.isDirectory) findLocalDirectory(root) else null
|
|
||||||
}
|
|
||||||
else -> throw IllegalStateException("Unexpected root: $root")
|
else -> throw IllegalStateException("Unexpected root: $root")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,9 +350,9 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
|
|
||||||
fun findJarFile(path: String) = applicationEnvironment.jarFileSystem.findFileByPath(path)
|
fun findJarFile(path: String) = applicationEnvironment.jarFileSystem.findFileByPath(path)
|
||||||
|
|
||||||
private fun findLocalDirectory(root: JvmContentRoot): VirtualFile? {
|
private fun findLocalFile(root: JvmContentRoot): VirtualFile? {
|
||||||
val path = root.file
|
val path = root.file
|
||||||
val localFile = findLocalDirectory(path.absolutePath)
|
val localFile = findLocalFile(path.absolutePath)
|
||||||
if (localFile == null) {
|
if (localFile == null) {
|
||||||
report(STRONG_WARNING, "Classpath entry points to a non-existent location: $path")
|
report(STRONG_WARNING, "Classpath entry points to a non-existent location: $path")
|
||||||
return null
|
return null
|
||||||
@@ -362,9 +360,6 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
return localFile
|
return localFile
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun findLocalDirectory(absolutePath: String): VirtualFile? =
|
|
||||||
applicationEnvironment.localFileSystem.findFileByPath(absolutePath)
|
|
||||||
|
|
||||||
private fun findJarRoot(root: JvmClasspathRoot): VirtualFile? =
|
private fun findJarRoot(root: JvmClasspathRoot): VirtualFile? =
|
||||||
applicationEnvironment.jarFileSystem.findFileByPath("${root.file}${URLUtil.JAR_SEPARATOR}")
|
applicationEnvironment.jarFileSystem.findFileByPath("${root.file}${URLUtil.JAR_SEPARATOR}")
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -362,7 +362,7 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
override fun analyze(): AnalysisResult {
|
override fun analyze(): AnalysisResult {
|
||||||
val project = environment.project
|
val project = environment.project
|
||||||
val moduleOutputs = environment.configuration.get(JVMConfigurationKeys.MODULES)?.mapNotNull { module ->
|
val moduleOutputs = environment.configuration.get(JVMConfigurationKeys.MODULES)?.mapNotNull { module ->
|
||||||
environment.findLocalDirectory(module.getOutputDirectory())
|
environment.findLocalFile(module.getOutputDirectory())
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
val sourcesOnly = TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, environment.getSourceFiles())
|
val sourcesOnly = TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, environment.getSourceFiles())
|
||||||
// To support partial and incremental compilation, we add the scope which contains binaries from output directories
|
// To support partial and incremental compilation, we add the scope which contains binaries from output directories
|
||||||
|
|||||||
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.cli.jvm.index
|
||||||
|
|
||||||
|
import com.intellij.lang.java.lexer.JavaLexer
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.pom.java.LanguageLevel
|
||||||
|
import com.intellij.psi.impl.source.tree.ElementType
|
||||||
|
import com.intellij.psi.tree.IElementType
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
class SingleJavaFileRootsIndex(private val roots: List<JavaRoot>) {
|
||||||
|
init {
|
||||||
|
for ((file) in roots) {
|
||||||
|
assert(!file.isDirectory) { "Should not be a directory: $file" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val classIdsInRoots = ArrayList<List<ClassId>>(roots.size)
|
||||||
|
|
||||||
|
fun findJavaSourceClass(classId: ClassId): VirtualFile? =
|
||||||
|
roots.indices
|
||||||
|
.find { index -> classId in getClassIdsForRootAt(index) }
|
||||||
|
?.let { index -> roots[index].file }
|
||||||
|
|
||||||
|
fun findJavaSourceClasses(packageFqName: FqName): List<ClassId> =
|
||||||
|
roots.indices.flatMap(this::getClassIdsForRootAt).filter { root -> root.packageFqName == packageFqName }
|
||||||
|
|
||||||
|
private fun getClassIdsForRootAt(index: Int): List<ClassId> {
|
||||||
|
for (i in classIdsInRoots.size..index) {
|
||||||
|
classIdsInRoots.add(JavaSourceClassIdReader(roots[i].file).readClassIds())
|
||||||
|
}
|
||||||
|
return classIdsInRoots[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a .java file, [readClassIds] uses lexer to determine which classes are declared in that file
|
||||||
|
*/
|
||||||
|
private class JavaSourceClassIdReader(file: VirtualFile) {
|
||||||
|
private val lexer = JavaLexer(LanguageLevel.JDK_1_9).apply {
|
||||||
|
start(String(file.contentsToByteArray()))
|
||||||
|
}
|
||||||
|
private var braceBalance = 0
|
||||||
|
|
||||||
|
private fun at(type: IElementType): Boolean = lexer.tokenType == type
|
||||||
|
|
||||||
|
private fun end(): Boolean = lexer.tokenType == null
|
||||||
|
|
||||||
|
private fun advance() {
|
||||||
|
when {
|
||||||
|
at(ElementType.LBRACE) -> braceBalance++
|
||||||
|
at(ElementType.RBRACE) -> braceBalance--
|
||||||
|
}
|
||||||
|
lexer.advance()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun tokenText(): String = lexer.tokenText
|
||||||
|
|
||||||
|
private fun atClass(): Boolean =
|
||||||
|
braceBalance == 0 && lexer.tokenType in CLASS_KEYWORDS
|
||||||
|
|
||||||
|
fun readClassIds(): List<ClassId> {
|
||||||
|
var packageFqName = FqName.ROOT
|
||||||
|
while (!end() && !at(ElementType.PACKAGE_KEYWORD) && !atClass()) {
|
||||||
|
advance()
|
||||||
|
}
|
||||||
|
if (at(ElementType.PACKAGE_KEYWORD)) {
|
||||||
|
val packageName = StringBuilder()
|
||||||
|
while (!end() && !at(ElementType.SEMICOLON)) {
|
||||||
|
if (at(ElementType.IDENTIFIER) || at(ElementType.DOT)) {
|
||||||
|
packageName.append(tokenText())
|
||||||
|
}
|
||||||
|
advance()
|
||||||
|
}
|
||||||
|
packageFqName = FqName(packageName.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
val result = ArrayList<ClassId>(1)
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
while (!end() && !atClass()) {
|
||||||
|
advance()
|
||||||
|
}
|
||||||
|
if (end()) break
|
||||||
|
while (!end() && !at(ElementType.IDENTIFIER)) {
|
||||||
|
advance()
|
||||||
|
}
|
||||||
|
if (end()) break
|
||||||
|
result.add(ClassId(packageFqName, Name.identifier(tokenText())))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val CLASS_KEYWORDS = setOf(ElementType.CLASS_KEYWORD, ElementType.INTERFACE_KEYWORD, ElementType.ENUM_KEYWORD)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
$TESTDATA_DIR$/singleJavaFileRoots/test.kt
|
||||||
|
$TESTDATA_DIR$/singleJavaFileRoots/DefaultPackage.java
|
||||||
|
$TESTDATA_DIR$/singleJavaFileRoots/lib/A.java
|
||||||
|
$TESTDATA_DIR$/singleJavaFileRoots/lib/B.java
|
||||||
|
$TESTDATA_DIR$/singleJavaFileRoots/lib/ext/SeveralClasses.java
|
||||||
|
$TESTDATA_DIR$/singleJavaFileRoots/lib/classKinds/ClassClass.java
|
||||||
|
$TESTDATA_DIR$/singleJavaFileRoots/lib/classKinds/InterfaceClass.java
|
||||||
|
$TESTDATA_DIR$/singleJavaFileRoots/lib/classKinds/EnumClass.java
|
||||||
|
$TESTDATA_DIR$/singleJavaFileRoots/lib/classKinds/AnnotationClass.java
|
||||||
|
-d
|
||||||
|
$TEMP_DIR$
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
compiler/testData/cli/jvm/singleJavaFileRoots/test.kt:7:9: error: cannot access class 'C'. Check your module classpath for missing or conflicting dependencies
|
||||||
|
B().c()
|
||||||
|
^
|
||||||
|
compiler/testData/cli/jvm/singleJavaFileRoots/test.kt:8:5: error: unresolved reference: C
|
||||||
|
C().a()
|
||||||
|
^
|
||||||
|
compiler/testData/cli/jvm/singleJavaFileRoots/test.kt:12:5: error: cannot access '<init>': it is public/*package*/ in 'PackageLocal1'
|
||||||
|
PackageLocal1()
|
||||||
|
^
|
||||||
|
compiler/testData/cli/jvm/singleJavaFileRoots/test.kt:13:5: error: cannot access '<init>': it is public/*package*/ in 'PackageLocal2'
|
||||||
|
PackageLocal2()
|
||||||
|
^
|
||||||
|
COMPILATION_ERROR
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
public class DefaultPackage {}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package lib;
|
||||||
|
|
||||||
|
public class A {
|
||||||
|
public B b() {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package lib;
|
||||||
|
|
||||||
|
public class B {
|
||||||
|
public C c() {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package lib;
|
||||||
|
|
||||||
|
public class C {
|
||||||
|
public A a() {}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package lib.classKinds;
|
||||||
|
|
||||||
|
public @interface AnnotationClass {
|
||||||
|
EnumClass value();
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package lib.classKinds;
|
||||||
|
|
||||||
|
public class ClassClass {}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package lib.classKinds;
|
||||||
|
|
||||||
|
public enum EnumClass { ENTRY }
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package lib.classKinds;
|
||||||
|
|
||||||
|
public interface InterfaceClass {}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package lib. /* comment */ ext;
|
||||||
|
|
||||||
|
class
|
||||||
|
PackageLocal1 {}
|
||||||
|
|
||||||
|
class /* comment */ PackageLocal2 {}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import lib.*
|
||||||
|
import lib.ext.*
|
||||||
|
import lib.classKinds.*
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
A().b()
|
||||||
|
B().c()
|
||||||
|
C().a()
|
||||||
|
|
||||||
|
DefaultPackage()
|
||||||
|
|
||||||
|
PackageLocal1()
|
||||||
|
PackageLocal2()
|
||||||
|
}
|
||||||
|
|
||||||
|
@AnnotationClass(EnumClass.ENTRY)
|
||||||
|
fun classKinds(
|
||||||
|
c: ClassClass,
|
||||||
|
i: InterfaceClass,
|
||||||
|
e: EnumClass
|
||||||
|
) {}
|
||||||
+1
-1
@@ -61,7 +61,7 @@ public abstract class AbstractTopLevelMembersInvocationTest extends AbstractByte
|
|||||||
getTestRootDisposable(),
|
getTestRootDisposable(),
|
||||||
KotlinTestUtils.newConfiguration(
|
KotlinTestUtils.newConfiguration(
|
||||||
ConfigurationKind.JDK_ONLY, TestJdkKind.MOCK_JDK,
|
ConfigurationKind.JDK_ONLY, TestJdkKind.MOCK_JDK,
|
||||||
CollectionsKt.plus(classPath, KotlinTestUtils.getAnnotationsJar()), classPath
|
CollectionsKt.plus(classPath, KotlinTestUtils.getAnnotationsJar()), Collections.emptyList()
|
||||||
),
|
),
|
||||||
EnvironmentConfigFiles.JVM_CONFIG_FILES);
|
EnvironmentConfigFiles.JVM_CONFIG_FILES);
|
||||||
|
|
||||||
|
|||||||
@@ -332,6 +332,12 @@ public class CliTestGenerated extends AbstractCliTest {
|
|||||||
doJvmTest(fileName);
|
doJvmTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("singleJavaFileRoots.args")
|
||||||
|
public void testSingleJavaFileRoots() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/singleJavaFileRoots.args");
|
||||||
|
doJvmTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("suppressAllWarningsJvm.args")
|
@TestMetadata("suppressAllWarningsJvm.args")
|
||||||
public void testSuppressAllWarningsJvm() throws Exception {
|
public void testSuppressAllWarningsJvm() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/suppressAllWarningsJvm.args");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/suppressAllWarningsJvm.args");
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
|||||||
import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
|
import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
|
||||||
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
||||||
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndexImpl
|
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndexImpl
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.index.SingleJavaFileRootsIndex
|
||||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
||||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
|
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
@@ -202,6 +203,7 @@ class KotlinCliJavaFileManagerTest : KotlinTestWithEnvironment() {
|
|||||||
val root = environment.contentRootToVirtualFile(JavaSourceRoot(javaFilesDir!!, null))!!
|
val root = environment.contentRootToVirtualFile(JavaSourceRoot(javaFilesDir!!, null))!!
|
||||||
coreJavaFileManager.initialize(
|
coreJavaFileManager.initialize(
|
||||||
JvmDependenciesIndexImpl(listOf(JavaRoot(root, JavaRoot.RootType.SOURCE))),
|
JvmDependenciesIndexImpl(listOf(JavaRoot(root, JavaRoot.RootType.SOURCE))),
|
||||||
|
SingleJavaFileRootsIndex(emptyList()),
|
||||||
useFastClassFilesReading = true
|
useFastClassFilesReading = true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user