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
|
@NotNull
|
||||||
public JetTypeInfo getArgumentTypeInfo(
|
public JetTypeInfo getArgumentTypeInfo(
|
||||||
@Nullable JetExpression expression,
|
@Nullable JetExpression expression,
|
||||||
@@ -174,9 +204,8 @@ public class ArgumentTypeResolver {
|
|||||||
if (expression == null) {
|
if (expression == null) {
|
||||||
return JetTypeInfo.create(null, context.dataFlowInfo);
|
return JetTypeInfo.create(null, context.dataFlowInfo);
|
||||||
}
|
}
|
||||||
JetExpression deparenthesizedExpression = JetPsiUtil.deparenthesize(expression, false);
|
if (isFunctionLiteralArgument(expression)) {
|
||||||
if (deparenthesizedExpression instanceof JetFunctionLiteralExpression) {
|
return getFunctionLiteralTypeInfo(expression, getFunctionLiteralArgument(expression), context, resolveArgumentsMode);
|
||||||
return getFunctionLiteralTypeInfo(expression, (JetFunctionLiteralExpression) deparenthesizedExpression, context, resolveArgumentsMode);
|
|
||||||
}
|
}
|
||||||
JetTypeInfo recordedTypeInfo = getRecordedTypeInfo(expression, context.trace.getBindingContext());
|
JetTypeInfo recordedTypeInfo = getRecordedTypeInfo(expression, context.trace.getBindingContext());
|
||||||
if (recordedTypeInfo != null) {
|
if (recordedTypeInfo != null) {
|
||||||
|
|||||||
@@ -470,9 +470,9 @@ public class CandidateResolver {
|
|||||||
) {
|
) {
|
||||||
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
||||||
if (argumentExpression == null) return;
|
if (argumentExpression == null) return;
|
||||||
JetExpression deparenthesizedExpression = JetPsiUtil.deparenthesize(argumentExpression, false);
|
if (!ArgumentTypeResolver.isFunctionLiteralArgument(argumentExpression)) return;
|
||||||
if (!(deparenthesizedExpression instanceof JetFunctionLiteralExpression)) return;
|
|
||||||
JetFunctionLiteralExpression functionLiteralExpression = (JetFunctionLiteralExpression) deparenthesizedExpression;
|
JetFunctionLiteralExpression functionLiteralExpression = ArgumentTypeResolver.getFunctionLiteralArgument(argumentExpression);
|
||||||
|
|
||||||
JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument);
|
JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument);
|
||||||
JetType expectedType = constraintSystem.getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT);
|
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");
|
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")
|
@TestMetadata("kt2906.kt")
|
||||||
public void testKt2906() throws Exception {
|
public void testKt2906() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/functionLiterals/kt2906.kt");
|
doTest("compiler/testData/diagnostics/tests/functionLiterals/kt2906.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user