Report errors when iterator() returns a nullable type
This commit is contained in:
@@ -210,11 +210,15 @@ public interface Errors {
|
||||
DiagnosticFactory1<JetSimpleNameExpression, ClassifierDescriptor> NO_CLASS_OBJECT = DiagnosticFactory1.create(ERROR);
|
||||
SimpleDiagnosticFactory<PsiElement> NO_GENERICS_IN_SUPERTYPE_SPECIFIER = SimpleDiagnosticFactory.create(ERROR);
|
||||
|
||||
SimpleDiagnosticFactory<JetExpression> HAS_NEXT_MISSING = SimpleDiagnosticFactory.create(ERROR);
|
||||
SimpleDiagnosticFactory<JetExpression> HAS_NEXT_FUNCTION_AMBIGUITY = SimpleDiagnosticFactory.create(ERROR);
|
||||
DiagnosticFactory1<JetExpression, JetType> HAS_NEXT_MISSING = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<JetExpression, JetType> HAS_NEXT_FUNCTION_AMBIGUITY = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<JetExpression, JetType> HAS_NEXT_FUNCTION_NONE_APPLICABLE = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<JetExpression, JetType> HAS_NEXT_FUNCTION_TYPE_MISMATCH = DiagnosticFactory1.create(ERROR);
|
||||
SimpleDiagnosticFactory<JetExpression> NEXT_AMBIGUITY = SimpleDiagnosticFactory.create(ERROR);
|
||||
SimpleDiagnosticFactory<JetExpression> NEXT_MISSING = SimpleDiagnosticFactory.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<JetExpression, JetType> NEXT_AMBIGUITY = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<JetExpression, JetType> NEXT_MISSING = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<JetExpression, JetType> NEXT_NONE_APPLICABLE = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
SimpleDiagnosticFactory<JetExpression> ITERATOR_MISSING = SimpleDiagnosticFactory.create(ERROR);
|
||||
AmbiguousDescriptorDiagnosticFactory ITERATOR_AMBIGUITY = AmbiguousDescriptorDiagnosticFactory.create();
|
||||
|
||||
|
||||
+8
-4
@@ -226,12 +226,16 @@ public class DefaultErrorMessages {
|
||||
MAP.put(NO_CLASS_OBJECT, "Please specify constructor invocation; classifier ''{0}'' does not have a class object", NAME);
|
||||
MAP.put(NO_GENERICS_IN_SUPERTYPE_SPECIFIER, "Generic arguments of the base type must be specified");
|
||||
|
||||
MAP.put(HAS_NEXT_MISSING, "Loop range must have an 'iterator().hasNext()' function or an 'iterator().hasNext' property");
|
||||
MAP.put(HAS_NEXT_FUNCTION_AMBIGUITY, "Function 'iterator().hasNext()' is ambiguous for this expression");
|
||||
MAP.put(HAS_NEXT_MISSING, "hasNext() cannot be called on iterator() of type ''{0}''", RENDER_TYPE);
|
||||
MAP.put(HAS_NEXT_FUNCTION_AMBIGUITY, "hasNext() is ambiguous for iterator() of type ''{0}''", RENDER_TYPE);
|
||||
MAP.put(HAS_NEXT_FUNCTION_NONE_APPLICABLE, "None of the hasNext() functions is applicable for iterator() of type ''{0}''", RENDER_TYPE);
|
||||
MAP.put(HAS_NEXT_FUNCTION_TYPE_MISMATCH, "The ''iterator().hasNext()'' function of the loop range must return jet.Boolean, but returns {0}",
|
||||
RENDER_TYPE);
|
||||
MAP.put(NEXT_AMBIGUITY, "Function 'iterator().next()' is ambiguous for this expression");
|
||||
MAP.put(NEXT_MISSING, "Loop range must have an 'iterator().next()' function");
|
||||
|
||||
MAP.put(NEXT_MISSING, "next() cannot be called on iterator() of type ''{0}''", RENDER_TYPE);
|
||||
MAP.put(NEXT_AMBIGUITY, "next() is ambiguous for iterator() of type ''{0}''", RENDER_TYPE);
|
||||
MAP.put(NEXT_NONE_APPLICABLE, "None of the next() functions is applicable for iterator() of type ''{0}''", RENDER_TYPE);
|
||||
|
||||
MAP.put(ITERATOR_MISSING, "For-loop range must have an iterator() method");
|
||||
MAP.put(ITERATOR_AMBIGUITY, "Method ''iterator()'' is ambiguous for this expression: {0}", AMBIGUOUS_CALLS);
|
||||
|
||||
|
||||
+13
-7
@@ -25,8 +25,8 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory1;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.diagnostics.SimpleDiagnosticFactory;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
@@ -340,12 +340,13 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
FunctionDescriptor iteratorFunction = iteratorResolvedCall.getResultingDescriptor();
|
||||
JetType iteratorType = iteratorFunction.getReturnType();
|
||||
JetType hasNextType = checkConventionForIterator(context, loopRangeExpression, iteratorType, "hasNext",
|
||||
HAS_NEXT_FUNCTION_AMBIGUITY, HAS_NEXT_MISSING,
|
||||
HAS_NEXT_FUNCTION_AMBIGUITY, HAS_NEXT_MISSING, HAS_NEXT_FUNCTION_NONE_APPLICABLE,
|
||||
LOOP_RANGE_HAS_NEXT_RESOLVED_CALL);
|
||||
if (hasNextType != null && !isBoolean(hasNextType)) {
|
||||
context.trace.report(HAS_NEXT_FUNCTION_TYPE_MISMATCH.on(loopRangeExpression, hasNextType));
|
||||
}
|
||||
return checkConventionForIterator(context, loopRangeExpression, iteratorType, "next", NEXT_AMBIGUITY, NEXT_MISSING,
|
||||
return checkConventionForIterator(context, loopRangeExpression, iteratorType, "next",
|
||||
NEXT_AMBIGUITY, NEXT_MISSING, NEXT_NONE_APPLICABLE,
|
||||
LOOP_RANGE_NEXT_RESOLVED_CALL);
|
||||
}
|
||||
else {
|
||||
@@ -370,19 +371,24 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
@NotNull JetExpression loopRangeExpression,
|
||||
@NotNull JetType iteratorType,
|
||||
@NotNull String name,
|
||||
@NotNull SimpleDiagnosticFactory<JetExpression> ambiguity,
|
||||
@NotNull SimpleDiagnosticFactory<JetExpression> missing,
|
||||
@NotNull DiagnosticFactory1<JetExpression, JetType> ambiguity,
|
||||
@NotNull DiagnosticFactory1<JetExpression, JetType> missing,
|
||||
@NotNull DiagnosticFactory1<JetExpression, JetType> noneApplicable,
|
||||
@NotNull WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> resolvedCallKey
|
||||
) {
|
||||
OverloadResolutionResults<FunctionDescriptor> nextResolutionResults = resolveFakeCall(
|
||||
new TransientReceiver(iteratorType), context, Name.identifier(name));
|
||||
if (nextResolutionResults.isAmbiguity()) {
|
||||
context.trace.report(ambiguity.on(loopRangeExpression));
|
||||
context.trace.report(ambiguity.on(loopRangeExpression, iteratorType));
|
||||
}
|
||||
else if (nextResolutionResults.isNothing()) {
|
||||
context.trace.report(missing.on(loopRangeExpression));
|
||||
context.trace.report(missing.on(loopRangeExpression, iteratorType));
|
||||
}
|
||||
else if (!nextResolutionResults.isSuccess()) {
|
||||
context.trace.report(noneApplicable.on(loopRangeExpression, iteratorType));
|
||||
}
|
||||
else {
|
||||
assert nextResolutionResults.isSuccess();
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall = nextResolutionResults.getResultingCall();
|
||||
context.trace.record(resolvedCallKey, loopRangeExpression, resolvedCall);
|
||||
return resolvedCall.getResultingDescriptor().getReturnType();
|
||||
|
||||
Reference in New Issue
Block a user