diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index a137f4a6511..62bf4712f7e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -64,6 +64,7 @@ import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject; import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant; import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant; import org.jetbrains.kotlin.resolve.constants.evaluate.EvaluatePackage; +import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; import org.jetbrains.kotlin.resolve.scopes.receivers.*; import org.jetbrains.kotlin.types.Approximation; @@ -1428,7 +1429,9 @@ public class ExpressionCodegen extends JetVisitor implem pushClosureOnStack(classDescriptor, true, defaultCallGenerator); - ResolvedCall superCall = bindingContext.get(CLOSURE, classDescriptor).getSuperCall(); + ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); + assert primaryConstructor != null : "There should be primary constructor for object literal"; + ResolvedCall superCall = getDelegationConstructorCall(bindingContext, primaryConstructor); if (superCall != null) { // For an anonymous object, we should also generate all non-default arguments that it captures for its super call ConstructorDescriptor superConstructor = superCall.getResultingDescriptor(); @@ -1496,10 +1499,11 @@ public class ExpressionCodegen extends JetVisitor implem callGenerator.putCapturedValueOnStack(capturedVar, sharedVarType, paramIndex++); } - ResolvedCall superCall = closure.getSuperCall(); - if (superCall != null) { + + ClassDescriptor superClass = DescriptorUtilPackage.getSuperClassNotAny(classDescriptor); + if (superClass != null) { pushClosureOnStack( - superCall.getResultingDescriptor().getContainingDeclaration(), + superClass, putThis && closure.getCaptureThis() == null, callGenerator ); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index d4302de2b13..8e38c8e9e1e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -52,6 +52,7 @@ import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument; import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument; +import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind; @@ -85,7 +86,6 @@ import static org.jetbrains.org.objectweb.asm.Opcodes.*; public class ImplementationBodyCodegen extends ClassBodyCodegen { private static final String ENUM_VALUES_FIELD_NAME = "$VALUES"; - private JetDelegatorToSuperCall superCall; private Type superClassAsmType; @Nullable // null means java/lang/Object private JetType superClassType; @@ -346,7 +346,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (!isInterface(superClassDescriptor)) { superClassType = superType; superClassAsmType = typeMapper.mapClass(superClassDescriptor); - superCall = (JetDelegatorToSuperCall) specifier; } } } @@ -1117,12 +1116,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - if (superCall == null) { - genSimpleSuperCall(iv); - } - else { - generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor); - } + generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor); if (isNonDefaultObject(descriptor)) { StackValue.singleton(descriptor, typeMapper).store(StackValue.LOCAL_0, iv); @@ -1329,15 +1323,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - if (superCall != null) { - ResolvedCall resolvedCall = CallUtilPackage.getResolvedCallWithAssert(superCall, bindingContext); - ClassDescriptor superClass = ((ConstructorDescriptor) resolvedCall.getResultingDescriptor()).getContainingDeclaration(); + ClassDescriptor superClass = DescriptorUtilPackage.getSuperClassNotAny(descriptor); + if (superClass != null) { if (superClass.isInner()) { constructorContext.lookupInContext(superClass.getContainingDeclaration(), StackValue.LOCAL_0, state, true); } if (!isAnonymousObject(descriptor)) { - JetValueArgumentList argumentList = superCall.getValueArgumentList(); + ResolvedCall delegationCall = + getDelegationConstructorCall(bindingContext, descriptor.getUnsubstitutedPrimaryConstructor()); + JetValueArgumentList argumentList = delegationCall != null ? delegationCall.getCall().getValueArgumentList() : null; if (argumentList != null) { argumentList.accept(visitor); } @@ -1419,9 +1414,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { @NotNull ExpressionCodegen codegen, @NotNull ConstructorDescriptor constructorDescriptor ) { + ResolvedCall resolvedCall = getDelegationConstructorCall(bindingContext, constructorDescriptor); + if (resolvedCall == null) { + genSimpleSuperCall(iv); + return; + } iv.load(0, OBJECT_TYPE); - - ResolvedCall resolvedCall = CallUtilPackage.getResolvedCallWithAssert(superCall, bindingContext); ConstructorDescriptor superConstructor = (ConstructorDescriptor) resolvedCall.getResultingDescriptor(); CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java index 79cbc8360be..8ea8dd8116b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java @@ -42,6 +42,7 @@ import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.InlineDescriptorUtils; +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor; import org.jetbrains.kotlin.types.JetType; @@ -236,4 +237,12 @@ public class JvmCodegenUtil { declaration.getParent() instanceof JetFunctionLiteralExpression && InlineDescriptorUtils.isInlineLambda((JetFunctionLiteralExpression) declaration.getParent(), bindingContext, false); } + + @Nullable + public static ResolvedCall getDelegationConstructorCall( + @NotNull BindingContext bindingContext, + @NotNull ConstructorDescriptor constructorDescriptor + ) { + return bindingContext.get(BindingContext.CONSTRUCTOR_RESOLVED_DELEGATION_CALL, constructorDescriptor); + } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CalculatedClosure.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CalculatedClosure.java index fe41a3613c2..988fe642c9b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CalculatedClosure.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CalculatedClosure.java @@ -31,9 +31,6 @@ import java.util.List; import java.util.Map; public interface CalculatedClosure { - @Nullable - ResolvedCall getSuperCall(); - @Nullable ClassDescriptor getCaptureThis(); 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 36f913018bd..598afcaf7c9 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java @@ -162,7 +162,7 @@ public class CodegenBinding { JetElement element = (JetElement) descriptorToDeclaration(classDescriptor); assert element != null : "No source element for " + classDescriptor; - MutableClosure closure = new MutableClosure(classDescriptor, findSuperCall(trace.getBindingContext(), element), enclosing); + MutableClosure closure = new MutableClosure(classDescriptor, enclosing); if (classDescriptor.isInner()) { closure.setCaptureThis(); @@ -271,31 +271,6 @@ public class CodegenBinding { return type; } - @Nullable - private static ResolvedCall findSuperCall( - @NotNull BindingContext bindingContext, - @NotNull JetElement classOrObject - ) { - if (!(classOrObject instanceof JetClassOrObject)) return null; - - if (classOrObject instanceof JetClass && ((JetClass) classOrObject).isTrait()) return null; - - for (JetDelegationSpecifier specifier : ((JetClassOrObject) classOrObject).getDelegationSpecifiers()) { - if (!(specifier instanceof JetDelegatorToSuperCall)) continue; - - ResolvedCall resolvedCall = getResolvedCall(specifier, bindingContext); - if (resolvedCall == null) continue; - - CallableDescriptor constructor = resolvedCall.getResultingDescriptor(); - if (constructor instanceof ConstructorDescriptor && !isInterface(constructor.getContainingDeclaration())) { - //noinspection unchecked - return (ResolvedCall) resolvedCall; - } - } - - return null; - } - @NotNull public static Collection getAllInnerClasses( @NotNull BindingContext bindingContext, @NotNull ClassDescriptor outermostClass diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/MutableClosure.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/MutableClosure.java index 4f7d43d8776..d6add3408eb 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/MutableClosure.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/MutableClosure.java @@ -30,8 +30,6 @@ import java.util.*; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.getDirectMember; public final class MutableClosure implements CalculatedClosure { - private final ResolvedCall superCall; - private final ClassDescriptor enclosingClass; private final CallableDescriptor enclosingFunWithReceiverDescriptor; @@ -41,13 +39,8 @@ public final class MutableClosure implements CalculatedClosure { private Map captureVariables; private List> recordedFields; - MutableClosure( - @NotNull ClassDescriptor classDescriptor, - @Nullable ResolvedCall superCall, - @Nullable ClassDescriptor enclosingClass - ) { + MutableClosure(@NotNull ClassDescriptor classDescriptor, @Nullable ClassDescriptor enclosingClass) { this.enclosingClass = enclosingClass; - this.superCall = superCall; this.enclosingFunWithReceiverDescriptor = enclosingExtensionMemberForClass(classDescriptor); } @@ -68,11 +61,6 @@ public final class MutableClosure implements CalculatedClosure { return enclosingClass; } - @Override - public ResolvedCall getSuperCall() { - return superCall; - } - @Override public ClassDescriptor getCaptureThis() { return captureThis ? enclosingClass : null; diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java index 24a0f0d0456..962843f6520 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java @@ -896,7 +896,7 @@ public class JetTypeMapper { } } - ResolvedCall superCall = closure.getSuperCall(); + ResolvedCall superCall = getDelegationConstructorCall(bindingContext, descriptor); // We may generate a slightly wrong signature for a local class / anonymous object in light classes mode but we don't care, // because such classes are not accessible from the outside world if (superCall != null && classBuilderMode == ClassBuilderMode.FULL) {