KT-3919 Automatic labeling of lambdas by receiving functions

#KT-3919 Fixed
This commit is contained in:
Andrey Breslav
2013-08-22 14:27:01 +04:00
parent 07a8dff5f4
commit 55eb994502
5 changed files with 98 additions and 0 deletions
@@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.descriptors.impl.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
import org.jetbrains.jet.lang.resolve.name.LabelName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.*;
@@ -99,6 +100,11 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
JetBlockExpression bodyExpression = expression.getFunctionLiteral().getBodyExpression();
if (bodyExpression == null) return null;
Name callerName = getCallerName(expression);
if (callerName != null) {
context.labelResolver.enterLabeledElement(new LabelName(callerName.asString()), expression);
}
JetType expectedType = context.expectedType;
boolean functionTypeExpected = expectedType != NO_EXPECTED_TYPE && KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(
expectedType);
@@ -115,9 +121,49 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
// all checks were done before
return JetTypeInfo.create(resultType, context.dataFlowInfo);
}
if (callerName != null) {
context.labelResolver.exitLabeledElement(expression);
}
return DataFlowUtils.checkType(resultType, expression, context, context.dataFlowInfo);
}
@Nullable
private static Name getCallerName(@NotNull JetFunctionLiteralExpression expression) {
JetCallExpression callExpression = getContainingCallExpression(expression);
if (callExpression == null) return null;
JetExpression calleeExpression = callExpression.getCalleeExpression();
if (calleeExpression instanceof JetSimpleNameExpression) {
JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) calleeExpression;
return nameExpression.getReferencedNameAsName();
}
return null;
}
@Nullable
private static JetCallExpression getContainingCallExpression(JetFunctionLiteralExpression expression) {
PsiElement parent = expression.getParent();
if (parent instanceof JetCallExpression) {
// f {}
return (JetCallExpression) parent;
}
if (parent instanceof JetValueArgument) {
// f ({}) or f(p = {})
JetValueArgument argument = (JetValueArgument) parent;
PsiElement argList = argument.getParent();
if (argList == null) return null;
PsiElement call = argList.getParent();
if (call instanceof JetCallExpression) {
return (JetCallExpression) call;
}
}
return null;
}
@NotNull
private static AnonymousFunctionDescriptor createFunctionDescriptor(
@NotNull JetFunctionLiteralExpression expression,