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.
This commit is contained in:
Alexander Udalov
2021-03-23 12:58:53 +01:00
parent 6aaff9dfb7
commit 7fb3f48c67
22 changed files with 214 additions and 11 deletions
@@ -6731,6 +6731,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/defaultWithInlineClassAndReceivers.kt"); 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 @Test
@TestMetadata("funInterface.kt") @TestMetadata("funInterface.kt")
public void testFunInterface() throws Exception { public void testFunInterface() throws Exception {
@@ -6824,6 +6830,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/defaultWithInlineClassAndReceivers.kt"); 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 @Test
@TestMetadata("inlineClassFakeOverrideMangling.kt") @TestMetadata("inlineClassFakeOverrideMangling.kt")
public void testInlineClassFakeOverrideMangling() throws Exception { public void testInlineClassFakeOverrideMangling() throws Exception {
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.AbstractClassTypeConstructor import org.jetbrains.kotlin.types.AbstractClassTypeConstructor
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
@@ -93,6 +94,7 @@ class SyntheticClassOrObjectDescriptor(
override fun getStaticScope() = MemberScope.Empty override fun getStaticScope() = MemberScope.Empty
override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner) = unsubstitutedMemberScope override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner) = unsubstitutedMemberScope
override fun getSealedSubclasses() = emptyList<ClassDescriptor>() override fun getSealedSubclasses() = emptyList<ClassDescriptor>()
override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? = null
init { init {
assert(modality != Modality.SEALED) { "Implement getSealedSubclasses() for this class: ${this::class.java}" } assert(modality != Modality.SEALED) { "Implement getSealedSubclasses() for this class: ${this::class.java}" }
@@ -22,14 +22,12 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation; import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt; import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt; import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor; import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil; import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
import org.jetbrains.kotlin.resolve.lazy.LazyClassContext; import org.jetbrains.kotlin.resolve.lazy.LazyClassContext;
import org.jetbrains.kotlin.resolve.lazy.LazyEntity; import org.jetbrains.kotlin.resolve.lazy.LazyEntity;
@@ -581,6 +579,25 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
return sealedSubclasses.invoke(); return sealedSubclasses.invoke();
} }
@Nullable
@Override
public InlineClassRepresentation<SimpleType> 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 @Override
public String toString() { public String toString() {
// not using DescriptorRenderer to preserve laziness // not using DescriptorRenderer to preserve laziness
@@ -615,6 +615,8 @@ open class IrBasedClassDescriptor(owner: IrClass) : ClassDescriptor, IrBasedDecl
TODO("not implemented") TODO("not implemented")
} }
override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? = TODO("not implemented")
override fun getOriginal() = this override fun getOriginal() = this
override fun isExpect() = false override fun isExpect() = false
@@ -739,6 +741,8 @@ open class IrBasedEnumEntryDescriptor(owner: IrEnumEntry) : ClassDescriptor, IrB
TODO("not implemented") TODO("not implemented")
} }
override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? = TODO("not implemented")
override fun getOriginal() = this override fun getOriginal() = this
override fun isExpect() = false override fun isExpect() = false
@@ -1157,4 +1161,4 @@ private fun IrSimpleFunctionSymbol.toIrBasedDescriptorIfPossible(): FunctionDesc
@OptIn(ObsoleteDescriptorBasedAPI::class) @OptIn(ObsoleteDescriptorBasedAPI::class)
private fun IrPropertySymbol.toIrBasedDescriptorIfPossible(): PropertyDescriptor = private fun IrPropertySymbol.toIrBasedDescriptorIfPossible(): PropertyDescriptor =
if (isBound) owner.toIrBasedDescriptor() else descriptor if (isBound) owner.toIrBasedDescriptor() else descriptor
@@ -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 }
@@ -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 }
@@ -6731,6 +6731,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/defaultWithInlineClassAndReceivers.kt"); 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 @Test
@TestMetadata("funInterface.kt") @TestMetadata("funInterface.kt")
public void testFunInterface() throws Exception { public void testFunInterface() throws Exception {
@@ -6824,6 +6830,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/defaultWithInlineClassAndReceivers.kt"); 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 @Test
@TestMetadata("inlineClassFakeOverrideMangling.kt") @TestMetadata("inlineClassFakeOverrideMangling.kt")
public void testInlineClassFakeOverrideMangling() throws Exception { public void testInlineClassFakeOverrideMangling() throws Exception {
@@ -6731,6 +6731,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/defaultWithInlineClassAndReceivers.kt"); 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 @Test
@TestMetadata("funInterface.kt") @TestMetadata("funInterface.kt")
public void testFunInterface() throws Exception { public void testFunInterface() throws Exception {
@@ -6824,6 +6830,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/defaultWithInlineClassAndReceivers.kt"); 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 @Test
@TestMetadata("inlineClassFakeOverrideMangling.kt") @TestMetadata("inlineClassFakeOverrideMangling.kt")
public void testInlineClassFakeOverrideMangling() throws Exception { public void testInlineClassFakeOverrideMangling() throws Exception {
@@ -518,6 +518,12 @@ public class JvmIrAgainstOldBoxTestGenerated extends AbstractJvmIrAgainstOldBoxT
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/defaultWithInlineClassAndReceivers.kt"); 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 @Test
@TestMetadata("funInterface.kt") @TestMetadata("funInterface.kt")
public void testFunInterface() throws Exception { public void testFunInterface() throws Exception {
@@ -611,6 +617,12 @@ public class JvmIrAgainstOldBoxTestGenerated extends AbstractJvmIrAgainstOldBoxT
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/defaultWithInlineClassAndReceivers.kt"); 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 @Test
@TestMetadata("inlineClassFakeOverrideMangling.kt") @TestMetadata("inlineClassFakeOverrideMangling.kt")
public void testInlineClassFakeOverrideMangling() throws Exception { public void testInlineClassFakeOverrideMangling() throws Exception {
@@ -518,6 +518,12 @@ public class JvmOldAgainstIrBoxTestGenerated extends AbstractJvmOldAgainstIrBoxT
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/defaultWithInlineClassAndReceivers.kt"); 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 @Test
@TestMetadata("funInterface.kt") @TestMetadata("funInterface.kt")
public void testFunInterface() throws Exception { public void testFunInterface() throws Exception {
@@ -611,6 +617,12 @@ public class JvmOldAgainstIrBoxTestGenerated extends AbstractJvmOldAgainstIrBoxT
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/defaultWithInlineClassAndReceivers.kt"); 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 @Test
@TestMetadata("inlineClassFakeOverrideMangling.kt") @TestMetadata("inlineClassFakeOverrideMangling.kt")
public void testInlineClassFakeOverrideMangling() throws Exception { public void testInlineClassFakeOverrideMangling() throws Exception {
@@ -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<Type : SimpleTypeMarker>(
val underlyingPropertyName: Name,
val underlyingType: Type,
)
@@ -195,6 +195,8 @@ class LazyJavaClassDescriptor(
emptyList() emptyList()
} }
override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? = null
override fun toString() = "Lazy Java class ${this.fqNameUnsafe}" override fun toString() = "Lazy Java class ${this.fqNameUnsafe}"
private inner class LazyJavaClassTypeConstructor : AbstractClassTypeConstructor(c.storageManager) { private inner class LazyJavaClassTypeConstructor : AbstractClassTypeConstructor(c.storageManager) {
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner 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. * 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 val annotations: Annotations get() = Annotations.EMPTY
override fun getSource(): SourceElement = SourceElement.NO_SOURCE override fun getSource(): SourceElement = SourceElement.NO_SOURCE
override fun getSealedSubclasses() = emptyList<ClassDescriptor>() override fun getSealedSubclasses() = emptyList<ClassDescriptor>()
override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? = null
override fun getDeclaredTypeParameters() = parameters override fun getDeclaredTypeParameters() = parameters
@@ -97,6 +97,9 @@ public interface ClassDescriptor extends ClassifierDescriptorWithTypeParameters,
@NotNull @NotNull
Collection<ClassDescriptor> getSealedSubclasses(); Collection<ClassDescriptor> getSealedSubclasses();
@Nullable
InlineClassRepresentation<SimpleType> getInlineClassRepresentation();
@NotNull @NotNull
@Override @Override
ClassDescriptor getOriginal(); ClassDescriptor getOriginal();
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.ClassTypeConstructorImpl import org.jetbrains.kotlin.types.ClassTypeConstructorImpl
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner 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 getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor? = null
override fun getCompanionObjectDescriptor(): ClassDescriptor? = null override fun getCompanionObjectDescriptor(): ClassDescriptor? = null
override fun getSealedSubclasses(): Collection<ClassDescriptor> = emptyList() override fun getSealedSubclasses(): Collection<ClassDescriptor> = emptyList()
override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? = null
override fun toString() = "class $name (not found)" override fun toString() = "class $name (not found)"
} }
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope;
import org.jetbrains.kotlin.storage.StorageManager; import org.jetbrains.kotlin.storage.StorageManager;
import org.jetbrains.kotlin.types.ClassTypeConstructorImpl; import org.jetbrains.kotlin.types.ClassTypeConstructorImpl;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.SimpleType;
import org.jetbrains.kotlin.types.TypeConstructor; import org.jetbrains.kotlin.types.TypeConstructor;
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner; import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner;
@@ -174,4 +175,10 @@ public class ClassDescriptorImpl extends ClassDescriptorBase {
public Collection<ClassDescriptor> getSealedSubclasses() { public Collection<ClassDescriptor> getSealedSubclasses() {
return Collections.emptyList(); return Collections.emptyList();
} }
@Nullable
@Override
public InlineClassRepresentation<SimpleType> getInlineClassRepresentation() {
return null;
}
} }
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.storage.NotNullLazyValue;
import org.jetbrains.kotlin.storage.StorageManager; import org.jetbrains.kotlin.storage.StorageManager;
import org.jetbrains.kotlin.types.ClassTypeConstructorImpl; import org.jetbrains.kotlin.types.ClassTypeConstructorImpl;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.SimpleType;
import org.jetbrains.kotlin.types.TypeConstructor; import org.jetbrains.kotlin.types.TypeConstructor;
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner; import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner;
import org.jetbrains.kotlin.utils.Printer; import org.jetbrains.kotlin.utils.Printer;
@@ -192,6 +193,12 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
return Collections.emptyList(); return Collections.emptyList();
} }
@Nullable
@Override
public InlineClassRepresentation<SimpleType> getInlineClassRepresentation() {
return null;
}
private class EnumEntryScope extends MemberScopeImpl { private class EnumEntryScope extends MemberScopeImpl {
private final MemoizedFunctionToNotNull<Name, Collection<? extends SimpleFunctionDescriptor>> functions; private final MemoizedFunctionToNotNull<Name, Collection<? extends SimpleFunctionDescriptor>> functions;
private final MemoizedFunctionToNotNull<Name, Collection<? extends PropertyDescriptor>> properties; private final MemoizedFunctionToNotNull<Name, Collection<? extends PropertyDescriptor>> properties;
@@ -314,10 +314,25 @@ public class LazySubstitutingClassDescriptor extends ModuleAwareClassDescriptor
return original.getSealedSubclasses(); return original.getSealedSubclasses();
} }
@Nullable
@Override
public InlineClassRepresentation<SimpleType> getInlineClassRepresentation() {
InlineClassRepresentation<SimpleType> representation = original.getInlineClassRepresentation();
//noinspection ConstantConditions
return representation == null ? null : new InlineClassRepresentation<SimpleType>(
representation.getUnderlyingPropertyName(),
substituteSimpleType(getInlineClassRepresentation().getUnderlyingType())
);
}
@Nullable @Nullable
@Override @Override
public SimpleType getDefaultFunctionTypeForSamInterface() { 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; if (type == null || originalSubstitutor.isEmpty()) return type;
TypeSubstitutor substitutor = getSubstitutor(); TypeSubstitutor substitutor = getSubstitutor();
@@ -189,6 +189,12 @@ public class MutableClassDescriptor extends ClassDescriptorBase {
return Collections.emptyList(); return Collections.emptyList();
} }
@Nullable
@Override
public InlineClassRepresentation<SimpleType> getInlineClassRepresentation() {
return null;
}
@Override @Override
public String toString() { public String toString() {
return DeclarationDescriptorImpl.toString(this); return DeclarationDescriptorImpl.toString(this);
@@ -15,10 +15,7 @@ import org.jetbrains.kotlin.incremental.record
import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.* import org.jetbrains.kotlin.metadata.deserialization.*
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorFactory import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.CliSealedClassInheritorsProvider
import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.MemberScope
@@ -68,6 +65,7 @@ class DeserializedClassDescriptor(
private val constructors = c.storageManager.createLazyValue { computeConstructors() } private val constructors = c.storageManager.createLazyValue { computeConstructors() }
private val companionObjectDescriptor = c.storageManager.createNullableLazyValue { computeCompanionObjectDescriptor() } private val companionObjectDescriptor = c.storageManager.createNullableLazyValue { computeCompanionObjectDescriptor() }
private val sealedSubclasses = c.storageManager.createLazyValue { computeSubclassesForSealedClass() } private val sealedSubclasses = c.storageManager.createLazyValue { computeSubclassesForSealedClass() }
private val inlineClassRepresentation = c.storageManager.createNullableLazyValue { computeInlineClassRepresentation() }
internal val thisAsProtoContainer: ProtoContainer.Class = ProtoContainer.Class( internal val thisAsProtoContainer: ProtoContainer.Class = ProtoContainer.Class(
classProto, c.nameResolver, c.typeTable, sourceElement, classProto, c.nameResolver, c.typeTable, sourceElement,
@@ -170,6 +168,35 @@ class DeserializedClassDescriptor(
override fun getSealedSubclasses() = sealedSubclasses() override fun getSealedSubclasses() = sealedSubclasses()
override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? = inlineClassRepresentation()
private fun computeInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? {
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() = override fun toString() =
"deserialized ${if (isExpect) "expect " else ""}class $name" // not using descriptor renderer to preserve laziness "deserialized ${if (isExpect) "expect " else ""}class $name" // not using descriptor renderer to preserve laziness
@@ -222,6 +222,8 @@ class KtSymbolBasedClassDescriptor(override val ktSymbol: KtNamedClassOrObjectSy
override fun getSealedSubclasses(): Collection<ClassDescriptor> = implementationPostponed() override fun getSealedSubclasses(): Collection<ClassDescriptor> = implementationPostponed()
override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType> = TODO("Not yet implemented")
override fun getMemberScope(typeArguments: MutableList<out TypeProjection>): MemberScope = noImplementation() override fun getMemberScope(typeArguments: MutableList<out TypeProjection>): MemberScope = noImplementation()
override fun getMemberScope(typeSubstitution: TypeSubstitution): MemberScope = noImplementation() override fun getMemberScope(typeSubstitution: TypeSubstitution): MemberScope = noImplementation()
override fun getUnsubstitutedMemberScope(): MemberScope = noImplementation() override fun getUnsubstitutedMemberScope(): MemberScope = noImplementation()
@@ -4470,6 +4470,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/defaultWithInlineClassAndReceivers.kt"); 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") @TestMetadata("funInterface.kt")
public void testFunInterface() throws Exception { public void testFunInterface() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/funInterface.kt"); runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/funInterface.kt");