Make anonymous class inner

This commit is contained in:
Alexander Udalov
2013-12-04 21:05:56 +04:00
parent 6276dd1483
commit fb370a4538
@@ -2450,10 +2450,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@Override @Override
public StackValue visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, StackValue data) { public StackValue visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, StackValue data) {
// TODO: properties // TODO: properties
final FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression); FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
assert functionDescriptor != null : "Callable reference is not resolved to descriptor: " + expression.getText(); assert functionDescriptor != null : "Callable reference is not resolved to descriptor: " + expression.getText();
final ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(RESOLVED_CALL, expression.getCallableReference()); ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(RESOLVED_CALL, expression.getCallableReference());
assert resolvedCall != null : "Callable reference is not resolved: " + functionDescriptor + " " + expression.getText(); assert resolvedCall != null : "Callable reference is not resolved: " + functionDescriptor + " " + expression.getText();
JetType kFunctionType = bindingContext.get(EXPRESSION_TYPE, expression); JetType kFunctionType = bindingContext.get(EXPRESSION_TYPE, expression);
@@ -2463,13 +2463,35 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Type closureSuperClass = typeMapper.mapType(kFunctionImpl); Type closureSuperClass = typeMapper.mapType(kFunctionImpl);
CallableReferenceGenerationStrategy strategy = new CallableReferenceGenerationStrategy(state, functionDescriptor, resolvedCall);
ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, closureSuperClass, context, this, ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, closureSuperClass, context, this,
new FunctionGenerationStrategy.CodegenBased<CallableDescriptor>(state, functionDescriptor) { strategy, getParentCodegen());
closureCodegen.gen();
return closureCodegen.putInstanceOnStack(v, this);
}
private static class CallableReferenceGenerationStrategy extends FunctionGenerationStrategy.CodegenBased<CallableDescriptor> {
private final FunctionDescriptor functionDescriptor;
private final ResolvedCall<? extends CallableDescriptor> resolvedCall;
public CallableReferenceGenerationStrategy(
@NotNull GenerationState state,
@NotNull FunctionDescriptor functionDescriptor,
@NotNull ResolvedCall<? extends CallableDescriptor> resolvedCall
) {
super(state, functionDescriptor);
this.functionDescriptor = functionDescriptor;
this.resolvedCall = resolvedCall;
}
@NotNull @NotNull
@Override @Override
public ExpressionCodegen initializeExpressionCodegen( public ExpressionCodegen initializeExpressionCodegen(
JvmMethodSignature signature, MethodContext context, MethodVisitor mv, JvmMethodSignature signature,
MethodContext context,
MethodVisitor mv,
Type returnType, Type returnType,
MemberCodegen parentCodegen MemberCodegen parentCodegen
) { ) {
@@ -2477,8 +2499,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
JetType returnJetType = referencedFunction.getReturnType(); JetType returnJetType = referencedFunction.getReturnType();
assert returnJetType != null : "Return type can't be null: " + referencedFunction; assert returnJetType != null : "Return type can't be null: " + referencedFunction;
return super.initializeExpressionCodegen(signature, context, return super.initializeExpressionCodegen(signature, context, mv, state.getTypeMapper().mapReturnType(returnJetType), parentCodegen);
mv, typeMapper.mapReturnType(returnJetType), parentCodegen);
} }
@Override @Override
@@ -2549,8 +2570,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@NotNull @NotNull
private JetCallExpression constructFakeFunctionCall(@NotNull CallableDescriptor referencedFunction) { private JetCallExpression constructFakeFunctionCall(@NotNull CallableDescriptor referencedFunction) {
StringBuilder fakeFunctionCall = new StringBuilder("callableReferenceFakeCall("); StringBuilder fakeFunctionCall = new StringBuilder("callableReferenceFakeCall(");
for (Iterator<ValueParameterDescriptor> iterator = referencedFunction.getValueParameters().iterator(); for (Iterator<ValueParameterDescriptor> iterator = referencedFunction.getValueParameters().iterator(); iterator.hasNext(); ) {
iterator.hasNext(); ) {
ValueParameterDescriptor descriptor = iterator.next(); ValueParameterDescriptor descriptor = iterator.next();
fakeFunctionCall.append("p").append(descriptor.getIndex()); fakeFunctionCall.append("p").append(descriptor.getIndex());
if (iterator.hasNext()) { if (iterator.hasNext()) {
@@ -2568,17 +2588,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
) { ) {
for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) { for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) {
ValueArgument fakeArgument = fakeArguments.get(parameter.getIndex()); ValueArgument fakeArgument = fakeArguments.get(parameter.getIndex());
Type type = typeMapper.mapType(parameter); Type type = state.getTypeMapper().mapType(parameter);
int localIndex = frameMap.getIndex(parameter); int localIndex = frameMap.getIndex(parameter);
codegen.tempVariables.put(fakeArgument.getArgumentExpression(), StackValue.local(localIndex, type)); codegen.tempVariables.put(fakeArgument.getArgumentExpression(), StackValue.local(localIndex, type));
} }
} }
@NotNull @NotNull
private ReceiverValue computeAndSaveReceiver( private ReceiverValue computeAndSaveReceiver(@NotNull JvmMethodSignature signature, @NotNull ExpressionCodegen codegen) {
@NotNull JvmMethodSignature signature,
@NotNull ExpressionCodegen codegen
) {
CallableDescriptor referencedFunction = resolvedCall.getCandidateDescriptor(); CallableDescriptor referencedFunction = resolvedCall.getCandidateDescriptor();
ReceiverParameterDescriptor receiverParameter = referencedFunction.getReceiverParameter(); ReceiverParameterDescriptor receiverParameter = referencedFunction.getReceiverParameter();
@@ -2592,8 +2609,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return NO_RECEIVER; return NO_RECEIVER;
} }
JetExpression receiverExpression = JetPsiFactory.createExpression(state.getProject(), JetExpression receiverExpression = JetPsiFactory.createExpression(state.getProject(), "callableReferenceFakeReceiver");
"callableReferenceFakeReceiver");
Type firstParameterType = signature.getAsmMethod().getArgumentTypes()[0]; Type firstParameterType = signature.getAsmMethod().getArgumentTypes()[0];
// 0 is this (the closure class), 1 is the method's first parameter // 0 is this (the closure class), 1 is the method's first parameter
@@ -2601,12 +2617,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return new ExpressionReceiver(receiverExpression, receiver.getType()); return new ExpressionReceiver(receiverExpression, receiver.getType());
} }
},
getParentCodegen());
closureCodegen.gen();
return closureCodegen.putInstanceOnStack(v, this);
} }
@Override @Override