Introduce experimental -Xuse-javac compilation mode
In this mode, javac AST and Symbol files are used during Kotlin compilation instead of PSI / binary stuff. Later, they are reused for Java file compilation. javac in this mode is integrated into kotlinc.
This commit is contained in:
committed by
Mikhail Glukhikh
parent
c9a04fe1e2
commit
5eea3b6569
+59
-11
@@ -16,36 +16,61 @@
|
||||
|
||||
package org.jetbrains.kotlin.jvm.compiler
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.renderer.AnnotationArgumentsRenderingPolicy
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRendererModifier
|
||||
import org.jetbrains.kotlin.renderer.ParameterNameRenderingPolicy
|
||||
import org.jetbrains.kotlin.renderer.*
|
||||
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils.*
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.TestCaseWithTmpdir
|
||||
import org.jetbrains.kotlin.test.TestJdkKind
|
||||
import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.validateAndCompareDescriptorWithFile
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.junit.Assert
|
||||
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.lang.annotation.Retention
|
||||
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils.*
|
||||
import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.validateAndCompareDescriptorWithFile
|
||||
|
||||
abstract class AbstractCompileJavaAgainstKotlinTest : TestCaseWithTmpdir() {
|
||||
|
||||
@Throws(IOException::class)
|
||||
protected fun doTest(ktFilePath: String) {
|
||||
protected fun doTestWithJavac(ktFilePath: String) {
|
||||
doTest(ktFilePath, true)
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
protected fun doTestWithoutJavac(ktFilePath: String) {
|
||||
doTest(ktFilePath, false)
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
protected fun doTest(ktFilePath: String, useJavac: Boolean) {
|
||||
Assert.assertTrue(ktFilePath.endsWith(".kt"))
|
||||
val ktFile = File(ktFilePath)
|
||||
val javaFile = File(ktFilePath.replaceFirst("\\.kt$".toRegex(), ".java"))
|
||||
|
||||
val javaErrorFile = File(ktFilePath.replaceFirst("\\.kt$".toRegex(), ".javaerr.txt"))
|
||||
|
||||
val out = File(tmpdir, "out")
|
||||
val compiledSuccessfully = compileKotlinWithJava(listOf(javaFile), listOf(ktFile),
|
||||
out, testRootDisposable, javaErrorFile)
|
||||
|
||||
val compiledSuccessfully = if (useJavac) {
|
||||
compileKotlinWithJava(listOf(javaFile),
|
||||
listOf(ktFile),
|
||||
out, testRootDisposable)
|
||||
} else {
|
||||
KotlinTestUtils.compileKotlinWithJava(listOf(javaFile),
|
||||
listOf(ktFile),
|
||||
out, testRootDisposable, javaErrorFile)
|
||||
}
|
||||
|
||||
if (!compiledSuccessfully) return
|
||||
|
||||
val environment = KotlinCoreEnvironment.createForTests(
|
||||
@@ -56,12 +81,35 @@ abstract class AbstractCompileJavaAgainstKotlinTest : TestCaseWithTmpdir() {
|
||||
|
||||
val analysisResult = JvmResolveUtil.analyze(environment)
|
||||
val packageView = analysisResult.moduleDescriptor.getPackage(LoadDescriptorUtil.TEST_PACKAGE_FQNAME)
|
||||
assertFalse("Nothing found in package " + LoadDescriptorUtil.TEST_PACKAGE_FQNAME, packageView.isEmpty())
|
||||
assertFalse("Nothing found in package ${LoadDescriptorUtil.TEST_PACKAGE_FQNAME}", packageView.isEmpty())
|
||||
|
||||
val expectedFile = File(ktFilePath.replaceFirst("\\.kt$".toRegex(), ".txt"))
|
||||
validateAndCompareDescriptorWithFile(packageView, CONFIGURATION, expectedFile)
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun compileKotlinWithJava(
|
||||
javaFiles: List<File>,
|
||||
ktFiles: List<File>,
|
||||
outDir: File,
|
||||
disposable: Disposable
|
||||
): Boolean {
|
||||
val environment = createEnvironmentWithMockJdkAndIdeaAnnotations(disposable)
|
||||
environment.configuration.put(JVMConfigurationKeys.USE_JAVAC, true)
|
||||
environment.configuration.put(JVMConfigurationKeys.OUTPUT_DIRECTORY, outDir)
|
||||
environment.configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
|
||||
environment.registerJavac(javaFiles, kotlinFiles = listOf(KotlinTestUtils.loadJetFile(environment.project, ktFiles.first())))
|
||||
if (!ktFiles.isEmpty()) {
|
||||
LoadDescriptorUtil.compileKotlinToDirAndGetModule(ktFiles, outDir, environment)
|
||||
}
|
||||
else {
|
||||
val mkdirs = outDir.mkdirs()
|
||||
assert(mkdirs) { "Not created: $outDir" }
|
||||
}
|
||||
|
||||
return JavacWrapper.getInstance(environment.project).use { it.compile() }
|
||||
}
|
||||
|
||||
companion object {
|
||||
// Do not render parameter names because there are test cases where classes inherit from JDK collections,
|
||||
// and some versions of JDK have debug information in the class files (including parameter names), and some don't
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.jvm.compiler
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.renderer.*
|
||||
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.TestCaseWithTmpdir
|
||||
import org.jetbrains.kotlin.test.TestJdkKind
|
||||
import org.junit.Assert
|
||||
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.lang.annotation.Retention
|
||||
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils.*
|
||||
import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.validateAndCompareDescriptorWithFile
|
||||
|
||||
abstract class AbstractCompileKotlinAgainstJavaTest : TestCaseWithTmpdir() {
|
||||
|
||||
@Throws(IOException::class)
|
||||
protected fun doTest(ktFilePath: String) {
|
||||
Assert.assertTrue(ktFilePath.endsWith(".kt"))
|
||||
val ktFile = File(ktFilePath)
|
||||
val javaFile = File(ktFilePath.replaceFirst("\\.kt$".toRegex(), ".java"))
|
||||
val out = File(tmpdir, "out")
|
||||
|
||||
val compiledSuccessfully = compileKotlinWithJava(listOf(javaFile),
|
||||
listOf(ktFile),
|
||||
out, testRootDisposable)
|
||||
if (!compiledSuccessfully) return
|
||||
|
||||
val environment = KotlinCoreEnvironment.createForTests(
|
||||
testRootDisposable,
|
||||
newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, getAnnotationsJar(), out),
|
||||
EnvironmentConfigFiles.JVM_CONFIG_FILES
|
||||
)
|
||||
|
||||
environment.configuration.put(JVMConfigurationKeys.USE_JAVAC, true)
|
||||
environment.configuration.put(JVMConfigurationKeys.OUTPUT_DIRECTORY, out)
|
||||
environment.registerJavac(emptyList<File>())
|
||||
|
||||
val analysisResult = JvmResolveUtil.analyze(environment)
|
||||
val packageView = analysisResult.moduleDescriptor.getPackage(LoadDescriptorUtil.TEST_PACKAGE_FQNAME)
|
||||
assertFalse("Nothing found in package ${LoadDescriptorUtil.TEST_PACKAGE_FQNAME}", packageView.isEmpty())
|
||||
|
||||
val expectedFile = File(ktFilePath.replaceFirst("\\.kt$".toRegex(), ".txt"))
|
||||
validateAndCompareDescriptorWithFile(packageView, CONFIGURATION, expectedFile)
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun compileKotlinWithJava(
|
||||
javaFiles: List<File>,
|
||||
ktFiles: List<File>,
|
||||
outDir: File,
|
||||
disposable: Disposable
|
||||
): Boolean {
|
||||
val environment = createEnvironmentWithMockJdkAndIdeaAnnotations(disposable)
|
||||
environment.configuration.put(JVMConfigurationKeys.USE_JAVAC, true)
|
||||
environment.configuration.put(JVMConfigurationKeys.OUTPUT_DIRECTORY, outDir)
|
||||
environment.registerJavac(javaFiles, kotlinFiles = listOf(KotlinTestUtils.loadJetFile(environment.project, ktFiles.first())))
|
||||
if (!ktFiles.isEmpty()) {
|
||||
LoadDescriptorUtil.compileKotlinToDirAndGetModule(ktFiles, outDir, environment)
|
||||
}
|
||||
else {
|
||||
val mkdirs = outDir.mkdirs()
|
||||
assert(mkdirs) { "Not created: $outDir" }
|
||||
}
|
||||
|
||||
return JavacWrapper.getInstance(environment.project).use { it.compile() }
|
||||
}
|
||||
|
||||
companion object {
|
||||
// Do not render parameter names because there are test cases where classes inherit from JDK collections,
|
||||
// and some versions of JDK have debug information in the class files (including parameter names), and some don't
|
||||
private val CONFIGURATION = AbstractLoadJavaTest.COMPARATOR_CONFIGURATION.withRenderer(
|
||||
DescriptorRenderer.withOptions {
|
||||
withDefinedIn = false
|
||||
parameterNameRenderingPolicy = ParameterNameRenderingPolicy.NONE
|
||||
verbose = true
|
||||
annotationArgumentsRenderingPolicy = AnnotationArgumentsRenderingPolicy.UNLESS_EMPTY
|
||||
excludedAnnotationClasses = setOf(FqName(Retention::class.java.name))
|
||||
modifiers = DescriptorRendererModifier.ALL
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
+1169
-530
File diff suppressed because it is too large
Load Diff
+350
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
* 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.jvm.compiler;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/testData/compileKotlinAgainstJava")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class CompileKotlinAgainstJavaTestGenerated extends AbstractCompileKotlinAgainstJavaTest {
|
||||
@TestMetadata("AbstractClass.kt")
|
||||
public void testAbstractClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/AbstractClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("AbstractEnum.kt")
|
||||
public void testAbstractEnum() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/AbstractEnum.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCompileKotlinAgainstJava() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/compileKotlinAgainstJava"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("AnnotationWithArguments.kt")
|
||||
public void testAnnotationWithArguments() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/AnnotationWithArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("AnnotationWithField.kt")
|
||||
public void testAnnotationWithField() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/AnnotationWithField.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("AsteriskInImport.kt")
|
||||
public void testAsteriskInImport() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/AsteriskInImport.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("CheckKotlinStub.kt")
|
||||
public void testCheckKotlinStub() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/CheckKotlinStub.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("CheckNotNull.kt")
|
||||
public void testCheckNotNull() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/CheckNotNull.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Class.kt")
|
||||
public void testClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/Class.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ClassWithNestedEnum.kt")
|
||||
public void testClassWithNestedEnum() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/ClassWithNestedEnum.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ClassWithTypeParameter.kt")
|
||||
public void testClassWithTypeParameter() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/ClassWithTypeParameter.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("CyclicDependencies.kt")
|
||||
public void testCyclicDependencies() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/CyclicDependencies.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("DefaultModifier.kt")
|
||||
public void testDefaultModifier() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/DefaultModifier.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("EnclosingClassInner.kt")
|
||||
public void testEnclosingClassInner() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/EnclosingClassInner.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Enum.kt")
|
||||
public void testEnum() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/Enum.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("EnumName.kt")
|
||||
public void testEnumName() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/EnumName.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Inheritance.kt")
|
||||
public void testInheritance() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/Inheritance.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InheritedInner.kt")
|
||||
public void testInheritedInner() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/InheritedInner.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InnerCanonicalName.kt")
|
||||
public void testInnerCanonicalName() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/InnerCanonicalName.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InnerClass.kt")
|
||||
public void testInnerClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/InnerClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InnerClassFromAsteriskImport.kt")
|
||||
public void testInnerClassFromAsteriskImport() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/InnerClassFromAsteriskImport.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InnerClassFromImport.kt")
|
||||
public void testInnerClassFromImport() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/InnerClassFromImport.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Interface.kt")
|
||||
public void testInterface() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/Interface.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InterfaceField.kt")
|
||||
public void testInterfaceField() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/InterfaceField.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InterfaceMemberClass.kt")
|
||||
public void testInterfaceMemberClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/InterfaceMemberClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InterfaceWithDefault.kt")
|
||||
public void testInterfaceWithDefault() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/InterfaceWithDefault.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ListImpl.kt")
|
||||
public void testListImpl() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/ListImpl.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MapExample.kt")
|
||||
public void testMapExample() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/MapExample.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Method.kt")
|
||||
public void testMethod() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/Method.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MethodWithArgument.kt")
|
||||
public void testMethodWithArgument() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/MethodWithArgument.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MethodWithSeveralTypeParameters.kt")
|
||||
public void testMethodWithSeveralTypeParameters() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/MethodWithSeveralTypeParameters.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MethodWithTypeParameter.kt")
|
||||
public void testMethodWithTypeParameter() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/MethodWithTypeParameter.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("MethodWithWildcard.kt")
|
||||
public void testMethodWithWildcard() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/MethodWithWildcard.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Nesting.kt")
|
||||
public void testNesting() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/Nesting.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("RawReturnType.kt")
|
||||
public void testRawReturnType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/RawReturnType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ReturnEnum.kt")
|
||||
public void testReturnEnum() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/ReturnEnum.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ReturnInnerClass.kt")
|
||||
public void testReturnInnerClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/ReturnInnerClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ReturnInnerInInner.kt")
|
||||
public void testReturnInnerInInner() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/ReturnInnerInInner.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ReturnInnerInner.kt")
|
||||
public void testReturnInnerInner() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/ReturnInnerInner.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ReturnNested.kt")
|
||||
public void testReturnNested() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/ReturnNested.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ReturnNestedFQ.kt")
|
||||
public void testReturnNestedFQ() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/ReturnNestedFQ.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ReturnType.kt")
|
||||
public void testReturnType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/ReturnType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ReturnTypeResolution.kt")
|
||||
public void testReturnTypeResolution() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/ReturnTypeResolution.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SeveralInnerClasses.kt")
|
||||
public void testSeveralInnerClasses() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/SeveralInnerClasses.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SimpleAnnotation.kt")
|
||||
public void testSimpleAnnotation() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/SimpleAnnotation.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SimpleWildcard.kt")
|
||||
public void testSimpleWildcard() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/SimpleWildcard.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Singleton.kt")
|
||||
public void testSingleton() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/Singleton.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("StaticNestedClass.kt")
|
||||
public void testStaticNestedClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/StaticNestedClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TypeArgumentInSuperType.kt")
|
||||
public void testTypeArgumentInSuperType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/TypeArgumentInSuperType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TypeParameter.kt")
|
||||
public void testTypeParameter() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/TypeParameter.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UseKotlinInner.kt")
|
||||
public void testUseKotlinInner() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/UseKotlinInner.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UseKtClass.kt")
|
||||
public void testUseKtClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/UseKtClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Vararg.kt")
|
||||
public void testVararg() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstJava/Vararg.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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.jvm.compiler
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||
import org.jetbrains.kotlin.javac.components.JavacBasedClassFinder
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.KotlinTestWithEnvironmentManagement
|
||||
import org.jetbrains.kotlin.test.TestJdkKind
|
||||
import java.io.File
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
|
||||
class KotlinJavacBasedClassFinderTest : KotlinTestWithEnvironmentManagement() {
|
||||
fun testAbsentClass() {
|
||||
val tmpdir = KotlinTestUtils.tmpDirForTest(this)
|
||||
|
||||
val environment = createEnvironment(tmpdir)
|
||||
val project = environment.project
|
||||
|
||||
val classFinder = createClassFinder(project)
|
||||
|
||||
val className = "test.A.B.D"
|
||||
|
||||
val found = classFinder.findClass(ClassId.topLevel(FqName(className)))
|
||||
assertNull(found, "Class is expected to be null, there should be no exceptions too.")
|
||||
}
|
||||
|
||||
fun testNestedClass() {
|
||||
val tmpdir = KotlinTestUtils.tmpDirForTest(this)
|
||||
KotlinTestUtils.compileKotlinWithJava(
|
||||
listOf(), listOf(File("compiler/testData/kotlinClassFinder/nestedClass.kt")), tmpdir, testRootDisposable, null
|
||||
)
|
||||
|
||||
val environment = createEnvironment(tmpdir)
|
||||
val project = environment.project
|
||||
|
||||
val classFinder = createClassFinder(project)
|
||||
|
||||
val className = "test.A.B.C"
|
||||
val classId = ClassId(FqName("test"), FqName("A.B.C"), false)
|
||||
val found = classFinder.findClass(classId)
|
||||
assertNotNull(found, "Class not found for $className")
|
||||
|
||||
val binaryClass = VirtualFileFinder.SERVICE.getInstance(project).findKotlinClass(found!!)
|
||||
assertNotNull(binaryClass, "No binary class for $className")
|
||||
|
||||
assertEquals("test/A.B.C", binaryClass?.classId?.toString())
|
||||
}
|
||||
|
||||
private fun createClassFinder(project: Project) = JavacBasedClassFinder().apply {
|
||||
this::class.java.superclass.getDeclaredField("project")?.let {
|
||||
it.isAccessible = true
|
||||
it.set(this, project)
|
||||
}
|
||||
setScope(GlobalSearchScope.allScope(project))
|
||||
|
||||
val javacField = this::class.java.getDeclaredField("javac")
|
||||
javacField.isAccessible = true
|
||||
javacField.set(this, JavacWrapper.getInstance(project))
|
||||
|
||||
val javaSearchScopeField = this::class.java.superclass.getDeclaredField("javaSearchScope")
|
||||
javaSearchScopeField.isAccessible = true
|
||||
javaSearchScopeField.set(this, GlobalSearchScope.allScope(project))
|
||||
}
|
||||
|
||||
private fun createEnvironment(tmpdir: File?, files: List<File> = emptyList()): KotlinCoreEnvironment {
|
||||
return KotlinCoreEnvironment.createForTests(
|
||||
testRootDisposable,
|
||||
KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, tmpdir),
|
||||
EnvironmentConfigFiles.JVM_CONFIG_FILES
|
||||
).apply {
|
||||
registerJavac(files)
|
||||
// Activate Kotlin light class finder
|
||||
JvmResolveUtil.analyze(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user