Refactoring: extract mangling utils that related to resolve out

This commit is contained in:
Mikhail Zarechenskiy
2018-09-10 10:10:50 +03:00
parent 26ca411423
commit 5f50977974
5 changed files with 55 additions and 45 deletions
@@ -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;
}
@@ -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);
}
@@ -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<StackValue, StackValue> 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(
@@ -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<KotlinType>) =
if (valueParameterTypes.none { it.requiresFunctionNameMangling() })
null
else
private fun getInlineClassSignatureManglingSuffix(valueParameterTypes: List<KotlinType>) =
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<KotlinType>) =
types.joinToString { getSignatureElementForMangling(it) }
@@ -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<KotlinType>): 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()
}