interpret block with function literal as function literal

(temporary)
This commit is contained in:
Svetlana Isakova
2013-10-10 15:25:10 +04:00
parent 73c5cb07d8
commit ab7e3ce78c
4 changed files with 51 additions and 6 deletions
@@ -165,6 +165,36 @@ public class ArgumentTypeResolver {
}
}
public static boolean isFunctionLiteralArgument(@NotNull JetExpression expression) {
return getFunctionLiteralArgumentIfAny(expression) != null;
}
@NotNull
public static JetFunctionLiteralExpression getFunctionLiteralArgument(@NotNull JetExpression expression) {
assert isFunctionLiteralArgument(expression);
//noinspection ConstantConditions
return getFunctionLiteralArgumentIfAny(expression);
}
@Nullable
private static JetFunctionLiteralExpression getFunctionLiteralArgumentIfAny(@NotNull JetExpression expression) {
JetExpression deparenthesizedExpression = JetPsiUtil.deparenthesize(expression, false);
if (deparenthesizedExpression instanceof JetBlockExpression) {
// todo
// This case is a temporary hack for 'if' branches.
// The right way to implement this logic is to interpret 'if' branches as function literals with explicitly-typed signatures
// (no arguments and no receiver) and therefore analyze them straight away (not in the 'complete' phase).
JetElement lastStatementInABlock = JetPsiUtil.getLastStatementInABlock((JetBlockExpression) deparenthesizedExpression);
if (lastStatementInABlock instanceof JetExpression) {
deparenthesizedExpression = JetPsiUtil.deparenthesize((JetExpression) lastStatementInABlock, false);
}
}
if (deparenthesizedExpression instanceof JetFunctionLiteralExpression) {
return (JetFunctionLiteralExpression) deparenthesizedExpression;
}
return null;
}
@NotNull
public JetTypeInfo getArgumentTypeInfo(
@Nullable JetExpression expression,
@@ -174,9 +204,8 @@ public class ArgumentTypeResolver {
if (expression == null) {
return JetTypeInfo.create(null, context.dataFlowInfo);
}
JetExpression deparenthesizedExpression = JetPsiUtil.deparenthesize(expression, false);
if (deparenthesizedExpression instanceof JetFunctionLiteralExpression) {
return getFunctionLiteralTypeInfo(expression, (JetFunctionLiteralExpression) deparenthesizedExpression, context, resolveArgumentsMode);
if (isFunctionLiteralArgument(expression)) {
return getFunctionLiteralTypeInfo(expression, getFunctionLiteralArgument(expression), context, resolveArgumentsMode);
}
JetTypeInfo recordedTypeInfo = getRecordedTypeInfo(expression, context.trace.getBindingContext());
if (recordedTypeInfo != null) {
@@ -470,9 +470,9 @@ public class CandidateResolver {
) {
JetExpression argumentExpression = valueArgument.getArgumentExpression();
if (argumentExpression == null) return;
JetExpression deparenthesizedExpression = JetPsiUtil.deparenthesize(argumentExpression, false);
if (!(deparenthesizedExpression instanceof JetFunctionLiteralExpression)) return;
JetFunctionLiteralExpression functionLiteralExpression = (JetFunctionLiteralExpression) deparenthesizedExpression;
if (!ArgumentTypeResolver.isFunctionLiteralArgument(argumentExpression)) return;
JetFunctionLiteralExpression functionLiteralExpression = ArgumentTypeResolver.getFunctionLiteralArgument(argumentExpression);
JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument);
JetType expectedType = constraintSystem.getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT);
@@ -0,0 +1,11 @@
fun test() {
val a = if (true) {
val x = 1
({ x })
} else {
{ 2 }
}
TypeOf(a): TypeOf<Function0<Int>>
}
class TypeOf<T>(t: T)
@@ -2710,6 +2710,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/functionLiterals/ExpectedParametersTypesMismatch.kt");
}
@TestMetadata("functionLIteralInBlockInIf.kt")
public void testFunctionLIteralInBlockInIf() throws Exception {
doTest("compiler/testData/diagnostics/tests/functionLiterals/functionLIteralInBlockInIf.kt");
}
@TestMetadata("kt2906.kt")
public void testKt2906() throws Exception {
doTest("compiler/testData/diagnostics/tests/functionLiterals/kt2906.kt");