diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java index 144e3cfd59b..60a898e2c0f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -1490,11 +1490,17 @@ public class JetControlFlowProcessor { CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor(); Map receivers = getReceiverValues(resolvedCall); SmartFMap parameterValues = SmartFMap.emptyMap(); - for (ValueParameterDescriptor parameterDescriptor : resultingDescriptor.getValueParameters()) { - ResolvedValueArgument argument = resolvedCall.getValueArguments().get(parameterDescriptor); - if (argument == null) continue; - - parameterValues = generateValueArgument(argument, parameterDescriptor, parameterValues); + List valueArguments = CallUtilPackage.getAllValueArguments(resolvedCall.getCall()); + for (ValueArgument argument : valueArguments) { + ArgumentMapping argumentMapping = resolvedCall.getArgumentMapping(argument); + JetExpression argumentExpression = argument.getArgumentExpression(); + if (argumentMapping instanceof ArgumentMatch) { + parameterValues = generateValueArgument(argument, ((ArgumentMatch) argumentMapping).getValueParameter(), parameterValues); + } + else if (argumentExpression != null) { + generateInstructions(argumentExpression); + createSyntheticValue(argumentExpression, MagicKind.VALUE_CONSUMER, argumentExpression); + } } if (resultingDescriptor instanceof VariableDescriptor) { @@ -1552,19 +1558,6 @@ public class JetControlFlowProcessor { return receiverValues; } - @NotNull - private SmartFMap generateValueArgument( - ResolvedValueArgument argument, - ValueParameterDescriptor parameterDescriptor, - SmartFMap parameterValues - ) { - for (ValueArgument valueArgument : argument.getArguments()) { - parameterValues = generateValueArgument(valueArgument, parameterDescriptor, parameterValues); - } - - return parameterValues; - } - @NotNull private SmartFMap generateValueArgument( ValueArgument valueArgument, diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 3fcc6b357cb..08cbb0f4c73 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -40,7 +40,10 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.Nullability; import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext; import org.jetbrains.jet.lang.resolve.calls.context.CheckValueArgumentsMode; import org.jetbrains.jet.lang.resolve.calls.context.TemporaryTraceAndCache; -import org.jetbrains.jet.lang.resolve.calls.model.*; +import org.jetbrains.jet.lang.resolve.calls.model.DataFlowInfoForArgumentsImpl; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl; +import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsUtil; @@ -688,11 +691,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } // Type check the base expression - JetTypeInfo typeInfo = facade.getTypeInfo(baseExpression, context); - JetType type = typeInfo.getType(); - if (type == null) { - return typeInfo; - } + JetTypeInfo typeInfo = facade.safeGetTypeInfo(baseExpression, context); + JetType type = ExpressionTypingUtils.safeGetType(typeInfo); + ExpressionReceiver receiver = new ExpressionReceiver(baseExpression, type); + + Call call = CallMaker.makeCall(receiver, expression); DataFlowInfo dataFlowInfo = typeInfo.getDataFlowInfo(); // Conventions for unary operations @@ -705,21 +708,15 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { // a[i]++/-- takes special treatment because it is actually let j = i, arr = a in arr.set(j, a.get(j).inc()) if ((operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) && baseExpression instanceof JetArrayAccessExpression) { JetExpression stubExpression = ExpressionTypingUtils.createFakeExpressionOfType(baseExpression.getProject(), context.trace, "$e", type); - resolveArrayAccessSetMethod((JetArrayAccessExpression) baseExpression, - stubExpression, - context.replaceBindingTrace( - TemporaryBindingTrace.create(context.trace, "trace to resolve array access set method for unary expression", expression)), - context.trace); + TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace + .create(context.trace, "trace to resolve array access set method for unary expression", expression); + ExpressionTypingContext newContext = context.replaceBindingTrace(temporaryBindingTrace); + resolveArrayAccessSetMethod((JetArrayAccessExpression) baseExpression, stubExpression, newContext, context.trace); } - ExpressionReceiver receiver = new ExpressionReceiver(baseExpression, type); - // Resolve the operation reference OverloadResolutionResults resolutionResults = components.callResolver.resolveCallWithGivenName( - context, - CallMaker.makeCall(receiver, expression), - expression.getOperationReference(), - name); + context, call, expression.getOperationReference(), name); if (!resolutionResults.isSuccess()) { return JetTypeInfo.create(null, dataFlowInfo); @@ -1302,29 +1299,20 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { JetExpression arrayExpression = arrayAccessExpression.getArrayExpression(); if (arrayExpression == null) return JetTypeInfo.create(null, oldContext.dataFlowInfo); - JetTypeInfo arrayTypeInfo = facade.getTypeInfo(arrayExpression, oldContext.replaceExpectedType(NO_EXPECTED_TYPE) + JetTypeInfo arrayTypeInfo = facade.safeGetTypeInfo(arrayExpression, oldContext.replaceExpectedType(NO_EXPECTED_TYPE) .replaceContextDependency(INDEPENDENT)); - JetType arrayType = arrayTypeInfo.getType(); - if (arrayType == null) { - for (JetExpression indexExpression : arrayAccessExpression.getIndexExpressions()) { - facade.getTypeInfo(indexExpression, oldContext); - } - return arrayTypeInfo; - } + JetType arrayType = ExpressionTypingUtils.safeGetType(arrayTypeInfo); DataFlowInfo dataFlowInfo = arrayTypeInfo.getDataFlowInfo(); ExpressionTypingContext context = oldContext.replaceDataFlowInfo(dataFlowInfo); ExpressionReceiver receiver = new ExpressionReceiver(arrayExpression, arrayType); if (!isGet) assert rightHandSide != null; + Call call = isGet + ? CallMaker.makeArrayGetCall(receiver, arrayAccessExpression, Call.CallType.ARRAY_GET_METHOD) + : CallMaker.makeArraySetCall(receiver, arrayAccessExpression, rightHandSide, Call.CallType.ARRAY_SET_METHOD); OverloadResolutionResults functionResults = components.callResolver.resolveCallWithGivenName( - context, - isGet - ? CallMaker.makeArrayGetCall(receiver, arrayAccessExpression, Call.CallType.ARRAY_GET_METHOD) - : CallMaker.makeArraySetCall(receiver, arrayAccessExpression, rightHandSide, Call.CallType.ARRAY_SET_METHOD), - arrayAccessExpression, - Name.identifier(isGet ? "get" : "set") - ); + context, call, arrayAccessExpression, Name.identifier(isGet ? "get" : "set")); List indices = arrayAccessExpression.getIndexExpressions(); // The accumulated data flow info of all index expressions is saved on the last index diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java index e278bebadd5..9e71da20338 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java @@ -84,11 +84,17 @@ public class ExpressionTypingUtils { @NotNull protected static ExpressionReceiver safeGetExpressionReceiver(@NotNull ExpressionTypingFacade facade, @NotNull JetExpression expression, ExpressionTypingContext context) { - JetType type = facade.safeGetTypeInfo(expression, context).getType(); - assert type != null : "safeGetTypeInfo should return @NotNull type"; + JetType type = safeGetType(facade.safeGetTypeInfo(expression, context)); return new ExpressionReceiver(expression, type); } + @NotNull + public static JetType safeGetType(@NotNull JetTypeInfo typeInfo) { + JetType type = typeInfo.getType(); + assert type != null : "safeGetType should be invoked on safe JetTypeInfo; safeGetTypeInfo should return @NotNull type"; + return type; + } + @NotNull public static WritableScopeImpl newWritableScopeImpl(ExpressionTypingContext context, @NotNull String scopeDebugName) { WritableScopeImpl scope = new WritableScopeImpl( diff --git a/compiler/testData/cfg/functions/unmappedArgs.instructions b/compiler/testData/cfg/functions/unmappedArgs.instructions new file mode 100644 index 00000000000..c261bf56f4e --- /dev/null +++ b/compiler/testData/cfg/functions/unmappedArgs.instructions @@ -0,0 +1,47 @@ +== foo == +fun foo(a: Int, b: Int) = a + b +--------------------- +L0: + 1 + v(a: Int) + magic[FAKE_INITIALIZER](a: Int) -> + w(a|) + v(b: Int) + magic[FAKE_INITIALIZER](b: Int) -> + w(b|) + r(a) -> + r(b) -> + mark(a + b) + call(a + b, plus|, ) -> + ret(*|) L1 +L1: + NEXT:[] +error: + PREV:[] +sink: + PREV:[, ] +===================== +== bar == +fun bar(i: Int) { + foo(1, 1, i) +} +--------------------- +L0: + 1 + v(i: Int) + magic[FAKE_INITIALIZER](i: Int) -> + w(i|) + 2 mark({ foo(1, 1, i) }) + r(1) -> + r(1) -> + r(i) -> + magic[VALUE_CONSUMER](i|) -> + mark(foo(1, 1, i)) + call(foo(1, 1, i), foo|, ) -> +L1: + 1 NEXT:[] +error: + PREV:[] +sink: + PREV:[, ] +===================== \ No newline at end of file diff --git a/compiler/testData/cfg/functions/unmappedArgs.kt b/compiler/testData/cfg/functions/unmappedArgs.kt new file mode 100644 index 00000000000..a3ab0ba8c73 --- /dev/null +++ b/compiler/testData/cfg/functions/unmappedArgs.kt @@ -0,0 +1,5 @@ +fun foo(a: Int, b: Int) = a + b + +fun bar(i: Int) { + foo(1, 1, i) +} diff --git a/compiler/testData/cfg/functions/unmappedArgs.values b/compiler/testData/cfg/functions/unmappedArgs.values new file mode 100644 index 00000000000..198b7899f46 --- /dev/null +++ b/compiler/testData/cfg/functions/unmappedArgs.values @@ -0,0 +1,22 @@ +== foo == +fun foo(a: Int, b: Int) = a + b +--------------------- + : Int NEW: magic[FAKE_INITIALIZER](a: Int) -> + : Int NEW: magic[FAKE_INITIALIZER](b: Int) -> +a : Int NEW: r(a) -> +b : Int NEW: r(b) -> +a + b : Int NEW: call(a + b, plus|, ) -> +===================== +== bar == +fun bar(i: Int) { + foo(1, 1, i) +} +--------------------- + : Int NEW: magic[FAKE_INITIALIZER](i: Int) -> + : * NEW: magic[VALUE_CONSUMER](i|) -> +1 : Int NEW: r(1) -> +1 : Int NEW: r(1) -> +i : * NEW: r(i) -> +foo(1, 1, i) : * NEW: call(foo(1, 1, i), foo|, ) -> +{ foo(1, 1, i) } : * COPY +===================== \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/unmappedArgs.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/unmappedArgs.kt new file mode 100644 index 00000000000..24d0f37bbcd --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/unmappedArgs.kt @@ -0,0 +1,5 @@ +fun foo(a: Int, b: Int) = a + b + +fun bar(i: Int) { + foo(1, 1, i) +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt index 3ab3468e5f5..786ef8dab41 100644 --- a/compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt @@ -9,7 +9,7 @@ class A(outer: Outer) { var b: String by foo(getMyProperty()) var r: String by foo(outer.getContainer().getMyProperty()) - var e: String by + foo(getMyProperty()) + var e: String by + foo(getMyProperty()) var f: String by foo(getMyProperty()) - 1 } diff --git a/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/arrayExpression.kt b/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/arrayExpression.kt index 8f3c36721fd..d5c89647e53 100644 --- a/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/arrayExpression.kt +++ b/compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/arrayExpression.kt @@ -1,7 +1,5 @@ package bar fun main(args : Array) { - String[] names = ["ads"] -} - - + String[] names = ["ads"] +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/incompleteCode/kt4866UnresolvedArrayAccess.kt b/compiler/testData/diagnostics/tests/incompleteCode/kt4866UnresolvedArrayAccess.kt index 34f7d17441e..d65fdddf436 100644 --- a/compiler/testData/diagnostics/tests/incompleteCode/kt4866UnresolvedArrayAccess.kt +++ b/compiler/testData/diagnostics/tests/incompleteCode/kt4866UnresolvedArrayAccess.kt @@ -1,5 +1,5 @@ //KT-4866 Resolve does not work inside brackets with unresolved reference before fun test(i: Int, j: Int) { - foo[i, j] + foo[i, j] } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/incompleteCode/unresolvedOperation.kt b/compiler/testData/diagnostics/tests/incompleteCode/unresolvedOperation.kt new file mode 100644 index 00000000000..5b6fceb8f4d --- /dev/null +++ b/compiler/testData/diagnostics/tests/incompleteCode/unresolvedOperation.kt @@ -0,0 +1,4 @@ +fun foo(a: Int) { + !bbb + bbb + a +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/cfg/ControlFlowTestGenerated.java b/compiler/tests/org/jetbrains/jet/cfg/ControlFlowTestGenerated.java index 15bf6b4a93c..7db1f0d6790 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/ControlFlowTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/cfg/ControlFlowTestGenerated.java @@ -472,6 +472,11 @@ public class ControlFlowTestGenerated extends AbstractControlFlowTest { doTest("compiler/testData/cfg/functions/DefaultValuesForArguments.kt"); } + @TestMetadata("unmappedArgs.kt") + public void testUnmappedArgs() throws Exception { + doTest("compiler/testData/cfg/functions/unmappedArgs.kt"); + } + } @TestMetadata("compiler/testData/cfg/tailCalls") diff --git a/compiler/tests/org/jetbrains/jet/cfg/PseudoValueTestGenerated.java b/compiler/tests/org/jetbrains/jet/cfg/PseudoValueTestGenerated.java index 533c9dd06f7..e2fc7e7164f 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/PseudoValueTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/cfg/PseudoValueTestGenerated.java @@ -474,6 +474,11 @@ public class PseudoValueTestGenerated extends AbstractPseudoValueTest { doTest("compiler/testData/cfg/functions/DefaultValuesForArguments.kt"); } + @TestMetadata("unmappedArgs.kt") + public void testUnmappedArgs() throws Exception { + doTest("compiler/testData/cfg/functions/unmappedArgs.kt"); + } + } @TestMetadata("compiler/testData/cfg/tailCalls") diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 4a61fcf18c5..b5e4883fbde 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -1435,6 +1435,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.kt"); } + @TestMetadata("unmappedArgs.kt") + public void testUnmappedArgs() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/unmappedArgs.kt"); + } + @TestMetadata("varInitializationInIfInCycle.kt") public void testVarInitializationInIfInCycle() throws Exception { doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/varInitializationInIfInCycle.kt"); @@ -3806,6 +3811,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest("compiler/testData/diagnostics/tests/incompleteCode/unresolvedArguments.kt"); } + @TestMetadata("unresolvedOperation.kt") + public void testUnresolvedOperation() throws Exception { + doTest("compiler/testData/diagnostics/tests/incompleteCode/unresolvedOperation.kt"); + } + @TestMetadata("variableDeclarationInSelector.kt") public void testVariableDeclarationInSelector() throws Exception { doTest("compiler/testData/diagnostics/tests/incompleteCode/variableDeclarationInSelector.kt");