Refine type of CalculatedClosure#superCall

Instead of PSI, store the actual resolved call
This commit is contained in:
Alexander Udalov
2014-07-08 18:52:30 +04:00
parent 780fb78529
commit dec5a80cdb
5 changed files with 40 additions and 41 deletions
@@ -1334,11 +1334,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
pushClosureOnStack(closure, false, defaultCallGenerator); pushClosureOnStack(closure, false, defaultCallGenerator);
JetDelegatorToSuperCall superCall = closure.getSuperCall(); ResolvedCall<ConstructorDescriptor> superCall = closure.getSuperCall();
if (superCall != null) { if (superCall != null) {
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(superCall, bindingContext); ConstructorDescriptor superConstructor = superCall.getResultingDescriptor();
ConstructorDescriptor superConstructor = (ConstructorDescriptor) resolvedCall.getResultingDescriptor(); List<ResolvedValueArgument> valueArguments = superCall.getValueArgumentsByIndex();
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
assert valueArguments != null : "Failed to arrange value arguments by index: " + superConstructor; assert valueArguments != null : "Failed to arrange value arguments by index: " + superConstructor;
ArgumentGenerator argumentGenerator = ArgumentGenerator argumentGenerator =
new CallBasedArgumentGenerator(this, defaultCallGenerator, superConstructor.getValueParameters(), new CallBasedArgumentGenerator(this, defaultCallGenerator, superConstructor.getValueParameters(),
@@ -19,23 +19,23 @@ package org.jetbrains.jet.codegen.binding;
import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.jet.codegen.context.EnclosedValueDescriptor; import org.jetbrains.jet.codegen.context.EnclosedValueDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.org.objectweb.asm.Type;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public interface CalculatedClosure { public interface CalculatedClosure {
@Nullable @Nullable
ClassDescriptor getEnclosingClass(); ClassDescriptor getEnclosingClass();
@Nullable @Nullable
JetDelegatorToSuperCall getSuperCall(); ResolvedCall<ConstructorDescriptor> getSuperCall();
@Nullable @Nullable
ClassDescriptor getCaptureThis(); ClassDescriptor getCaptureThis();
@@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorImpl;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
@@ -42,6 +43,7 @@ import java.util.*;
import static org.jetbrains.jet.codegen.JvmCodegenUtil.isInterface; import static org.jetbrains.jet.codegen.JvmCodegenUtil.isInterface;
import static org.jetbrains.jet.lang.resolve.BindingContext.*; import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPackage.getResolvedCall;
public class CodegenBinding { public class CodegenBinding {
public static final WritableSlice<ClassDescriptor, MutableClosure> CLOSURE = Slices.createSimpleSlice(); public static final WritableSlice<ClassDescriptor, MutableClosure> CLOSURE = Slices.createSimpleSlice();
@@ -170,7 +172,7 @@ public class CodegenBinding {
@Nullable ClassDescriptor enclosing, @Nullable ClassDescriptor enclosing,
@NotNull Type asmType @NotNull Type asmType
) { ) {
JetDelegatorToSuperCall superCall = findSuperCall(bindingTrace.getBindingContext(), element); ResolvedCall<ConstructorDescriptor> superCall = findSuperCall(bindingTrace.getBindingContext(), element);
CallableDescriptor enclosingReceiver = null; CallableDescriptor enclosingReceiver = null;
if (classDescriptor.getContainingDeclaration() instanceof CallableDescriptor) { if (classDescriptor.getContainingDeclaration() instanceof CallableDescriptor) {
@@ -324,7 +326,11 @@ public class CodegenBinding {
return closure != null && closure.getCaptureThis() != null; return closure != null && closure.getCaptureThis() != null;
} }
private static JetDelegatorToSuperCall findSuperCall(BindingContext bindingContext, JetElement classOrObject) { @Nullable
private static ResolvedCall<ConstructorDescriptor> findSuperCall(
@NotNull BindingContext bindingContext,
@Nullable JetElement classOrObject
) {
if (!(classOrObject instanceof JetClassOrObject)) { if (!(classOrObject instanceof JetClassOrObject)) {
return null; return null;
} }
@@ -335,16 +341,17 @@ public class CodegenBinding {
for (JetDelegationSpecifier specifier : ((JetClassOrObject) classOrObject).getDelegationSpecifiers()) { for (JetDelegationSpecifier specifier : ((JetClassOrObject) classOrObject).getDelegationSpecifiers()) {
if (specifier instanceof JetDelegatorToSuperCall) { if (specifier instanceof JetDelegatorToSuperCall) {
JetTypeReference typeReference = specifier.getTypeReference(); JetType supertype = bindingContext.get(TYPE, specifier.getTypeReference());
assert supertype != null : String.format(
JetType superType = bindingContext.get(TYPE, typeReference);
assert superType != null: String.format(
"No type in binding context for \n---\n%s\n---\n", JetPsiUtil.getElementTextWithContext(specifier)); "No type in binding context for \n---\n%s\n---\n", JetPsiUtil.getElementTextWithContext(specifier));
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); ClassifierDescriptor superClass = supertype.getConstructor().getDeclarationDescriptor();
assert superClassDescriptor != null; if (superClass != null && !isInterface(superClass)) {
if (!isInterface(superClassDescriptor)) { ResolvedCall<?> resolvedCall = getResolvedCall(specifier, bindingContext);
return (JetDelegatorToSuperCall) specifier; if (resolvedCall != null && resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor) {
//noinspection unchecked
return (ResolvedCall<ConstructorDescriptor>) resolvedCall;
}
} }
} }
} }
@@ -19,19 +19,16 @@ package org.jetbrains.jet.codegen.binding;
import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.jet.codegen.context.EnclosedValueDescriptor; import org.jetbrains.jet.codegen.context.EnclosedValueDescriptor;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor;
import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.org.objectweb.asm.Type;
import java.util.*; import java.util.*;
public final class MutableClosure implements CalculatedClosure { public final class MutableClosure implements CalculatedClosure {
private final JetDelegatorToSuperCall superCall; private final ResolvedCall<ConstructorDescriptor> superCall;
private final ClassDescriptor enclosingClass; private final ClassDescriptor enclosingClass;
private final CallableDescriptor enclosingReceiverDescriptor; private final CallableDescriptor enclosingReceiverDescriptor;
@@ -43,9 +40,9 @@ public final class MutableClosure implements CalculatedClosure {
private List<Pair<String, Type>> recordedFields; private List<Pair<String, Type>> recordedFields;
MutableClosure( MutableClosure(
JetDelegatorToSuperCall superCall, @Nullable ResolvedCall<ConstructorDescriptor> superCall,
ClassDescriptor enclosingClass, @Nullable ClassDescriptor enclosingClass,
CallableDescriptor enclosingReceiverDescriptor @Nullable CallableDescriptor enclosingReceiverDescriptor
) { ) {
this.superCall = superCall; this.superCall = superCall;
this.enclosingClass = enclosingClass; this.enclosingClass = enclosingClass;
@@ -59,7 +56,7 @@ public final class MutableClosure implements CalculatedClosure {
} }
@Override @Override
public JetDelegatorToSuperCall getSuperCall() { public ResolvedCall<ConstructorDescriptor> getSuperCall() {
return superCall; return superCall;
} }
@@ -75,6 +72,7 @@ public final class MutableClosure implements CalculatedClosure {
@Override @Override
public JetType getCaptureReceiverType() { public JetType getCaptureReceiverType() {
if (captureReceiver) { if (captureReceiver) {
//noinspection ConstantConditions
ReceiverParameterDescriptor parameter = enclosingReceiverDescriptor.getReceiverParameter(); ReceiverParameterDescriptor parameter = enclosingReceiverDescriptor.getReceiverParameter();
assert parameter != null : "Receiver parameter should exist in " + enclosingReceiverDescriptor; assert parameter != null : "Receiver parameter should exist in " + enclosingReceiverDescriptor;
return parameter.getType(); return parameter.getType();
@@ -29,12 +29,12 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotated; import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor; import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils; import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.OverrideResolver; import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.StringValue; import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
@@ -805,17 +805,12 @@ public class JetTypeMapper {
} }
} }
JetDelegatorToSuperCall superCall = closure.getSuperCall(); ResolvedCall<ConstructorDescriptor> superCall = closure.getSuperCall();
if (superCall != null) { if (superCall != null && isAnonymousObject(descriptor.getContainingDeclaration())) {
DeclarationDescriptor superDescriptor = bindingContext for (JvmMethodParameterSignature parameter : mapSignature(superCall.getResultingDescriptor()).getValueParameters()) {
.get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression()); signatureWriter.writeParameterType(JvmMethodParameterKind.SUPER_OF_ANONYMOUS_CALL_PARAM);
signatureWriter.writeAsmType(parameter.getAsmType());
if (superDescriptor instanceof ConstructorDescriptor && isAnonymousObject(descriptor.getContainingDeclaration())) { signatureWriter.writeParameterTypeEnd();
for (JvmMethodParameterSignature parameter : mapSignature((ConstructorDescriptor) superDescriptor).getValueParameters()) {
signatureWriter.writeParameterType(JvmMethodParameterKind.SUPER_OF_ANONYMOUS_CALL_PARAM);
signatureWriter.writeAsmType(parameter.getAsmType());
signatureWriter.writeParameterTypeEnd();
}
} }
} }
} }