[IR] Unite inline class and multi-field value class representation

#KT-1179
This commit is contained in:
Evgeniy.Zhelenskiy
2022-03-10 00:02:35 +03:00
committed by teamcity
parent 282ab398c6
commit 28bf83ceac
69 changed files with 2464 additions and 3598 deletions
@@ -94,8 +94,7 @@ class SyntheticClassOrObjectDescriptor(
override fun getStaticScope() = MemberScope.Empty
override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner) = unsubstitutedMemberScope
override fun getSealedSubclasses() = emptyList<ClassDescriptor>()
override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? = null
override fun getMultiFieldValueClassRepresentation(): MultiFieldValueClassRepresentation<SimpleType>? = null
override fun getValueClassRepresentation(): ValueClassRepresentation<SimpleType>? = null
init {
assert(modality != Modality.SEALED) { "Implement getSealedSubclasses() for this class: ${this::class.java}" }
@@ -271,7 +271,7 @@ class DeclarationsChecker(
if (declaration is KtPrimaryConstructor &&
!DescriptorUtils.isAnnotationClass(constructorDescriptor.constructedClass) &&
!constructorDescriptor.constructedClass.isInlineOrValueClass()
!constructorDescriptor.constructedClass.isValueClass()
) {
for (parameter in declaration.valueParameters) {
if (parameter.hasValOrVar()) {
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.inlineClassRepresentation
import org.jetbrains.kotlin.types.KotlinType
object InlineClassDescriptorResolver {
@@ -77,7 +77,7 @@ object InlineClassDeclarationChecker : DeclarationChecker {
return
}
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ValueClasses) && descriptor.isValueClass()) {
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ValueClasses)) {
if (primaryConstructor.valueParameters.isEmpty()) {
(primaryConstructor.valueParameterList ?: declaration).let {
trace.report(Errors.VALUE_CLASS_EMPTY_CONSTRUCTOR.on(it))
@@ -176,7 +176,7 @@ class PropertiesWithBackingFieldsInsideInlineClass : DeclarationChecker {
if (declaration !is KtProperty) return
if (descriptor !is PropertyDescriptor) return
if (!descriptor.containingDeclaration.isInlineOrValueClass()) return
if (!descriptor.containingDeclaration.isValueClass()) return
if (context.trace.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor) == true) {
context.trace.report(Errors.PROPERTY_WITH_BACKING_FIELD_INSIDE_VALUE_CLASS.on(declaration))
@@ -194,7 +194,7 @@ class InnerClassInsideInlineClass : DeclarationChecker {
if (descriptor !is ClassDescriptor) return
if (!descriptor.isInner) return
if (!descriptor.containingDeclaration.isInlineOrValueClass()) return
if (!descriptor.containingDeclaration.isValueClass()) return
context.trace.report(Errors.INNER_CLASS_INSIDE_VALUE_CLASS.on(declaration.modifierList!!.getModifier(KtTokens.INNER_KEYWORD)!!))
}
@@ -208,7 +208,7 @@ class ReservedMembersAndConstructsForInlineClass : DeclarationChecker {
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
val containingDeclaration = descriptor.containingDeclaration ?: return
if (!containingDeclaration.isInlineOrValueClass()) return
if (!containingDeclaration.isValueClass()) return
if (descriptor !is FunctionDescriptor) return
@@ -23,8 +23,6 @@ import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.resolve.descriptorUtil.isCompanionObject
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.parsing.*
@@ -32,15 +30,18 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.BindingContext.COLLECTION_LITERAL_CALL
import org.jetbrains.kotlin.resolve.calls.util.getEffectiveExpectedType
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.util.getEffectiveExpectedType
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker
import org.jetbrains.kotlin.resolve.constants.*
import org.jetbrains.kotlin.resolve.constants.evaluate.CompileTimeType.*
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.inlineClassRepresentation
import org.jetbrains.kotlin.resolve.descriptorUtil.isCompanionObject
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.TypeUtils
@@ -52,7 +53,6 @@ import org.jetbrains.kotlin.types.typeUtil.isBoolean
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.util.OperatorNameConventions
import java.math.BigInteger
import java.util.*
class ConstantExpressionEvaluator(
internal val module: ModuleDescriptor,
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase;
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl;
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.lexer.KtTokens;
@@ -41,7 +40,6 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProv
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum;
import org.jetbrains.kotlin.resolve.scopes.receivers.ContextClassReceiver;
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
import org.jetbrains.kotlin.storage.MemoizedFunctionToNotNull;
import org.jetbrains.kotlin.storage.NotNullLazyValue;
@@ -631,43 +629,49 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
@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());
}
public ValueClassRepresentation<SimpleType> getValueClassRepresentation() {
if (!this.isValue && !this.isInline) {
return null;
}
ClassConstructorDescriptor constructor = getUnsubstitutedPrimaryConstructor();
// Don't crash on invalid code.
return new InlineClassRepresentation<>(
InlineClassRepresentation<SimpleType> invalidValueClassRepresentation = new InlineClassRepresentation<>(
SpecialNames.SAFE_IDENTIFIER_FOR_NO_NAME, c.getModuleDescriptor().getBuiltIns().getAnyType()
);
}
@Nullable
@Override
public MultiFieldValueClassRepresentation<SimpleType> getMultiFieldValueClassRepresentation() {
if (!InlineClassesUtilsKt.isValueClass(this) || InlineClassesUtilsKt.isInlineClass(this)) {
return null;
}
ClassConstructorDescriptor constructor = getUnsubstitutedPrimaryConstructor();
// Don't crash on invalid code. It is IC, not MFVC.
if (constructor == null) {
return null;
return invalidValueClassRepresentation;
}
List<ValueParameterDescriptor> parameters = constructor.getValueParameters();
if (parameters.size() <= 1) {
return null;
SimpleClassicTypeSystemContext context = SimpleClassicTypeSystemContext.INSTANCE;
if (isRecursiveInlineClass(constructor, new HashSet<>())) {
return new InlineClassRepresentation<>(parameters.get(0).getName(), (SimpleType) parameters.get(0).getType());
}
List<Pair<Name, SimpleType>> properties = parameters.stream()
if (parameters.size() == 0) {
return invalidValueClassRepresentation;
}
List<Pair<Name, SimpleType>> fields = parameters.stream()
.map(parameter -> new Pair<>(parameter.getName(), (SimpleType) parameter.getType()))
.collect(Collectors.toList());
return new MultiFieldValueClassRepresentation<>(properties);
return ValueClassRepresentationKt.createValueClassRepresentation(context, fields);
}
private static boolean isRecursiveInlineClass(@Nullable ClassConstructorDescriptor constructor, @NotNull Set<ClassDescriptor> visited) {
if (constructor == null || constructor.getValueParameters().size() != 1 ||
!(constructor.getConstructedClass().isValue() || constructor.getConstructedClass().isInline())) {
return false;
}
if (!visited.add(constructor.getConstructedClass())) {
return true;
}
SimpleType type = (SimpleType) constructor.getValueParameters().get(0).getType();
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof ClassDescriptor) {
ClassConstructorDescriptor newConstructor = ((ClassDescriptor) descriptor).getUnsubstitutedPrimaryConstructor();
return isRecursiveInlineClass(newConstructor, visited);
}
return false;
}
@Override
@@ -296,7 +296,7 @@ open class LazyClassMemberScope(
}
result.addAll(generateDelegatingDescriptors(name, EXTRACT_FUNCTIONS, result))
generateDataClassMethods(result, name, location, fromSupertypes)
generateFunctionsFromAnyForInlineClass(result, name, fromSupertypes)
generateFunctionsFromAnyForValueClass(result, name, fromSupertypes)
c.syntheticResolveExtension.generateSyntheticMethods(thisDescriptor, name, trace.bindingContext, fromSupertypes, result)
c.additionalClassPartsProvider.generateAdditionalMethods(thisDescriptor, result, name, location, fromSupertypes)
@@ -304,12 +304,12 @@ open class LazyClassMemberScope(
generateFakeOverrides(name, fromSupertypes, result, SimpleFunctionDescriptor::class.java)
}
private fun generateFunctionsFromAnyForInlineClass(
private fun generateFunctionsFromAnyForValueClass(
result: MutableCollection<SimpleFunctionDescriptor>,
name: Name,
fromSupertypes: List<SimpleFunctionDescriptor>
) {
if (!thisDescriptor.isInlineOrValueClass()) return
if (!thisDescriptor.isValueClass()) return
FunctionsFromAny.addFunctionFromAnyIfNeeded(thisDescriptor, result, name, fromSupertypes)
}