diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index 690b578eeb2..a42cc807b40 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -20,7 +20,6 @@ import org.jetbrains.kotlin.codegen.context.CodegenContext; import org.jetbrains.kotlin.codegen.intrinsics.HashCode; import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods; import org.jetbrains.kotlin.codegen.state.GenerationState; -import org.jetbrains.kotlin.codegen.state.InlineClassManglingUtilsKt; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.config.JvmTarget; import org.jetbrains.kotlin.descriptors.*; @@ -38,10 +37,7 @@ import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver; import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt; import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker; import org.jetbrains.kotlin.resolve.inline.InlineUtil; -import org.jetbrains.kotlin.resolve.jvm.AsmTypes; -import org.jetbrains.kotlin.resolve.jvm.JvmClassName; -import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType; -import org.jetbrains.kotlin.resolve.jvm.RuntimeAssertionInfo; +import org.jetbrains.kotlin.resolve.jvm.*; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin; import org.jetbrains.kotlin.serialization.DescriptorSerializer; import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor; @@ -406,7 +402,7 @@ public class AsmUtil { if (kind != OwnerKind.ERASED_INLINE_CLASS && memberDescriptor instanceof ConstructorDescriptor && !(memberDescriptor instanceof AccessorForConstructorDescriptor) && - InlineClassManglingUtilsKt.shouldHideConstructorDueToInlineClassTypeValueParameters((ConstructorDescriptor) memberDescriptor) + InlineClassManglingRulesKt.shouldHideConstructorDueToInlineClassTypeValueParameters((ConstructorDescriptor) memberDescriptor) ) { return ACC_PRIVATE; } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ConstructorCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ConstructorCodegen.java index e643b13aa2c..6c8adee4a6d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ConstructorCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ConstructorCodegen.java @@ -12,13 +12,13 @@ import org.jetbrains.kotlin.codegen.context.ConstructorContext; import org.jetbrains.kotlin.codegen.context.FieldOwnerContext; import org.jetbrains.kotlin.codegen.context.MethodContext; import org.jetbrains.kotlin.codegen.state.GenerationState; -import org.jetbrains.kotlin.codegen.state.InlineClassManglingUtilsKt; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; +import org.jetbrains.kotlin.resolve.jvm.InlineClassManglingRulesKt; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind; @@ -115,7 +115,7 @@ public class ConstructorCodegen { } private void registerAccessorForHiddenConstructorIfNeeded(ClassConstructorDescriptor descriptor) { - if (!InlineClassManglingUtilsKt.shouldHideConstructorDueToInlineClassTypeValueParameters(descriptor)) return; + if (!InlineClassManglingRulesKt.shouldHideConstructorDueToInlineClassTypeValueParameters(descriptor)) return; context.getAccessor(descriptor, AccessorKind.NORMAL, null, null); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 5a5202c81b2..8dcbea602a6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -36,7 +36,6 @@ import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator; import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter; import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter; import org.jetbrains.kotlin.codegen.state.GenerationState; -import org.jetbrains.kotlin.codegen.state.InlineClassManglingUtilsKt; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.codegen.when.SwitchCodegen; import org.jetbrains.kotlin.codegen.when.SwitchCodegenProvider; @@ -69,10 +68,7 @@ import org.jetbrains.kotlin.resolve.constants.*; import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluatorKt; import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; import org.jetbrains.kotlin.resolve.inline.InlineUtil; -import org.jetbrains.kotlin.resolve.jvm.AsmTypes; -import org.jetbrains.kotlin.resolve.jvm.JvmBindingContextSlices; -import org.jetbrains.kotlin.resolve.jvm.JvmConstantsKt; -import org.jetbrains.kotlin.resolve.jvm.RuntimeAssertionInfo; +import org.jetbrains.kotlin.resolve.jvm.*; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature; @@ -2261,7 +2257,7 @@ public class ExpressionCodegen extends KtVisitor impleme // $default method is not private, so you need no accessor to call it return descriptor; } - else if (InlineClassManglingUtilsKt.shouldHideConstructorDueToInlineClassTypeValueParameters(descriptor.getOriginal())) { + else if (InlineClassManglingRulesKt.shouldHideConstructorDueToInlineClassTypeValueParameters(descriptor.getOriginal())) { // Constructors with inline class type value parameters should always be called using an accessor. // NB this will require accessors even if the constructor itself is in a different module. return new AccessorForConstructorDescriptor( diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/inlineClassManglingUtils.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/inlineClassManglingUtils.kt index b9287352729..a209e3a18d1 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/inlineClassManglingUtils.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/inlineClassManglingUtils.kt @@ -7,11 +7,9 @@ package org.jetbrains.kotlin.codegen.state import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.load.kotlin.getRepresentativeUpperBound -import org.jetbrains.kotlin.resolve.DescriptorUtils.RESULT_FQ_NAME import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe -import org.jetbrains.kotlin.resolve.isInlineClassType +import org.jetbrains.kotlin.resolve.jvm.* import org.jetbrains.kotlin.types.KotlinType import java.security.MessageDigest import java.util.* @@ -26,35 +24,11 @@ fun getInlineClassSignatureManglingSuffix(descriptor: CallableMemberDescriptor): return getInlineClassSignatureManglingSuffix(actualValueParameterTypes) } -fun shouldHideConstructorDueToInlineClassTypeValueParameters(descriptor: CallableMemberDescriptor): Boolean { - if (descriptor !is ClassConstructorDescriptor) return false - if (Visibilities.isPrivate(descriptor.visibility)) return false - if (descriptor.constructedClass.isInline) return false - - // TODO inner class in inline class - - return descriptor.valueParameters.any { it.type.requiresFunctionNameMangling() } -} - -fun getInlineClassSignatureManglingSuffix(valueParameterTypes: List) = - if (valueParameterTypes.none { it.requiresFunctionNameMangling() }) - null - else +private fun getInlineClassSignatureManglingSuffix(valueParameterTypes: List) = + if (requiresFunctionNameMangling(valueParameterTypes)) "-" + md5base64(collectSignatureForMangling(valueParameterTypes)) - -private fun KotlinType.requiresFunctionNameMangling() = - isInlineClassThatRequiresMangling() || isTypeParameterWithUpperBoundThatRequiresMangling() - -private fun KotlinType.isInlineClassThatRequiresMangling() = - isInlineClassType() && !isDontMangleClass(this.constructor.declarationDescriptor as ClassDescriptor) - -private fun isDontMangleClass(classDescriptor: ClassDescriptor) = - classDescriptor.fqNameSafe == RESULT_FQ_NAME - -private fun KotlinType.isTypeParameterWithUpperBoundThatRequiresMangling(): Boolean { - val descriptor = constructor.declarationDescriptor as? TypeParameterDescriptor ?: return false - return getRepresentativeUpperBound(descriptor).requiresFunctionNameMangling() -} + else + null private fun collectSignatureForMangling(types: List) = types.joinToString { getSignatureElementForMangling(it) } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/resolve/jvm/inlineClassManglingRules.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/resolve/jvm/inlineClassManglingRules.kt new file mode 100644 index 00000000000..314588eb439 --- /dev/null +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/resolve/jvm/inlineClassManglingRules.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.resolve.jvm + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.load.kotlin.getRepresentativeUpperBound +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe +import org.jetbrains.kotlin.resolve.isInlineClassType +import org.jetbrains.kotlin.types.KotlinType +import java.security.MessageDigest +import java.util.* + +fun shouldHideConstructorDueToInlineClassTypeValueParameters(descriptor: CallableMemberDescriptor): Boolean { + if (descriptor !is ClassConstructorDescriptor) return false + if (Visibilities.isPrivate(descriptor.visibility)) return false + if (descriptor.constructedClass.isInline) return false + + // TODO inner class in inline class + + return descriptor.valueParameters.any { it.type.requiresFunctionNameMangling() } +} + +fun requiresFunctionNameMangling(valueParameterTypes: List): Boolean { + return valueParameterTypes.any { it.requiresFunctionNameMangling() } +} + +private fun KotlinType.requiresFunctionNameMangling() = + isInlineClassThatRequiresMangling() || isTypeParameterWithUpperBoundThatRequiresMangling() + +private fun KotlinType.isInlineClassThatRequiresMangling() = + isInlineClassType() && !isDontMangleClass(this.constructor.declarationDescriptor as ClassDescriptor) + +private fun isDontMangleClass(classDescriptor: ClassDescriptor) = + classDescriptor.fqNameSafe == DescriptorUtils.RESULT_FQ_NAME + +private fun KotlinType.isTypeParameterWithUpperBoundThatRequiresMangling(): Boolean { + val descriptor = constructor.declarationDescriptor as? TypeParameterDescriptor ?: return false + return getRepresentativeUpperBound(descriptor).requiresFunctionNameMangling() +}