diff --git a/compiler/testData/codegen/java15/box/recordDifferentPropertyOverride.kt b/compiler/testData/codegen/java15/box/recordDifferentPropertyOverride.kt new file mode 100644 index 00000000000..2752ede043d --- /dev/null +++ b/compiler/testData/codegen/java15/box/recordDifferentPropertyOverride.kt @@ -0,0 +1,20 @@ +// FILE: MyRec.java +public record MyRec(String name) implements KI { + public String getName() { + return "OK"; + } +} + +// FILE: main.kt + +interface KI { + val name: String +} + +fun box(): String { + val r = MyRec("fail") + if (r.name() != "fail") return "fail 1" + if ((r as KI).name != "OK") return "fail 2" + + return r.name +} diff --git a/compiler/testData/codegen/java15/box/recordDifferentSyntheticProperty.kt b/compiler/testData/codegen/java15/box/recordDifferentSyntheticProperty.kt new file mode 100644 index 00000000000..80b39f384aa --- /dev/null +++ b/compiler/testData/codegen/java15/box/recordDifferentSyntheticProperty.kt @@ -0,0 +1,15 @@ +// FILE: MyRec.java +public record MyRec(String name) { + public String getName() { + return "OK"; + } +} + +// FILE: main.kt +fun box(): String { + val r = MyRec("fail") + if (r.name() != "fail") return "fail 1" + if (r.getName() != "OK") return "fail 2" + + return r.name +} diff --git a/compiler/testData/codegen/java15/box/recordPropertyAccess.kt b/compiler/testData/codegen/java15/box/recordPropertyAccess.kt new file mode 100644 index 00000000000..05939f3dea5 --- /dev/null +++ b/compiler/testData/codegen/java15/box/recordPropertyAccess.kt @@ -0,0 +1,10 @@ +// FILE: MyRec.java +public record MyRec(String name) {} + +// FILE: recordPropertyAccess.kt +fun box(): String { + val r = MyRec("OK") + if (r.name() != "OK") return "fail 1" + + return r.name +} \ No newline at end of file diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractBlackBoxCodegenTest.java b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractBlackBoxCodegenTest.java index 118df8a46e2..505173a92a4 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractBlackBoxCodegenTest.java +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractBlackBoxCodegenTest.java @@ -136,7 +136,7 @@ public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase { } @Nullable - private static String getFacadeFqName(@NotNull KtFile file) { + protected static String getFacadeFqName(@NotNull KtFile file) { return CodegenUtil.getMemberDeclarationsToGenerate(file).isEmpty() ? null : JvmFileClassUtil.getFileClassInfoNoResolve(file).getFacadeClassFqName().asString(); diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractCustomJDKBlackBoxCodegenTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractCustomJDKBlackBoxCodegenTest.kt new file mode 100644 index 00000000000..e53093e5d2e --- /dev/null +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractCustomJDKBlackBoxCodegenTest.kt @@ -0,0 +1,81 @@ +/* + * Copyright 2010-2020 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.codegen + +import org.jetbrains.kotlin.cli.common.output.writeAll +import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime +import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils +import org.jetbrains.kotlin.test.ConfigurationKind +import org.jetbrains.kotlin.test.KotlinTestUtils +import org.jetbrains.kotlin.test.TestJdkKind +import java.io.File +import java.util.concurrent.TimeUnit + +abstract class AbstractCustomJDKBlackBoxCodegenTest : AbstractBlackBoxCodegenTest() { + @Throws(Exception::class) + override fun doTest(filePath: String) { + val file = File(filePath) + val expectedText = + KotlinTestUtils.doLoadFile(file) + + "\n" + + """ + fun main() { + val res = box() + if (res != "OK") throw AssertionError(res) + } + """.trimIndent() + val testFiles = createTestFilesFromFile(file, expectedText) + doMultiFileTest(file, testFiles) + } + + override fun extractConfigurationKind(files: List): ConfigurationKind { + return ConfigurationKind.NO_KOTLIN_REFLECT + } + + override fun runJavacTask(files: MutableCollection, options: List) { + KotlinTestUtils.compileJavaFilesExternally(files, options + getAdditionalJavacArgs(), getJdkHome()) + } + + override fun getTestJdkKind(files: List): TestJdkKind { + return getTestJdkKind() + } + + abstract fun getTestJdkKind(): TestJdkKind + abstract fun getJdkHome(): File + + open fun getAdditionalJavacArgs(): List = emptyList() + open fun getAdditionalJvmArgs(): List = emptyList() + + abstract override fun getPrefix(): String + + override fun blackBox(reportProblems: Boolean, unexpectedBehaviour: Boolean) { + val tmpdir = KotlinTestUtils.tmpDirForTest(this) + val fileFactory = generateClassesInFile() + fileFactory.writeAll(tmpdir, null) + + val jdkHome = getJdkHome() + val javaExe = File(jdkHome, "bin/java.exe").takeIf(File::exists) + ?: File(jdkHome, "bin/java").takeIf(File::exists) + ?: error("Can't find 'java' executable in $jdkHome") + + + val command = arrayOf( + javaExe.absolutePath, + "-ea", + *getAdditionalJvmArgs().toTypedArray(), + "-classpath", + listOfNotNull( + tmpdir, ForTestCompileRuntime.runtimeJarForTests(), + javaClassesOutputDirectory + ).joinToString(File.pathSeparator, transform = File::getAbsolutePath), + getFacadeFqName(myFiles.psiFile) + ) + + val process = ProcessBuilder(*command).inheritIO().start() + process.waitFor(1, TimeUnit.MINUTES) + assertEquals(0, process.exitValue()) + } +} \ No newline at end of file diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractJdk15BlackBoxCodegenTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractJdk15BlackBoxCodegenTest.kt new file mode 100644 index 00000000000..6e50e9a59be --- /dev/null +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractJdk15BlackBoxCodegenTest.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2020 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.codegen + +import org.jetbrains.kotlin.jvm.compiler.ADDITIONAL_JAVAC_ARGS_FOR_15 +import org.jetbrains.kotlin.test.KotlinTestUtils +import org.jetbrains.kotlin.test.TestJdkKind +import java.io.File + +abstract class AbstractJdk15BlackBoxCodegenTest : AbstractCustomJDKBlackBoxCodegenTest() { + override fun getTestJdkKind(): TestJdkKind = TestJdkKind.FULL_JDK_15 + override fun getJdkHome(): File = KotlinTestUtils.getJdk15Home() + override fun getPrefix(): String = "java15/box" + + override fun getAdditionalJavacArgs(): List = ADDITIONAL_JAVAC_ARGS_FOR_15 + override fun getAdditionalJvmArgs(): List = listOf("--enable-preview") +} \ No newline at end of file diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/CodegenTestCase.java b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/CodegenTestCase.java index 9debd333195..60072773ce9 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/CodegenTestCase.java +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/CodegenTestCase.java @@ -58,6 +58,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.*; +import java.util.stream.Collectors; import static org.jetbrains.kotlin.cli.common.output.OutputUtilsKt.writeAllTo; import static org.jetbrains.kotlin.codegen.CodegenTestUtil.*; @@ -529,10 +530,24 @@ public abstract class CodegenTestCase extends KotlinBaseTest javacOptions = extractJavacOptions(files, configuration.get(JVMConfigurationKeys.JVM_TARGET)); - compileJava(findJavaSourcesInDirectory(javaSourceDir), javaClasspath, javacOptions, javaClassesOutputDirectory); + List finalJavacOptions = prepareJavacOptions(javaClasspath, javacOptions, javaClassesOutputDirectory); + + try { + runJavacTask( + findJavaSourcesInDirectory(javaSourceDir).stream().map(File::new).collect(Collectors.toList()), + finalJavacOptions + ); + } + catch (IOException e) { + throw ExceptionUtilsKt.rethrow(e); + } } } + protected void runJavacTask(@NotNull Collection files, @NotNull List options) throws IOException { + KotlinTestUtils.compileJavaFiles(files, options); + } + protected void updateJavaClasspath(@NotNull List javaClasspath) {} @NotNull diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/CodegenTestUtil.java b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/CodegenTestUtil.java index 57ecc004ffd..b526bd0d784 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/CodegenTestUtil.java +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/CodegenTestUtil.java @@ -101,18 +101,7 @@ public class CodegenTestUtil { @NotNull File outDirectory ) { try { - List classpath = new ArrayList<>(); - classpath.add(ForTestCompileRuntime.runtimeJarForTests().getPath()); - classpath.add(ForTestCompileRuntime.reflectJarForTests().getPath()); - classpath.add(KotlinTestUtils.getAnnotationsJar().getPath()); - classpath.addAll(additionalClasspath); - - List options = new ArrayList<>(Arrays.asList( - "-classpath", StringsKt.join(classpath, File.pathSeparator), - "-d", outDirectory.getPath() - )); - options.addAll(additionalOptions); - + List options = prepareJavacOptions(additionalClasspath, additionalOptions, outDirectory); KotlinTestUtils.compileJavaFiles(CollectionsKt.map(fileNames, File::new), options); } catch (IOException e) { @@ -120,6 +109,27 @@ public class CodegenTestUtil { } } + @NotNull + public static List prepareJavacOptions( + @NotNull List additionalClasspath, + @NotNull List additionalOptions, + @NotNull File outDirectory + ) { + List classpath = new ArrayList<>(); + classpath.add(ForTestCompileRuntime.runtimeJarForTests().getPath()); + classpath.add(ForTestCompileRuntime.reflectJarForTests().getPath()); + classpath.add(KotlinTestUtils.getAnnotationsJar().getPath()); + classpath.addAll(additionalClasspath); + + List options = new ArrayList<>(Arrays.asList( + "-classpath", StringsKt.join(classpath, File.pathSeparator), + "-d", outDirectory.getPath() + )); + options.addAll(additionalOptions); + return options; + } + + @NotNull public static Method findTheOnlyMethod(@NotNull Class aClass) { Method r = null; diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/Jdk15BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/Jdk15BlackBoxCodegenTestGenerated.java new file mode 100644 index 00000000000..3fb4b629608 --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/codegen/Jdk15BlackBoxCodegenTestGenerated.java @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2020 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.codegen; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +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/codegen/java15/box") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class Jdk15BlackBoxCodegenTestGenerated extends AbstractJdk15BlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInBox() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/java15/box"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("recordDifferentPropertyOverride.kt") + public void testRecordDifferentPropertyOverride() throws Exception { + runTest("compiler/testData/codegen/java15/box/recordDifferentPropertyOverride.kt"); + } + + @TestMetadata("recordDifferentSyntheticProperty.kt") + public void testRecordDifferentSyntheticProperty() throws Exception { + runTest("compiler/testData/codegen/java15/box/recordDifferentSyntheticProperty.kt"); + } + + @TestMetadata("recordPropertyAccess.kt") + public void testRecordPropertyAccess() throws Exception { + runTest("compiler/testData/codegen/java15/box/recordPropertyAccess.kt"); + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt b/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt index 5ebd70e752d..55105acc4af 100644 --- a/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt +++ b/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt @@ -211,6 +211,10 @@ fun main(args: Array) { model("codegen/boxAgainstJava") } + testClass { + model("codegen/java15/box") + } + testClass { model("codegen/script", extension = "kts") }