Always take java source before class files.
Also when searching for inner classes. ^Fixes KT-51025
This commit is contained in:
committed by
Alexander Udalov
parent
84b0e0b934
commit
c6d7c23940
+9
-6
@@ -174,6 +174,15 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
val result = ArrayList<PsiClass>(1)
|
val result = ArrayList<PsiClass>(1)
|
||||||
forEachClassId(qName) { classId ->
|
forEachClassId(qName) { classId ->
|
||||||
val relativeClassName = classId.relativeClassName.asString()
|
val relativeClassName = classId.relativeClassName.asString()
|
||||||
|
|
||||||
|
// Search java sources first. For build tools, it makes sense to build new files passing all the
|
||||||
|
// class files for the previous build on the class path.
|
||||||
|
result.addIfNotNull(
|
||||||
|
singleJavaFileRootsIndex.findJavaSourceClass(classId)
|
||||||
|
?.takeIf { it in scope }
|
||||||
|
?.findPsiClassInVirtualFile(relativeClassName)
|
||||||
|
)
|
||||||
|
|
||||||
index.traverseDirectoriesInPackage(classId.packageFqName) { dir, rootType ->
|
index.traverseDirectoriesInPackage(classId.packageFqName) { dir, rootType ->
|
||||||
val psiClass =
|
val psiClass =
|
||||||
findVirtualFileGivenPackage(dir, relativeClassName, rootType)
|
findVirtualFileGivenPackage(dir, relativeClassName, rootType)
|
||||||
@@ -186,12 +195,6 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
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()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.cli
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
||||||
|
import org.jetbrains.kotlin.test.TestCaseWithTmpdir
|
||||||
|
|
||||||
|
class JavaSourceInnerClassInClassPathTest : TestCaseWithTmpdir() {
|
||||||
|
|
||||||
|
// Test that a java source file for a class is taken before a class file for the same
|
||||||
|
// class on the class path.
|
||||||
|
fun test() {
|
||||||
|
val aJava = tmpdir.resolve("A.java").also {
|
||||||
|
it.writeText("class A { interface AInner { int foo(); } }")
|
||||||
|
}
|
||||||
|
val bJava = tmpdir.resolve("B.java").also {
|
||||||
|
it.writeText("class B implements A.AInner { public int foo() { return 42; } }")
|
||||||
|
}
|
||||||
|
val cKt = tmpdir.resolve("C.kt").also {
|
||||||
|
it.writeText("fun main() { B().foo() }")
|
||||||
|
}
|
||||||
|
val (output, exit) = AbstractCliTest.executeCompilerGrabOutput(
|
||||||
|
K2JVMCompiler(),
|
||||||
|
listOf(aJava.path, bJava.path, cKt.path, "-d", tmpdir.path, "-Xcompile-java", "-Xuse-javac")
|
||||||
|
)
|
||||||
|
assert(exit == ExitCode.OK) { output }
|
||||||
|
val (output2, exit2) = AbstractCliTest.executeCompilerGrabOutput(
|
||||||
|
K2JVMCompiler(),
|
||||||
|
listOf(aJava.path, bJava.path, cKt.path, "-cp", tmpdir.path)
|
||||||
|
)
|
||||||
|
assert(exit2 == ExitCode.OK) { output2 }
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user