Do direct call to local functions, inplace closures, and callable references (not via bridge method)
This commit is contained in:
@@ -2095,22 +2095,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isCallAsFunctionObject(FunctionDescriptor fd) {
|
private boolean isCallAsFunctionObject(FunctionDescriptor fd) {
|
||||||
if (fd.getContainingDeclaration() instanceof ScriptDescriptor) {
|
if (fd instanceof ExpressionAsFunctionDescriptor) {
|
||||||
JetNamedFunction psi = (JetNamedFunction) descriptorToDeclaration(bindingContext, fd);
|
JetExpression deparenthesize = JetPsiUtil.deparenthesize(((ExpressionAsFunctionDescriptor) fd).getExpression());
|
||||||
assert psi != null;
|
return !(deparenthesize instanceof JetCallableReferenceExpression || deparenthesize instanceof JetFunctionLiteralExpression);
|
||||||
return !JetPsiUtil.isScriptDeclaration(psi);
|
|
||||||
}
|
|
||||||
else if (fd instanceof ExpressionAsFunctionDescriptor) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (fd instanceof SimpleFunctionDescriptor &&
|
|
||||||
(fd.getContainingDeclaration() instanceof FunctionDescriptor ||
|
|
||||||
fd.getContainingDeclaration() instanceof ScriptDescriptor)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2134,9 +2123,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
if (!(resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor)) { // otherwise already
|
if (!(resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor)) { // otherwise already
|
||||||
receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod);
|
receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod);
|
||||||
receiver.put(receiver.type, v);
|
receiver.put(receiver.type, v);
|
||||||
if (calleeType != null) {
|
|
||||||
StackValue.onStack(receiver.type).put(boxType(receiver.type), v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pushArgumentsAndInvoke(resolvedCall, callableMethod);
|
pushArgumentsAndInvoke(resolvedCall, callableMethod);
|
||||||
@@ -3037,7 +3023,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
private StackValue invokeOperation(JetOperationExpression expression, FunctionDescriptor op, CallableMethod callable) {
|
private StackValue invokeOperation(JetOperationExpression expression, FunctionDescriptor op, CallableMethod callable) {
|
||||||
int functionLocalIndex = lookupLocalIndex(op);
|
int functionLocalIndex = lookupLocalIndex(op);
|
||||||
if (functionLocalIndex >= 0) {
|
if (functionLocalIndex >= 0) {
|
||||||
stackValueForLocal(op, functionLocalIndex).put(getFunctionImplClassName(op).getAsmType(), v);
|
stackValueForLocal(op, functionLocalIndex).put(callable.getOwner().getAsmType(), v);
|
||||||
}
|
}
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
||||||
bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
||||||
|
|||||||
@@ -31,13 +31,12 @@ import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind;
|
|||||||
import org.jetbrains.jet.codegen.signature.JvmMethodParameterSignature;
|
import org.jetbrains.jet.codegen.signature.JvmMethodParameterSignature;
|
||||||
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
|
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
|
||||||
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.BindingContextUtils;
|
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.java.*;
|
import org.jetbrains.jet.lang.resolve.java.*;
|
||||||
import org.jetbrains.jet.lang.resolve.java.mapping.KotlinToJavaTypesMap;
|
import org.jetbrains.jet.lang.resolve.java.mapping.KotlinToJavaTypesMap;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
@@ -55,6 +54,7 @@ import static org.jetbrains.jet.codegen.AsmUtil.getTraitImplThisParameterType;
|
|||||||
import static org.jetbrains.jet.codegen.CodegenUtil.*;
|
import static org.jetbrains.jet.codegen.CodegenUtil.*;
|
||||||
import static org.jetbrains.jet.codegen.FunctionTypesUtil.getFunctionTraitClassName;
|
import static org.jetbrains.jet.codegen.FunctionTypesUtil.getFunctionTraitClassName;
|
||||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
|
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
|
||||||
|
import static org.jetbrains.jet.codegen.binding.CodegenBinding.classNameForAnonymousClass;
|
||||||
|
|
||||||
public class JetTypeMapper extends BindingTraceAware {
|
public class JetTypeMapper extends BindingTraceAware {
|
||||||
|
|
||||||
@@ -487,7 +487,25 @@ public class JetTypeMapper extends BindingTraceAware {
|
|||||||
JvmClassName ownerForDefaultParam;
|
JvmClassName ownerForDefaultParam;
|
||||||
int invokeOpcode;
|
int invokeOpcode;
|
||||||
JvmClassName thisClass;
|
JvmClassName thisClass;
|
||||||
if (functionParent instanceof NamespaceDescriptor) {
|
Type calleeType = null;
|
||||||
|
|
||||||
|
if (isLocalNamedFun(functionDescriptor) || functionDescriptor instanceof ExpressionAsFunctionDescriptor) {
|
||||||
|
if (functionDescriptor instanceof ExpressionAsFunctionDescriptor) {
|
||||||
|
JetExpression expression = JetPsiUtil.deparenthesize(((ExpressionAsFunctionDescriptor) functionDescriptor).getExpression());
|
||||||
|
if (expression instanceof JetFunctionLiteralExpression) {
|
||||||
|
expression = ((JetFunctionLiteralExpression) expression).getFunctionLiteral();
|
||||||
|
}
|
||||||
|
functionDescriptor = bindingContext.get(BindingContext.FUNCTION, expression);
|
||||||
|
}
|
||||||
|
functionDescriptor = functionDescriptor.getOriginal();
|
||||||
|
|
||||||
|
owner = classNameForAnonymousClass(bindingContext, functionDescriptor);
|
||||||
|
ownerForDefaultImpl = ownerForDefaultParam = thisClass = owner;
|
||||||
|
invokeOpcode = INVOKEVIRTUAL;
|
||||||
|
descriptor = mapSignature("invoke", functionDescriptor, true, kind);
|
||||||
|
calleeType = owner.getAsmType();
|
||||||
|
}
|
||||||
|
else if (functionParent instanceof NamespaceDescriptor) {
|
||||||
assert !superCall;
|
assert !superCall;
|
||||||
owner = jvmClassNameForNamespace((NamespaceDescriptor) functionParent, functionDescriptor, isInsideModule);
|
owner = jvmClassNameForNamespace((NamespaceDescriptor) functionParent, functionDescriptor, isInsideModule);
|
||||||
ownerForDefaultImpl = ownerForDefaultParam = owner;
|
ownerForDefaultImpl = ownerForDefaultParam = owner;
|
||||||
@@ -571,7 +589,7 @@ public class JetTypeMapper extends BindingTraceAware {
|
|||||||
}
|
}
|
||||||
return new CallableMethod(
|
return new CallableMethod(
|
||||||
owner, ownerForDefaultImpl, ownerForDefaultParam, descriptor, invokeOpcode,
|
owner, ownerForDefaultImpl, ownerForDefaultParam, descriptor, invokeOpcode,
|
||||||
thisClass, receiverParameterType, null);
|
thisClass, receiverParameterType, calleeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isAccessor(@NotNull CallableMemberDescriptor descriptor) {
|
public static boolean isAccessor(@NotNull CallableMemberDescriptor descriptor) {
|
||||||
|
|||||||
@@ -56,8 +56,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
|
import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.NON_DEFAULT_EXPRESSION_DATA_FLOW;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLUTION_SCOPE;
|
|
||||||
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS;
|
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS;
|
||||||
import static org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults.Code.*;
|
import static org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults.Code.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
|
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
|
||||||
@@ -245,7 +244,7 @@ public class CallResolver {
|
|||||||
return checkArgumentTypesAndFail(context);
|
return checkArgumentTypesAndFail(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionDescriptorImpl functionDescriptor = new ExpressionAsFunctionDescriptor(context.scope.getContainingDeclaration(), Name.special("<for expression " + calleeExpression.getText() + ">"));
|
FunctionDescriptorImpl functionDescriptor = new ExpressionAsFunctionDescriptor(context.scope.getContainingDeclaration(), Name.special("<for expression " + calleeExpression.getText() + ">"), calleeExpression);
|
||||||
FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, calleeType, NO_RECEIVER_PARAMETER, Modality.FINAL,
|
FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, calleeType, NO_RECEIVER_PARAMETER, Modality.FINAL,
|
||||||
Visibilities.LOCAL);
|
Visibilities.LOCAL);
|
||||||
ResolutionCandidate<CallableDescriptor> resolutionCandidate = ResolutionCandidate.<CallableDescriptor>create(functionDescriptor, JetPsiUtil.isSafeCall(context.call));
|
ResolutionCandidate<CallableDescriptor> resolutionCandidate = ResolutionCandidate.<CallableDescriptor>create(functionDescriptor, JetPsiUtil.isSafeCall(context.call));
|
||||||
|
|||||||
+10
-1
@@ -20,13 +20,18 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorImpl;
|
import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorImpl;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
public class ExpressionAsFunctionDescriptor extends FunctionDescriptorImpl {
|
public class ExpressionAsFunctionDescriptor extends FunctionDescriptorImpl {
|
||||||
public ExpressionAsFunctionDescriptor(DeclarationDescriptor containingDeclaration, Name name) {
|
|
||||||
|
private final JetExpression expression;
|
||||||
|
|
||||||
|
public ExpressionAsFunctionDescriptor(DeclarationDescriptor containingDeclaration, Name name, JetExpression expression) {
|
||||||
super(containingDeclaration, Collections.<AnnotationDescriptor>emptyList(), name, Kind.DECLARATION);
|
super(containingDeclaration, Collections.<AnnotationDescriptor>emptyList(), name, Kind.DECLARATION);
|
||||||
|
this.expression = expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -39,4 +44,8 @@ public class ExpressionAsFunctionDescriptor extends FunctionDescriptorImpl {
|
|||||||
public FunctionDescriptor copy(DeclarationDescriptor newOwner, Modality modality, Visibility visibility, Kind kind, boolean copyOverrides) {
|
public FunctionDescriptor copy(DeclarationDescriptor newOwner, Modality modality, Visibility visibility, Kind kind, boolean copyOverrides) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JetExpression getExpression() {
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-3
@@ -26,6 +26,7 @@ import org.jetbrains.jet.JetNodeTypes;
|
|||||||
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
|
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
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.diagnostics.Errors;
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.*;
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
@@ -507,13 +508,15 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
receiverParameter != null
|
receiverParameter != null
|
||||||
);
|
);
|
||||||
|
|
||||||
ExpressionAsFunctionDescriptor functionDescriptor = new ExpressionAsFunctionDescriptor(
|
AnonymousFunctionDescriptor functionDescriptor = new AnonymousFunctionDescriptor(
|
||||||
context.scope.getContainingDeclaration(),
|
context.scope.getContainingDeclaration(),
|
||||||
Name.special("<callable-reference>")
|
Collections.<AnnotationDescriptor>emptyList(),
|
||||||
);
|
CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
|
|
||||||
FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, type, null, Modality.FINAL, Visibilities.PUBLIC);
|
FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, type, null, Modality.FINAL, Visibilities.PUBLIC);
|
||||||
|
|
||||||
context.trace.record(CALLABLE_REFERENCE, expression, functionDescriptor);
|
context.trace.record(CALLABLE_REFERENCE, expression, functionDescriptor);
|
||||||
|
context.trace.record(FUNCTION, expression, functionDescriptor);
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user