From 7fb3f48c672cc8ddcc953b47ddba28538c8528f7 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 23 Mar 2021 12:58:53 +0100 Subject: [PATCH] Add ClassDescriptor.getInlineClassRepresentation This will be used at least in the JVM backend instead of the current approach where we're loading the primary constructor's first parameter, which isn't good enough since primary constructor can be private, and we can't rely on private declarations in case they're declared in another module. --- .../FirBlackBoxCodegenTestGenerated.java | 12 +++++++ .../SyntheticClassOrObjectDescriptor.kt | 2 ++ .../lazy/descriptors/LazyClassDescriptor.java | 25 ++++++++++--- .../ir/descriptors/IrBasedDescriptors.kt | 6 +++- .../extensionPropertyWithSameName.kt | 14 ++++++++ .../extensionPropertyWithSameName.kt | 16 +++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 12 +++++++ .../IrBlackBoxCodegenTestGenerated.java | 12 +++++++ .../JvmIrAgainstOldBoxTestGenerated.java | 12 +++++++ .../JvmOldAgainstIrBoxTestGenerated.java | 12 +++++++ .../descriptors/InlineClassRepresentation.kt | 14 ++++++++ .../descriptors/LazyJavaClassDescriptor.kt | 2 ++ .../functions/FunctionClassDescriptor.kt | 2 +- .../kotlin/descriptors/ClassDescriptor.java | 3 ++ .../kotlin/descriptors/NotFoundClasses.kt | 2 ++ .../descriptors/impl/ClassDescriptorImpl.java | 7 ++++ .../EnumEntrySyntheticClassDescriptor.java | 7 ++++ .../impl/LazySubstitutingClassDescriptor.java | 17 ++++++++- .../impl/MutableClassDescriptor.java | 6 ++++ .../DeserializedClassDescriptor.kt | 35 ++++++++++++++++--- .../idea/fir/fe10/BaseDescriptorsWrappers.kt | 2 ++ .../IrJsCodegenBoxES6TestGenerated.java | 5 +++ 22 files changed, 214 insertions(+), 11 deletions(-) create mode 100644 compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/extensionPropertyWithSameName.kt create mode 100644 compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/extensionPropertyWithSameName.kt create mode 100644 core/compiler.common/src/org/jetbrains/kotlin/descriptors/InlineClassRepresentation.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index bd13b7860f2..2ee2a012e59 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -6731,6 +6731,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/defaultWithInlineClassAndReceivers.kt"); } + @Test + @TestMetadata("extensionPropertyWithSameName.kt") + public void testExtensionPropertyWithSameName() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/extensionPropertyWithSameName.kt"); + } + @Test @TestMetadata("funInterface.kt") public void testFunInterface() throws Exception { @@ -6824,6 +6830,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/defaultWithInlineClassAndReceivers.kt"); } + @Test + @TestMetadata("extensionPropertyWithSameName.kt") + public void testExtensionPropertyWithSameName() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/extensionPropertyWithSameName.kt"); + } + @Test @TestMetadata("inlineClassFakeOverrideMangling.kt") public void testInlineClassFakeOverrideMangling() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt index 5d4e71fc46a..7ceeee822c1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.AbstractClassTypeConstructor import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.SimpleType import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner @@ -93,6 +94,7 @@ class SyntheticClassOrObjectDescriptor( override fun getStaticScope() = MemberScope.Empty override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner) = unsubstitutedMemberScope override fun getSealedSubclasses() = emptyList() + override fun getInlineClassRepresentation(): InlineClassRepresentation? = null init { assert(modality != Modality.SEALED) { "Implement getSealedSubclasses() for this class: ${this::class.java}" } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java index 9d21cb787c1..d7c07916e3e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -22,14 +22,12 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0; import org.jetbrains.kotlin.incremental.components.NoLookupLocation; import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.name.Name; +import org.jetbrains.kotlin.name.SpecialNames; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt; import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt; import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor; -import org.jetbrains.kotlin.resolve.BindingContext; -import org.jetbrains.kotlin.resolve.BindingTrace; -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; -import org.jetbrains.kotlin.resolve.DescriptorUtils; +import org.jetbrains.kotlin.resolve.*; import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil; import org.jetbrains.kotlin.resolve.lazy.LazyClassContext; import org.jetbrains.kotlin.resolve.lazy.LazyEntity; @@ -581,6 +579,25 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes return sealedSubclasses.invoke(); } + @Nullable + @Override + public InlineClassRepresentation getInlineClassRepresentation() { + if (!InlineClassesUtilsKt.isInlineClass(this)) return null; + + ClassConstructorDescriptor constructor = getUnsubstitutedPrimaryConstructor(); + if (constructor != null) { + ValueParameterDescriptor parameter = firstOrNull(constructor.getValueParameters()); + if (parameter != null) { + return new InlineClassRepresentation<>(parameter.getName(), (SimpleType) parameter.getType()); + } + } + + // Don't crash on invalid code. + return new InlineClassRepresentation<>( + SpecialNames.SAFE_IDENTIFIER_FOR_NO_NAME, c.getModuleDescriptor().getBuiltIns().getAnyType() + ); + } + @Override public String toString() { // not using DescriptorRenderer to preserve laziness diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt index 9e58a69d64a..0db34acd287 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt @@ -615,6 +615,8 @@ open class IrBasedClassDescriptor(owner: IrClass) : ClassDescriptor, IrBasedDecl TODO("not implemented") } + override fun getInlineClassRepresentation(): InlineClassRepresentation? = TODO("not implemented") + override fun getOriginal() = this override fun isExpect() = false @@ -739,6 +741,8 @@ open class IrBasedEnumEntryDescriptor(owner: IrEnumEntry) : ClassDescriptor, IrB TODO("not implemented") } + override fun getInlineClassRepresentation(): InlineClassRepresentation? = TODO("not implemented") + override fun getOriginal() = this override fun isExpect() = false @@ -1157,4 +1161,4 @@ private fun IrSimpleFunctionSymbol.toIrBasedDescriptorIfPossible(): FunctionDesc @OptIn(ObsoleteDescriptorBasedAPI::class) private fun IrPropertySymbol.toIrBasedDescriptorIfPossible(): PropertyDescriptor = - if (isBound) owner.toIrBasedDescriptor() else descriptor \ No newline at end of file + if (isBound) owner.toIrBasedDescriptor() else descriptor diff --git a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/extensionPropertyWithSameName.kt b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/extensionPropertyWithSameName.kt new file mode 100644 index 00000000000..81b90c60114 --- /dev/null +++ b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/extensionPropertyWithSameName.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// MODULE: lib +// FILE: A.kt + +inline class A(val value: String) { + val Char.value: String get() = this + nonExtensionValue() + + fun nonExtensionValue(): String = value +} + +// MODULE: main(lib) +// FILE: B.kt + +fun box(): String = with(A("K")) { 'O'.value } diff --git a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/extensionPropertyWithSameName.kt b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/extensionPropertyWithSameName.kt new file mode 100644 index 00000000000..deb2f44f5a7 --- /dev/null +++ b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/extensionPropertyWithSameName.kt @@ -0,0 +1,16 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// MODULE: lib +// USE_OLD_INLINE_CLASSES_MANGLING_SCHEME +// FILE: A.kt + +inline class A(val value: String) { + val Char.value: String get() = this + nonExtensionValue() + + fun nonExtensionValue(): String = value +} + +// MODULE: main(lib) +// FILE: B.kt + +fun box(): String = with(A("K")) { 'O'.value } diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 1495926d6fa..c04992ce7cc 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -6731,6 +6731,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/defaultWithInlineClassAndReceivers.kt"); } + @Test + @TestMetadata("extensionPropertyWithSameName.kt") + public void testExtensionPropertyWithSameName() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/extensionPropertyWithSameName.kt"); + } + @Test @TestMetadata("funInterface.kt") public void testFunInterface() throws Exception { @@ -6824,6 +6830,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/defaultWithInlineClassAndReceivers.kt"); } + @Test + @TestMetadata("extensionPropertyWithSameName.kt") + public void testExtensionPropertyWithSameName() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/extensionPropertyWithSameName.kt"); + } + @Test @TestMetadata("inlineClassFakeOverrideMangling.kt") public void testInlineClassFakeOverrideMangling() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 0b51fa1ee60..b254a62fb27 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -6731,6 +6731,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/defaultWithInlineClassAndReceivers.kt"); } + @Test + @TestMetadata("extensionPropertyWithSameName.kt") + public void testExtensionPropertyWithSameName() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/extensionPropertyWithSameName.kt"); + } + @Test @TestMetadata("funInterface.kt") public void testFunInterface() throws Exception { @@ -6824,6 +6830,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/defaultWithInlineClassAndReceivers.kt"); } + @Test + @TestMetadata("extensionPropertyWithSameName.kt") + public void testExtensionPropertyWithSameName() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/extensionPropertyWithSameName.kt"); + } + @Test @TestMetadata("inlineClassFakeOverrideMangling.kt") public void testInlineClassFakeOverrideMangling() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxTestGenerated.java index be25d4b8f73..b16b5deb282 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxTestGenerated.java @@ -518,6 +518,12 @@ public class JvmIrAgainstOldBoxTestGenerated extends AbstractJvmIrAgainstOldBoxT runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/defaultWithInlineClassAndReceivers.kt"); } + @Test + @TestMetadata("extensionPropertyWithSameName.kt") + public void testExtensionPropertyWithSameName() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/extensionPropertyWithSameName.kt"); + } + @Test @TestMetadata("funInterface.kt") public void testFunInterface() throws Exception { @@ -611,6 +617,12 @@ public class JvmIrAgainstOldBoxTestGenerated extends AbstractJvmIrAgainstOldBoxT runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/defaultWithInlineClassAndReceivers.kt"); } + @Test + @TestMetadata("extensionPropertyWithSameName.kt") + public void testExtensionPropertyWithSameName() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/extensionPropertyWithSameName.kt"); + } + @Test @TestMetadata("inlineClassFakeOverrideMangling.kt") public void testInlineClassFakeOverrideMangling() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxTestGenerated.java index 0f34d2bf945..eab53a3a563 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxTestGenerated.java @@ -518,6 +518,12 @@ public class JvmOldAgainstIrBoxTestGenerated extends AbstractJvmOldAgainstIrBoxT runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/defaultWithInlineClassAndReceivers.kt"); } + @Test + @TestMetadata("extensionPropertyWithSameName.kt") + public void testExtensionPropertyWithSameName() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/extensionPropertyWithSameName.kt"); + } + @Test @TestMetadata("funInterface.kt") public void testFunInterface() throws Exception { @@ -611,6 +617,12 @@ public class JvmOldAgainstIrBoxTestGenerated extends AbstractJvmOldAgainstIrBoxT runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/defaultWithInlineClassAndReceivers.kt"); } + @Test + @TestMetadata("extensionPropertyWithSameName.kt") + public void testExtensionPropertyWithSameName() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/extensionPropertyWithSameName.kt"); + } + @Test @TestMetadata("inlineClassFakeOverrideMangling.kt") public void testInlineClassFakeOverrideMangling() throws Exception { diff --git a/core/compiler.common/src/org/jetbrains/kotlin/descriptors/InlineClassRepresentation.kt b/core/compiler.common/src/org/jetbrains/kotlin/descriptors/InlineClassRepresentation.kt new file mode 100644 index 00000000000..ad6b207135a --- /dev/null +++ b/core/compiler.common/src/org/jetbrains/kotlin/descriptors/InlineClassRepresentation.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2010-2021 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.descriptors + +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.model.SimpleTypeMarker + +class InlineClassRepresentation( + val underlyingPropertyName: Name, + val underlyingType: Type, +) diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt index 04fcb739d66..638ecea589c 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt @@ -195,6 +195,8 @@ class LazyJavaClassDescriptor( emptyList() } + override fun getInlineClassRepresentation(): InlineClassRepresentation? = null + override fun toString() = "Lazy Java class ${this.fqNameUnsafe}" private inner class LazyJavaClassTypeConstructor : AbstractClassTypeConstructor(c.storageManager) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt index 6260b799b20..18b1eb67629 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassDescriptor.kt @@ -18,7 +18,6 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner -import java.util.* /** * A [ClassDescriptor] representing the fictitious class for a function type, such as kotlin.Function1 or kotlin.reflect.KFunction2. @@ -88,6 +87,7 @@ class FunctionClassDescriptor( override val annotations: Annotations get() = Annotations.EMPTY override fun getSource(): SourceElement = SourceElement.NO_SOURCE override fun getSealedSubclasses() = emptyList() + override fun getInlineClassRepresentation(): InlineClassRepresentation? = null override fun getDeclaredTypeParameters() = parameters diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/ClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/ClassDescriptor.java index 1dc500cd374..f3960d40ab7 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/ClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/ClassDescriptor.java @@ -97,6 +97,9 @@ public interface ClassDescriptor extends ClassifierDescriptorWithTypeParameters, @NotNull Collection getSealedSubclasses(); + @Nullable + InlineClassRepresentation getInlineClassRepresentation(); + @NotNull @Override ClassDescriptor getOriginal(); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/NotFoundClasses.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/NotFoundClasses.kt index 13aae6577c1..3bccebad2d5 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/NotFoundClasses.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/NotFoundClasses.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.ClassTypeConstructorImpl +import org.jetbrains.kotlin.types.SimpleType import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner @@ -83,6 +84,7 @@ class NotFoundClasses(private val storageManager: StorageManager, private val mo override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor? = null override fun getCompanionObjectDescriptor(): ClassDescriptor? = null override fun getSealedSubclasses(): Collection = emptyList() + override fun getInlineClassRepresentation(): InlineClassRepresentation? = null override fun toString() = "class $name (not found)" } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorImpl.java index b6ff4a1a21f..e0abf5dace8 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorImpl.java @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.storage.StorageManager; import org.jetbrains.kotlin.types.ClassTypeConstructorImpl; import org.jetbrains.kotlin.types.KotlinType; +import org.jetbrains.kotlin.types.SimpleType; import org.jetbrains.kotlin.types.TypeConstructor; import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner; @@ -174,4 +175,10 @@ public class ClassDescriptorImpl extends ClassDescriptorBase { public Collection getSealedSubclasses() { return Collections.emptyList(); } + + @Nullable + @Override + public InlineClassRepresentation getInlineClassRepresentation() { + return null; + } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java index 32340869521..aa56db0ccb3 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.storage.NotNullLazyValue; import org.jetbrains.kotlin.storage.StorageManager; import org.jetbrains.kotlin.types.ClassTypeConstructorImpl; import org.jetbrains.kotlin.types.KotlinType; +import org.jetbrains.kotlin.types.SimpleType; import org.jetbrains.kotlin.types.TypeConstructor; import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner; import org.jetbrains.kotlin.utils.Printer; @@ -192,6 +193,12 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase { return Collections.emptyList(); } + @Nullable + @Override + public InlineClassRepresentation getInlineClassRepresentation() { + return null; + } + private class EnumEntryScope extends MemberScopeImpl { private final MemoizedFunctionToNotNull> functions; private final MemoizedFunctionToNotNull> properties; diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java index b16b085e013..8a607926df1 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/LazySubstitutingClassDescriptor.java @@ -314,10 +314,25 @@ public class LazySubstitutingClassDescriptor extends ModuleAwareClassDescriptor return original.getSealedSubclasses(); } + @Nullable + @Override + public InlineClassRepresentation getInlineClassRepresentation() { + InlineClassRepresentation representation = original.getInlineClassRepresentation(); + //noinspection ConstantConditions + return representation == null ? null : new InlineClassRepresentation( + representation.getUnderlyingPropertyName(), + substituteSimpleType(getInlineClassRepresentation().getUnderlyingType()) + ); + } + @Nullable @Override public SimpleType getDefaultFunctionTypeForSamInterface() { - SimpleType type = original.getDefaultFunctionTypeForSamInterface(); + return substituteSimpleType(original.getDefaultFunctionTypeForSamInterface()); + } + + @Nullable + private SimpleType substituteSimpleType(@Nullable SimpleType type) { if (type == null || originalSubstitutor.isEmpty()) return type; TypeSubstitutor substitutor = getSubstitutor(); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java index de5fbac9c3a..487321378e6 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java @@ -189,6 +189,12 @@ public class MutableClassDescriptor extends ClassDescriptorBase { return Collections.emptyList(); } + @Nullable + @Override + public InlineClassRepresentation getInlineClassRepresentation() { + return null; + } + @Override public String toString() { return DeclarationDescriptorImpl.toString(this); diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index 1f9be75662b..8ddaeabcbf3 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -15,10 +15,7 @@ import org.jetbrains.kotlin.incremental.record import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.* import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.DescriptorFactory -import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy -import org.jetbrains.kotlin.resolve.OverridingUtil -import org.jetbrains.kotlin.resolve.CliSealedClassInheritorsProvider +import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -68,6 +65,7 @@ class DeserializedClassDescriptor( private val constructors = c.storageManager.createLazyValue { computeConstructors() } private val companionObjectDescriptor = c.storageManager.createNullableLazyValue { computeCompanionObjectDescriptor() } private val sealedSubclasses = c.storageManager.createLazyValue { computeSubclassesForSealedClass() } + private val inlineClassRepresentation = c.storageManager.createNullableLazyValue { computeInlineClassRepresentation() } internal val thisAsProtoContainer: ProtoContainer.Class = ProtoContainer.Class( classProto, c.nameResolver, c.typeTable, sourceElement, @@ -170,6 +168,35 @@ class DeserializedClassDescriptor( override fun getSealedSubclasses() = sealedSubclasses() + override fun getInlineClassRepresentation(): InlineClassRepresentation? = inlineClassRepresentation() + + private fun computeInlineClassRepresentation(): InlineClassRepresentation? { + if (!isInlineClass()) return null + + val propertyName = when { + classProto.hasInlineClassUnderlyingPropertyName() -> + c.nameResolver.getName(classProto.inlineClassUnderlyingPropertyName) + !metadataVersion.isAtLeast(1, 5, 1) -> { + // Before 1.5, inline classes did not have underlying property name & type in the metadata. + // However, they were experimental, so supposedly this logic can be removed at some point in the future. + val constructor = unsubstitutedPrimaryConstructor ?: error("Inline class has no primary constructor: $this") + constructor.valueParameters.first().name + } + else -> error("Inline class has no underlying property name in metadata: $this") + } + + val type = classProto.inlineClassUnderlyingType(c.typeTable)?.let(c.typeDeserializer::simpleType) + ?: run { + val underlyingProperty = + memberScope.getContributedVariables(propertyName, NoLookupLocation.FROM_DESERIALIZATION) + .singleOrNull { it.extensionReceiverParameter == null } + ?: error("Inline class has no underlying property: $this") + underlyingProperty.type as SimpleType + } + + return InlineClassRepresentation(propertyName, type) + } + override fun toString() = "deserialized ${if (isExpect) "expect " else ""}class $name" // not using descriptor renderer to preserve laziness diff --git a/idea/idea-fir-fe10-binding/src/org/jetbrains/kotlin/idea/fir/fe10/BaseDescriptorsWrappers.kt b/idea/idea-fir-fe10-binding/src/org/jetbrains/kotlin/idea/fir/fe10/BaseDescriptorsWrappers.kt index 42927ecb06a..14418da84e7 100644 --- a/idea/idea-fir-fe10-binding/src/org/jetbrains/kotlin/idea/fir/fe10/BaseDescriptorsWrappers.kt +++ b/idea/idea-fir-fe10-binding/src/org/jetbrains/kotlin/idea/fir/fe10/BaseDescriptorsWrappers.kt @@ -222,6 +222,8 @@ class KtSymbolBasedClassDescriptor(override val ktSymbol: KtNamedClassOrObjectSy override fun getSealedSubclasses(): Collection = implementationPostponed() + override fun getInlineClassRepresentation(): InlineClassRepresentation = TODO("Not yet implemented") + override fun getMemberScope(typeArguments: MutableList): MemberScope = noImplementation() override fun getMemberScope(typeSubstitution: TypeSubstitution): MemberScope = noImplementation() override fun getUnsubstitutedMemberScope(): MemberScope = noImplementation() diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 18c5d600f3d..c8f849e3aea 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -4470,6 +4470,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/defaultWithInlineClassAndReceivers.kt"); } + @TestMetadata("extensionPropertyWithSameName.kt") + public void testExtensionPropertyWithSameName() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/extensionPropertyWithSameName.kt"); + } + @TestMetadata("funInterface.kt") public void testFunInterface() throws Exception { runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/funInterface.kt");