From 7b2a80ffa464991c5997e259b0976dd0c7d42222 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 18 Oct 2016 16:06:39 +0300 Subject: [PATCH] Fix incremental recompilation of JvmMultifileClass with top level function See 53b584f and previous changes where this behavior was broken (this was untested, however). Fixes EA-90065 --- .../codegen/state/KotlinTypeMapper.java | 27 ++++++++++++------- .../IncrementalPackageFragmentProvider.kt | 3 +++ ...perimentalIncrementalJpsTestGenerated.java | 6 +++++ .../build/IncrementalJpsTestGenerated.java | 6 +++++ .../a.kt | 4 +++ .../b.kt | 4 +++ .../b.kt.new | 5 ++++ .../build.log | 24 +++++++++++++++++ .../experimental-ic-build.log | 26 ++++++++++++++++++ .../usage.kt | 8 ++++++ 10 files changed, 104 insertions(+), 9 deletions(-) create mode 100644 jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/a.kt create mode 100644 jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/b.kt create mode 100644 jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/b.kt.new create mode 100644 jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/build.log create mode 100644 jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/experimental-ic-build.log create mode 100644 jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/usage.kt 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 8ae8a3e7778..e0f4d8ab06c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java @@ -51,6 +51,7 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor; import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment; import org.jetbrains.kotlin.load.kotlin.*; +import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider.IncrementalMultifileClassPackageFragment; import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.Name; @@ -83,7 +84,6 @@ 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.*; @@ -301,18 +301,27 @@ public class KotlinTypeMapper { return new ContainingClassesInfo(FAKE_CLASS_ID_FOR_BUILTINS, FAKE_CLASS_ID_FOR_BUILTINS); } - assert containingDeclaration instanceof LazyJavaPackageFragment : - "Unexpected package fragment for " + descriptor + ": " + containingDeclaration + - " (" + containingDeclaration.getClass().getSimpleName() + ")"; - LazyJavaPackageFragment packageFragment = (LazyJavaPackageFragment) containingDeclaration; - Name implClassName = JvmFileClassUtil.getImplClassName(descriptor); assert implClassName != null : "No implClassName for " + descriptor; + String implSimpleName = implClassName.asString(); - String facadeSimpleName = packageFragment.getFacadeSimpleNameForPartSimpleName(implClassName.asString()); - if (facadeSimpleName == null) return null; + String facadeSimpleName; - return ContainingClassesInfo.forPackageMember(packageFragment.getFqName(), facadeSimpleName, implClassName.asString()); + if (containingDeclaration instanceof LazyJavaPackageFragment) { + facadeSimpleName = ((LazyJavaPackageFragment) containingDeclaration).getFacadeSimpleNameForPartSimpleName(implSimpleName); + if (facadeSimpleName == null) return null; + } + else if (containingDeclaration instanceof IncrementalMultifileClassPackageFragment) { + facadeSimpleName = ((IncrementalMultifileClassPackageFragment) containingDeclaration).getMultifileClassName().asString(); + } + else { + throw new AssertionError("Unexpected package fragment for " + descriptor + ": " + + containingDeclaration + " (" + containingDeclaration.getClass().getSimpleName() + ")"); + } + + return ContainingClassesInfo.forPackageMember( + ((PackageFragmentDescriptor) containingDeclaration).getFqName(), facadeSimpleName, implSimpleName + ); } @NotNull diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackageFragmentProvider.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackageFragmentProvider.kt index a0b2c416cf6..87a92ed4cca 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackageFragmentProvider.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackageFragmentProvider.kt @@ -93,6 +93,9 @@ class IncrementalPackageFragmentProvider( ) } + val multifileClassName: Name + get() = multifileClassFqName.shortName() + override fun getMemberScope() = memberScope() } } 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 47103158ce6..9cfdae0f0f9 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 @@ -581,6 +581,12 @@ public class ExperimentalIncrementalJpsTestGenerated extends AbstractExperimenta doTest(fileName); } + @TestMetadata("multifileClassAddTopLevelFunWithDefault") + public void testMultifileClassAddTopLevelFunWithDefault() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/"); + doTest(fileName); + } + @TestMetadata("multifileClassFileAdded") public void testMultifileClassFileAdded() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/multifileClassFileAdded/"); 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 27ef2946781..813be4e36f3 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 @@ -581,6 +581,12 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest { doTest(fileName); } + @TestMetadata("multifileClassAddTopLevelFunWithDefault") + public void testMultifileClassAddTopLevelFunWithDefault() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/"); + doTest(fileName); + } + @TestMetadata("multifileClassFileAdded") public void testMultifileClassFileAdded() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/multifileClassFileAdded/"); diff --git a/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/a.kt b/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/a.kt new file mode 100644 index 00000000000..63a63e173a0 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/a.kt @@ -0,0 +1,4 @@ +@file:[JvmName("Test") JvmMultifileClass] +package test + +fun a() = "a" diff --git a/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/b.kt b/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/b.kt new file mode 100644 index 00000000000..dcb3f87f413 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/b.kt @@ -0,0 +1,4 @@ +@file:[JvmName("Test") JvmMultifileClass] +package test + +fun b() = "" diff --git a/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/b.kt.new b/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/b.kt.new new file mode 100644 index 00000000000..1aa2c839861 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/b.kt.new @@ -0,0 +1,5 @@ +@file:[JvmName("Test") JvmMultifileClass] +package test + +fun b() = "" +fun b(s: String = "") = s diff --git a/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/build.log b/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/build.log new file mode 100644 index 00000000000..582ead1c07f --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/build.log @@ -0,0 +1,24 @@ +================ Step #1 ================= + +Cleaning output files: + out/production/module/META-INF/module.kotlin_module + out/production/module/test/Test.class + out/production/module/test/Test__BKt.class +End of files +Compiling files: + src/b.kt +End of files +Exit code: ADDITIONAL_PASS_REQUIRED +------------------------------------------ +Cleaning output files: + out/production/module/META-INF/module.kotlin_module + out/production/module/test/Test.class + out/production/module/test/Test__AKt.class + out/production/module/usage/UsageKt.class +End of files +Compiling files: + src/a.kt + src/usage.kt +End of files +Exit code: OK +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/experimental-ic-build.log b/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/experimental-ic-build.log new file mode 100644 index 00000000000..b13957b6b52 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/experimental-ic-build.log @@ -0,0 +1,26 @@ +================ Step #1 ================= + +Cleaning output files: + out/production/module/META-INF/module.kotlin_module + out/production/module/test/Test.class + out/production/module/test/Test__BKt.class +End of files +Compiling files: + src/b.kt +End of files +Marked as dirty by Kotlin: + src/usage.kt +Exit code: ADDITIONAL_PASS_REQUIRED +------------------------------------------ +Cleaning output files: + out/production/module/META-INF/module.kotlin_module + out/production/module/test/Test.class + out/production/module/test/Test__AKt.class + out/production/module/usage/UsageKt.class +End of files +Compiling files: + src/a.kt + src/usage.kt +End of files +Exit code: OK +------------------------------------------ \ No newline at end of file diff --git a/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/usage.kt b/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/usage.kt new file mode 100644 index 00000000000..7b1bf24bdd1 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/multifileClassAddTopLevelFunWithDefault/usage.kt @@ -0,0 +1,8 @@ +package usage + +import test.* + +fun usage() { + a() + b() +}