From db27a885f15f7929f90b326ec87e1d5d69e3a654 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 9 Jun 2017 12:02:47 +0300 Subject: [PATCH] Rework property metadata generation for local delegated properties Instead of generating an anonymous class for each delegated local variable, store metadatas in the $$delegatedProperties array of the containing class, as is done for member properties --- .../org/jetbrains/kotlin/codegen/AsmUtil.java | 6 ++ .../kotlin/codegen/ClosureCodegen.java | 23 ++++++- .../kotlin/codegen/ExpressionCodegen.java | 49 ++----------- .../codegen/ImplementationBodyCodegen.java | 3 +- .../kotlin/codegen/MemberCodegen.java | 6 +- .../kotlin/codegen/PropertyCodegen.java | 69 +++++++------------ .../codegen/PropertyReferenceCodegen.kt | 11 +++ .../binding/CodegenAnnotatingVisitor.java | 59 +++++++--------- .../codegen/binding/CodegenBinding.java | 15 +--- .../codegen/context/PackageContext.java | 5 -- 10 files changed, 101 insertions(+), 145 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index 1faa105b6ab..925f8e7f919 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -38,6 +38,7 @@ import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.load.java.JavaVisibilities; import org.jetbrains.kotlin.load.java.JvmAnnotationNames; +import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.protobuf.MessageLite; import org.jetbrains.kotlin.renderer.DescriptorRenderer; @@ -895,6 +896,11 @@ public class AsmUtil { return Type.getObjectType(internalNameByFqNameWithoutInnerClasses(fqName)); } + @NotNull + public static Type asmTypeByClassId(@NotNull ClassId classId) { + return Type.getObjectType(classId.asString().replace('.', '$')); + } + @NotNull public static String internalNameByFqNameWithoutInnerClasses(@NotNull FqName fqName) { return JvmClassName.byFqNameWithoutInnerClasses(fqName).getInternalName(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java index 4c33503bf73..e48457f66f8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java @@ -24,6 +24,7 @@ import kotlin.collections.CollectionsKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.codegen.binding.CalculatedClosure; +import org.jetbrains.kotlin.codegen.binding.CodegenBinding; import org.jetbrains.kotlin.codegen.context.ClosureContext; import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor; import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt; @@ -33,6 +34,7 @@ import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.descriptors.*; +import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor; import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.kotlin.incremental.components.NoLookupLocation; import org.jetbrains.kotlin.load.java.JvmAbi; @@ -358,13 +360,30 @@ public class ClosureCodegen extends MemberCodegen { @NotNull GenerationState state ) { DeclarationDescriptor container = descriptor.getContainingDeclaration(); + if (container instanceof ClassDescriptor) { // TODO: getDefaultType() here is wrong and won't work for arrays putJavaLangClassInstance(iv, state.getTypeMapper().mapType(((ClassDescriptor) container).getDefaultType())); - wrapJavaClassIntoKClass(iv); } else if (container instanceof PackageFragmentDescriptor) { iv.aconst(state.getTypeMapper().mapOwner(descriptor)); + } + else if (descriptor instanceof VariableDescriptorWithAccessors) { + iv.aconst(state.getBindingContext().get( + CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER, ((VariableDescriptorWithAccessors) descriptor) + )); + } + else { + iv.aconst(null); + return; + } + + boolean isContainerPackage = + descriptor instanceof LocalVariableDescriptor + ? DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class) == null + : container instanceof PackageFragmentDescriptor; + + if (isContainerPackage) { // Note that this name is not used in reflection. There should be the name of the referenced declaration's module instead, // but there's no nice API to obtain that name here yet // TODO: write the referenced declaration's module name and use it in reflection @@ -373,7 +392,7 @@ public class ClosureCodegen extends MemberCodegen { Type.getMethodDescriptor(K_DECLARATION_CONTAINER_TYPE, getType(Class.class), getType(String.class)), false); } else { - iv.aconst(null); + wrapJavaClassIntoKClass(iv); } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 4f55378928d..8ee2cfa6df3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -1309,10 +1309,6 @@ public class ExpressionCodegen extends KtVisitor impleme Type type = getVariableType(variableDescriptor); int index = myFrameMap.enter(variableDescriptor, type); - if (isDelegatedLocalVariable(variableDescriptor)) { - myFrameMap.enter(getDelegatedLocalVariableMetadata(variableDescriptor, bindingContext), AsmTypes.K_PROPERTY0_TYPE); - } - if (isSharedVarType(type)) { markLineNumber(statement, false); v.anew(type); @@ -1360,10 +1356,6 @@ public class ExpressionCodegen extends KtVisitor impleme v.mark(scopeStart); leaveTasks.add(answer -> { - if (isDelegatedLocalVariable(variableDescriptor)) { - myFrameMap.leave(getDelegatedLocalVariableMetadata(variableDescriptor, bindingContext)); - } - int index = myFrameMap.leave(variableDescriptor); v.visitLocalVariable(variableDescriptor.getName().asString(), type.getDescriptor(), null, scopeStart, blockEnd, index); @@ -1776,31 +1768,10 @@ public class ExpressionCodegen extends KtVisitor impleme return lookupCapturedValueInConstructorParameters(descriptor); } - return lookupValuaAndLocalVariableMetadata(descriptor, StackValue.LOCAL_0, state, false, context, this); - } + StackValue value = context.lookupInContext(descriptor, StackValue.LOCAL_0, state, false); + if (value == null) return null; - @Nullable - static StackValue lookupValuaAndLocalVariableMetadata( - @NotNull DeclarationDescriptor descriptor, - @NotNull StackValue prefix, - @NotNull GenerationState state, - boolean ignoreNoOuter, - @NotNull CodegenContext context, - @Nullable ExpressionCodegen codegen - ) { - StackValue value = context.lookupInContext(descriptor, prefix, state, ignoreNoOuter); - if(!isDelegatedLocalVariable(descriptor) || value == null) { - return value; - } - - - VariableDescriptor metadata = getDelegatedLocalVariableMetadata((VariableDescriptor) descriptor, state.getBindingContext()); - StackValue metadataValue = context.lookupInContext(metadata, prefix, state, ignoreNoOuter); - assert metadataValue != null : "Metadata stack value should be non-null for local delegated property"; - //required for ImplementationBodyCodegen.lookupConstructorExpressionsInClosureIfPresent - if (codegen == null) return null; - return codegen.delegatedVariableValue(value, metadataValue, (VariableDescriptorWithAccessors) descriptor, - state.getTypeMapper()); + return adjustVariableValue(value, descriptor); } @Nullable @@ -1811,7 +1782,7 @@ public class ExpressionCodegen extends KtVisitor impleme int parameterOffsetInConstructor = context.closure.getCapturedParameterOffsetInConstructor(descriptor); // when captured parameter is singleton // see compiler/testData/codegen/box/objects/objectInLocalAnonymousObject.kt (fun local() captured in A) - if (parameterOffsetInConstructor == -1) return adjustVariableValue(parentResult , descriptor); + if (parameterOffsetInConstructor == -1) return adjustVariableValue(parentResult, descriptor); assert parentResult instanceof StackValue.Field || parentResult instanceof StackValue.FieldForSharedVar : "Part of closure should be either Field or FieldForSharedVar"; @@ -3495,19 +3466,12 @@ public class ExpressionCodegen extends KtVisitor impleme } } - @NotNull - private StackValue getVariableMetadataValue(VariableDescriptor variableDescriptor) { - StackValue value = findLocalOrCapturedValue(getDelegatedLocalVariableMetadata(variableDescriptor, bindingContext)); - assert value != null : "Can't find stack value for local delegated variable metadata: " + variableDescriptor; - return value; - } - @NotNull private StackValue adjustVariableValue(@NotNull StackValue varValue, DeclarationDescriptor descriptor) { if (!isDelegatedLocalVariable(descriptor)) return varValue; VariableDescriptorWithAccessors variableDescriptor = (VariableDescriptorWithAccessors) descriptor; - StackValue metadataValue = getVariableMetadataValue(variableDescriptor); + StackValue metadataValue = PropertyCodegen.getDelegatedPropertyMetadata(variableDescriptor, bindingContext); return delegatedVariableValue(varValue, metadataValue, variableDescriptor, typeMapper); } @@ -3539,8 +3503,7 @@ public class ExpressionCodegen extends KtVisitor impleme Type resultType = initializer.type; if (isDelegatedLocalVariable(variableDescriptor)) { - StackValue metadataValue = getVariableMetadataValue(variableDescriptor); - initializePropertyMetadata((KtProperty) variableDeclaration, variableDescriptor, metadataValue); + StackValue metadataValue = PropertyCodegen.getDelegatedPropertyMetadata(variableDescriptor, bindingContext); ResolvedCall provideDelegateResolvedCall = bindingContext.get(PROVIDE_DELEGATE_RESOLVED_CALL, variableDescriptor); if (provideDelegateResolvedCall != null) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index 40385c0e140..77328160c9c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -1237,9 +1237,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - private void lookupInContext(@NotNull DeclarationDescriptor toLookup) { - ExpressionCodegen.lookupValuaAndLocalVariableMetadata(toLookup, StackValue.LOCAL_0, state, true, context, null); + context.lookupInContext(toLookup, StackValue.LOCAL_0, state, true); } @Override diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 4f0805128e0..ed48be497b4 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -36,6 +36,7 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget; import org.jetbrains.kotlin.descriptors.annotations.Annotations; +import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor; import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.kotlin.fileClasses.FileClasses; import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider; @@ -49,6 +50,7 @@ import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; +import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; @@ -528,7 +530,7 @@ public abstract class MemberCodegen", Type.getMethodDescriptor(Type.VOID_TYPE, K_DECLARATION_CONTAINER_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE), false diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java index 6bc887e407f..f927a24b8c6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java @@ -21,7 +21,10 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.codegen.annotation.AnnotatedWithFakeAnnotations; -import org.jetbrains.kotlin.codegen.context.*; +import org.jetbrains.kotlin.codegen.context.CodegenContextUtil; +import org.jetbrains.kotlin.codegen.context.FieldOwnerContext; +import org.jetbrains.kotlin.codegen.context.MultifileClassFacadeContext; +import org.jetbrains.kotlin.codegen.context.MultifileClassPartContext; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.descriptors.*; @@ -60,6 +63,7 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityForBackingField; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface; import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTIES; +import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER; import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.FIELD_FOR_PROPERTY; import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY; import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject; @@ -532,60 +536,36 @@ public class PropertyCodegen { public static StackValue invokeDelegatedPropertyConventionMethod( @NotNull ExpressionCodegen codegen, - @NotNull KotlinTypeMapper typeMapper, @NotNull ResolvedCall resolvedCall, @Nullable StackValue receiver, @NotNull PropertyDescriptor propertyDescriptor ) { - Type owner = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor) ? - codegen.getState().getTypeMapper().mapOwner(propertyDescriptor) : - getDelegatedPropertyMetadataOwner(codegen, typeMapper); - codegen.tempVariables.put( resolvedCall.getCall().getValueArguments().get(1).asElement(), - new StackValue(K_PROPERTY_TYPE) { - @Override - public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { - Field array = StackValue.field( - Type.getType("[" + K_PROPERTY_TYPE), owner, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME, true, StackValue.none() - ); - int index = findDelegatedProperty(typeMapper.getBindingContext(), owner, propertyDescriptor); - StackValue.arrayElement(K_PROPERTY_TYPE, array, StackValue.constant(index, Type.INT_TYPE)).put(type, v); - } - - private int findDelegatedProperty( - @NotNull BindingContext bindingContext, - @NotNull Type owner, - @NotNull PropertyDescriptor propertyDescriptor - ) { - List allDelegatedProperties = bindingContext.get(DELEGATED_PROPERTIES, owner); - int result = allDelegatedProperties == null ? -1 : allDelegatedProperties.indexOf(propertyDescriptor); - if (result < 0) { - throw new AssertionError("Delegated property not found in " + owner + ": " + propertyDescriptor); - } - - return result; - } - } + getDelegatedPropertyMetadata(propertyDescriptor, codegen.getBindingContext()) ); return codegen.invokeFunction(resolvedCall, receiver); } - private static Type getDelegatedPropertyMetadataOwner(@NotNull ExpressionCodegen codegen, @NotNull KotlinTypeMapper typeMapper) { - CodegenContext ownerContext = codegen.getContext().getClassOrPackageParentContext(); - if (ownerContext instanceof ClassContext) { - return typeMapper.mapClass(((ClassContext) ownerContext).getContextDescriptor()); - } - else if (ownerContext instanceof PackageContext) { - return ((PackageContext) ownerContext).getPackagePartType(); - } - else if (ownerContext instanceof MultifileClassContextBase) { - return ((MultifileClassContextBase) ownerContext).getFilePartType(); - } - else { - throw new UnsupportedOperationException("Unknown context: " + ownerContext); + @NotNull + public static StackValue getDelegatedPropertyMetadata( + @NotNull VariableDescriptorWithAccessors descriptor, + @NotNull BindingContext bindingContext + ) { + Type owner = bindingContext.get(DELEGATED_PROPERTY_METADATA_OWNER, descriptor); + assert owner != null : "Delegated property owner not found: " + descriptor; + + List allDelegatedProperties = bindingContext.get(DELEGATED_PROPERTIES, owner); + int index = allDelegatedProperties == null ? -1 : allDelegatedProperties.indexOf(descriptor); + if (index < 0) { + throw new AssertionError("Delegated property not found in " + owner + ": " + descriptor); } + + StackValue.Field array = StackValue.field( + Type.getType("[" + K_PROPERTY_TYPE), owner, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME, true, StackValue.none() + ); + return StackValue.arrayElement(K_PROPERTY_TYPE, array, StackValue.constant(index, Type.INT_TYPE)); } private static class DelegatedPropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased { @@ -607,8 +587,7 @@ public class PropertyCodegen { PropertyDescriptor propertyDescriptor = propertyAccessorDescriptor.getCorrespondingProperty(); StackValue.Property receiver = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.LOCAL_0); - StackValue lastValue = - invokeDelegatedPropertyConventionMethod(codegen, state.getTypeMapper(), resolvedCall, receiver, propertyDescriptor); + StackValue lastValue = invokeDelegatedPropertyConventionMethod(codegen, resolvedCall, receiver, propertyDescriptor); Type asmType = signature.getReturnType(); lastValue.put(asmType, v); v.areturn(asmType); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt index 8c0f83eb734..e1939769d04 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt @@ -194,6 +194,17 @@ class PropertyReferenceCodegen( @JvmStatic fun generateCallableReferenceSignature(iv: InstructionAdapter, callable: CallableDescriptor, state: GenerationState) { + if (callable is LocalVariableDescriptor) { + val asmType = state.bindingContext.get(CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER, callable) + val allDelegatedProperties = state.bindingContext.get(CodegenBinding.DELEGATED_PROPERTIES, asmType) + val index = allDelegatedProperties?.indexOf(callable) ?: -1 + if (index < 0) { + throw AssertionError("Local delegated property is not found in $asmType: $callable") + } + iv.aconst("") // v = "variable" + return + } + val accessor = when (callable) { is FunctionDescriptor -> callable is VariableDescriptorWithAccessors -> diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java index 36954417b36..bdf76c18bc3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java @@ -34,12 +34,11 @@ import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil; import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping; import org.jetbrains.kotlin.coroutines.CoroutineUtilKt; import org.jetbrains.kotlin.descriptors.*; -import org.jetbrains.kotlin.descriptors.annotations.Annotations; -import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor; import org.jetbrains.kotlin.fileClasses.FileClasses; import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider; import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor; import org.jetbrains.kotlin.load.kotlin.TypeMappingConfiguration; +import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.BindingContext; @@ -373,32 +372,12 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { return CodegenBinding.recordClosure(bindingTrace, classDescriptor, peekFromStack(classStack), Type.getObjectType(name)); } - private void recordLocalVariablePropertyMetadata(LocalVariableDescriptor variableDescriptor) { - KotlinType delegateType = JvmCodegenUtil.getPropertyDelegateType(variableDescriptor, bindingContext); - if (delegateType == null) return; - - LocalVariableDescriptor metadataVariableDescriptor = new LocalVariableDescriptor( - variableDescriptor.getContainingDeclaration(), - Annotations.Companion.getEMPTY(), - Name.identifier(variableDescriptor.getName().asString() + "$metadata"), - ReflectionTypes.Companion.createKPropertyStarType(DescriptorUtilsKt.getModule(variableDescriptor)), - false, - false, - SourceElement.NO_SOURCE - ); - bindingTrace.record(LOCAL_VARIABLE_PROPERTY_METADATA, variableDescriptor, metadataVariableDescriptor); - } - @Override public void visitProperty(@NotNull KtProperty property) { DeclarationDescriptor descriptor = bindingContext.get(DECLARATION_TO_DESCRIPTOR, property); // working around a problem with shallow analysis if (descriptor == null) return; - if (descriptor instanceof LocalVariableDescriptor) { - recordLocalVariablePropertyMetadata((LocalVariableDescriptor) descriptor); - } - String nameForClassOrPackageMember = getNameForClassOrPackageMember(descriptor); if (nameForClassOrPackageMember != null) { nameStack.push(nameForClassOrPackageMember); @@ -416,25 +395,37 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { ClassDescriptor classDescriptor = recordClassForCallable(delegate, variableDescriptor, Collections.singleton(supertype), name); recordClosure(classDescriptor, name); - if (!(variableDescriptor instanceof LocalVariableDescriptor)) { - ClassDescriptor containerClass = peekFromStack(classStack); - Type containerType = - containerClass != null - ? CodegenBinding.getAsmType(bindingContext, containerClass) - : Type.getObjectType(FileClasses.getFileClassInternalName(fileClassesProvider, property.getContainingKtFile())); - List descriptors = bindingTrace.get(DELEGATED_PROPERTIES, containerType); - if (descriptors == null) { - descriptors = new ArrayList<>(1); - bindingTrace.record(DELEGATED_PROPERTIES, containerType, descriptors); - } - descriptors.add(variableDescriptor); + Type containerType = getMetadataOwner(property); + List descriptors = bindingTrace.get(DELEGATED_PROPERTIES, containerType); + if (descriptors == null) { + descriptors = new ArrayList<>(1); + bindingTrace.record(DELEGATED_PROPERTIES, containerType, descriptors); } + descriptors.add(variableDescriptor); + + bindingTrace.record(DELEGATED_PROPERTY_METADATA_OWNER, variableDescriptor, containerType); } super.visitProperty(property); nameStack.pop(); } + @NotNull + private Type getMetadataOwner(@NotNull KtProperty property) { + for (int i = classStack.size() - 1; i >= 0; i--) { + ClassDescriptor descriptor = classStack.get(i); + // The first "real" containing class (not a synthetic class for lambda) is the owner of the delegated property metadata + if (!(descriptor instanceof SyntheticClassDescriptorForLambda)) { + ClassId classId = DescriptorUtilsKt.getClassId(descriptor); + return classId != null + ? AsmUtil.asmTypeByClassId(classId) + : CodegenBinding.getAsmType(bindingContext, descriptor); + } + } + + return Type.getObjectType(FileClasses.getFileClassInternalName(fileClassesProvider, property.getContainingKtFile())); + } + @Override public void visitNamedFunction(@NotNull KtNamedFunction function) { FunctionDescriptor functionDescriptor = (FunctionDescriptor) bindingContext.get(DECLARATION_TO_DESCRIPTOR, function); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java index 6ea86d913a8..17e1c1bae73 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java @@ -59,9 +59,6 @@ public class CodegenBinding { public static final WritableSlice> MAPPINGS_FOR_WHENS_BY_ENUM_IN_CLASS_FILE = Slices.createSimpleSlice(); - public static final WritableSlice LOCAL_VARIABLE_PROPERTY_METADATA = - Slices.createSimpleSlice(); - public static final WritableSlice SUSPEND_FUNCTION_TO_JVM_VIEW = Slices.createSimpleSlice(); @@ -70,6 +67,8 @@ public class CodegenBinding { public static final WritableSlice> DELEGATED_PROPERTIES = Slices.createSimpleSlice(); + public static final WritableSlice DELEGATED_PROPERTY_METADATA_OWNER = + Slices.createSimpleSlice(); static { BasicWritableSlice.initSliceDebugNames(CodegenBinding.class); @@ -224,14 +223,4 @@ public class CodegenBinding { assert type != null : "Type is not yet recorded for " + klass; return type; } - - @NotNull - public static VariableDescriptor getDelegatedLocalVariableMetadata( - @NotNull VariableDescriptor variableDescriptor, - @NotNull BindingContext bindingContext - ) { - VariableDescriptor metadataVariableDescriptor = bindingContext.get(LOCAL_VARIABLE_PROPERTY_METADATA, variableDescriptor); - assert metadataVariableDescriptor != null : "Metadata for local delegated property should be not null: " + variableDescriptor; - return metadataVariableDescriptor; - } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/PackageContext.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/PackageContext.java index 7606e998a83..323e232bdf1 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/PackageContext.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/PackageContext.java @@ -43,11 +43,6 @@ public class PackageContext extends FieldOwnerContext return "Package: " + getContextDescriptor().getName(); } - @Nullable - public Type getPackagePartType() { - return packagePartType; - } - @Nullable @Override public Type getImplementationOwnerClassType() {