[IR] Unite inline class and multi-field value class representation
#KT-1179
This commit is contained in:
committed by
teamcity
parent
282ab398c6
commit
28bf83ceac
+1
-2
@@ -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 {
|
||||
|
||||
+4
-4
@@ -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
|
||||
|
||||
|
||||
+5
-5
@@ -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,
|
||||
|
||||
+32
-28
@@ -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
|
||||
|
||||
+3
-3
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user