Typecheck call arguments if callee is resolved to variable
#KT-11579 Fixed
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -315,7 +315,7 @@ public class ArgumentTypeResolver {
|
|||||||
* Visits function call arguments and determines data flow information changes
|
* Visits function call arguments and determines data flow information changes
|
||||||
*/
|
*/
|
||||||
public void analyzeArgumentsAndRecordTypes(
|
public void analyzeArgumentsAndRecordTypes(
|
||||||
@NotNull CallResolutionContext<?> context
|
@NotNull CallResolutionContext<?> context, @NotNull ResolveArgumentsMode resolveArgumentsMode
|
||||||
) {
|
) {
|
||||||
MutableDataFlowInfoForArguments infoForArguments = context.dataFlowInfoForArguments;
|
MutableDataFlowInfoForArguments infoForArguments = context.dataFlowInfoForArguments;
|
||||||
Call call = context.call;
|
Call call = context.call;
|
||||||
@@ -326,7 +326,7 @@ public class ArgumentTypeResolver {
|
|||||||
|
|
||||||
CallResolutionContext<?> newContext = context.replaceDataFlowInfo(infoForArguments.getInfo(argument));
|
CallResolutionContext<?> newContext = context.replaceDataFlowInfo(infoForArguments.getInfo(argument));
|
||||||
// Here we go inside arguments and determine additional data flow information for them
|
// Here we go inside arguments and determine additional data flow information for them
|
||||||
KotlinTypeInfo typeInfoForCall = getArgumentTypeInfo(expression, newContext, SHAPE_FUNCTION_ARGUMENTS);
|
KotlinTypeInfo typeInfoForCall = getArgumentTypeInfo(expression, newContext, resolveArgumentsMode);
|
||||||
infoForArguments.updateInfo(argument, typeInfoForCall.getDataFlowInfo());
|
infoForArguments.updateInfo(argument, typeInfoForCall.getDataFlowInfo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
|||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.*
|
||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.recordDataFlowInfo
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.recordDataFlowInfo
|
||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.recordScope
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.recordScope
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
|
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
|
||||||
@@ -64,6 +65,7 @@ import javax.inject.Inject
|
|||||||
class CallExpressionResolver(
|
class CallExpressionResolver(
|
||||||
private val callResolver: CallResolver,
|
private val callResolver: CallResolver,
|
||||||
private val constantExpressionEvaluator: ConstantExpressionEvaluator,
|
private val constantExpressionEvaluator: ConstantExpressionEvaluator,
|
||||||
|
private val argumentTypeResolver: ArgumentTypeResolver,
|
||||||
private val dataFlowAnalyzer: DataFlowAnalyzer,
|
private val dataFlowAnalyzer: DataFlowAnalyzer,
|
||||||
private val builtIns: KotlinBuiltIns,
|
private val builtIns: KotlinBuiltIns,
|
||||||
private val qualifiedExpressionResolver: QualifiedExpressionResolver,
|
private val qualifiedExpressionResolver: QualifiedExpressionResolver,
|
||||||
@@ -247,6 +249,13 @@ class CallExpressionResolver(
|
|||||||
temporaryForVariable.commit()
|
temporaryForVariable.commit()
|
||||||
context.trace.report(FUNCTION_EXPECTED.on(calleeExpression, calleeExpression,
|
context.trace.report(FUNCTION_EXPECTED.on(calleeExpression, calleeExpression,
|
||||||
type ?: ErrorUtils.createErrorType("")))
|
type ?: ErrorUtils.createErrorType("")))
|
||||||
|
argumentTypeResolver.analyzeArgumentsAndRecordTypes(
|
||||||
|
BasicCallResolutionContext.create(
|
||||||
|
context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
||||||
|
DataFlowInfoForArgumentsImpl(initialDataFlowInfoForArguments, call)
|
||||||
|
),
|
||||||
|
ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS
|
||||||
|
)
|
||||||
return noTypeInfo(context)
|
return noTypeInfo(context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -575,7 +575,7 @@ public class CallResolver {
|
|||||||
@NotNull TracingStrategy tracing
|
@NotNull TracingStrategy tracing
|
||||||
) {
|
) {
|
||||||
if (context.checkArguments == CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) {
|
if (context.checkArguments == CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) {
|
||||||
argumentTypeResolver.analyzeArgumentsAndRecordTypes(context);
|
argumentTypeResolver.analyzeArgumentsAndRecordTypes(context, ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<KtTypeProjection> typeArguments = context.call.getTypeArguments();
|
List<KtTypeProjection> typeArguments = context.call.getTypeArguments();
|
||||||
|
|||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
fun f() {
|
||||||
|
val g = 3
|
||||||
|
<error>g</error>(object : Any() {})
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun f() {
|
||||||
|
val g = 3
|
||||||
|
<error>g</error> { <error>workingSet</error>, <error>customer</error> ->
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -436,6 +436,18 @@ public class PsiCheckerTestGenerated extends AbstractPsiCheckerTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("callVariableAsFunctionWithAnonymousObjectArg.kt")
|
||||||
|
public void testCallVariableAsFunctionWithAnonymousObjectArg() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/callVariableAsFunctionWithAnonymousObjectArg.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("callVariableAsFunctionWithLambdaArg.kt")
|
||||||
|
public void testCallVariableAsFunctionWithLambdaArg() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/callVariableAsFunctionWithLambdaArg.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("ClassDeclarationAfterDot.kt")
|
@TestMetadata("ClassDeclarationAfterDot.kt")
|
||||||
public void testClassDeclarationAfterDot() throws Exception {
|
public void testClassDeclarationAfterDot() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/ClassDeclarationAfterDot.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/regression/ClassDeclarationAfterDot.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user