From d48ef2efc7aeea888366991d5d2b699aeebd94d5 Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Mon, 17 Oct 2016 12:16:13 +0300 Subject: [PATCH] Fix for KT-14012: Back-end (JVM) Internal error every first compilation after the source code change #KT-14012 Fixed --- .../codegen/state/KotlinTypeMapper.java | 31 +++++++++++++++---- .../compileKotlinAgainstKotlin/kt14012.kt | 18 +++++++++++ .../kt14012_multi.kt | 20 ++++++++++++ ...mpileKotlinAgainstKotlinTestGenerated.java | 12 +++++++ ...perimentalIncrementalJpsTestGenerated.java | 12 +++++++ .../build/IncrementalJpsTestGenerated.java | 12 +++++++ .../publicPropertyWithPrivateSetter/build.log | 11 +++++++ .../publicPropertyWithPrivateSetter/prop1.kt | 4 +++ .../publicPropertyWithPrivateSetter/prop2.kt | 6 ++++ .../prop2.kt.new | 5 +++ .../build.log | 11 +++++++ .../prop1.kt | 6 ++++ .../prop2.kt | 6 ++++ .../prop2.kt.new | 5 +++ 14 files changed, 153 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/compileKotlinAgainstKotlin/kt14012.kt create mode 100644 compiler/testData/compileKotlinAgainstKotlin/kt14012_multi.kt create mode 100644 jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/build.log create mode 100644 jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/prop1.kt create mode 100644 jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/prop2.kt create mode 100644 jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/prop2.kt.new create mode 100644 jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/build.log create mode 100644 jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/prop1.kt create mode 100644 jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/prop2.kt create mode 100644 jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/prop2.kt.new diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java index 74d69a739c9..8ae8a3e7778 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java @@ -83,6 +83,7 @@ import java.util.List; import static org.jetbrains.kotlin.codegen.AsmUtil.isStaticMethod; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*; import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*; +import static org.jetbrains.kotlin.fileClasses.JvmFileClassUtil.getPartFqNameForDeserializedCallable; import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall; import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure; import static org.jetbrains.kotlin.resolve.DescriptorUtils.*; @@ -866,12 +867,8 @@ public class KotlinTypeMapper { if (DescriptorUtils.isTopLevelDeclaration(descriptor)) { if (Visibilities.isPrivate(descriptor.getVisibility()) && !(descriptor instanceof ConstructorDescriptor) && !"".equals(name)) { - KtFile containingFile = DescriptorToSourceUtils.getContainingFile(descriptor); - assert containingFile != null : "Private descriptor accessed outside of corresponding file scope: " + descriptor; - JvmFileClassInfo fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(containingFile); - if (fileClassInfo.getWithJvmMultifileClass()) { - return name + "$" + fileClassInfo.getFileClassFqName().shortName().asString(); - } + String partName = getPartSimpleNameForMangling(descriptor); + if (partName != null) return name + "$" + partName; } return name; } @@ -883,6 +880,28 @@ public class KotlinTypeMapper { return name; } + @Nullable + private String getPartSimpleNameForMangling(@NotNull CallableMemberDescriptor descriptor) { + KtFile containingFile = DescriptorToSourceUtils.getContainingFile(descriptor); + if (containingFile != null) { + JvmFileClassInfo fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(containingFile); + if (fileClassInfo.getWithJvmMultifileClass()) { + return fileClassInfo.getFileClassFqName().shortName().asString(); + } + return null; + } + + descriptor = getDirectMember(descriptor); + assert descriptor instanceof DeserializedCallableMemberDescriptor : + "Descriptor without sources should be instance of DeserializedCallableMemberDescriptor, but: " + + descriptor; + ContainingClassesInfo containingClassesInfo = + getContainingClassesForDeserializedCallable((DeserializedCallableMemberDescriptor) descriptor); + String facadeShortName = containingClassesInfo.getFacadeClassId().getShortClassName().asString(); + String implShortName = containingClassesInfo.getImplClassId().getShortClassName().asString(); + return !facadeShortName.equals(implShortName) ? implShortName : null; + } + @NotNull public Method mapAsmMethod(@NotNull FunctionDescriptor descriptor) { return mapSignature(descriptor, true).getAsmMethod(); diff --git a/compiler/testData/compileKotlinAgainstKotlin/kt14012.kt b/compiler/testData/compileKotlinAgainstKotlin/kt14012.kt new file mode 100644 index 00000000000..71da17120c4 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstKotlin/kt14012.kt @@ -0,0 +1,18 @@ +// FILE: A.kt +package test + +var property = "fail" + private set + +fun test() { + property = "OK" +} + +// FILE: B.kt + +import test.* + +fun box(): String { + test() + return property +} diff --git a/compiler/testData/compileKotlinAgainstKotlin/kt14012_multi.kt b/compiler/testData/compileKotlinAgainstKotlin/kt14012_multi.kt new file mode 100644 index 00000000000..466908be208 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstKotlin/kt14012_multi.kt @@ -0,0 +1,20 @@ +// FILE: A.kt +@file:JvmName("TTest") +@file:JvmMultifileClass +package test + +var property = "fail" + private set + +fun test() { + property = "OK" +} + +// FILE: B.kt + +import test.* + +fun box(): String { + test() + return property +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java index 964e5dd1977..9eaacec82fd 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java @@ -149,6 +149,18 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl doTest(fileName); } + @TestMetadata("kt14012.kt") + public void testKt14012() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/kt14012.kt"); + doTest(fileName); + } + + @TestMetadata("kt14012_multi.kt") + public void testKt14012_multi() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/kt14012_multi.kt"); + doTest(fileName); + } + @TestMetadata("multifileClassInlineFunctionAccessingProperty.kt") public void testMultifileClassInlineFunctionAccessingProperty() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/multifileClassInlineFunctionAccessingProperty.kt"); diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/ExperimentalIncrementalJpsTestGenerated.java b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/ExperimentalIncrementalJpsTestGenerated.java index 3e527eadfe8..47103158ce6 100644 --- a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/ExperimentalIncrementalJpsTestGenerated.java +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/ExperimentalIncrementalJpsTestGenerated.java @@ -821,6 +821,18 @@ public class ExperimentalIncrementalJpsTestGenerated extends AbstractExperimenta doTest(fileName); } + @TestMetadata("publicPropertyWithPrivateSetter") + public void testPublicPropertyWithPrivateSetter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/"); + doTest(fileName); + } + + @TestMetadata("publicPropertyWithPrivateSetterMultiFileFacade") + public void testPublicPropertyWithPrivateSetterMultiFileFacade() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/"); + doTest(fileName); + } + @TestMetadata("removeAndRestoreCompanion") public void testRemoveAndRestoreCompanion() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/removeAndRestoreCompanion/"); diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java index 47451ca06ab..27ef2946781 100644 --- a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java @@ -821,6 +821,18 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest { doTest(fileName); } + @TestMetadata("publicPropertyWithPrivateSetter") + public void testPublicPropertyWithPrivateSetter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/"); + doTest(fileName); + } + + @TestMetadata("publicPropertyWithPrivateSetterMultiFileFacade") + public void testPublicPropertyWithPrivateSetterMultiFileFacade() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/"); + doTest(fileName); + } + @TestMetadata("removeAndRestoreCompanion") public void testRemoveAndRestoreCompanion() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/removeAndRestoreCompanion/"); diff --git a/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/build.log b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/build.log new file mode 100644 index 00000000000..157ba41596f --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/build.log @@ -0,0 +1,11 @@ +================ Step #1 ================= + +Cleaning output files: + out/production/module/META-INF/module.kotlin_module + out/production/module/test2/Prop2Kt.class +End of files +Compiling files: + src/prop2.kt +End of files +Exit code: OK +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/prop1.kt b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/prop1.kt new file mode 100644 index 00000000000..046382d5cc4 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/prop1.kt @@ -0,0 +1,4 @@ +package test + +var property = 1 + private set \ No newline at end of file diff --git a/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/prop2.kt b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/prop2.kt new file mode 100644 index 00000000000..5378c878b13 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/prop2.kt @@ -0,0 +1,6 @@ +package test2 +import test.* + +fun dummy() { + if (true) 1 else property +} diff --git a/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/prop2.kt.new b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/prop2.kt.new new file mode 100644 index 00000000000..7060f03a59b --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetter/prop2.kt.new @@ -0,0 +1,5 @@ +package test + +fun dummy() { + if (true) 2 else property +} diff --git a/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/build.log b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/build.log new file mode 100644 index 00000000000..157ba41596f --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/build.log @@ -0,0 +1,11 @@ +================ Step #1 ================= + +Cleaning output files: + out/production/module/META-INF/module.kotlin_module + out/production/module/test2/Prop2Kt.class +End of files +Compiling files: + src/prop2.kt +End of files +Exit code: OK +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/prop1.kt b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/prop1.kt new file mode 100644 index 00000000000..ebb7a7603e6 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/prop1.kt @@ -0,0 +1,6 @@ +@file:JvmName("TTest") +@file:JvmMultifileClass +package test + +var property = 1 + private set \ No newline at end of file diff --git a/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/prop2.kt b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/prop2.kt new file mode 100644 index 00000000000..5378c878b13 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/prop2.kt @@ -0,0 +1,6 @@ +package test2 +import test.* + +fun dummy() { + if (true) 1 else property +} diff --git a/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/prop2.kt.new b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/prop2.kt.new new file mode 100644 index 00000000000..7060f03a59b --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/publicPropertyWithPrivateSetterMultiFileFacade/prop2.kt.new @@ -0,0 +1,5 @@ +package test + +fun dummy() { + if (true) 2 else property +}