From 1db026aac5635859b5376889a06d16024d6caa0f Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 17 Apr 2013 15:41:10 +0400 Subject: [PATCH] Add CheckValueArgumentsMode to call resolver Now it's ENABLED everywhere. DISABLED will be used for resolving callable reference expressions, since there won't be any arguments near the function call to check #KT-1183 In Progress --- .../resolve/calls/CallExpressionResolver.java | 13 ++++--- .../jet/lang/resolve/calls/CallResolver.java | 20 +++++++---- .../lang/resolve/calls/CallTransformer.java | 6 ++-- .../lang/resolve/calls/CandidateResolver.java | 35 ++++++++++--------- .../context/BasicCallResolutionContext.java | 15 ++++---- .../CallCandidateResolutionContext.java | 22 +++++++----- .../calls/context/CallResolutionContext.java | 5 ++- .../context/CheckValueArgumentsMode.java | 22 ++++++++++++ .../resolve/calls/tasks/ResolutionTask.java | 12 ++++--- .../expressions/ExpressionTypingContext.java | 7 ++-- 10 files changed, 105 insertions(+), 52 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/CheckValueArgumentsMode.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java index d71e8272047..11f2e585a66 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java @@ -192,11 +192,12 @@ public class CallExpressionResolver { private ResolvedCallWithTrace getResolvedCallForFunction( @NotNull Call call, @NotNull JetExpression callExpression, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode, - @NotNull ResolutionResultsCache resolutionResultsCache, @NotNull boolean[] result + @NotNull CheckValueArgumentsMode checkArguments, @NotNull ResolutionResultsCache resolutionResultsCache, + @NotNull boolean[] result ) { CallResolver callResolver = expressionTypingServices.getCallResolver(); OverloadResolutionResultsImpl results = callResolver.resolveFunctionCall( - BasicCallResolutionContext.create(context, call, resolveMode, resolutionResultsCache)); + BasicCallResolutionContext.create(context, call, resolveMode, checkArguments, resolutionResultsCache)); if (!results.isNothing()) { checkSuper(call.getExplicitReceiver(), results, context.trace, callExpression); result[0] = true; @@ -220,7 +221,7 @@ public class CallExpressionResolver { Call call = CallMaker.makePropertyCall(receiver, callOperationNode, nameExpression); OverloadResolutionResults resolutionResult = callResolver.resolveSimpleProperty( BasicCallResolutionContext.create(context.replaceBindingTrace(traceForVariable), call, ResolveMode.TOP_LEVEL_CALL, - ResolutionResultsCache.create())); + CheckValueArgumentsMode.ENABLED, ResolutionResultsCache.create())); if (!resolutionResult.isNothing()) { traceForVariable.commit(); checkSuper(receiver, resolutionResult, context.trace, nameExpression); @@ -268,7 +269,8 @@ public class CallExpressionResolver { Call call = CallMaker.makeCall(nameExpression, receiver, callOperationNode, nameExpression, Collections.emptyList()); TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", nameExpression); ResolvedCall resolvedCall = getResolvedCallForFunction( - call, nameExpression, context, ResolveMode.TOP_LEVEL_CALL, ResolutionResultsCache.create(), result); + call, nameExpression, context, ResolveMode.TOP_LEVEL_CALL, CheckValueArgumentsMode.ENABLED, + ResolutionResultsCache.create(), result); if (result[0]) { FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null; traceForFunction.commit(); @@ -307,7 +309,8 @@ public class CallExpressionResolver { TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function call", callExpression); ResolvedCallWithTrace resolvedCall = getResolvedCallForFunction( - call, callExpression, context.replaceBindingTrace(traceForFunction), resolveMode, resolutionResultsCache, result); + call, callExpression, context.replaceBindingTrace(traceForFunction), resolveMode, CheckValueArgumentsMode.ENABLED, + resolutionResultsCache, result); if (result[0]) { FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null; traceForFunction.commit(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index eb07f95bcb5..ebee3a0a702 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -29,7 +29,10 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.context.*; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; -import org.jetbrains.jet.lang.resolve.calls.results.*; +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.ResolutionDebugInfo; +import org.jetbrains.jet.lang.resolve.calls.results.ResolutionResultsHandler; import org.jetbrains.jet.lang.resolve.calls.tasks.*; import org.jetbrains.jet.lang.resolve.calls.util.DelegatingCall; import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; @@ -45,11 +48,15 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lexer.JetTokens; import javax.inject.Inject; -import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER; import static org.jetbrains.jet.lang.diagnostics.Errors.*; -import static org.jetbrains.jet.lang.resolve.BindingContext.*; +import static org.jetbrains.jet.lang.resolve.BindingContext.NON_DEFAULT_EXPRESSION_DATA_FLOW; +import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLUTION_SCOPE; import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS; import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; @@ -125,8 +132,8 @@ public class CallResolver { @NotNull DataFlowInfo dataFlowInfo ) { return resolveFunctionCall(BasicCallResolutionContext.create( - trace, scope, call, expectedType, dataFlowInfo, ResolveMode.TOP_LEVEL_CALL, ExpressionPosition.FREE, - ResolutionResultsCache.create())); + trace, scope, call, expectedType, dataFlowInfo, ResolveMode.TOP_LEVEL_CALL, CheckValueArgumentsMode.ENABLED, + ExpressionPosition.FREE, ResolutionResultsCache.create())); } @NotNull @@ -482,7 +489,8 @@ public class CallResolver { public List getFunctionLiteralArguments() { return Collections.emptyList(); } - }, task.expectedType, task.dataFlowInfo, task.resolveMode, task.expressionPosition, task.resolutionResultsCache); + }, task.expectedType, task.dataFlowInfo, task.resolveMode, task.checkArguments, + task.expressionPosition, task.resolutionResultsCache); OverloadResolutionResultsImpl resultsWithFunctionLiteralsStripped = performResolution(newTask, callTransformer, traceForResolutionCache); if (resultsWithFunctionLiteralsStripped.isSuccess() || resultsWithFunctionLiteralsStripped.isAmbiguity()) { task.tracing.danglingFunctionLiteralArgumentSuspected(task.trace, task.call.getFunctionLiteralArguments()); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallTransformer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallTransformer.java index add94b637ef..2b63eb07847 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallTransformer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallTransformer.java @@ -25,7 +25,9 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.*; +import org.jetbrains.jet.lang.resolve.ChainedTemporaryBindingTrace; +import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; +import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext; import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl; @@ -194,7 +196,7 @@ public class CallTransformer { DelegatingBindingTrace variableCallTrace = context.candidateCall.getTrace(); BasicCallResolutionContext basicCallResolutionContext = BasicCallResolutionContext.create( variableCallTrace, context.scope, functionCall, context.expectedType, context.dataFlowInfo, - context.resolveMode, context.expressionPosition, context.resolutionResultsCache); + context.resolveMode, context.checkArguments, context.expressionPosition, context.resolutionResultsCache); // 'invoke' call resolve OverloadResolutionResults results = callResolver.resolveCallWithGivenName(basicCallResolutionContext, task.reference, Name.identifier("invoke")); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index aaec75b59fe..cc5e29548c7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.calls.autocasts.*; import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext; import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext; +import org.jetbrains.jet.lang.resolve.calls.context.CheckValueArgumentsMode; import org.jetbrains.jet.lang.resolve.calls.context.ResolveMode; import org.jetbrains.jet.lang.resolve.calls.inference.*; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; @@ -98,23 +99,25 @@ public class CandidateResolver { return; } - Set unmappedArguments = Sets.newLinkedHashSet(); - ValueArgumentsToParametersMapper.Status - argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(context.call, context.tracing, - candidateCall, unmappedArguments); - if (!argumentMappingStatus.isSuccess()) { - if (argumentMappingStatus == ValueArgumentsToParametersMapper.Status.STRONG_ERROR) { - candidateCall.addStatus(STRONG_ERROR); + if (task.checkArguments == CheckValueArgumentsMode.ENABLED) { + Set unmappedArguments = Sets.newLinkedHashSet(); + ValueArgumentsToParametersMapper.Status + argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(context.call, context.tracing, + candidateCall, unmappedArguments); + if (!argumentMappingStatus.isSuccess()) { + if (argumentMappingStatus == ValueArgumentsToParametersMapper.Status.STRONG_ERROR) { + candidateCall.addStatus(STRONG_ERROR); + } + else { + candidateCall.addStatus(OTHER_ERROR); + } + if ((argumentMappingStatus == ValueArgumentsToParametersMapper.Status.ERROR && candidate.getTypeParameters().isEmpty()) || + argumentMappingStatus == ValueArgumentsToParametersMapper.Status.STRONG_ERROR) { + argumentTypeResolver.checkTypesWithNoCallee(context.toBasic()); + return; + } + candidateCall.setUnmappedArguments(unmappedArguments); } - else { - candidateCall.addStatus(OTHER_ERROR); - } - if ((argumentMappingStatus == ValueArgumentsToParametersMapper.Status.ERROR && candidate.getTypeParameters().isEmpty()) || - argumentMappingStatus == ValueArgumentsToParametersMapper.Status.STRONG_ERROR) { - argumentTypeResolver.checkTypesWithNoCallee(context.toBasic()); - return; - } - candidateCall.setUnmappedArguments(unmappedArguments); } List jetTypeArguments = context.call.getTypeArguments(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/BasicCallResolutionContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/BasicCallResolutionContext.java index e6fb9510aec..c0343251861 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/BasicCallResolutionContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/BasicCallResolutionContext.java @@ -32,23 +32,26 @@ public class BasicCallResolutionContext extends CallResolutionContext @NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo, @NotNull ResolveMode resolveMode, + @NotNull CheckValueArgumentsMode checkArguments, @NotNull ExpressionPosition expressionPosition, @NotNull ResolutionResultsCache resolutionResultsCache ) { - super(trace, scope, call, expectedType, dataFlowInfo, resolveMode, expressionPosition, resolutionResultsCache); + super(trace, scope, call, expectedType, dataFlowInfo, resolveMode, checkArguments, expressionPosition, resolutionResultsCache); this.candidateCall = candidateCall; this.tracing = tracing; } @@ -55,7 +56,8 @@ public final class CallCandidateResolutionContext candidateCall.setInitialDataFlowInfo(context.dataFlowInfo); return new CallCandidateResolutionContext( candidateCall, tracing, trace, context.scope, call, context.expectedType, - context.dataFlowInfo, context.resolveMode, context.expressionPosition, context.resolutionResultsCache); + context.dataFlowInfo, context.resolveMode, context.checkArguments, + context.expressionPosition, context.resolutionResultsCache); } public static CallCandidateResolutionContext create( @@ -67,16 +69,18 @@ public final class CallCandidateResolutionContext public static CallCandidateResolutionContext createForCallBeingAnalyzed( @NotNull ResolvedCallImpl candidateCall, @NotNull BasicCallResolutionContext context, @NotNull TracingStrategy tracing ) { - return createForCallBeingAnalyzed(candidateCall, context, context.call, context.resolveMode, tracing, context.resolutionResultsCache); + return createForCallBeingAnalyzed(candidateCall, context, context.call, context.resolveMode, + context.checkArguments, tracing, context.resolutionResultsCache); } public static CallCandidateResolutionContext createForCallBeingAnalyzed( @NotNull ResolvedCallImpl candidateCall, @NotNull ResolutionContext context, @NotNull Call call, - @NotNull ResolveMode resolveMode, @NotNull TracingStrategy tracing, @NotNull ResolutionResultsCache resolutionResultsCache + @NotNull ResolveMode resolveMode, @NotNull CheckValueArgumentsMode checkArguments, @NotNull TracingStrategy tracing, + @NotNull ResolutionResultsCache resolutionResultsCache ) { return new CallCandidateResolutionContext( candidateCall, tracing, context.trace, context.scope, call, context.expectedType, - context.dataFlowInfo, resolveMode, context.expressionPosition, resolutionResultsCache); + context.dataFlowInfo, resolveMode, checkArguments, context.expressionPosition, resolutionResultsCache); } @Override @@ -88,8 +92,8 @@ public final class CallCandidateResolutionContext @NotNull ExpressionPosition expressionPosition ) { return new CallCandidateResolutionContext( - candidateCall, tracing, trace, scope, call, expectedType, dataFlowInfo, resolveMode, expressionPosition, - resolutionResultsCache); + candidateCall, tracing, trace, scope, call, expectedType, dataFlowInfo, resolveMode, + checkArguments, expressionPosition, resolutionResultsCache); } @Override @@ -101,7 +105,7 @@ public final class CallCandidateResolutionContext public CallCandidateResolutionContext replaceResolveMode(@NotNull ResolveMode newResolveMode) { if (newResolveMode == resolveMode) return this; return new CallCandidateResolutionContext( - candidateCall, tracing, trace, scope, call, expectedType, dataFlowInfo, newResolveMode, expressionPosition, - resolutionResultsCache); + candidateCall, tracing, trace, scope, call, expectedType, dataFlowInfo, newResolveMode, + checkArguments, expressionPosition, resolutionResultsCache); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/CallResolutionContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/CallResolutionContext.java index 1c1c185f6dc..9df3b445dd7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/CallResolutionContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/CallResolutionContext.java @@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.types.JetType; public abstract class CallResolutionContext extends ResolutionContext { public final Call call; public final ResolveMode resolveMode; + public final CheckValueArgumentsMode checkArguments; public final ResolutionResultsCache resolutionResultsCache; protected CallResolutionContext( @@ -35,16 +36,18 @@ public abstract class CallResolutionContext extends C public ResolutionTask( @NotNull Collection> candidates, @NotNull JetReferenceExpression reference, @NotNull TracingStrategy tracing, BindingTrace trace, JetScope scope, Call call, JetType expectedType, - DataFlowInfo dataFlowInfo, ResolveMode resolveMode, ExpressionPosition expressionPosition, ResolutionResultsCache resolutionResultsCache + DataFlowInfo dataFlowInfo, ResolveMode resolveMode, CheckValueArgumentsMode checkArguments, + ExpressionPosition expressionPosition, ResolutionResultsCache resolutionResultsCache ) { - super(trace, scope, call, expectedType, dataFlowInfo, resolveMode, expressionPosition, resolutionResultsCache); + super(trace, scope, call, expectedType, dataFlowInfo, resolveMode, checkArguments, expressionPosition, resolutionResultsCache); this.candidates = candidates; this.reference = reference; this.tracing = tracing; @@ -54,7 +55,8 @@ public class ResolutionTask extends C public ResolutionTask(@NotNull Collection> candidates, @NotNull JetReferenceExpression reference, @NotNull BasicCallResolutionContext context) { this(candidates, reference, TracingStrategyImpl.create(reference, context.call), context.trace, context.scope, context.call, - context.expectedType, context.dataFlowInfo, context.resolveMode, context.expressionPosition, context.resolutionResultsCache); + context.expectedType, context.dataFlowInfo, context.resolveMode, context.checkArguments, + context.expressionPosition, context.resolutionResultsCache); } @NotNull @@ -87,8 +89,8 @@ public class ResolutionTask extends C @NotNull ExpressionPosition expressionPosition ) { ResolutionTask newTask = new ResolutionTask( - candidates, reference, tracing, trace, scope, call, expectedType, dataFlowInfo, resolveMode, expressionPosition, - resolutionResultsCache); + candidates, reference, tracing, trace, scope, call, expectedType, dataFlowInfo, resolveMode, checkArguments, + expressionPosition, resolutionResultsCache); newTask.setCheckingStrategy(checkingStrategy); return newTask; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java index 5d96d1f29cd..d05bb00c3ae 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java @@ -21,7 +21,6 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.psi.Call; import org.jetbrains.jet.lang.psi.JetReferenceExpression; import org.jetbrains.jet.lang.resolve.BindingTrace; -import org.jetbrains.jet.lang.resolve.TraceUtil; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.context.*; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; @@ -105,6 +104,10 @@ public class ExpressionTypingContext extends ResolutionContext resolveCallWithGivenName(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull Name name) { return expressionTypingServices.getCallResolver().resolveCallWithGivenName( - BasicCallResolutionContext.create(this, call, ResolveMode.TOP_LEVEL_CALL, ResolutionResultsCache.create()), functionReference, name); + BasicCallResolutionContext.create(this, call, ResolveMode.TOP_LEVEL_CALL, + CheckValueArgumentsMode.ENABLED, ResolutionResultsCache.create()), + functionReference, + name + ); } }