interpret block with function literal as function literal
(temporary)
This commit is contained in:
+32
-3
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user