diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionStatus.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionStatus.java index 5e53fbb25aa..d1584abad00 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionStatus.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionStatus.java @@ -49,7 +49,7 @@ public enum ResolutionStatus { } public ResolutionStatus combine(ResolutionStatus other) { - if (this.isSuccess()) return other; + if (this == UNKNOWN_STATUS || this.isSuccess()) return other; if (!other.isSuccess() && this.getSeverityIndex() < other.getSeverityIndex()) return other; return this; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolvedCallImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolvedCallImpl.java index 7f7d1b84411..2bf2516e751 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolvedCallImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolvedCallImpl.java @@ -81,8 +81,8 @@ public class ResolvedCallImpl implements ResolvedC return status; } - public void setStatus(@NotNull ResolutionStatus status) { - this.status = status; + public void addStatus(@NotNull ResolutionStatus status) { + this.status = this.status.combine(status); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java index b0310bafbef..e88d16dd086 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java @@ -33,17 +33,49 @@ import java.util.Set; import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; +import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMapper.Status.ERROR; +import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMapper.Status.OK; +import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMapper.Status.WEAK_ERROR; /** * @author abreslav */ /*package*/ class ValueArgumentsToParametersMapper { - public static boolean mapValueArgumentsToParameters( + + public enum Status { + ERROR(false), + WEAK_ERROR(false), + OK(true); + + private final boolean success; + + private Status(boolean success) { + this.success = success; + } + + public boolean isSuccess() { + return success; + } + + public Status compose(Status other) { + switch (other) { + case ERROR: + return ERROR; + case WEAK_ERROR: + if (this != ERROR) { + return WEAK_ERROR; + } + default: + return this; + } + } + } + + public static Status mapValueArgumentsToParameters( @NotNull Call call, @NotNull TracingStrategy tracing, @NotNull ResolvedCallImpl candidateCall ) { - TemporaryBindingTrace temporaryTrace = candidateCall.getTrace(); Map varargs = Maps.newHashMap(); Set usedParameters = Sets.newHashSet(); @@ -61,7 +93,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; List valueArguments = call.getValueArguments(); - boolean error = false; + Status status = OK; boolean someNamed = false; boolean somePositioned = false; for (int i = 0; i < valueArguments.size(); i++) { @@ -72,47 +104,47 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(nameReference.getReferencedName()); if (valueParameterDescriptor == null) { temporaryTrace.report(NAMED_PARAMETER_NOT_FOUND.on(nameReference)); - error = true; + status = ERROR; } else { if (!usedParameters.add(valueParameterDescriptor)) { temporaryTrace.report(ARGUMENT_PASSED_TWICE.on(nameReference)); } temporaryTrace.record(REFERENCE_TARGET, nameReference, valueParameterDescriptor); - put(candidateCall, valueParameterDescriptor, valueArgument, varargs); + status = status.compose(put(candidateCall, valueParameterDescriptor, valueArgument, varargs)); } if (somePositioned) { temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(nameReference)); - error = true; + status = ERROR; } } else { somePositioned = true; if (someNamed) { temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(valueArgument.asElement())); - error = true; + status = ERROR; } else { int parameterCount = valueParameters.size(); if (i < parameterCount) { ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(i); usedParameters.add(valueParameterDescriptor); - put(candidateCall, valueParameterDescriptor, valueArgument, varargs); + status = status.compose(put(candidateCall, valueParameterDescriptor, valueArgument, varargs)); } else if (!valueParameters.isEmpty()) { ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1); if (valueParameterDescriptor.getVarargElementType() != null) { - put(candidateCall, valueParameterDescriptor, valueArgument, varargs); + status = status.compose(put(candidateCall, valueParameterDescriptor, valueArgument, varargs)); usedParameters.add(valueParameterDescriptor); } else { temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate)); - error = true; + status = ERROR; } } else { temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate)); - error = true; + status = ERROR; } } } @@ -124,7 +156,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; if (valueParameters.isEmpty()) { temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate)); - error = true; + status = ERROR; } else { JetFunctionLiteralExpression functionLiteral; @@ -139,15 +171,15 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1); if (valueParameterDescriptor.getVarargElementType() != null) { temporaryTrace.report(VARARG_OUTSIDE_PARENTHESES.on(possiblyLabeledFunctionLiteral)); - error = true; + status = ERROR; } else { if (!usedParameters.add(valueParameterDescriptor)) { temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate)); - error = true; + status = ERROR; } else { - put(candidateCall, valueParameterDescriptor, CallMaker.makeValueArgument(functionLiteral), varargs); + status = status.compose(put(candidateCall, valueParameterDescriptor, CallMaker.makeValueArgument(functionLiteral), varargs)); } } } @@ -155,7 +187,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; for (int i = 1; i < functionLiteralArguments.size(); i++) { JetExpression argument = functionLiteralArguments.get(i); temporaryTrace.report(MANY_FUNCTION_LITERAL_ARGUMENTS.on(argument)); - error = true; + status = ERROR; } } @@ -171,7 +203,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; else { // tracing.reportWrongValueArguments(temporaryTrace, "No value passed for parameter " + valueParameter.getName()); tracing.noValueForParameter(temporaryTrace, valueParameter); - error = true; + status = ERROR; } } } @@ -180,21 +212,22 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; ReceiverDescriptor receiverArgument = candidateCall.getReceiverArgument(); if (receiverParameter.exists() &&!receiverArgument.exists()) { tracing.missingReceiver(temporaryTrace, receiverParameter); - error = true; + status = ERROR; } if (!receiverParameter.exists() && receiverArgument.exists()) { tracing.noReceiverAllowed(temporaryTrace); - error = true; + status = ERROR; } if (candidateCall.getThisObject().exists() != candidateCall.getResultingDescriptor().getExpectedThisObject().exists()) { assert false : "Shouldn't happen because of TaskPrioritizer: " + candidateCall.getCandidateDescriptor(); } - return error; + return status; } - private static void put(ResolvedCallImpl candidateCall, ValueParameterDescriptor valueParameterDescriptor, ValueArgument valueArgument, Map varargs) { + private static Status put(ResolvedCallImpl candidateCall, ValueParameterDescriptor valueParameterDescriptor, ValueArgument valueArgument, Map varargs) { + Status error = OK; if (valueParameterDescriptor.getVarargElementType() != null) { VarargValueArgument vararg = varargs.get(valueParameterDescriptor); if (vararg == null) { @@ -207,11 +240,13 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; else { LeafPsiElement spread = valueArgument.getSpreadElement(); if (spread != null) { - candidateCall.getTrace().report(NON_VARARG_SPREAD.on(spread)); + candidateCall.getTrace().report(NON_VARARG_SPREAD.on(spread)); + error = WEAK_ERROR; } ResolvedValueArgument argument = new ExpressionValueArgument(valueArgument); candidateCall.recordValueArgument(valueParameterDescriptor, argument); } + return error; } /**