Get rid of superCall fields in class/closure codegen
Because their semantics looks wrong in case of secondary constructors. Use resolved delegation call instead.
This commit is contained in:
@@ -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<StackValue, StackValue> implem
|
||||
|
||||
pushClosureOnStack(classDescriptor, true, defaultCallGenerator);
|
||||
|
||||
ResolvedCall<ConstructorDescriptor> superCall = bindingContext.get(CLOSURE, classDescriptor).getSuperCall();
|
||||
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
||||
assert primaryConstructor != null : "There should be primary constructor for object literal";
|
||||
ResolvedCall<ConstructorDescriptor> 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<StackValue, StackValue> implem
|
||||
callGenerator.putCapturedValueOnStack(capturedVar, sharedVarType, paramIndex++);
|
||||
}
|
||||
|
||||
ResolvedCall<ConstructorDescriptor> superCall = closure.getSuperCall();
|
||||
if (superCall != null) {
|
||||
|
||||
ClassDescriptor superClass = DescriptorUtilPackage.getSuperClassNotAny(classDescriptor);
|
||||
if (superClass != null) {
|
||||
pushClosureOnStack(
|
||||
superCall.getResultingDescriptor().getContainingDeclaration(),
|
||||
superClass,
|
||||
putThis && closure.getCaptureThis() == null,
|
||||
callGenerator
|
||||
);
|
||||
|
||||
@@ -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<ConstructorDescriptor> 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);
|
||||
|
||||
@@ -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<ConstructorDescriptor> getDelegationConstructorCall(
|
||||
@NotNull BindingContext bindingContext,
|
||||
@NotNull ConstructorDescriptor constructorDescriptor
|
||||
) {
|
||||
return bindingContext.get(BindingContext.CONSTRUCTOR_RESOLVED_DELEGATION_CALL, constructorDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,9 +31,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface CalculatedClosure {
|
||||
@Nullable
|
||||
ResolvedCall<ConstructorDescriptor> getSuperCall();
|
||||
|
||||
@Nullable
|
||||
ClassDescriptor getCaptureThis();
|
||||
|
||||
|
||||
@@ -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<ConstructorDescriptor> 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<ConstructorDescriptor>) resolvedCall;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Collection<ClassDescriptor> getAllInnerClasses(
|
||||
@NotNull BindingContext bindingContext, @NotNull ClassDescriptor outermostClass
|
||||
|
||||
@@ -30,8 +30,6 @@ import java.util.*;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.getDirectMember;
|
||||
|
||||
public final class MutableClosure implements CalculatedClosure {
|
||||
private final ResolvedCall<ConstructorDescriptor> superCall;
|
||||
|
||||
private final ClassDescriptor enclosingClass;
|
||||
private final CallableDescriptor enclosingFunWithReceiverDescriptor;
|
||||
|
||||
@@ -41,13 +39,8 @@ public final class MutableClosure implements CalculatedClosure {
|
||||
private Map<DeclarationDescriptor, EnclosedValueDescriptor> captureVariables;
|
||||
private List<Pair<String, Type>> recordedFields;
|
||||
|
||||
MutableClosure(
|
||||
@NotNull ClassDescriptor classDescriptor,
|
||||
@Nullable ResolvedCall<ConstructorDescriptor> 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<ConstructorDescriptor> getSuperCall() {
|
||||
return superCall;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassDescriptor getCaptureThis() {
|
||||
return captureThis ? enclosingClass : null;
|
||||
|
||||
@@ -896,7 +896,7 @@ public class JetTypeMapper {
|
||||
}
|
||||
}
|
||||
|
||||
ResolvedCall<ConstructorDescriptor> superCall = closure.getSuperCall();
|
||||
ResolvedCall<ConstructorDescriptor> 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) {
|
||||
|
||||
Reference in New Issue
Block a user