Use new getInlineClassRepresentation in some utilities
This commit is contained in:
@@ -12,6 +12,7 @@ import kotlin.Unit;
|
|||||||
import kotlin.collections.CollectionsKt;
|
import kotlin.collections.CollectionsKt;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.kotlin.backend.common.SamType;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||||
import org.jetbrains.kotlin.codegen.context.ClosureContext;
|
import org.jetbrains.kotlin.codegen.context.ClosureContext;
|
||||||
@@ -31,7 +32,6 @@ import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
|
|||||||
import org.jetbrains.kotlin.metadata.ProtoBuf;
|
import org.jetbrains.kotlin.metadata.ProtoBuf;
|
||||||
import org.jetbrains.kotlin.psi.KtElement;
|
import org.jetbrains.kotlin.psi.KtElement;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||||
@@ -40,7 +40,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
|
|||||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
import org.jetbrains.kotlin.types.SimpleType;
|
import org.jetbrains.kotlin.types.SimpleType;
|
||||||
import org.jetbrains.kotlin.backend.common.SamType;
|
import org.jetbrains.kotlin.types.TypeUtils;
|
||||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
|
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
@@ -376,10 +376,12 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
|||||||
value = StackValue.local(slot, type, bridgeParameterKotlinTypes.get(i));
|
value = StackValue.local(slot, type, bridgeParameterKotlinTypes.get(i));
|
||||||
slot += type.getSize();
|
slot += type.getSize();
|
||||||
}
|
}
|
||||||
if (InlineClassesCodegenUtilKt.isInlineClassWithUnderlyingTypeAnyOrAnyN(parameterType) &&
|
if (InlineClassesCodegenUtilKt.isInlineClassWithUnderlyingTypeAnyOrAnyN(parameterType) && functionReferenceCall == null) {
|
||||||
functionReferenceCall == null
|
ClassDescriptor descriptor = TypeUtils.getClassDescriptor(parameterType);
|
||||||
) {
|
InlineClassRepresentation<SimpleType> representation =
|
||||||
parameterType = InlineClassesUtilsKt.unsubstitutedUnderlyingParameter(parameterType).getType();
|
descriptor != null ? descriptor.getInlineClassRepresentation() : null;
|
||||||
|
assert representation != null : "Not an inline class type: " + parameterType;
|
||||||
|
parameterType = representation.getUnderlyingType();
|
||||||
}
|
}
|
||||||
value.put(typeMapper.mapType(calleeParameter), parameterType, iv);
|
value.put(typeMapper.mapType(calleeParameter), parameterType, iv);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class ErasedInlineClassBodyCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateUnboxMethod() {
|
private fun generateUnboxMethod() {
|
||||||
val boxMethodDescriptor = InlineClassDescriptorResolver.createBoxFunctionDescriptor(descriptor) ?: return
|
val boxMethodDescriptor = InlineClassDescriptorResolver.createBoxFunctionDescriptor(descriptor)
|
||||||
|
|
||||||
functionCodegen.generateMethod(
|
functionCodegen.generateMethod(
|
||||||
Synthetic(null, boxMethodDescriptor), boxMethodDescriptor, object : FunctionGenerationStrategy.CodegenBased(state) {
|
Synthetic(null, boxMethodDescriptor), boxMethodDescriptor, object : FunctionGenerationStrategy.CodegenBased(state) {
|
||||||
@@ -103,7 +103,7 @@ class ErasedInlineClassBodyCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateSpecializedEqualsStub() {
|
private fun generateSpecializedEqualsStub() {
|
||||||
val specializedEqualsDescriptor = InlineClassDescriptorResolver.createSpecializedEqualsDescriptor(descriptor) ?: return
|
val specializedEqualsDescriptor = InlineClassDescriptorResolver.createSpecializedEqualsDescriptor(descriptor)
|
||||||
|
|
||||||
functionCodegen.generateMethod(
|
functionCodegen.generateMethod(
|
||||||
Synthetic(null, specializedEqualsDescriptor), specializedEqualsDescriptor, object : FunctionGenerationStrategy.CodegenBased(state) {
|
Synthetic(null, specializedEqualsDescriptor), specializedEqualsDescriptor, object : FunctionGenerationStrategy.CodegenBased(state) {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import kotlin.text.StringsKt;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||||
|
import org.jetbrains.kotlin.backend.common.SamType;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||||
@@ -92,7 +93,6 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker;
|
|||||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker;
|
import org.jetbrains.kotlin.types.model.TypeParameterMarker;
|
||||||
import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt;
|
import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt;
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||||
import org.jetbrains.kotlin.backend.common.SamType;
|
|
||||||
import org.jetbrains.org.objectweb.asm.Label;
|
import org.jetbrains.org.objectweb.asm.Label;
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||||
@@ -2024,10 +2024,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
// Do not unbox parameters of suspend lambda, they are unboxed in `invoke` method
|
// Do not unbox parameters of suspend lambda, they are unboxed in `invoke` method
|
||||||
!CoroutineCodegenUtilKt.isInvokeSuspendOfLambda(context.getFunctionDescriptor())
|
!CoroutineCodegenUtilKt.isInvokeSuspendOfLambda(context.getFunctionDescriptor())
|
||||||
) {
|
) {
|
||||||
KotlinType underlyingType = InlineClassesUtilsKt.underlyingRepresentation(
|
ClassDescriptor inlineClass = (ClassDescriptor) inlineClassType.getConstructor().getDeclarationDescriptor();
|
||||||
(ClassDescriptor) inlineClassType.getConstructor().getDeclarationDescriptor()).getType();
|
InlineClassRepresentation<SimpleType> representation =
|
||||||
return StackValue.underlyingValueOfInlineClass(
|
inlineClass != null ? inlineClass.getInlineClassRepresentation() : null;
|
||||||
typeMapper.mapType(underlyingType), underlyingType, localOrCaptured);
|
assert representation != null : "Not an inline class: " + inlineClassType;
|
||||||
|
KotlinType underlyingType = representation.getUnderlyingType();
|
||||||
|
return StackValue.underlyingValueOfInlineClass(typeMapper.mapType(underlyingType), underlyingType, localOrCaptured);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return localOrCaptured;
|
return localOrCaptured;
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
|
import org.jetbrains.kotlin.types.SimpleType;
|
||||||
import org.jetbrains.kotlin.types.TypeUtils;
|
import org.jetbrains.kotlin.types.TypeUtils;
|
||||||
import org.jetbrains.org.objectweb.asm.Label;
|
import org.jetbrains.org.objectweb.asm.Label;
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
@@ -369,23 +370,22 @@ public class FunctionCodegen {
|
|||||||
public static void generateMethodInsideInlineClassWrapper(
|
public static void generateMethodInsideInlineClassWrapper(
|
||||||
@NotNull JvmDeclarationOrigin origin,
|
@NotNull JvmDeclarationOrigin origin,
|
||||||
@NotNull FunctionDescriptor functionDescriptor,
|
@NotNull FunctionDescriptor functionDescriptor,
|
||||||
@NotNull ClassDescriptor containingDeclaration,
|
@NotNull ClassDescriptor inlineClass,
|
||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
@NotNull KotlinTypeMapper typeMapper
|
@NotNull KotlinTypeMapper typeMapper
|
||||||
) {
|
) {
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
|
||||||
Type fieldOwnerType = typeMapper.mapClass(containingDeclaration);
|
Type fieldOwnerType = typeMapper.mapClass(inlineClass);
|
||||||
Method erasedMethodImpl = typeMapper.mapAsmMethod(functionDescriptor.getOriginal(), OwnerKind.ERASED_INLINE_CLASS);
|
Method erasedMethodImpl = typeMapper.mapAsmMethod(functionDescriptor.getOriginal(), OwnerKind.ERASED_INLINE_CLASS);
|
||||||
|
|
||||||
ValueParameterDescriptor valueRepresentation = InlineClassesUtilsKt.underlyingRepresentation(containingDeclaration);
|
InlineClassRepresentation<SimpleType> representation = inlineClass.getInlineClassRepresentation();
|
||||||
if (valueRepresentation == null) return;
|
assert representation != null : "Not an inline class: " + inlineClass;
|
||||||
|
|
||||||
Type fieldType = typeMapper.mapType(valueRepresentation);
|
|
||||||
|
|
||||||
generateDelegateToStaticErasedVersion(
|
generateDelegateToStaticErasedVersion(
|
||||||
mv, erasedMethodImpl,
|
mv, erasedMethodImpl, fieldOwnerType,
|
||||||
fieldOwnerType, valueRepresentation.getName().asString(), fieldType
|
representation.getUnderlyingPropertyName().asString(),
|
||||||
|
typeMapper.mapType(representation.getUnderlyingType())
|
||||||
);
|
);
|
||||||
|
|
||||||
endVisit(mv, null, origin.getElement());
|
endVisit(mv, null, origin.getElement());
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
|
import org.jetbrains.kotlin.types.SimpleType;
|
||||||
import org.jetbrains.org.objectweb.asm.FieldVisitor;
|
import org.jetbrains.org.objectweb.asm.FieldVisitor;
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
@@ -274,26 +275,25 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
@Override
|
@Override
|
||||||
protected void generateUnboxMethodForInlineClass() {
|
protected void generateUnboxMethodForInlineClass() {
|
||||||
if (!(myClass instanceof KtClass)) return;
|
if (!(myClass instanceof KtClass)) return;
|
||||||
if (!InlineClassesUtilsKt.isInlineClass(descriptor)) return;
|
InlineClassRepresentation<SimpleType> inlineClassRepresentation = descriptor.getInlineClassRepresentation();
|
||||||
|
if (inlineClassRepresentation == null) return;
|
||||||
|
|
||||||
Type ownerType = typeMapper.mapClass(descriptor);
|
Type ownerType = typeMapper.mapClass(descriptor);
|
||||||
ValueParameterDescriptor inlinedValue = InlineClassesUtilsKt.underlyingRepresentation(this.descriptor);
|
Type valueType = typeMapper.mapType(inlineClassRepresentation.getUnderlyingType());
|
||||||
if (inlinedValue == null) return;
|
|
||||||
|
|
||||||
Type valueType = typeMapper.mapType(inlinedValue.getType());
|
|
||||||
SimpleFunctionDescriptor functionDescriptor = InlineClassDescriptorResolver.createUnboxFunctionDescriptor(this.descriptor);
|
SimpleFunctionDescriptor functionDescriptor = InlineClassDescriptorResolver.createUnboxFunctionDescriptor(this.descriptor);
|
||||||
assert functionDescriptor != null : "FunctionDescriptor for unbox method should be not null during codegen";
|
|
||||||
|
|
||||||
functionCodegen.generateMethod(
|
functionCodegen.generateMethod(
|
||||||
JvmDeclarationOriginKt.UnboxMethodOfInlineClass(functionDescriptor), functionDescriptor,
|
JvmDeclarationOriginKt.UnboxMethodOfInlineClass(functionDescriptor), functionDescriptor,
|
||||||
new FunctionGenerationStrategy.CodegenBased(state) {
|
new FunctionGenerationStrategy.CodegenBased(state) {
|
||||||
@Override
|
@Override
|
||||||
public void doGenerateBody(
|
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||||
@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature
|
|
||||||
) {
|
|
||||||
InstructionAdapter iv = codegen.v;
|
InstructionAdapter iv = codegen.v;
|
||||||
iv.load(0, OBJECT_TYPE);
|
iv.load(0, OBJECT_TYPE);
|
||||||
iv.getfield(ownerType.getInternalName(), inlinedValue.getName().asString(), valueType.getDescriptor());
|
iv.getfield(
|
||||||
|
ownerType.getInternalName(),
|
||||||
|
inlineClassRepresentation.getUnderlyingPropertyName().asString(),
|
||||||
|
valueType.getDescriptor()
|
||||||
|
);
|
||||||
iv.areturn(valueType);
|
iv.areturn(valueType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
|||||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
|
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
import org.jetbrains.kotlin.resolve.isInlineClassType
|
|
||||||
import org.jetbrains.kotlin.resolve.underlyingRepresentation
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -26,9 +24,8 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
|||||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||||
|
|
||||||
fun KotlinType.isInlineClassWithUnderlyingTypeAnyOrAnyN(): Boolean {
|
fun KotlinType.isInlineClassWithUnderlyingTypeAnyOrAnyN(): Boolean {
|
||||||
if (!isInlineClassType()) return false
|
val classDescriptor = constructor.declarationDescriptor
|
||||||
val classDescriptor = constructor.declarationDescriptor as? ClassDescriptor ?: return false
|
return classDescriptor is ClassDescriptor && classDescriptor.inlineClassRepresentation?.underlyingType?.isAnyOrNullableAny() == true
|
||||||
return classDescriptor.underlyingRepresentation()?.type?.isAnyOrNullableAny() == true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CallableDescriptor.isGenericParameter(): Boolean {
|
fun CallableDescriptor.isGenericParameter(): Boolean {
|
||||||
@@ -79,4 +76,4 @@ fun classFileContainsMethod(classId: ClassId, state: GenerationState, method: Me
|
|||||||
}
|
}
|
||||||
}, ClassReader.SKIP_FRAMES)
|
}, ClassReader.SKIP_FRAMES)
|
||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-40
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
object InlineClassDescriptorResolver {
|
object InlineClassDescriptorResolver {
|
||||||
@JvmField
|
@JvmField
|
||||||
@@ -28,11 +29,11 @@ object InlineClassDescriptorResolver {
|
|||||||
val SPECIALIZED_EQUALS_SECOND_PARAMETER_NAME = Name.identifier("p2")
|
val SPECIALIZED_EQUALS_SECOND_PARAMETER_NAME = Name.identifier("p2")
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun createBoxFunctionDescriptor(owner: ClassDescriptor): SimpleFunctionDescriptor? =
|
fun createBoxFunctionDescriptor(owner: ClassDescriptor): SimpleFunctionDescriptor =
|
||||||
createConversionFunctionDescriptor(true, owner)
|
createConversionFunctionDescriptor(true, owner)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun createUnboxFunctionDescriptor(owner: ClassDescriptor): SimpleFunctionDescriptor? =
|
fun createUnboxFunctionDescriptor(owner: ClassDescriptor): SimpleFunctionDescriptor =
|
||||||
createConversionFunctionDescriptor(false, owner)
|
createConversionFunctionDescriptor(false, owner)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@@ -57,9 +58,7 @@ object InlineClassDescriptorResolver {
|
|||||||
private fun isSynthesizedInlineClassMember(descriptor: CallableMemberDescriptor) =
|
private fun isSynthesizedInlineClassMember(descriptor: CallableMemberDescriptor) =
|
||||||
descriptor.kind == CallableMemberDescriptor.Kind.SYNTHESIZED && descriptor.containingDeclaration.isInlineClass()
|
descriptor.kind == CallableMemberDescriptor.Kind.SYNTHESIZED && descriptor.containingDeclaration.isInlineClass()
|
||||||
|
|
||||||
fun createSpecializedEqualsDescriptor(owner: ClassDescriptor): SimpleFunctionDescriptor? {
|
fun createSpecializedEqualsDescriptor(owner: ClassDescriptor): SimpleFunctionDescriptor {
|
||||||
val inlinedValue = owner.underlyingRepresentation() ?: return null
|
|
||||||
|
|
||||||
val functionDescriptor = SimpleFunctionDescriptorImpl.create(
|
val functionDescriptor = SimpleFunctionDescriptorImpl.create(
|
||||||
owner,
|
owner,
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
@@ -72,7 +71,7 @@ object InlineClassDescriptorResolver {
|
|||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
emptyList<TypeParameterDescriptor>(),
|
emptyList<TypeParameterDescriptor>(),
|
||||||
createValueParametersForSpecializedEquals(functionDescriptor, inlinedValue),
|
createValueParametersForSpecializedEquals(functionDescriptor, owner.inlineClassRepresentation!!.underlyingType),
|
||||||
owner.builtIns.booleanType,
|
owner.builtIns.booleanType,
|
||||||
Modality.FINAL,
|
Modality.FINAL,
|
||||||
DescriptorVisibilities.PUBLIC
|
DescriptorVisibilities.PUBLIC
|
||||||
@@ -81,12 +80,7 @@ object InlineClassDescriptorResolver {
|
|||||||
return functionDescriptor
|
return functionDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createConversionFunctionDescriptor(
|
private fun createConversionFunctionDescriptor(isBoxMethod: Boolean, owner: ClassDescriptor): SimpleFunctionDescriptor {
|
||||||
isBoxMethod: Boolean,
|
|
||||||
owner: ClassDescriptor
|
|
||||||
): SimpleFunctionDescriptor? {
|
|
||||||
val inlinedValue = owner.underlyingRepresentation() ?: return null
|
|
||||||
|
|
||||||
val functionDescriptor = SimpleFunctionDescriptorImpl.create(
|
val functionDescriptor = SimpleFunctionDescriptorImpl.create(
|
||||||
owner,
|
owner,
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
@@ -95,12 +89,13 @@ object InlineClassDescriptorResolver {
|
|||||||
SourceElement.NO_SOURCE
|
SourceElement.NO_SOURCE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val underlyingType = owner.inlineClassRepresentation!!.underlyingType
|
||||||
functionDescriptor.initialize(
|
functionDescriptor.initialize(
|
||||||
null,
|
null,
|
||||||
if (isBoxMethod) null else owner.thisAsReceiverParameter,
|
if (isBoxMethod) null else owner.thisAsReceiverParameter,
|
||||||
emptyList<TypeParameterDescriptor>(),
|
emptyList<TypeParameterDescriptor>(),
|
||||||
if (isBoxMethod) listOf(createValueParameterForBoxing(functionDescriptor, inlinedValue)) else emptyList(),
|
if (isBoxMethod) listOf(createValueParameterForBoxing(functionDescriptor, underlyingType)) else emptyList(),
|
||||||
if (isBoxMethod) owner.defaultType else inlinedValue.returnType,
|
if (isBoxMethod) owner.defaultType else underlyingType,
|
||||||
Modality.FINAL,
|
Modality.FINAL,
|
||||||
DescriptorVisibilities.PUBLIC
|
DescriptorVisibilities.PUBLIC
|
||||||
)
|
)
|
||||||
@@ -109,36 +104,22 @@ object InlineClassDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createValueParameterForBoxing(
|
private fun createValueParameterForBoxing(
|
||||||
functionDescriptor: FunctionDescriptor,
|
functionDescriptor: FunctionDescriptor, underlyingType: KotlinType
|
||||||
inlinedValue: ValueParameterDescriptor
|
): ValueParameterDescriptorImpl =
|
||||||
): ValueParameterDescriptorImpl {
|
createValueParameter(functionDescriptor, underlyingType, BOXING_VALUE_PARAMETER_NAME, 0)
|
||||||
return createValueParameter(functionDescriptor, inlinedValue, BOXING_VALUE_PARAMETER_NAME, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createValueParametersForSpecializedEquals(
|
private fun createValueParametersForSpecializedEquals(
|
||||||
functionDescriptor: FunctionDescriptor,
|
functionDescriptor: FunctionDescriptor, underlyingType: KotlinType
|
||||||
inlinedValue: ValueParameterDescriptor
|
): List<ValueParameterDescriptor> =
|
||||||
): List<ValueParameterDescriptor> {
|
listOf(
|
||||||
return listOf(
|
createValueParameter(functionDescriptor, underlyingType, SPECIALIZED_EQUALS_FIRST_PARAMETER_NAME, 0),
|
||||||
createValueParameter(functionDescriptor, inlinedValue, SPECIALIZED_EQUALS_FIRST_PARAMETER_NAME, 0),
|
createValueParameter(functionDescriptor, underlyingType, SPECIALIZED_EQUALS_SECOND_PARAMETER_NAME, 1)
|
||||||
createValueParameter(functionDescriptor, inlinedValue, SPECIALIZED_EQUALS_SECOND_PARAMETER_NAME, 1)
|
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
private fun createValueParameter(
|
private fun createValueParameter(
|
||||||
functionDescriptor: FunctionDescriptor,
|
functionDescriptor: FunctionDescriptor, type: KotlinType, name: Name, index: Int
|
||||||
inlinedValue: ValueParameterDescriptor,
|
): ValueParameterDescriptorImpl =
|
||||||
name: Name,
|
ValueParameterDescriptorImpl(
|
||||||
index: Int
|
functionDescriptor, null, index, Annotations.EMPTY, name, type, false, false, false, null, SourceElement.NO_SOURCE
|
||||||
): ValueParameterDescriptorImpl {
|
|
||||||
return ValueParameterDescriptorImpl(
|
|
||||||
functionDescriptor,
|
|
||||||
null,
|
|
||||||
index,
|
|
||||||
Annotations.EMPTY,
|
|
||||||
name,
|
|
||||||
inlinedValue.type,
|
|
||||||
false, false, false, null, SourceElement.NO_SOURCE
|
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-6
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.resolve.constants.*
|
|||||||
import org.jetbrains.kotlin.resolve.constants.evaluate.CompileTimeType.*
|
import org.jetbrains.kotlin.resolve.constants.evaluate.CompileTimeType.*
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.SimpleType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
||||||
@@ -857,7 +858,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
classDescriptor.isInlineClass() && UnsignedTypes.isUnsignedClass(classDescriptor) ->
|
classDescriptor.isInlineClass() && UnsignedTypes.isUnsignedClass(classDescriptor) ->
|
||||||
createConstantValueForUnsignedTypeConstructor(call, resultingDescriptor, classDescriptor)
|
createConstantValueForUnsignedTypeConstructor(call, resultingDescriptor, classDescriptor.inlineClassRepresentation!!)
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -869,20 +870,17 @@ private class ConstantExpressionEvaluatorVisitor(
|
|||||||
private fun createConstantValueForUnsignedTypeConstructor(
|
private fun createConstantValueForUnsignedTypeConstructor(
|
||||||
call: ResolvedCall<*>,
|
call: ResolvedCall<*>,
|
||||||
constructorDescriptor: ConstructorDescriptor,
|
constructorDescriptor: ConstructorDescriptor,
|
||||||
classDescriptor: ClassDescriptor
|
representation: InlineClassRepresentation<SimpleType>,
|
||||||
): TypedCompileTimeConstant<*>? {
|
): TypedCompileTimeConstant<*>? {
|
||||||
assert(classDescriptor.isInlineClass()) { "Unsigned type should be an inline class type, but it is: $classDescriptor" }
|
|
||||||
|
|
||||||
if (!constructorDescriptor.isPrimary) return null
|
if (!constructorDescriptor.isPrimary) return null
|
||||||
|
|
||||||
val valueArguments = call.valueArguments
|
val valueArguments = call.valueArguments
|
||||||
if (valueArguments.size > 1) return null
|
if (valueArguments.size > 1) return null
|
||||||
|
|
||||||
val underlyingType = classDescriptor.underlyingRepresentation()?.type ?: return null
|
|
||||||
|
|
||||||
val argument = valueArguments.values.singleOrNull()?.arguments?.singleOrNull() ?: return null
|
val argument = valueArguments.values.singleOrNull()?.arguments?.singleOrNull() ?: return null
|
||||||
val argumentExpression = argument.getArgumentExpression() ?: return null
|
val argumentExpression = argument.getArgumentExpression() ?: return null
|
||||||
|
|
||||||
|
val underlyingType = representation.underlyingType
|
||||||
val compileTimeConstant = evaluate(argumentExpression, underlyingType)
|
val compileTimeConstant = evaluate(argumentExpression, underlyingType)
|
||||||
val evaluatedArgument = compileTimeConstant?.toConstantValue(underlyingType) ?: return null
|
val evaluatedArgument = compileTimeConstant?.toConstantValue(underlyingType) ?: return null
|
||||||
|
|
||||||
|
|||||||
+6
-5
@@ -165,17 +165,18 @@ class DescriptorSerializer private constructor(
|
|||||||
builder.typeTable = typeTableProto
|
builder.typeTable = typeTableProto
|
||||||
}
|
}
|
||||||
|
|
||||||
classDescriptor.underlyingRepresentation()?.let { parameter ->
|
val representation = classDescriptor.inlineClassRepresentation
|
||||||
builder.inlineClassUnderlyingPropertyName = getSimpleNameIndex(parameter.name)
|
if (representation != null) {
|
||||||
|
builder.inlineClassUnderlyingPropertyName = getSimpleNameIndex(representation.underlyingPropertyName)
|
||||||
|
|
||||||
val property = callableMembers.single {
|
val property = callableMembers.single {
|
||||||
it is PropertyDescriptor && it.extensionReceiverParameter == null && it.name == parameter.name
|
it is PropertyDescriptor && it.extensionReceiverParameter == null && it.name == representation.underlyingPropertyName
|
||||||
}
|
}
|
||||||
if (!property.visibility.isPublicAPI) {
|
if (!property.visibility.isPublicAPI) {
|
||||||
if (useTypeTable()) {
|
if (useTypeTable()) {
|
||||||
builder.inlineClassUnderlyingTypeId = typeId(parameter.type)
|
builder.inlineClassUnderlyingTypeId = typeId(representation.underlyingType)
|
||||||
} else {
|
} else {
|
||||||
builder.setInlineClassUnderlyingType(type(parameter.type))
|
builder.setInlineClassUnderlyingType(type(representation.underlyingType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
|||||||
|
|
||||||
val JVM_INLINE_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmInline")
|
val JVM_INLINE_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmInline")
|
||||||
|
|
||||||
fun ClassDescriptor.underlyingRepresentation(): ValueParameterDescriptor? {
|
private fun ClassDescriptor.underlyingRepresentation(): ValueParameterDescriptor? {
|
||||||
if (!isInlineClass()) return null
|
if (!isInlineClass()) return null
|
||||||
return unsubstitutedPrimaryConstructor?.valueParameters?.singleOrNull()
|
return unsubstitutedPrimaryConstructor?.valueParameters?.singleOrNull()
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ fun ClassDescriptor.underlyingRepresentation(): ValueParameterDescriptor? {
|
|||||||
// FIXME: would like to check as well.
|
// FIXME: would like to check as well.
|
||||||
fun DeclarationDescriptor.isInlineClass() = this is ClassDescriptor && (isInline || isValue)
|
fun DeclarationDescriptor.isInlineClass() = this is ClassDescriptor && (isInline || isValue)
|
||||||
|
|
||||||
fun KotlinType.unsubstitutedUnderlyingParameter(): ValueParameterDescriptor? {
|
private fun KotlinType.unsubstitutedUnderlyingParameter(): ValueParameterDescriptor? {
|
||||||
return constructor.declarationDescriptor.safeAs<ClassDescriptor>()?.underlyingRepresentation()
|
return constructor.declarationDescriptor.safeAs<ClassDescriptor>()?.underlyingRepresentation()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,10 +67,6 @@ fun KotlinType.isNullableUnderlyingType(): Boolean {
|
|||||||
fun CallableDescriptor.isGetterOfUnderlyingPropertyOfInlineClass() =
|
fun CallableDescriptor.isGetterOfUnderlyingPropertyOfInlineClass() =
|
||||||
this is PropertyGetterDescriptor && correspondingProperty.isUnderlyingPropertyOfInlineClass()
|
this is PropertyGetterDescriptor && correspondingProperty.isUnderlyingPropertyOfInlineClass()
|
||||||
|
|
||||||
fun VariableDescriptor.isUnderlyingPropertyOfInlineClass(): Boolean {
|
fun VariableDescriptor.isUnderlyingPropertyOfInlineClass(): Boolean =
|
||||||
if (extensionReceiverParameter != null) return false
|
extensionReceiverParameter == null &&
|
||||||
val containingDeclaration = this.containingDeclaration
|
(containingDeclaration as? ClassDescriptor)?.inlineClassRepresentation?.underlyingPropertyName == this.name
|
||||||
if (!containingDeclaration.isInlineClass()) return false
|
|
||||||
|
|
||||||
return (containingDeclaration as ClassDescriptor).underlyingRepresentation()?.name == this.name
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user