diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 01a1d76eaed..cc569781877 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -8,7 +8,7 @@ import gnu.trove.THashSet; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods; -import org.jetbrains.jet.lang.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java index 8e342f3ef52..529efb13de6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java @@ -7,7 +7,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.util.containers.Stack; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods; -import org.jetbrains.jet.lang.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.psi.*; 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 e70d6126f13..5c6a6707b46 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -3,7 +3,6 @@ package org.jetbrains.jet.lang.cfg; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTrace; @@ -12,6 +11,8 @@ import org.jetbrains.jet.lexer.JetTokens; import java.util.*; +import static org.jetbrains.jet.lang.diagnostics.Errors.*; + /** * @author abreslav */ @@ -75,12 +76,13 @@ public class JetControlFlowProcessor { Stack stack = labeledElements.get(labelName); if (stack == null || stack.isEmpty()) { if (reportUnresolved) { - trace.getErrorHandler().unresolvedReference(labelExpression); + trace.report(UNRESOLVED_REFERENCE.on(labelExpression)); } return null; } else if (stack.size() > 1) { - trace.getErrorHandler().genericWarning(labelExpression.getNode(), "There is more than one label with such a name in this scope"); +// trace.getErrorHandler().genericWarning(labelExpression.getNode(), "There is more than one label with such a name in this scope"); + trace.report(LABEL_NAME_CLASH.on(labelExpression)); } JetElement result = stack.peek(); @@ -437,14 +439,16 @@ public class JetControlFlowProcessor { assert targetLabel != null; loop = resolveLabel(labelName, targetLabel, true); if (!isLoop(loop)) { - trace.getErrorHandler().genericError(expression.getNode(), "The label '" + targetLabel.getText() + "' does not denote a loop"); +// trace.getErrorHandler().genericError(expression.getNode(), "The label '" + targetLabel.getText() + "' does not denote a loop"); + trace.report(NOT_A_LOOP_LABEL.on(expression, targetLabel.getText())); loop = null; } } else { loop = builder.getCurrentLoop(); if (loop == null) { - trace.getErrorHandler().genericError(expression.getNode(), "'break' and 'continue' are only allowed inside a loop"); +// trace.getErrorHandler().genericError(expression.getNode(), "'break' and 'continue' are only allowed inside a loop"); + trace.report(BREAK_OR_CONTINUE_OUTSIDE_A_LOOP.on(expression)); } } return loop; @@ -627,7 +631,8 @@ public class JetControlFlowProcessor { if (whenEntry.isElse()) { if (iterator.hasNext()) { - trace.getErrorHandler().genericError(whenEntry.getNode(), "'else' entry must be the last one in a when-expression"); +// trace.getErrorHandler().genericError(whenEntry.getNode(), "'else' entry must be the last one in a when-expression"); + trace.report(ELSE_MISPLACED_IN_WHEN.on(whenEntry)); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/CollectingErrorHandler.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/CollectingErrorHandler.java similarity index 97% rename from compiler/frontend/src/org/jetbrains/jet/lang/CollectingErrorHandler.java rename to compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/CollectingErrorHandler.java index f28dd05c061..94bb3aa7d6e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/CollectingErrorHandler.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/CollectingErrorHandler.java @@ -1,4 +1,4 @@ -package org.jetbrains.jet.lang; +package org.jetbrains.jet.lang.diagnostics; import com.google.common.collect.Lists; import com.intellij.lang.ASTNode; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/CompositeErrorHandler.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/CompositeErrorHandler.java similarity index 97% rename from compiler/frontend/src/org/jetbrains/jet/lang/CompositeErrorHandler.java rename to compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/CompositeErrorHandler.java index b1e05adbe23..b35893cf3b1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/CompositeErrorHandler.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/CompositeErrorHandler.java @@ -1,4 +1,4 @@ -package org.jetbrains.jet.lang; +package org.jetbrains.jet.lang.diagnostics; import com.intellij.lang.ASTNode; import org.jetbrains.annotations.NotNull; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Diagnostic.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Diagnostic.java new file mode 100644 index 00000000000..12531a8c59e --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Diagnostic.java @@ -0,0 +1,18 @@ +package org.jetbrains.jet.lang.diagnostics; + +import org.jetbrains.annotations.NotNull; + +/** +* @author abreslav +*/ +public interface Diagnostic { + + @NotNull + DiagnosticFactory getFactory(); + + @NotNull + String getMessage(); + + @NotNull + Severity getSeverity(); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactory.java new file mode 100644 index 00000000000..ddf0e14d23e --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactory.java @@ -0,0 +1,12 @@ +package org.jetbrains.jet.lang.diagnostics; + +import com.intellij.openapi.util.TextRange; +import org.jetbrains.annotations.NotNull; + +/** +* @author abreslav +*/ +public interface DiagnosticFactory { + @NotNull + TextRange getMarkerPosition(@NotNull Diagnostic diagnostic); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticHolder.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticHolder.java new file mode 100644 index 00000000000..82e58183371 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticHolder.java @@ -0,0 +1,10 @@ +package org.jetbrains.jet.lang.diagnostics; + +import org.jetbrains.annotations.NotNull; + +/** +* @author abreslav +*/ +public interface DiagnosticHolder { + void report(@NotNull Diagnostic diagnostic); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticWithTextRange.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticWithTextRange.java new file mode 100644 index 00000000000..8bce93377ef --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticWithTextRange.java @@ -0,0 +1,13 @@ +package org.jetbrains.jet.lang.diagnostics; + +import com.intellij.openapi.util.TextRange; +import org.jetbrains.annotations.NotNull; + +/** + * @author abreslav + */ +public interface DiagnosticWithTextRange extends Diagnostic { + @NotNull + TextRange getTextRange(); + +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/ErrorHandler.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/ErrorHandler.java similarity index 78% rename from compiler/frontend/src/org/jetbrains/jet/lang/ErrorHandler.java rename to compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/ErrorHandler.java index ad8c92bb091..7c121afe51d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/ErrorHandler.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/ErrorHandler.java @@ -1,4 +1,4 @@ -package org.jetbrains.jet.lang; +package org.jetbrains.jet.lang.diagnostics; import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; @@ -65,17 +65,31 @@ public class ErrorHandler { } public static void applyHandler(@NotNull ErrorHandler errorHandler, @NotNull BindingContext bindingContext) { - Collection diagnostics = bindingContext.getDiagnostics(); - applyHandler(errorHandler, diagnostics); + Collection diagnostics = bindingContext.getOld_Diagnostics(); + old_applyHandler(errorHandler, diagnostics); + applyHandler(errorHandler, bindingContext.getDiagnostics()); } - public static void applyHandler(@NotNull ErrorHandler errorHandler, @NotNull Collection diagnostics) { + public static void applyHandler(@NotNull ErrorHandler errorHandler, @NotNull Collection diagnostics) { + for (Diagnostic diagnostic : diagnostics) { + if (diagnostic instanceof Errors.UnresolvedReferenceDiagnosticFactory.UnresolvedReferenceDiagnostic) { + Errors.UnresolvedReferenceDiagnosticFactory.UnresolvedReferenceDiagnostic unresolvedReferenceDiagnostic = (Errors.UnresolvedReferenceDiagnosticFactory.UnresolvedReferenceDiagnostic) diagnostic; + errorHandler.unresolvedReference(unresolvedReferenceDiagnostic.getReference()); + } +// else { +// if (diagnostic.getSeverity() == Severity.ERROR) { +// +// } +// } + } + } + + public static void old_applyHandler(@NotNull ErrorHandler errorHandler, @NotNull Collection diagnostics) { for (JetDiagnostic jetDiagnostic : diagnostics) { jetDiagnostic.acceptHandler(errorHandler); } } - public void unresolvedReference(@NotNull JetReferenceExpression referenceExpression) { } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/ErrorHandlerAdapter.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/ErrorHandlerAdapter.java similarity index 96% rename from compiler/frontend/src/org/jetbrains/jet/lang/ErrorHandlerAdapter.java rename to compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/ErrorHandlerAdapter.java index ba2461c11e6..8a7817924a7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/ErrorHandlerAdapter.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/ErrorHandlerAdapter.java @@ -1,4 +1,4 @@ -package org.jetbrains.jet.lang; +package org.jetbrains.jet.lang.diagnostics; import com.intellij.lang.ASTNode; import org.jetbrains.annotations.NotNull; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java new file mode 100644 index 00000000000..9b7a477a590 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -0,0 +1,481 @@ +package org.jetbrains.jet.lang.diagnostics; + +import com.intellij.lang.ASTNode; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.resolve.DescriptorRenderer; + +import java.util.Collection; +import java.util.Iterator; + +import static org.jetbrains.jet.lang.diagnostics.Severity.ERROR; +import static org.jetbrains.jet.lang.diagnostics.Severity.WARNING; + +/** + * @author abreslav + */ +public interface Errors { + + public class AbstractDiagnosticFactory implements DiagnosticFactory { + protected final String message; + protected final Severity severity; + + public AbstractDiagnosticFactory(Severity severity, String message) { + this.severity = severity; + this.message = message; + } + + @NotNull + @Override + public TextRange getMarkerPosition(@NotNull Diagnostic diagnostic) { + return ((DiagnosticWithTextRange) diagnostic).getTextRange(); + } + } + + public class SimpleDiagnosticFactory extends AbstractDiagnosticFactory { + + public static SimpleDiagnosticFactory create(Severity severity, String message) { + return new SimpleDiagnosticFactory(severity, message); + } + + protected SimpleDiagnosticFactory(Severity severity, String message) { + super(severity, message); + } + + @NotNull + public Diagnostic on(@NotNull TextRange range) { + return new GenericDiagnostic(this, severity, message, range); + } + + @NotNull + public Diagnostic on(@NotNull ASTNode node) { + return on(node.getTextRange()); + } + + @NotNull + public Diagnostic on(@NotNull PsiElement element) { + return on(element.getTextRange()); + } + + } + + public class ParameterizedDiagnosticFactory1 extends AbstractDiagnosticFactory { + public static ParameterizedDiagnosticFactory1 create(Severity severity, String messageStub) { + return new ParameterizedDiagnosticFactory1(severity, messageStub); + } + + protected ParameterizedDiagnosticFactory1(Severity severity, String messageStub) { + super(severity, messageStub); + } + + protected String makeMessage(@NotNull T argument) { + return String.format(message, argument); + } + + @NotNull + public Diagnostic on(@NotNull TextRange range, @NotNull T argument) { + return new GenericDiagnostic(this, severity, makeMessage(argument), range); + } + + @NotNull + public Diagnostic on(@NotNull ASTNode node, @NotNull T argument) { + return on(node.getTextRange(), argument); + } + + @NotNull + public Diagnostic on(@NotNull PsiElement element, @NotNull T argument) { + return on(element.getTextRange(), argument); + } + } + + public class ParameterizedDiagnosticFactory2 extends AbstractDiagnosticFactory { + public static ParameterizedDiagnosticFactory2 create(Severity severity, String messageStub) { + return new ParameterizedDiagnosticFactory2(severity, messageStub); + } + + protected ParameterizedDiagnosticFactory2(Severity severity, String messageStub) { + super(severity, messageStub); + } + + protected String makeMessage(@NotNull A a, @NotNull B b) { + return String.format(message, makeMessageForA(a), makeMessageForB(b)); + } + + protected String makeMessageForA(@NotNull A a) { + return a.toString(); + } + + protected String makeMessageForB(@NotNull B b) { + return b.toString(); + } + + @NotNull + public Diagnostic on(@NotNull TextRange range, @NotNull A a, @NotNull B b) { + return new GenericDiagnostic(this, severity, makeMessage(a, b), range); + } + + @NotNull + public Diagnostic on(@NotNull ASTNode node, @NotNull A a, @NotNull B b) { + return on(node.getTextRange(), a, b); + } + + @NotNull + public Diagnostic on(@NotNull PsiElement element, @NotNull A a, @NotNull B b) { + return on(element.getTextRange(), a, b); + } + } + + public class ParameterizedDiagnosticFactory3 extends AbstractDiagnosticFactory { + public static ParameterizedDiagnosticFactory3 create(Severity severity, String messageStub) { + return new ParameterizedDiagnosticFactory3(severity, messageStub); + } + + protected ParameterizedDiagnosticFactory3(Severity severity, String messageStub) { + super(severity, messageStub); + } + + protected String makeMessage(@NotNull A a, @NotNull B b, @NotNull C c) { + return String.format(message, makeMessageForA(a), makeMessageForB(b), makeMessageForC(c)); + } + + protected String makeMessageForA(@NotNull A a) { + return a.toString(); + } + + protected String makeMessageForB(@NotNull B b) { + return b.toString(); + } + + protected String makeMessageForC(@NotNull C c) { + return c.toString(); + } + + @NotNull + public Diagnostic on(@NotNull TextRange range, @NotNull A a, @NotNull B b, @NotNull C c) { + return new GenericDiagnostic(this, severity, makeMessage(a, b, c), range); + } + + @NotNull + public Diagnostic on(@NotNull ASTNode node, @NotNull A a, @NotNull B b, @NotNull C c) { + return on(node.getTextRange(), a, b, c); + } + + @NotNull + public Diagnostic on(@NotNull PsiElement element, @NotNull A a, @NotNull B b, @NotNull C c) { + return on(element.getTextRange(), a, b, c); + } + } + + public class UnresolvedReferenceDiagnosticFactory implements DiagnosticFactory { + private UnresolvedReferenceDiagnosticFactory() {} + + public UnresolvedReferenceDiagnostic on(@NotNull JetReferenceExpression reference) { + return new UnresolvedReferenceDiagnostic(reference); + } + + @NotNull + @Override + public TextRange getMarkerPosition(@NotNull Diagnostic diagnostic) { + return ((UnresolvedReferenceDiagnostic) diagnostic).getTextRange(); + } + + public class UnresolvedReferenceDiagnostic extends GenericDiagnostic { + + private final JetReferenceExpression reference; + + public UnresolvedReferenceDiagnostic(JetReferenceExpression referenceExpression) { + super(UnresolvedReferenceDiagnosticFactory.this, ERROR, "Unresolved reference", referenceExpression.getTextRange()); + this.reference = referenceExpression; + } + + @NotNull + public JetReferenceExpression getReference() { + return reference; + } + } + } + + public class AmbiguousDescriptorDiagnosticFactory extends ParameterizedDiagnosticFactory1> { + public static AmbiguousDescriptorDiagnosticFactory create(String messageTemplate) { + return new AmbiguousDescriptorDiagnosticFactory(messageTemplate); + } + + protected AmbiguousDescriptorDiagnosticFactory(String messageTemplate) { + super(Severity.ERROR, messageTemplate); + } + + @Override + protected String makeMessage(@NotNull Collection argument) { + StringBuilder stringBuilder = new StringBuilder("\n"); + for (CallableDescriptor descriptor : argument) { + stringBuilder.append(DescriptorRenderer.TEXT.render(descriptor)).append("\n"); + } + return stringBuilder.toString(); + } + } + + UnresolvedReferenceDiagnosticFactory UNRESOLVED_REFERENCE = new UnresolvedReferenceDiagnosticFactory(); + SimpleDiagnosticFactory SAFE_CALLS_ARE_NOT_ALLOWED_ON_NAMESPACES = SimpleDiagnosticFactory.create(ERROR, "Safe calls are not allowed on namespaces"); + SimpleDiagnosticFactory TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM = SimpleDiagnosticFactory.create(ERROR, "Type checking has run into a recursive problem"); // TODO: message + SimpleDiagnosticFactory RETURN_NOT_ALLOWED = SimpleDiagnosticFactory.create(ERROR, "'return' is not allowed here"); + SimpleDiagnosticFactory PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE = SimpleDiagnosticFactory.create(ERROR, "Projections are not allowed for immediate arguments of a supertype"); + SimpleDiagnosticFactory LABEL_NAME_CLASH = SimpleDiagnosticFactory.create(WARNING, "There is more than one label with such a name in this scope"); + SimpleDiagnosticFactory EXPRESSION_EXPECTED_NAMESPACE_FOUND = SimpleDiagnosticFactory.create(ERROR, "Expression expected, but a namespace name found"); + SimpleDiagnosticFactory CANNOT_INFER_PARAMETER_TYPE = SimpleDiagnosticFactory.create(ERROR, "Cannot infer a type for this parameter. To specify it explicitly use the {(p : Type) => ...} notation"); + + SimpleDiagnosticFactory NO_BACKING_FIELD = SimpleDiagnosticFactory.create(ERROR, "This property does not have a backing field"); + + SimpleDiagnosticFactory MIXING_NAMED_AND_POSITIONED_ARGUMENTS = SimpleDiagnosticFactory.create(ERROR, "Mixing named and positioned arguments in not allowed"); + SimpleDiagnosticFactory ARGUMENT_PASSED_TWICE = SimpleDiagnosticFactory.create(ERROR, "An argument is already passed for this parameter"); + SimpleDiagnosticFactory NAMED_PARAMETER_NOT_FOUND = SimpleDiagnosticFactory.create(ERROR, "Cannot find a parameter with this name"); + SimpleDiagnosticFactory VARARG_OUTSIDE_PARENTHESES = SimpleDiagnosticFactory.create(ERROR, "Passing value as a vararg is only allowed inside a parenthesized argument list"); + SimpleDiagnosticFactory MANY_FUNCTION_LITERAL_ARGUMENTS = SimpleDiagnosticFactory.create(ERROR, "Only one function literal is allowed outside a parenthesized argument list"); + + SimpleDiagnosticFactory PROPERTY_WITH_NO_TYPE_NO_INITIALIZER = SimpleDiagnosticFactory.create(ERROR, "This property must either have a type annotation or be initialized"); + + SimpleDiagnosticFactory ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS = SimpleDiagnosticFactory.create(ERROR, "This property cannot be declared abstract"); + SimpleDiagnosticFactory ABSTRACT_PROPERTY_NOT_IN_CLASS = SimpleDiagnosticFactory.create(ERROR, "A property may be abstract only when defined in a class or trait"); + SimpleDiagnosticFactory ABSTRACT_PROPERTY_WITH_INITIALIZER = SimpleDiagnosticFactory.create(ERROR, "Property with initializer cannot be abstract"); + SimpleDiagnosticFactory ABSTRACT_PROPERTY_WITH_GETTER = SimpleDiagnosticFactory.create(ERROR, "Property with getter implementation cannot be abstract"); + SimpleDiagnosticFactory ABSTRACT_PROPERTY_WITH_SETTER = SimpleDiagnosticFactory.create(ERROR, "Property with setter implementation cannot be abstract"); + SimpleDiagnosticFactory BACKING_FIELD_IN_TRAIT = SimpleDiagnosticFactory.create(ERROR, "Property in a trait cannot have a backing field"); + SimpleDiagnosticFactory MUST_BE_INITIALIZED = SimpleDiagnosticFactory.create(ERROR, "Property must be initialized"); + SimpleDiagnosticFactory MUST_BE_INITIALIZED_OR_BE_ABSTRACT = SimpleDiagnosticFactory.create(ERROR, "Property must be initialized or be abstract"); + SimpleDiagnosticFactory PROPERTY_INITIALIZER_IN_TRAIT = SimpleDiagnosticFactory.create(ERROR, "Property initializers are not allowed in traits"); + SimpleDiagnosticFactory PROPERTY_INITIALIZER_NO_BACKING_FIELD = SimpleDiagnosticFactory.create(ERROR, "Initializer is not allowed here because this property has no backing field"); + SimpleDiagnosticFactory PROPERTY_INITIALIZER_NO_PRIMARY_CONSTRUCTOR = SimpleDiagnosticFactory.create(ERROR, "Property initializers are not allowed when no primary constructor is present"); + SimpleDiagnosticFactory REDUNDANT_ABSTRACT = SimpleDiagnosticFactory.create(WARNING, "Abstract modifier is redundant in traits"); + ParameterizedDiagnosticFactory2 ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS = ParameterizedDiagnosticFactory2.create(ERROR, "Abstract property {0} in non-abstract class {1}"); + ParameterizedDiagnosticFactory2 ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS = ParameterizedDiagnosticFactory2.create(ERROR, "Abstract function {0} in non-abstract class {1}"); + ParameterizedDiagnosticFactory1 ABSTRACT_FUNCTION_WITH_BODY = ParameterizedDiagnosticFactory1.create(ERROR, "A function {0} with body cannot be abstract"); + ParameterizedDiagnosticFactory1 NON_ABSTRACT_FUNCTION_WITH_NO_BODY = ParameterizedDiagnosticFactory1.create(ERROR, "Method {0} without a body must be abstract"); + ParameterizedDiagnosticFactory1 NON_MEMBER_ABSTRACT_FUNCTION = ParameterizedDiagnosticFactory1.create(ERROR, "Function {0} is not a class or trait member and cannot be abstract"); + ParameterizedDiagnosticFactory1 NON_MEMBER_ABSTRACT_ACCESSOR = ParameterizedDiagnosticFactory1.create(ERROR, "Property {0} is not a class or trait member and thus cannot have be abstract accessors"); + ParameterizedDiagnosticFactory1 NON_MEMBER_FUNCTION_NO_BODY = ParameterizedDiagnosticFactory1.create(ERROR, "Function {0} must have a body"); + + SimpleDiagnosticFactory PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT = SimpleDiagnosticFactory.create(ERROR, "Projections are not allowed on type arguments of functions and properties"); // TODO : better positioning + + SimpleDiagnosticFactory SUPERTYPE_NOT_INITIALIZED = SimpleDiagnosticFactory.create(ERROR, "This type has a constructor, and thus must be initialized here"); + SimpleDiagnosticFactory SECONDARY_CONSTRUCTOR_BUT_NO_PRIMARY = SimpleDiagnosticFactory.create(ERROR, "A secondary constructor may appear only in a class that has a primary constructor"); + SimpleDiagnosticFactory SECONDARY_CONSTRUCTOR_NO_INITIALIZER_LIST = SimpleDiagnosticFactory.create(ERROR, "Secondary constructors must have an initializer list"); + SimpleDiagnosticFactory BY_IN_SECONDARY_CONSTRUCTOR = SimpleDiagnosticFactory.create(ERROR, "'by'-clause is only supported for primary constructors"); + SimpleDiagnosticFactory INITIALIZER_WITH_NO_ARGUMENTS = SimpleDiagnosticFactory.create(ERROR, "Constructor arguments required"); + SimpleDiagnosticFactory MANY_CALLS_TO_THIS = SimpleDiagnosticFactory.create(ERROR, "Only one call to 'this(...)' is allowed"); + ParameterizedDiagnosticFactory1 NOTHING_TO_OVERRIDE = ParameterizedDiagnosticFactory1.create(ERROR, "Function {0} overrides nothing"); + ParameterizedDiagnosticFactory1 PRIMARY_CONSTRUCTOR_MISSING_STATEFUL_PROPERTY = ParameterizedDiagnosticFactory1.create(ERROR, "This class must have a primary constructor, because property {0} has a backing field"); + ParameterizedDiagnosticFactory1 PRIMARY_CONSTRUCTOR_MISSING_SUPER_CONSTRUCTOR_CALL = new ParameterizedDiagnosticFactory1(ERROR, "Class {0} must have a constructor in order to be able to initialize supertypes") { + @Override + protected String makeMessage(@NotNull JetClassOrObject argument) { + return JetPsiUtil.safeName(argument.getName()); + } + }; + ParameterizedDiagnosticFactory1 EXCEPTION_WHILE_ANALYZING = new ParameterizedDiagnosticFactory1(ERROR, "{0}") { + @Override + protected String makeMessage(@NotNull Throwable e) { + return e.getClass().getSimpleName() + ": " + e.getMessage(); + } + }; + ParameterizedDiagnosticFactory3 VIRTUAL_METHOD_HIDDEN = ParameterizedDiagnosticFactory3.create(ERROR, "Function '{0}' hides '{1}' in class {2} and needs 'override' modifier"); + + SimpleDiagnosticFactory UNREACHABLE_CODE = SimpleDiagnosticFactory.create(ERROR, "Unreachable code"); + ParameterizedDiagnosticFactory1 UNREACHABLE_BECAUSE_OF_NOTHING = ParameterizedDiagnosticFactory1.create(ERROR, "This code is unreachable, because '{0}' never terminates normally"); + + SimpleDiagnosticFactory MANY_CLASS_OBJECTS = SimpleDiagnosticFactory.create(ERROR, "Only one class object is allowed per class"); + SimpleDiagnosticFactory CLASS_OBJECT_NOT_ALLOWED = SimpleDiagnosticFactory.create(ERROR, "A class object is not allowed here"); + SimpleDiagnosticFactory DELEGATION_IN_TRAIT = SimpleDiagnosticFactory.create(ERROR, "Traits cannot use delegation"); + SimpleDiagnosticFactory NO_CONSTRUCTOR = SimpleDiagnosticFactory.create(ERROR, "This class does not have a constructor"); + SimpleDiagnosticFactory NOT_A_CLASS = SimpleDiagnosticFactory.create(ERROR, "Not a class"); + SimpleDiagnosticFactory ILLEGAL_ESCAPE_SEQUENCE = SimpleDiagnosticFactory.create(ERROR, "Illegal escape sequence"); + + SimpleDiagnosticFactory LOCAL_EXTENSION_PROPERTY = SimpleDiagnosticFactory.create(ERROR, "Local extension properties are not allowed"); + SimpleDiagnosticFactory LOCAL_VARIABLE_WITH_GETTER = SimpleDiagnosticFactory.create(ERROR, "Local variables are not allowed to have getters"); + SimpleDiagnosticFactory LOCAL_VARIABLE_WITH_SETTER = SimpleDiagnosticFactory.create(ERROR, "Local variables are not allowed to have setters"); + SimpleDiagnosticFactory VAL_WITH_SETTER = SimpleDiagnosticFactory.create(ERROR, "A 'val'-property cannot have a setter"); + + SimpleDiagnosticFactory EQUALS_MISSING = SimpleDiagnosticFactory.create(ERROR, "No method 'equals(Any?) : Boolean' available"); + SimpleDiagnosticFactory ASSIGNMENT_IN_EXPRESSION_CONTEXT = SimpleDiagnosticFactory.create(ERROR, "Assignments are not expressions, and only expressions are allowed in this context"); + SimpleDiagnosticFactory NAMESPACE_IS_NOT_AN_EXPRESSION = SimpleDiagnosticFactory.create(ERROR, "'namespace' is not an expression"); + SimpleDiagnosticFactory DECLARATION_IN_ILLEGAL_CONTEXT = SimpleDiagnosticFactory.create(ERROR, "Declarations are not allowed in this position"); + SimpleDiagnosticFactory REF_SETTER_PARAMETER = SimpleDiagnosticFactory.create(ERROR, "Setter parameters can not be 'ref'"); + SimpleDiagnosticFactory SETTER_PARAMETER_WITH_DEFAULT_VALUE = SimpleDiagnosticFactory.create(ERROR, "Setter parameters can not have default values"); + SimpleDiagnosticFactory NO_THIS = SimpleDiagnosticFactory.create(ERROR, "'this' is not defined in this context"); + SimpleDiagnosticFactory NOT_A_SUPERTYPE = SimpleDiagnosticFactory.create(ERROR, "Not a supertype"); + SimpleDiagnosticFactory NO_WHEN_ENTRIES = SimpleDiagnosticFactory.create(ERROR, "Entries are required for when-expression"); // TODO : Scope, and maybe this should not be an error + SimpleDiagnosticFactory USELESS_CAST_STATIC_ASSERT_IS_FINE = SimpleDiagnosticFactory.create(WARNING, "No cast needed, use ':' instead"); + SimpleDiagnosticFactory USELESS_CAST = SimpleDiagnosticFactory.create(WARNING, "No cast needed"); + SimpleDiagnosticFactory CAST_NEVER_SUCCEEDS = SimpleDiagnosticFactory.create(WARNING, "This cast can never succeed"); + ParameterizedDiagnosticFactory1 WRONG_SETTER_PARAMETER_TYPE = ParameterizedDiagnosticFactory1.create(ERROR, "Setter parameter type must be equal to the type of the property, i.e. {0}"); + ParameterizedDiagnosticFactory1 WRONG_GETTER_RETURN_TYPE = ParameterizedDiagnosticFactory1.create(ERROR, "Getter return type must be equal to the type of the property, i.e. {0}"); + ParameterizedDiagnosticFactory1 NO_CLASS_OBJECT = new ParameterizedDiagnosticFactory1(ERROR, "Classifier {0} does not have a class object") { + @Override + protected String makeMessage(@NotNull ClassifierDescriptor argument) { + return argument.getName(); + } + }; + + SimpleDiagnosticFactory NO_GENERICS_IN_SUPERTYPE_SPECIFIER = SimpleDiagnosticFactory.create(ERROR, "Generic arguments of the base type must be specified"); + + SimpleDiagnosticFactory HAS_NEXT_PROPERTY_AND_FUNCTION_AMBIGUITY = SimpleDiagnosticFactory.create(ERROR, "An ambiguity between 'iterator().hasNext()' function and 'iterator().hasNext' property"); + SimpleDiagnosticFactory HAS_NEXT_MISSING = SimpleDiagnosticFactory.create(ERROR, "Loop range must have an 'iterator().hasNext()' function or an 'iterator().hasNext' property"); + SimpleDiagnosticFactory HAS_NEXT_FUNCTION_AMBIGUITY = SimpleDiagnosticFactory.create(ERROR, "Function 'iterator().hasNext()' is ambiguous for this expression"); + SimpleDiagnosticFactory HAS_NEXT_MUST_BE_READABLE = SimpleDiagnosticFactory.create(ERROR, "The 'iterator().hasNext' property of the loop range must be readable"); + ParameterizedDiagnosticFactory1 HAS_NEXT_PROPERTY_TYPE_MISMATCH = ParameterizedDiagnosticFactory1.create(ERROR, "The 'iterator().hasNext' property of the loop range must return Boolean, but returns {0}"); + ParameterizedDiagnosticFactory1 HAS_NEXT_FUNCTION_TYPE_MISMATCH = ParameterizedDiagnosticFactory1.create(ERROR, "The 'iterator().hasNext()' function of the loop range must return Boolean, but returns {0}"); + SimpleDiagnosticFactory NEXT_AMBIGUITY = SimpleDiagnosticFactory.create(ERROR, "Function 'iterator().next()' is ambiguous for this expression"); + SimpleDiagnosticFactory NEXT_MISSING = SimpleDiagnosticFactory.create(ERROR, "Loop range must have an 'iterator().next()' function"); + SimpleDiagnosticFactory ITERATOR_MISSING = SimpleDiagnosticFactory.create(ERROR, "For-loop range must have an iterator() method"); + AmbiguousDescriptorDiagnosticFactory ITERATOR_AMBIGUITY = AmbiguousDescriptorDiagnosticFactory.create("Method 'iterator()' is ambiguous for this expression: {0}"); + + ParameterizedDiagnosticFactory1 COMPARE_TO_TYPE_MISMATCH = ParameterizedDiagnosticFactory1.create(ERROR, "compareTo() must return Int, but returns {0}"); + + SimpleDiagnosticFactory RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY = SimpleDiagnosticFactory.create(ERROR, "Returns are not allowed for functions with expression body. Use block body in '{...}'"); + SimpleDiagnosticFactory NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY = SimpleDiagnosticFactory.create(ERROR, "A 'return' expression required in a function with a block body ('{...}')"); + ParameterizedDiagnosticFactory1 RETURN_TYPE_MISMATCH = ParameterizedDiagnosticFactory1.create(ERROR, "This function must return a value of type {0}"); + + ParameterizedDiagnosticFactory1 UPPER_BOUND_VIOLATED = ParameterizedDiagnosticFactory1.create(ERROR, "An upper bound {0} is violated"); // TODO : Message + ParameterizedDiagnosticFactory1 FINAL_CLASS_OBJECT_UPPER_BOUND = ParameterizedDiagnosticFactory1.create(ERROR, "{0} is a final type, and thus a class object cannot extend it"); + ParameterizedDiagnosticFactory1 FINAL_UPPER_BOUND = ParameterizedDiagnosticFactory1.create(WARNING, "{0} is a final type, and thus a value of the type parameter is predetermined"); + ParameterizedDiagnosticFactory1 USELESS_ELVIS = ParameterizedDiagnosticFactory1.create(WARNING, "Elvis operator (?:) always returns the left operand of non-nullable type {0}"); + ParameterizedDiagnosticFactory1 CONFLICTING_UPPER_BOUNDS = new ParameterizedDiagnosticFactory1(ERROR, "Upper bounds of {0} have empty intersection") { + @Override + protected String makeMessage(@NotNull TypeParameterDescriptor argument) { + return argument.getName(); + } + }; + ParameterizedDiagnosticFactory1 CONFLICTING_CLASS_OBJECT_UPPER_BOUNDS = new ParameterizedDiagnosticFactory1(ERROR, "Class object upper bounds of {0} have empty intersection") { + @Override + protected String makeMessage(@NotNull TypeParameterDescriptor argument) { + return argument.getName(); + } + }; + + ParameterizedDiagnosticFactory1 TOO_MANY_ARGUMENTS = ParameterizedDiagnosticFactory1.create(ERROR, "Too many arguments for {0}"); + ParameterizedDiagnosticFactory1 ERROR_COMPILE_TIME_VALUE = ParameterizedDiagnosticFactory1.create(ERROR, "{0}"); + + SimpleDiagnosticFactory ELSE_MISPLACED_IN_WHEN = SimpleDiagnosticFactory.create(ERROR, "'else' entry must be the last one in a when-expression"); + SimpleDiagnosticFactory CYCLIC_INHERITANCE_HIERARCHY = SimpleDiagnosticFactory.create(ERROR, "There's a cycle in the inheritance hierarchy for this type"); + + SimpleDiagnosticFactory MANY_CLASSES_IN_SUPERTYPE_LIST = SimpleDiagnosticFactory.create(ERROR, "Only one class may appear in a supertype list"); + SimpleDiagnosticFactory SUPERTYPE_NOT_A_CLASS_OR_TRAIT = SimpleDiagnosticFactory.create(ERROR, "Only classes and traits may serve as supertypes"); + SimpleDiagnosticFactory SUPERTYPE_INITIALIZED_IN_TRAIT = SimpleDiagnosticFactory.create(ERROR, "Traits cannot initialize supertypes"); + SimpleDiagnosticFactory CONSTRUCTOR_IN_TRAIT = SimpleDiagnosticFactory.create(ERROR, "A trait may not have a constructor"); + SimpleDiagnosticFactory SUPERTYPE_APPEARS_TWICE = SimpleDiagnosticFactory.create(ERROR, "A supertype appears twice"); + SimpleDiagnosticFactory FINAL_SUPERTYPE = SimpleDiagnosticFactory.create(ERROR, "This type is final, so it cannot be inherited from"); + + SimpleDiagnosticFactory REF_PARAMETER_WITH_VAL_OR_VAR = SimpleDiagnosticFactory.create(ERROR, "'val' and 'var' are not allowed on ref-parameters"); + SimpleDiagnosticFactory VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION = SimpleDiagnosticFactory.create(ERROR, "A type annotation is required on a value parameter"); + SimpleDiagnosticFactory BREAK_OR_CONTINUE_OUTSIDE_A_LOOP = SimpleDiagnosticFactory.create(ERROR, "'break' and 'continue' are only allowed inside a loop"); + ParameterizedDiagnosticFactory1 NOT_A_LOOP_LABEL = ParameterizedDiagnosticFactory1.create(ERROR, "The label '{0}' does not denote a loop"); + + SimpleDiagnosticFactory ANONYMOUS_INITIALIZER_WITHOUT_CONSTRUCTOR = SimpleDiagnosticFactory.create(ERROR, "Anonymous initializers are only allowed in the presence of a primary constructor"); + SimpleDiagnosticFactory NULLABLE_SUPERTYPE = SimpleDiagnosticFactory.create(ERROR, "A supertype cannot be nullable"); + ParameterizedDiagnosticFactory1 UNSAFE_CALL = ParameterizedDiagnosticFactory1.create(ERROR, "Only safe calls (?.) are allowed on a nullable receiver of type {0}"); + SimpleDiagnosticFactory AMBIGUOUS_LABEL = SimpleDiagnosticFactory.create(ERROR, "Ambiguous label"); + ParameterizedDiagnosticFactory1 UNSUPPORTED = ParameterizedDiagnosticFactory1.create(ERROR, "Unsupported [{0}]"); + ParameterizedDiagnosticFactory1 UNNECESSARY_SAFE_CALL = ParameterizedDiagnosticFactory1.create(ERROR, "Unnecessary safe call on a non-null receiver of type {0}"); + ParameterizedDiagnosticFactory2 NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER = new ParameterizedDiagnosticFactory2(ERROR, "{0} does not refer to a type parameter of {1}") { + @Override + protected String makeMessageForA(@NotNull JetTypeConstraint jetTypeConstraint) { + return jetTypeConstraint.getSubjectTypeParameterName().getReferencedName(); + } + + @Override + protected String makeMessageForB(@NotNull JetTypeParameterListOwner constraintOwner) { + return constraintOwner.getName(); + } + }; + ParameterizedDiagnosticFactory2 AUTOCAST_IMPOSSIBLE = new ParameterizedDiagnosticFactory2(ERROR, "Automatic cast to {0} is impossible, because variable {1} is mutable") { + @Override + protected String makeMessageForB(@NotNull VariableDescriptor variableDescriptor) { + return variableDescriptor.getName(); + } + }; + + ParameterizedDiagnosticFactory2 TYPE_MISMATCH_IN_FOR_LOOP = ParameterizedDiagnosticFactory2.create(ERROR, "The loop iterates over values of type {0} but the parameter is declared to be {1}"); + ParameterizedDiagnosticFactory1 TYPE_MISMATCH_IN_CONDITION = ParameterizedDiagnosticFactory1.create(ERROR, "Condition must be of type Boolean, but was of type {0}"); + ParameterizedDiagnosticFactory2 TYPE_MISMATCH_IN_TUPLE_PATTERN = ParameterizedDiagnosticFactory2.create(ERROR, "Type mismatch: subject is of type {0} but the pattern is of type Tuple{1}"); // TODO: message + ParameterizedDiagnosticFactory2 TYPE_MISMATCH_IN_BINDING_PATTERN = ParameterizedDiagnosticFactory2.create(ERROR, "{0} must be a supertype of {1}. Use 'is' to match against {0}"); + ParameterizedDiagnosticFactory2 TYPE_MISMATCH = ParameterizedDiagnosticFactory2.create(ERROR, "Type mismatch: inferred type is {0} but {1} was expected"); + ParameterizedDiagnosticFactory2 INCOMPATIBLE_TYPES = ParameterizedDiagnosticFactory2.create(ERROR, "Incompatible types: {0} and {1}"); + + ParameterizedDiagnosticFactory3> INCONSISTENT_TYPE_PARAMETER_VALUES = new ParameterizedDiagnosticFactory3>(ERROR, "Type parameter {0} of {1} has inconsistent values: {2}") { + @Override + protected String makeMessageForA(@NotNull TypeParameterDescriptor typeParameterDescriptor) { + return typeParameterDescriptor.getName(); + } + + @Override + protected String makeMessageForB(@NotNull ClassDescriptor classDescriptor) { + return DescriptorRenderer.TEXT.render(classDescriptor); + } + + @Override + protected String makeMessageForC(@NotNull Collection jetTypes) { + StringBuilder builder = new StringBuilder(); + for (Iterator iterator = jetTypes.iterator(); iterator.hasNext(); ) { + JetType jetType = iterator.next(); + builder.append(jetType); + if (iterator.hasNext()) { + builder.append(", "); + } + } + return builder.toString(); + } + }; + + ParameterizedDiagnosticFactory3 EQUALITY_NOT_APPLICABLE = new ParameterizedDiagnosticFactory3(ERROR, "Operator {0} cannot be applied to {1} and {2}") { + @Override + protected String makeMessageForA(@NotNull JetSimpleNameExpression nameExpression) { + return nameExpression.getReferencedName(); + } + }; + ParameterizedDiagnosticFactory2 OVERRIDING_FINAL_FUNCTION = new ParameterizedDiagnosticFactory2(ERROR, "Method {0} in {1} is final and cannot be overridden") { + @Override + protected String makeMessageForA(@NotNull FunctionDescriptor functionDescriptor) { + return functionDescriptor.getName(); + } + + @Override + protected String makeMessageForB(@NotNull DeclarationDescriptor descriptor) { + return descriptor.getName(); + } + }; + ParameterizedDiagnosticFactory3 ABSTRACT_METHOD_NOT_IMPLEMENTED = new ParameterizedDiagnosticFactory3(ERROR, "Class '{0}' must be declared abstract or implement abstract method '{1}' declared in {2}") { + @Override + protected String makeMessageForA(@NotNull JetClassOrObject jetClassOrObject) { + return jetClassOrObject.getName(); + } + + @Override + protected String makeMessageForB(@NotNull FunctionDescriptor functionDescriptor) { + return DescriptorRenderer.TEXT.render(functionDescriptor); + } + + @Override + protected String makeMessageForC(@NotNull DeclarationDescriptor descriptor) { + return descriptor.getName(); + } + }; + + ParameterizedDiagnosticFactory3 RESULT_TYPE_MISMATCH = ParameterizedDiagnosticFactory3.create(ERROR, "{0} must return {1} but returns {2}"); + ParameterizedDiagnosticFactory3 UNSAFE_INFIX_CALL = ParameterizedDiagnosticFactory3.create(ERROR, "Infix call corresponds to a dot-qualified call '{0}.{1}({2})' which is not allowed on a nullable receiver '{0}'. Use '?.'-qualified call instead"); + + ParameterizedDiagnosticFactory1> OVERLOAD_RESOLUTION_AMBIGUITY = new AmbiguousDescriptorDiagnosticFactory("Overload resolution ambiguity: {0}"); + ParameterizedDiagnosticFactory1> NONE_APPLICABLE = new AmbiguousDescriptorDiagnosticFactory("None of the following functions can be called with the arguments supplied: {0}"); + ParameterizedDiagnosticFactory1 NO_VALUE_FOR_PARAMETER = ParameterizedDiagnosticFactory1.create(ERROR, "No value passed for parameter {0}"); + ParameterizedDiagnosticFactory1 MISSING_RECEIVER = ParameterizedDiagnosticFactory1.create(ERROR, "A receiver of type {0} is required"); + SimpleDiagnosticFactory NO_RECEIVER_ADMITTED = SimpleDiagnosticFactory.create(ERROR, "No receiver can be passed to this function or property"); + + SimpleDiagnosticFactory CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS = SimpleDiagnosticFactory.create(ERROR, "Can not create an instance of an abstract class"); + SimpleDiagnosticFactory TYPE_INFERENCE_FAILED = SimpleDiagnosticFactory.create(ERROR, "Type inference failed"); + ParameterizedDiagnosticFactory1 WRONG_NUMBER_OF_TYPE_ARGUMENTS = new ParameterizedDiagnosticFactory1(ERROR, "{0} type arguments expected") { + @Override + protected String makeMessage(@NotNull Integer argument) { + return argument == 0 ? "No" : argument.toString(); + } + }; +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/GenericDiagnostic.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/GenericDiagnostic.java new file mode 100644 index 00000000000..914a33ef4dd --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/GenericDiagnostic.java @@ -0,0 +1,45 @@ +package org.jetbrains.jet.lang.diagnostics; + +import com.intellij.openapi.util.TextRange; +import org.jetbrains.annotations.NotNull; + +/** +* @author abreslav +*/ +public class GenericDiagnostic implements DiagnosticWithTextRange { + + private final TextRange textRange; + private final String message; + private final DiagnosticFactory factory; + private final Severity severity; + + public GenericDiagnostic(DiagnosticFactory factory, Severity severity, String message, TextRange textRange) { + this.factory = factory; + this.textRange = textRange; + this.severity = severity; + this.message = message; + } + + @NotNull + @Override + public DiagnosticFactory getFactory() { + return factory; + } + + @NotNull + public TextRange getTextRange() { + return textRange; + } + + @NotNull + @Override + public String getMessage() { + return message; + } + + @NotNull + @Override + public Severity getSeverity() { + return severity; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/JetDiagnostic.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/JetDiagnostic.java similarity index 98% rename from compiler/frontend/src/org/jetbrains/jet/lang/JetDiagnostic.java rename to compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/JetDiagnostic.java index 068d101b13f..273d229a38f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/JetDiagnostic.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/JetDiagnostic.java @@ -1,4 +1,4 @@ -package org.jetbrains.jet.lang; +package org.jetbrains.jet.lang.diagnostics; import com.intellij.lang.ASTNode; import org.jetbrains.annotations.NotNull; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Severity.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Severity.java new file mode 100644 index 00000000000..6c8ee194921 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Severity.java @@ -0,0 +1,10 @@ +package org.jetbrains.jet.lang.diagnostics; + +/** + * @author abreslav + */ +public enum Severity { + INFO, + ERROR, + WARNING +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetModifierList.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetModifierList.java index a8f61283fe5..2c5e47472c5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetModifierList.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetModifierList.java @@ -5,8 +5,6 @@ import com.intellij.lang.ASTNode; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetNodeTypes; -import org.jetbrains.jet.lang.resolve.BindingTrace; -import org.jetbrains.jet.lexer.JetKeywordToken; import org.jetbrains.jet.lexer.JetToken; import java.util.ArrayList; @@ -59,14 +57,4 @@ public class JetModifierList extends JetElement { } return null; } - - public boolean checkNotContains(BindingTrace trace, JetToken... tokens) { - for (JetToken token : tokens) { - if (hasModifier(token)) { - trace.getErrorHandler().genericError(getModifierNode(token), "Annotation " + ((JetKeywordToken) token).getValue() + " is not allowed here"); - return false; - } - } - return true; - } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java index cd2b005ff16..4086d581966 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java @@ -11,18 +11,20 @@ import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.PsiModificationTracker; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.ErrorHandler; import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetNamespace; -//import org.jetbrains.jet.lang.resolve.java.JavaPackageScope; -//import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices; import java.util.Collections; +//import org.jetbrains.jet.lang.resolve.java.JavaPackageScope; +//import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices; + /** * @author abreslav */ @@ -118,7 +120,8 @@ public class AnalyzingUtils { catch (Throwable e) { e.printStackTrace(); BindingTraceContext bindingTraceContext = new BindingTraceContext(); - bindingTraceContext.getErrorHandler().genericError(file.getNode(), e.getClass().getSimpleName() + ": " + e.getMessage()); +// bindingTraceContext.getErrorHandler().genericError(file.getNode(), e.getClass().getSimpleName() + ": " + e.getMessage()); + bindingTraceContext.report(Errors.EXCEPTION_WHILE_ANALYZING.on(file, e)); return new Result(bindingTraceContext.getBindingContext(), PsiModificationTracker.MODIFICATION_COUNT); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index 0628cf1eb20..83a20666919 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -2,7 +2,8 @@ package org.jetbrains.jet.lang.resolve; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.JetDiagnostic; +import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.diagnostics.JetDiagnostic; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.*; @@ -111,7 +112,8 @@ public interface BindingContext { WritableSlice LABEL_TARGET = Slices.sliceBuilder("LABEL_TARGET").build(); WritableSlice VALUE_PARAMETER_AS_PROPERTY = Slices.sliceBuilder("VALUE_PARAMETER_AS_PROPERTY").build(); - Collection getDiagnostics(); + Collection getOld_Diagnostics(); + Collection getDiagnostics(); @Nullable V get(ReadOnlySlice slice, K key); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingTrace.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingTrace.java index 393a7645812..945cc09b942 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingTrace.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingTrace.java @@ -2,14 +2,15 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; import org.jetbrains.jet.util.slicedmap.ReadOnlySlice; import org.jetbrains.jet.util.slicedmap.WritableSlice; /** * @author abreslav */ -public interface BindingTrace { +public interface BindingTrace extends DiagnosticHolder { @NotNull ErrorHandler getErrorHandler(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingTraceAdapter.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingTraceAdapter.java index 6eba9f2e4bd..4e3bb908650 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingTraceAdapter.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingTraceAdapter.java @@ -2,7 +2,8 @@ package org.jetbrains.jet.lang.resolve; import com.google.common.collect.Maps; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; import org.jetbrains.jet.util.slicedmap.ReadOnlySlice; import org.jetbrains.jet.util.slicedmap.WritableSlice; @@ -13,16 +14,21 @@ import java.util.Map; */ public class BindingTraceAdapter implements BindingTrace { public interface RecordHandler { + void handleRecord(WritableSlice slice, K key, V value); } - private final BindingTrace originalTrace; - private Map handlers = Maps.newHashMap(); + private Map handlers = Maps.newHashMap(); public BindingTraceAdapter(BindingTrace originalTrace) { this.originalTrace = originalTrace; } + @Override + public void report(@NotNull Diagnostic diagnostic) { + originalTrace.report(diagnostic); + } + @Override @NotNull public ErrorHandler getErrorHandler() { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java index d97f992aaaf..8d2b3e7b057 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java @@ -2,9 +2,10 @@ package org.jetbrains.jet.lang.resolve; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.CollectingErrorHandler; -import org.jetbrains.jet.lang.ErrorHandler; -import org.jetbrains.jet.lang.JetDiagnostic; +import org.jetbrains.jet.lang.diagnostics.CollectingErrorHandler; +import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.JetDiagnostic; import org.jetbrains.jet.util.slicedmap.MutableSlicedMap; import org.jetbrains.jet.util.slicedmap.ReadOnlySlice; import org.jetbrains.jet.util.slicedmap.SlicedMapImpl; @@ -17,14 +18,20 @@ import java.util.List; * @author abreslav */ public class BindingTraceContext implements BindingTrace { - private final List diagnostics = Lists.newArrayList(); - private final ErrorHandler errorHandler = new CollectingErrorHandler(diagnostics); + private final List diagnostics = Lists.newArrayList(); + private final List old_diagnostics = Lists.newArrayList(); + private final ErrorHandler errorHandler = new CollectingErrorHandler(old_diagnostics); private final MutableSlicedMap map = SlicedMapImpl.create(); private final BindingContext bindingContext = new BindingContext() { @Override - public Collection getDiagnostics() { + public Collection getOld_Diagnostics() { + return old_diagnostics; + } + + @Override + public Collection getDiagnostics() { return diagnostics; } @@ -34,6 +41,11 @@ public class BindingTraceContext implements BindingTrace { } }; + @Override + public void report(@NotNull Diagnostic diagnostic) { + diagnostics.add(diagnostic); + } + @NotNull @Override public ErrorHandler getErrorHandler() { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index fd0b8313a6d..9222fff323e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -16,6 +16,7 @@ import org.jetbrains.jet.util.slicedmap.WritableSlice; import java.util.*; +import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.types.JetTypeInferrer.NO_EXPECTED_TYPE; /** @@ -38,7 +39,8 @@ public class BodyResolver { JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression; if (simpleNameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) { if (!BodyResolver.this.context.getTrace().getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) descriptor)) { - BodyResolver.this.context.getTrace().getErrorHandler().genericError(expression.getNode(), "This property does not have a backing field"); +// BodyResolver.this.context.getTrace().getErrorHandler().genericError(expression.getNode(), "This property does not have a backing field"); + BodyResolver.this.context.getTrace().report(NO_BACKING_FIELD.on(expression)); } } } @@ -152,8 +154,9 @@ public class BodyResolver { if (functionDescriptor.getModality() == Modality.ABSTRACT && !allOverriddenFunctions.contains(functionDescriptor.getOriginal()) && !foundError && nameIdentifier != null) { DeclarationDescriptor declarationDescriptor = functionDescriptor.getContainingDeclaration(); if (declarationDescriptor != classDescriptor) { - context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), "Class '" + klass.getName() + "' must be declared abstract or implement abstract method '" + - functionDescriptor.getName() + "' in " + declarationDescriptor.getName()); +// context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), "Class '" + klass.getName() + "' must be declared abstract or implement abstract method '" + +// functionDescriptor.getName() + "' declared in " + declarationDescriptor.getName()); + context.getTrace().report(ABSTRACT_METHOD_NOT_IMPLEMENTED.on(nameIdentifier, klass, functionDescriptor, declarationDescriptor)); foundError = true; } } @@ -172,20 +175,23 @@ public class BodyResolver { for (FunctionDescriptor overridden : declaredFunction.getOverriddenDescriptors()) { if (overridden != null) { if (hasOverrideModifier && !overridden.getModality().isOpen() && !foundError) { - context.getTrace().getErrorHandler().genericError(overrideNode, "Method " + overridden.getName() + " in " + overridden.getContainingDeclaration().getName() + " is final and cannot be overridden"); +// context.getTrace().getErrorHandler().genericError(overrideNode, "Method " + overridden.getName() + " in " + overridden.getContainingDeclaration().getName() + " is final and cannot be overridden"); + context.getTrace().report(OVERRIDING_FINAL_FUNCTION.on(overrideNode, overridden, overridden.getContainingDeclaration())); foundError = true; } } } if (hasOverrideModifier && declaredFunction.getOverriddenDescriptors().size() == 0) { - context.getTrace().getErrorHandler().genericError(overrideNode, "Method " + declaredFunction.getName() + " overrides nothing"); +// context.getTrace().getErrorHandler().genericError(overrideNode, "Method " + declaredFunction.getName() + " overrides nothing"); + context.getTrace().report(NOTHING_TO_OVERRIDE.on(overrideNode, declaredFunction)); } PsiElement nameIdentifier = function.getNameIdentifier(); if (!hasOverrideModifier && declaredFunction.getOverriddenDescriptors().size() > 0 && nameIdentifier != null) { - FunctionDescriptor overriddenMethod = declaredFunction.getOverriddenDescriptors().iterator().next(); - context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), - "Method '" + declaredFunction.getName() + "' overrides method '" + overriddenMethod.getName() + "' in class " + - overriddenMethod.getContainingDeclaration().getName() + " and needs 'override' modifier"); + FunctionDescriptor overriddenFunction = declaredFunction.getOverriddenDescriptors().iterator().next(); +// context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), +// "Method '" + declaredFunction.getName() + "' overrides method '" + overriddenFunction.getName() + "' in class " + +// overriddenFunction.getContainingDeclaration().getName() + " and needs 'override' modifier"); + context.getTrace().report(VIRTUAL_METHOD_HIDDEN.on(nameIdentifier, declaredFunction, overriddenFunction, overriddenFunction.getContainingDeclaration())); } } @@ -199,8 +205,9 @@ public class BodyResolver { if (context.getTrace().getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) { PsiElement nameIdentifier = jetClass.getNameIdentifier(); if (nameIdentifier != null) { - context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), - "This class must have a primary constructor, because property " + propertyDescriptor.getName() + " has a backing field"); +// context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), +// "This class must have a primary constructor, because property " + propertyDescriptor.getName() + " has a backing field"); + context.getTrace().report(PRIMARY_CONSTRUCTOR_MISSING_STATEFUL_PROPERTY.on(nameIdentifier, propertyDescriptor)); } break; } @@ -236,7 +243,8 @@ public class BodyResolver { @Override public void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier) { if (descriptor.getKind() == ClassKind.TRAIT) { - context.getTrace().getErrorHandler().genericError(specifier.getNode(), "Traits cannot use delegation"); +// context.getTrace().getErrorHandler().genericError(specifier.getNode(), "Traits cannot use delegation"); + context.getTrace().report(DELEGATION_IN_TRAIT.on(specifier)); } JetType supertype = context.getTrace().getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference()); recordSupertype(specifier.getTypeReference(), supertype); @@ -247,7 +255,7 @@ public class BodyResolver { : scopeForConstructor; JetType type = typeInferrer.getType(scope, delegateExpression, NO_EXPECTED_TYPE); if (type != null && supertype != null && !context.getSemanticServices().getTypeChecker().isSubtypeOf(type, supertype)) { - context.getTrace().getErrorHandler().typeMismatch(delegateExpression, supertype, type); + context.getTrace().report(TYPE_MISMATCH.on(delegateExpression, supertype, type)); } } } @@ -257,7 +265,8 @@ public class BodyResolver { JetValueArgumentList valueArgumentList = call.getValueArgumentList(); ASTNode node = valueArgumentList == null ? call.getNode() : valueArgumentList.getNode(); if (descriptor.getKind() == ClassKind.TRAIT) { - context.getTrace().getErrorHandler().genericError(node, "Traits cannot initialize supertypes"); +// context.getTrace().getErrorHandler().genericError(node, "Traits cannot initialize supertypes"); + context.getTrace().report(SUPERTYPE_INITIALIZED_IN_TRAIT.on(node)); } JetTypeReference typeReference = call.getTypeReference(); if (typeReference != null) { @@ -268,7 +277,8 @@ public class BodyResolver { ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype); if (classDescriptor != null) { if (classDescriptor.getKind() == ClassKind.TRAIT) { - context.getTrace().getErrorHandler().genericError(node, "A trait may not have a constructor"); +// context.getTrace().getErrorHandler().genericError(node, "A trait may not have a constructor"); + context.getTrace().report(CONSTRUCTOR_IN_TRAIT.on(node)); } } } @@ -281,8 +291,9 @@ public class BodyResolver { recordSupertype(typeReference, supertype); assert valueArgumentList != null; - context.getTrace().getErrorHandler().genericError(valueArgumentList.getNode(), - "Class " + JetPsiUtil.safeName(jetClass.getName()) + " must have a constructor in order to be able to initialize supertypes"); +// context.getTrace().getErrorHandler().genericError(valueArgumentList.getNode(), +// "Class " + JetPsiUtil.safeName(jetClass.getName()) + " must have a constructor in order to be able to initialize supertypes"); + context.getTrace().report(PRIMARY_CONSTRUCTOR_MISSING_SUPER_CONSTRUCTOR_CALL.on(valueArgumentList, jetClass)); } } } @@ -297,7 +308,8 @@ public class BodyResolver { if (classDescriptor != null) { if (descriptor.getKind() != ClassKind.TRAIT) { if (classDescriptor.hasConstructors() && !ErrorUtils.isError(classDescriptor.getTypeConstructor()) && classDescriptor.getKind() != ClassKind.TRAIT) { - context.getTrace().getErrorHandler().genericError(specifier.getNode(), "This type has a constructor, and thus must be initialized here"); +// context.getTrace().getErrorHandler().genericError(specifier.getNode(), "This type has a constructor, and thus must be initialized here"); + context.getTrace().report(SUPERTYPE_NOT_INITIALIZED.on(specifier)); } } } @@ -340,7 +352,8 @@ public class BodyResolver { if (classDescriptor != null) { if (classDescriptor.getKind() != ClassKind.TRAIT) { if (classAppeared) { - context.getTrace().getErrorHandler().genericError(typeReference.getNode(), "Only one class may appear in a supertype list"); +// context.getTrace().getErrorHandler().genericError(typeReference.getNode(), "Only one class may appear in a supertype list"); + context.getTrace().report(MANY_CLASSES_IN_SUPERTYPE_LIST.on(typeReference)); } else { classAppeared = true; @@ -348,16 +361,19 @@ public class BodyResolver { } } else { - context.getTrace().getErrorHandler().genericError(typeReference.getNode(), "Only classes and traits may serve as supertypes"); +// context.getTrace().getErrorHandler().genericError(typeReference.getNode(), "Only classes and traits may serve as supertypes"); + context.getTrace().report(SUPERTYPE_NOT_A_CLASS_OR_TRAIT.on(typeReference)); } TypeConstructor constructor = supertype.getConstructor(); if (!typeConstructors.add(constructor)) { - context.getTrace().getErrorHandler().genericError(typeReference.getNode(), "A supertype appears twice"); +// context.getTrace().getErrorHandler().genericError(typeReference.getNode(), "A supertype appears twice"); + context.getTrace().report(SUPERTYPE_APPEARS_TWICE.on(typeReference)); } if (constructor.isSealed() && !allowedFinalSupertypes.contains(constructor)) { - context.getTrace().getErrorHandler().genericError(typeReference.getNode(), "This type is final, so it cannot be inherited from"); +// context.getTrace().getErrorHandler().genericError(typeReference.getNode(), "This type is final, so it cannot be inherited from"); + context.getTrace().report(FINAL_SUPERTYPE.on(typeReference)); } } } @@ -388,7 +404,8 @@ public class BodyResolver { } else { for (JetClassInitializer anonymousInitializer : anonymousInitializers) { - context.getTrace().getErrorHandler().genericError(anonymousInitializer.getNode(), "Anonymous initializers are only allowed in the presence of a primary constructor"); +// context.getTrace().getErrorHandler().genericError(anonymousInitializer.getNode(), "Anonymous initializers are only allowed in the presence of a primary constructor"); + context.getTrace().report(ANONYMOUS_INITIALIZER_WITHOUT_CONSTRUCTOR.on(anonymousInitializer)); } } } @@ -412,12 +429,14 @@ public class BodyResolver { JetClass containingClass = PsiTreeUtil.getParentOfType(declaration, JetClass.class); assert containingClass != null : "This must be guaranteed by the parser"; if (!containingClass.hasPrimaryConstructor()) { - context.getTrace().getErrorHandler().genericError(declaration.getNameNode(), "A secondary constructor may appear only in a class that has a primary constructor"); +// context.getTrace().getErrorHandler().genericError(declaration.getNameNode(), "A secondary constructor may appear only in a class that has a primary constructor"); + context.getTrace().report(SECONDARY_CONSTRUCTOR_BUT_NO_PRIMARY.on(declaration)); } else { List initializers = declaration.getInitializers(); if (initializers.isEmpty()) { - context.getTrace().getErrorHandler().genericError(declaration.getNameNode(), "Secondary constructors must have an initializer list"); +// context.getTrace().getErrorHandler().genericError(declaration.getNameNode(), "Secondary constructors must have an initializer list"); + context.getTrace().report(SECONDARY_CONSTRUCTOR_NO_INITIALIZER_LIST.on(declaration)); } else { initializers.get(0).accept(new JetVisitorVoid() { @@ -447,12 +466,14 @@ public class BodyResolver { @Override public void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier) { - context.getTrace().getErrorHandler().genericError(specifier.getNode(), "'by'-clause is only supported for primary constructors"); +// context.getTrace().getErrorHandler().genericError(specifier.getNode(), "'by'-clause is only supported for primary constructors"); + context.getTrace().report(BY_IN_SECONDARY_CONSTRUCTOR.on(specifier)); } @Override public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) { - context.getTrace().getErrorHandler().genericError(specifier.getNode(), "Constructor parameters required"); +// context.getTrace().getErrorHandler().genericError(specifier.getNode(), "Constructor parameters required"); + context.getTrace().report(INITIALIZER_WITH_NO_ARGUMENTS.on(specifier)); } @Override @@ -462,7 +483,8 @@ public class BodyResolver { }); for (int i = 1, initializersSize = initializers.size(); i < initializersSize; i++) { JetDelegationSpecifier initializer = initializers.get(i); - context.getTrace().getErrorHandler().genericError(initializer.getNode(), "Only one call to 'this(...)' is allowed"); +// context.getTrace().getErrorHandler().genericError(initializer.getNode(), "Only one call to 'this(...)' is allowed"); + context.getTrace().report(MANY_CALLS_TO_THIS.on(initializer)); } } } @@ -588,35 +610,43 @@ public class BodyResolver { if (abstractNode != null) { //has abstract modifier if (classDescriptor == null) { - context.getTrace().getErrorHandler().genericError(abstractNode, "This property cannot be abstract"); +// context.getTrace().getErrorHandler().genericError(abstractNode, "A property may be abstract only when defined in a class or trait"); + context.getTrace().report(ABSTRACT_PROPERTY_NOT_IN_CLASS.on(abstractNode)); return; } if (!(classDescriptor.getModality() == Modality.ABSTRACT) && classDescriptor.getKind() != ClassKind.ENUM_CLASS) { - context.getTrace().getErrorHandler().genericError(abstractNode, "Abstract property " + property.getName() + " in non-abstract class " + classDescriptor.getName()); +// context.getTrace().getErrorHandler().genericError(abstractNode, "Abstract property " + property.getName() + " in non-abstract class " + classDescriptor.getName()); + context.getTrace().report(ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS.on(abstractNode, property.getName(), classDescriptor)); return; } if (classDescriptor.getKind() == ClassKind.TRAIT) { - context.getTrace().getErrorHandler().genericWarning(abstractNode, "Abstract modifier is redundant in traits"); +// context.getTrace().getErrorHandler().genericWarning(abstractNode, "Abstract modifier is redundant in traits"); + context.getTrace().report(REDUNDANT_ABSTRACT.on(abstractNode)); } } if (propertyDescriptor.getModality() == Modality.ABSTRACT) { JetExpression initializer = property.getInitializer(); if (initializer != null) { - context.getTrace().getErrorHandler().genericError(initializer.getNode(), "Property with initializer cannot be abstract"); +// context.getTrace().getErrorHandler().genericError(initializer.getNode(), "Property with initializer cannot be abstract"); + context.getTrace().report(ABSTRACT_PROPERTY_WITH_INITIALIZER.on(initializer)); } if (getter != null && getter.getBodyExpression() != null) { - context.getTrace().getErrorHandler().genericError(getter.getNode(), "Property with getter implementation cannot be abstract"); +// context.getTrace().getErrorHandler().genericError(getter.getNode(), "Property with getter implementation cannot be abstract"); + context.getTrace().report(ABSTRACT_PROPERTY_WITH_GETTER.on(getter)); } if (setter != null && setter.getBodyExpression() != null) { - context.getTrace().getErrorHandler().genericError(setter.getNode(), "Property with setter implementation cannot be abstract"); +// context.getTrace().getErrorHandler().genericError(setter.getNode(), "Property with setter implementation cannot be abstract"); + context.getTrace().report(ABSTRACT_PROPERTY_WITH_SETTER.on(setter)); } } } private void checkPropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, ClassDescriptor classDescriptor) { - boolean hasAccessorImplementation = (property.getGetter() != null && property.getGetter().getBodyExpression() != null) || - (property.getSetter() != null && property.getSetter().getBodyExpression() != null); + JetPropertyAccessor getter = property.getGetter(); + JetPropertyAccessor setter = property.getSetter(); + boolean hasAccessorImplementation = (getter != null && getter.getBodyExpression() != null) || + (setter != null && setter.getBodyExpression() != null); if (propertyDescriptor.getModality() == Modality.ABSTRACT) return; boolean inTrait = classDescriptor != null && classDescriptor.getKind() == ClassKind.TRAIT; @@ -627,26 +657,32 @@ public class BodyResolver { ASTNode nameNode = nameIdentifier == null ? property.getNode() : nameIdentifier.getNode(); if (inTrait && backingFieldRequired && hasAccessorImplementation) { - context.getTrace().getErrorHandler().genericError(nameNode, "Property in trait cannot have backing field"); +// context.getTrace().getErrorHandler().genericError(nameNode, "Property in a trait cannot have a backing field"); + context.getTrace().report(BACKING_FIELD_IN_TRAIT.on(nameNode)); } if (initializer == null) { if (backingFieldRequired && !inTrait && !context.getTrace().getBindingContext().get(BindingContext.IS_INITIALIZED, propertyDescriptor)) { if (classDescriptor == null || hasAccessorImplementation) { - context.getTrace().getErrorHandler().genericError(nameNode, "Property must be initialized"); +// context.getTrace().getErrorHandler().genericError(nameNode, "Property must be initialized"); + context.getTrace().report(MUST_BE_INITIALIZED.on(nameNode)); } else { - context.getTrace().getErrorHandler().genericError(nameNode, "Property must be initialized or be abstract"); +// context.getTrace().getErrorHandler().genericError(nameNode, "Property must be initialized or be abstract"); + context.getTrace().report(MUST_BE_INITIALIZED_OR_BE_ABSTRACT.on(nameNode)); } } return; } if (inTrait) { - context.getTrace().getErrorHandler().genericError(initializer.getNode(), "Property initializers are not allowed in trait"); +// context.getTrace().getErrorHandler().genericError(initializer.getNode(), "Property initializers are not allowed in traits"); + context.getTrace().report(PROPERTY_INITIALIZER_IN_TRAIT.on(initializer)); } else if (!backingFieldRequired) { - context.getTrace().getErrorHandler().genericError(initializer.getNode(), "Initializer is not allowed here because this property has no backing field"); +// context.getTrace().getErrorHandler().genericError(initializer.getNode(), "Initializer is not allowed here because this property has no backing field"); + context.getTrace().report(PROPERTY_INITIALIZER_NO_BACKING_FIELD.on(initializer)); } else if (classDescriptor != null && classDescriptor.getUnsubstitutedPrimaryConstructor() == null) { - context.getTrace().getErrorHandler().genericError(initializer.getNode(), "Property initializers are not allowed when no primary constructor is present"); +// context.getTrace().getErrorHandler().genericError(initializer.getNode(), "Property initializers are not allowed when no primary constructor is present"); + context.getTrace().report(PROPERTY_INITIALIZER_NO_PRIMARY_CONSTRUCTOR.on(initializer)); } } @@ -694,7 +730,7 @@ public class BodyResolver { } if (type != null && expectedType != null && !context.getSemanticServices().getTypeChecker().isSubtypeOf(type, expectedType)) { - context.getTrace().getErrorHandler().typeMismatch(initializer, expectedType, type); + context.getTrace().report(TYPE_MISMATCH.on(initializer, expectedType, type)); } } @@ -756,31 +792,38 @@ public class BodyResolver { boolean inTrait = classDescriptor.getKind() == ClassKind.TRAIT; boolean inEnum = classDescriptor.getKind() == ClassKind.ENUM_CLASS; boolean inAbstractClass = classDescriptor.getModality() == Modality.ABSTRACT; - String methodName = function.getName() != null ? function.getName() + " " : ""; +// String methodName = function.getName() != null ? function.getName() + " " : ""; if (hasAbstractModifier && !inAbstractClass && !inTrait && !inEnum) { - context.getTrace().getErrorHandler().genericError(abstractNode, "Abstract method " + methodName + "in non-abstract class " + classDescriptor.getName()); +// context.getTrace().getErrorHandler().genericError(abstractNode, "Abstract method " + methodName + " in non-abstract class " + classDescriptor.getName()); + context.getTrace().report(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(abstractNode, functionDescriptor.getName(), classDescriptor)); } if (hasAbstractModifier && inTrait && !isPropertyAccessor) { - context.getTrace().getErrorHandler().genericWarning(abstractNode, "Abstract modifier is redundant in trait"); +// context.getTrace().getErrorHandler().genericWarning(abstractNode, "Abstract modifier is redundant in trait"); + context.getTrace().report(REDUNDANT_ABSTRACT.on(abstractNode)); } if (function.getBodyExpression() != null && hasAbstractModifier) { - context.getTrace().getErrorHandler().genericError(abstractNode, "Method " + methodName + "with body cannot be abstract"); +// context.getTrace().getErrorHandler().genericError(abstractNode, "Method " + methodName + "with body cannot be abstract"); + context.getTrace().report(ABSTRACT_FUNCTION_WITH_BODY.on(abstractNode, functionDescriptor)); } if (function.getBodyExpression() == null && !hasAbstractModifier && !inTrait && nameIdentifier != null && !isPropertyAccessor) { - context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), "Method " + function.getName() + " without body must be abstract"); +// context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), "Method " + function.getName() + " without body must be abstract"); + context.getTrace().report(NON_ABSTRACT_FUNCTION_WITH_NO_BODY.on(nameIdentifier, functionDescriptor)); } return; } if (hasAbstractModifier) { if (!isPropertyAccessor) { - context.getTrace().getErrorHandler().genericError(abstractNode, "Function " + function.getName() + " cannot be abstract"); +// context.getTrace().getErrorHandler().genericError(abstractNode, "Function " + function.getName() + " is not a member and cannot be abstract"); + context.getTrace().report(NON_MEMBER_ABSTRACT_FUNCTION.on(abstractNode, functionDescriptor)); } else { - context.getTrace().getErrorHandler().genericError(abstractNode, "This property accessor cannot be abstract"); +// context.getTrace().getErrorHandler().genericError(abstractNode, "Property {0} is not a class or trait member and thus cannot have be abstract accessors"); + context.getTrace().report(NON_MEMBER_ABSTRACT_ACCESSOR.on(abstractNode, (PropertyDescriptor) functionDescriptor.getContainingDeclaration())); } } if (function.getBodyExpression() == null && !hasAbstractModifier && nameIdentifier != null && !isPropertyAccessor) { - context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), "Function " + function.getName() + " must have body"); +// context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), "Function " + function.getName() + " must have a body"); + context.getTrace().report(NON_MEMBER_FUNCTION_NO_BODY.on(nameIdentifier, functionDescriptor)); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index 484d2fef303..0ead0487866 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -15,12 +15,15 @@ import org.jetbrains.jet.lang.cfg.LoopInfo; import org.jetbrains.jet.lang.cfg.pseudocode.*; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lexer.JetTokens; import java.util.*; +import static org.jetbrains.jet.lang.diagnostics.Errors.*; + /** * @author abreslav */ @@ -90,7 +93,8 @@ public class ClassDescriptorResolver { return parentDescriptor.getDefaultType(); } else { - trace.getErrorHandler().genericError(((JetEnumEntry) jetClass).getNameIdentifier().getNode(), "generic arguments of the base type must be specified"); +// trace.getErrorHandler().genericError(((JetEnumEntry) jetClass).getNameIdentifier().getNode(), "Generic arguments of the base type must be specified"); + trace.report(NO_GENERICS_IN_SUPERTYPE_SPECIFIER.on(((JetEnumEntry) jetClass).getNameIdentifier())); return ErrorUtils.createErrorType("Supertype not specified"); } } @@ -109,7 +113,8 @@ public class ClassDescriptorResolver { JetTypeElement typeElement = typeReference.getTypeElement(); while (typeElement instanceof JetNullableType) { JetNullableType nullableType = (JetNullableType) typeElement; - trace.getErrorHandler().genericError(nullableType.getQuestionMarkNode(), "A supertype cannot be nullable"); +// trace.getErrorHandler().genericError(nullableType.getQuestionMarkNode(), "A supertype cannot be nullable"); + trace.report(NULLABLE_SUPERTYPE.on(nullableType.getQuestionMarkNode())); typeElement = nullableType.getInnerType(); } if (typeElement instanceof JetUserType) { @@ -117,7 +122,8 @@ public class ClassDescriptorResolver { List typeArguments = userType.getTypeArguments(); for (JetTypeProjection typeArgument : typeArguments) { if (typeArgument.getProjectionKind() != JetProjectionKind.NONE) { - trace.getErrorHandler().genericError(typeArgument.getProjectionNode(), "Projections are not allowed for immediate arguments of a supertype"); +// trace.getErrorHandler().genericError(typeArgument.getProjectionNode(), "Projections are not allowed for immediate arguments of a supertype"); + trace.report(PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE.on(typeArgument)); } } } @@ -207,12 +213,14 @@ public class ClassDescriptorResolver { ASTNode valOrVarNode = valueParameter.getValOrVarNode(); if (valueParameter.isRef() && valOrVarNode != null) { - trace.getErrorHandler().genericError(valOrVarNode, "'val' and 'var' are not allowed on ref-parameters"); +// trace.getErrorHandler().genericError(valOrVarNode, "'val' and 'var' are not allowed on ref-parameters"); + trace.report(REF_PARAMETER_WITH_VAL_OR_VAR.on(valOrVarNode)); } JetType type; if (typeReference == null) { - trace.getErrorHandler().genericError(valueParameter.getNode(), "A type annotation is required on a value parameter"); +// trace.getErrorHandler().genericError(valueParameter.getNode(), "A type annotation is required on a value parameter"); + trace.report(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION.on(valueParameter)); type = ErrorUtils.createErrorType("Type annotation was missing"); } else { type = typeResolver.resolveType(parameterScope, typeReference); @@ -298,11 +306,12 @@ public class ClassDescriptorResolver { // To tell the user that we look only for locally defined type parameters ClassifierDescriptor classifier = scope.getClassifier(referencedName); if (classifier != null) { - trace.getErrorHandler().genericError(subjectTypeParameterName.getNode(), referencedName + " does not refer to a type parameter of " + declaration.getName()); +// trace.getErrorHandler().genericError(subjectTypeParameterName.getNode(), referencedName + " does not refer to a type parameter of " + declaration.getName()); + trace.report(NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER.on(subjectTypeParameterName, constraint, declaration)); trace.record(BindingContext.REFERENCE_TARGET, subjectTypeParameterName, classifier); } else { - trace.getErrorHandler().unresolvedReference(subjectTypeParameterName); + trace.report(UNRESOLVED_REFERENCE.on(subjectTypeParameterName)); } } else { @@ -326,7 +335,8 @@ public class ClassDescriptorResolver { if (JetStandardClasses.isNothing(parameter.getBoundsAsType())) { PsiElement nameIdentifier = typeParameters.get(parameter.getIndex()).getNameIdentifier(); if (nameIdentifier != null) { - trace.getErrorHandler().genericError(nameIdentifier.getNode(), "Upper bounds of " + parameter.getName() + " have empty intersection"); +// trace.getErrorHandler().genericError(nameIdentifier.getNode(), "Upper bounds of " + parameter.getName() + " have empty intersection"); + trace.report(CONFLICTING_UPPER_BOUNDS.on(nameIdentifier, parameter)); } } @@ -334,7 +344,8 @@ public class ClassDescriptorResolver { if (classObjectType != null && JetStandardClasses.isNothing(classObjectType)) { PsiElement nameIdentifier = typeParameters.get(parameter.getIndex()).getNameIdentifier(); if (nameIdentifier != null) { - trace.getErrorHandler().genericError(nameIdentifier.getNode(), "Class object upper bounds of " + parameter.getName() + " have empty intersection"); +// trace.getErrorHandler().genericError(nameIdentifier.getNode(), "Class object upper bounds of " + parameter.getName() + " have empty intersection"); + trace.report(CONFLICTING_CLASS_OBJECT_UPPER_BOUNDS.on(nameIdentifier, parameter)); } } } @@ -343,12 +354,13 @@ public class ClassDescriptorResolver { private JetType resolveAndCheckUpperBoundType(@NotNull JetTypeReference upperBound, @NotNull JetScope scope, boolean classObjectConstaint) { JetType jetType = typeResolverNotCheckingBounds.resolveType(scope, upperBound); if (!TypeUtils.canHaveSubtypes(semanticServices.getTypeChecker(), jetType)) { - String message = jetType + " is a final type, and thus a class object cannot extend it"; if (classObjectConstaint) { - trace.getErrorHandler().genericError(upperBound.getNode(), message); +// trace.getErrorHandler().genericError(upperBound.getNode(), jetType + " is a final type, and thus a class object cannot extend it"); + trace.report(FINAL_CLASS_OBJECT_UPPER_BOUND.on(upperBound, jetType)); } else { - trace.getErrorHandler().genericWarning(upperBound.getNode(), message); +// trace.getErrorHandler().genericWarning(upperBound.getNode(), jetType + " is a final type, and thus a value of the type parameter is predetermined"); + trace.report(FINAL_UPPER_BOUND.on(upperBound, jetType)); } } return jetType; @@ -482,7 +494,8 @@ public class ClassDescriptorResolver { if (propertyTypeRef == null) { final JetExpression initializer = property.getInitializer(); if (initializer == null) { - trace.getErrorHandler().genericError(property.getNode(), "This property must either have a type annotation or be initialized"); +// trace.getErrorHandler().genericError(property.getNode(), "This property must either have a type annotation or be initialized"); + trace.report(PROPERTY_WITH_NO_TYPE_NO_INITIALIZER.on(property)); return ErrorUtils.createErrorType("No type, no body"); } else { // TODO : a risk of a memory leak @@ -541,13 +554,15 @@ public class ClassDescriptorResolver { propertyDescriptor, annotations, setter.getBodyExpression() != null, false); if (parameter != null) { if (parameter.isRef()) { - trace.getErrorHandler().genericError(parameter.getRefNode(), "Setter parameters can not be 'ref'"); +// trace.getErrorHandler().genericError(parameter.getRefNode(), "Setter parameters can not be 'ref'"); + trace.report(Errors.REF_SETTER_PARAMETER.on(parameter.getRefNode())); } // This check is redundant: the parser does not allow a default value, but we'll keep it just in case JetExpression defaultValue = parameter.getDefaultValue(); if (defaultValue != null) { - trace.getErrorHandler().genericError(defaultValue.getNode(), "Setter parameters can not have default values"); +// trace.getErrorHandler().genericError(defaultValue.getNode(), "Setter parameters can not have default values"); + trace.report(SETTER_PARAMETER_WITH_DEFAULT_VALUE.on(defaultValue)); } JetType type; @@ -560,7 +575,8 @@ public class ClassDescriptorResolver { JetType inType = propertyDescriptor.getInType(); if (inType != null) { if (!semanticServices.getTypeChecker().equalTypes(type, inType)) { - trace.getErrorHandler().genericError(typeReference.getNode(), "Setter parameter type must be equal to the type of the property, i.e. " + inType); +// trace.getErrorHandler().genericError(typeReference.getNode(), "Setter parameter type must be equal to the type of the property, i.e. " + inType); + trace.report(WRONG_SETTER_PARAMETER_TYPE.on(typeReference, inType)); } } else { @@ -581,7 +597,8 @@ public class ClassDescriptorResolver { if (! property.isVar()) { if (setter != null) { - trace.getErrorHandler().genericError(setter.asElement().getNode(), "A 'val'-property cannot have a setter"); +// trace.getErrorHandler().genericError(setter.asElement().getNode(), "A 'val'-property cannot have a setter"); + trace.report(VAL_WITH_SETTER.on(setter)); } } return setterDescriptor; @@ -600,7 +617,8 @@ public class ClassDescriptorResolver { if (returnTypeReference != null) { returnType = typeResolver.resolveType(scope, returnTypeReference); if (outType != null && !semanticServices.getTypeChecker().equalTypes(returnType, outType)) { - trace.getErrorHandler().genericError(returnTypeReference.getNode(), "Getter return type must be equal to the type of the property, i.e. " + propertyDescriptor.getReturnType()); +// trace.getErrorHandler().genericError(returnTypeReference.getNode(), "Getter return type must be equal to the type of the property, i.e. " + propertyDescriptor.getReturnType()); + trace.report(WRONG_GETTER_RETURN_TYPE.on(returnTypeReference, propertyDescriptor.getReturnType())); } } @@ -636,9 +654,6 @@ public class ClassDescriptorResolver { isPrimary ); trace.record(BindingContext.CONSTRUCTOR, declarationToTrace, constructorDescriptor); - if (modifierList != null) { - modifierList.checkNotContains(trace, JetTokens.ABSTRACT_KEYWORD, JetTokens.OPEN_KEYWORD, JetTokens.OVERRIDE_KEYWORD, JetTokens.FINAL_KEYWORD); - } return constructorDescriptor.initialize( typeParameters, resolveValueParameters( @@ -673,7 +688,8 @@ public class ClassDescriptorResolver { if (modifierList != null) { ASTNode abstractNode = modifierList.getModifierNode(JetTokens.ABSTRACT_KEYWORD); if (abstractNode != null) { - trace.getErrorHandler().genericError(abstractNode, "This property cannot be declared abstract"); +// trace.getErrorHandler().genericError(abstractNode, "This property cannot be declared abstract"); + trace.report(ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS.on(abstractNode)); } } @@ -726,7 +742,8 @@ public class ClassDescriptorResolver { for (JetType bound : typeParameterDescriptor.getUpperBounds()) { JetType substitutedBound = substitutor.safeSubstitute(bound, Variance.INVARIANT); if (!semanticServices.getTypeChecker().isSubtypeOf(typeArgument, substitutedBound)) { - trace.getErrorHandler().genericError(argumentTypeReference.getNode(), "An upper bound " + substitutedBound + " is violated"); // TODO : Message +// trace.getErrorHandler().genericError(argumentTypeReference.getNode(), "An upper bound " + substitutedBound + " is violated"); + trace.report(UPPER_BOUND_VIOLATED.on(argumentTypeReference, substitutedBound)); } } } @@ -921,7 +938,8 @@ public class ClassDescriptorResolver { @Override public void visitUnsupportedElementInstruction(UnsupportedElementInstruction instruction) { - trace.getErrorHandler().genericError(instruction.getElement().getNode(), "Unsupported by control-flow builder " + instruction.getElement()); +// trace.getErrorHandler().genericError(instruction.getElement().getNode(), "Unsupported by control-flow builder " + instruction.getElement()); + trace.report(UNSUPPORTED.on(instruction.getElement(), "Control-flow builder")); } @Override @@ -943,7 +961,8 @@ public class ClassDescriptorResolver { public void visitInstruction(Instruction instruction) { if (instruction instanceof JetElementInstructionImpl) { JetElementInstructionImpl elementInstruction = (JetElementInstructionImpl) instruction; - trace.getErrorHandler().genericError(elementInstruction.getElement().getNode(), "Unsupported by control-flow builder " + elementInstruction.getElement()); +// trace.getErrorHandler().genericError(elementInstruction.getElement().getNode(), "Unsupported by control-flow builder " + elementInstruction.getElement()); + trace.report(UNSUPPORTED.on(elementInstruction.getElement(), "Control-flow builder")); } else { throw new UnsupportedOperationException(instruction.toString()); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java index 2eba49a2047..6aca3fe1866 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationResolver.java @@ -8,6 +8,7 @@ import org.jetbrains.jet.lang.psi.*; import java.util.List; import java.util.Map; +import static org.jetbrains.jet.lang.diagnostics.Errors.CONSTRUCTOR_IN_TRAIT; import static org.jetbrains.jet.lang.resolve.BindingContext.ANNOTATION; /** @@ -128,7 +129,8 @@ public class DeclarationResolver { if (!klass.hasPrimaryConstructor()) return; if (classDescriptor.getKind() == ClassKind.TRAIT) { - context.getTrace().getErrorHandler().genericError(klass.getPrimaryConstructorParameterList().getNode(), "A trait may not have a constructor"); +// context.getTrace().getErrorHandler().genericError(klass.getPrimaryConstructorParameterList().getNode(), "A trait may not have a constructor"); + context.getTrace().report(CONSTRUCTOR_IN_TRAIT.on(klass.getPrimaryConstructorParameterList())); } // TODO : not all the parameters are real properties @@ -150,7 +152,8 @@ public class DeclarationResolver { private void processSecondaryConstructor(MutableClassDescriptor classDescriptor, JetConstructor constructor) { if (classDescriptor.getKind() == ClassKind.TRAIT) { - context.getTrace().getErrorHandler().genericError(constructor.getNameNode(), "A trait may not have a constructor"); +// context.getTrace().getErrorHandler().genericError(constructor.getNameNode(), "A trait may not have a constructor"); + context.getTrace().report(CONSTRUCTOR_IN_TRAIT.on(constructor.getNameNode())); } ConstructorDescriptor constructorDescriptor = context.getClassDescriptorResolver().resolveSecondaryConstructorDescriptor( classDescriptor.getScopeForMemberResolution(), diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegatingBindingTrace.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegatingBindingTrace.java index 426ec625d97..5fc2331d4bb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegatingBindingTrace.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegatingBindingTrace.java @@ -2,9 +2,10 @@ package org.jetbrains.jet.lang.resolve; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.CollectingErrorHandler; -import org.jetbrains.jet.lang.ErrorHandler; -import org.jetbrains.jet.lang.JetDiagnostic; +import org.jetbrains.jet.lang.diagnostics.CollectingErrorHandler; +import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.JetDiagnostic; import org.jetbrains.jet.util.slicedmap.*; import java.util.Collection; @@ -17,12 +18,18 @@ import java.util.Map; public class DelegatingBindingTrace implements BindingTrace { private final BindingContext parentContext; private final MutableSlicedMap map = SlicedMapImpl.create(); - private final List diagnostics = Lists.newArrayList(); - private final ErrorHandler errorHandler = new CollectingErrorHandler(diagnostics); + private final List old_diagnostics = Lists.newArrayList(); + private final List diagnostics = Lists.newArrayList(); + private final ErrorHandler errorHandler = new CollectingErrorHandler(old_diagnostics); private final BindingContext bindingContext = new BindingContext() { @Override - public Collection getDiagnostics() { + public Collection getOld_Diagnostics() { + throw new UnsupportedOperationException(); // TODO + } + + @Override + public Collection getDiagnostics() { throw new UnsupportedOperationException(); // TODO } @@ -74,6 +81,15 @@ public class DelegatingBindingTrace implements BindingTrace { trace.record(slicedMapKey.getSlice(), slicedMapKey.getKey(), value); } - ErrorHandler.applyHandler(trace.getErrorHandler(), diagnostics); + ErrorHandler.old_applyHandler(trace.getErrorHandler(), old_diagnostics); + + for (Diagnostic diagnostic : diagnostics) { + trace.report(diagnostic); + } + } + + @Override + public void report(@NotNull Diagnostic diagnostic) { + diagnostics.add(diagnostic); } } \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index b92d0ea64ed..5e097c990ba 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -16,6 +16,7 @@ import org.jetbrains.jet.lexer.JetTokens; import java.util.*; +import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.BindingContext.DESCRIPTOR_TO_DECLARATION; import static org.jetbrains.jet.lang.resolve.BindingContext.TYPE; @@ -164,7 +165,8 @@ public class TypeHierarchyResolver { @Override public void visitTypedef(JetTypedef typedef) { - context.getTrace().getErrorHandler().genericError(typedef.getNode(), "Unsupported [TopDownAnalyzer]"); +// context.getTrace().getErrorHandler().genericError(typedef.getNode(), "Unsupported [TopDownAnalyzer]"); + context.getTrace().report(UNSUPPORTED.on(typedef, "TypeHierarchyResolver")); } @Override @@ -174,10 +176,12 @@ public class TypeHierarchyResolver { NamespaceLike.ClassObjectStatus status = owner.setClassObjectDescriptor(createClassDescriptorForObject(objectDeclaration, owner)); switch (status) { case DUPLICATE: - context.getTrace().getErrorHandler().genericError(classObject.getNode(), "Only one class object is allowed per class"); +// context.getTrace().getErrorHandler().genericError(classObject.getNode(), "Only one class object is allowed per class"); + context.getTrace().report(MANY_CLASS_OBJECTS.on(classObject)); break; case NOT_ALLOWED: - context.getTrace().getErrorHandler().genericError(classObject.getNode(), "A class object is not allowed here"); +// context.getTrace().getErrorHandler().genericError(classObject.getNode(), "A class object is not allowed here"); + context.getTrace().report(CLASS_OBJECT_NOT_ALLOWED.on(classObject)); break; } } @@ -198,7 +202,8 @@ public class TypeHierarchyResolver { List importDirectives = namespace.getImportDirectives(); for (JetImportDirective importDirective : importDirectives) { if (importDirective.isAbsoluteInRootNamespace()) { - context.getTrace().getErrorHandler().genericError(namespace.getNode(), "Unsupported by TDA"); // TODO +// context.getTrace().getErrorHandler().genericError(namespace.getNode(), "Unsupported by TDA"); // TODO + context.getTrace().report(UNSUPPORTED.on(namespace, "TypeHierarchyResolver")); // TODO continue; } if (importDirective.isAllUnder()) { @@ -378,7 +383,8 @@ public class TypeHierarchyResolver { } } if (node != null) { - context.getTrace().getErrorHandler().genericError(node, "There's a cycle in the inheritance hierarchy for this type"); +// context.getTrace().getErrorHandler().genericError(node, "There's a cycle in the inheritance hierarchy for this type"); + context.getTrace().report(CYCLIC_INHERITANCE_HIERARCHY.on(node)); } } } @@ -421,7 +427,8 @@ public class TypeHierarchyResolver { JetClassOrObject declaration = (JetClassOrObject) psiElement; JetDelegationSpecifierList delegationSpecifierList = declaration.getDelegationSpecifierList(); assert delegationSpecifierList != null; - context.getTrace().getErrorHandler().genericError(delegationSpecifierList.getNode(), "Type parameter " + typeParameterDescriptor.getName() + " of " + containingDeclaration.getName() + " has inconsistent values: " + conflictingTypes); +// context.getTrace().getErrorHandler().genericError(delegationSpecifierList.getNode(), "Type parameter " + typeParameterDescriptor.getName() + " of " + containingDeclaration.getName() + " has inconsistent values: " + conflictingTypes); + context.getTrace().report(INCONSISTENT_TYPE_PARAMETER_VALUES.on(delegationSpecifierList, typeParameterDescriptor, (ClassDescriptor) containingDeclaration, conflictingTypes)); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java index 63ed59ab9c5..ff2b24df2d3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -3,7 +3,10 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.JetSemanticServices; -import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.types.*; @@ -12,6 +15,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import static org.jetbrains.jet.lang.diagnostics.Errors.UNRESOLVED_REFERENCE; +import static org.jetbrains.jet.lang.diagnostics.Errors.WRONG_NUMBER_OF_TYPE_ARGUMENTS; + /** * @author abreslav */ @@ -95,11 +101,13 @@ public class TypeResolver { } else { if (actualArgumentCount != expectedArgumentCount) { - String errorMessage = (expectedArgumentCount == 0 ? "No" : expectedArgumentCount) + " type arguments expected"; +// String errorMessage = (expectedArgumentCount == 0 ? "No" : expectedArgumentCount) + " type arguments expected"; if (actualArgumentCount == 0) { - trace.getErrorHandler().genericError(type.getNode(), errorMessage); +// trace.getErrorHandler().genericError(type.getNode(), errorMessage); + trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(type, expectedArgumentCount)); } else { - trace.getErrorHandler().genericError(type.getTypeArgumentList().getNode(), errorMessage); +// trace.getErrorHandler().genericError(type.getTypeArgumentList().getNode(), errorMessage); + trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(type, expectedArgumentCount)); } } else { result[0] = new JetTypeImpl( @@ -227,7 +235,7 @@ public class TypeResolver { ClassifierDescriptor classifierDescriptor = resolveClassWithoutErrorReporting(scope, userType); if (classifierDescriptor == null) { - trace.getErrorHandler().unresolvedReference(userType.getReferenceExpression()); + trace.report(UNRESOLVED_REFERENCE.on(userType.getReferenceExpression())); } return classifierDescriptor; @@ -270,7 +278,7 @@ public class TypeResolver { NamespaceDescriptor namespaceDescriptor = resolveNamespace(scope, userType); if (namespaceDescriptor == null) { - trace.getErrorHandler().unresolvedReference(userType.getReferenceExpression()); + trace.report(UNRESOLVED_REFERENCE.on(userType.getReferenceExpression())); return null; } return namespaceDescriptor.getMemberScope(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeImpl.java index e74280957d5..35609367fd7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeImpl.java @@ -5,7 +5,7 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.types.*; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeWithImports.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeWithImports.java index 8b63aca7abc..ad007816ddb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeWithImports.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WritableScopeWithImports.java @@ -2,7 +2,7 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; import org.jetbrains.jet.lang.descriptors.*; import java.util.ArrayList; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WriteThroughScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WriteThroughScope.java index 37f9e5410cf..1adaa32ea78 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WriteThroughScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/WriteThroughScope.java @@ -3,7 +3,7 @@ package org.jetbrains.jet.lang.resolve; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.types.*; 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 792948941c8..b03aad99a9e 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 @@ -18,6 +18,7 @@ import org.jetbrains.jet.resolve.DescriptorRenderer; import java.util.*; +import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_REFERENCE_TARGET; import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; import static org.jetbrains.jet.lang.types.JetTypeInferrer.NO_EXPECTED_TYPE; @@ -103,7 +104,8 @@ public class CallResolver { if (descriptor instanceof ConstructorDescriptor) { Modality modality = ((ConstructorDescriptor) descriptor).getContainingDeclaration().getModality(); if (modality == Modality.ABSTRACT) { - tracing.reportOverallResolutionError(trace, "Can not create an instance of an abstract class"); +// tracing.reportOverallResolutionError(trace, "Can not create an instance of an abstract class"); + tracing.instantiationOfAbstractClass(trace); return false; } } @@ -135,13 +137,15 @@ public class CallResolver { ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; Set constructors = classDescriptor.getConstructors().getFunctionDescriptors(); if (constructors.isEmpty()) { - trace.getErrorHandler().genericError(reportAbsenceOn, "This class does not have a constructor"); +// trace.getErrorHandler().genericError(reportAbsenceOn, "This class does not have a constructor"); + trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn)); return checkArgumentTypesAndFail(trace, scope, call); } prioritizedTasks.add(new ResolutionTask(constructors, null, call)); } else { - trace.getErrorHandler().genericError(calleeExpression.getNode(), "Not a class"); +// trace.getErrorHandler().genericError(calleeExpression.getNode(), "Not a class"); + trace.report(NOT_A_CLASS.on(calleeExpression)); return checkArgumentTypesAndFail(trace, scope, call); } } @@ -154,7 +158,8 @@ public class CallResolver { Set constructors = classDescriptor.getConstructors().getFunctionDescriptors(); if (constructors.isEmpty()) { - trace.getErrorHandler().genericError(reportAbsenceOn, "This class does not have a constructor"); +// trace.getErrorHandler().genericError(reportAbsenceOn, "This class does not have a constructor"); + trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn)); return checkArgumentTypesAndFail(trace, scope, call); } prioritizedTasks = Collections.singletonList(new ResolutionTask(constructors, null, call)); @@ -189,24 +194,53 @@ public class CallResolver { trace.record(REFERENCE_TARGET, reference, descriptor); } +// public void reportOverallResolutionError(@NotNull BindingTrace trace, @NotNull String message) { +// trace.getErrorHandler().genericError(callNode, message); +// } +// +// public void reportWrongTypeArguments(@NotNull BindingTrace trace, @NotNull String message) { +// JetTypeArgumentList typeArgumentList = call.getTypeArgumentList(); +// if (typeArgumentList != null) { +// trace.getErrorHandler().genericError(typeArgumentList.getNode(), message); +// } +// else { +// reportOverallResolutionError(trace, message); +// } +// } +// +// public void reportWrongValueArguments(@NotNull BindingTrace trace, @NotNull String message) { +// ASTNode node; +// +// JetValueArgumentList valueArgumentList = call.getValueArgumentList(); +// if (valueArgumentList != null) { +// node = valueArgumentList.getNode(); +// } +// else if (!call.getFunctionLiteralArguments().isEmpty()) { +// node = call.getFunctionLiteralArguments().get(0).getNode(); +// } +// else { +// node = callNode; +// } +// +// trace.getErrorHandler().genericError(node, message); +// } +// +// public void reportErrorOnReference(BindingTrace trace, String message) { +// trace.getErrorHandler().genericError(reference.getNode(), message); +// } + @Override - public void reportOverallResolutionError(@NotNull BindingTrace trace, @NotNull String message) { - trace.getErrorHandler().genericError(callNode, message); + public void recordAmbiguity(BindingTrace trace, Collection candidates) { + trace.record(AMBIGUOUS_REFERENCE_TARGET, reference, candidates); } @Override - public void reportWrongTypeArguments(@NotNull BindingTrace trace, @NotNull String message) { - JetTypeArgumentList typeArgumentList = call.getTypeArgumentList(); - if (typeArgumentList != null) { - trace.getErrorHandler().genericError(typeArgumentList.getNode(), message); - } - else { - reportOverallResolutionError(trace, message); - } + public void unresolvedReference(@NotNull BindingTrace trace) { + trace.report(UNRESOLVED_REFERENCE.on(reference)); } @Override - public void reportWrongValueArguments(@NotNull BindingTrace trace, @NotNull String message) { + public void noValueForParameter(@NotNull BindingTrace trace, @NotNull ValueParameterDescriptor valueParameter) { ASTNode node; JetValueArgumentList valueArgumentList = call.getValueArgumentList(); @@ -219,23 +253,50 @@ public class CallResolver { else { node = callNode; } - - trace.getErrorHandler().genericError(node, message); + trace.report(NO_VALUE_FOR_PARAMETER.on(node, valueParameter)); } @Override - public void reportUnresolvedReference(@NotNull BindingTrace trace) { - trace.getErrorHandler().unresolvedReference(reference); + public void missingReceiver(@NotNull BindingTrace trace, @NotNull JetType candidateReceiverType) { + trace.report(MISSING_RECEIVER.on(reference, candidateReceiverType)); } @Override - public void reportErrorOnReference(BindingTrace trace, String message) { - trace.getErrorHandler().genericError(reference.getNode(), message); + public void noReceiverAllowed(@NotNull BindingTrace trace) { + trace.report(NO_RECEIVER_ADMITTED.on(reference)); } @Override - public void recordAmbiguity(BindingTrace trace, Collection candidates) { - trace.record(AMBIGUOUS_REFERENCE_TARGET, reference, candidates); + public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) { + JetTypeArgumentList typeArgumentList = call.getTypeArgumentList(); + if (typeArgumentList != null) { +// trace.getErrorHandler().genericError(typeArgumentList.getNode(), message); + trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(typeArgumentList, expectedTypeArgumentCount)); + } + else { +// reportOverallResolutionError(trace, message); + trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(reference, expectedTypeArgumentCount)); + } + } + + @Override + public void ambiguity(@NotNull BindingTrace trace, @NotNull Set descriptors) { + trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(callNode, descriptors)); + } + + @Override + public void noneApplicable(@NotNull BindingTrace trace, @NotNull Set descriptors) { + trace.report(NONE_APPLICABLE.on(callNode, descriptors)); + } + + @Override + public void instantiationOfAbstractClass(@NotNull BindingTrace trace) { + trace.report(CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS.on(callNode)); + } + + @Override + public void typeInferenceFailed(@NotNull BindingTrace trace) { + trace.report(TYPE_INFERENCE_FAILED.on(callNode)); } }; @@ -258,7 +319,7 @@ public class CallResolver { } } else { - trace.getErrorHandler().unresolvedReference(reference); + trace.report(UNRESOLVED_REFERENCE.on(reference)); checkTypesWithNoCallee(trace, scope, call.getTypeArguments(), call.getValueArguments(), call.getFunctionLiteralArguments()); } return null; @@ -350,7 +411,7 @@ public class CallResolver { successfulCandidates.put(candidate, substitute); } else { - tracing.reportOverallResolutionError(temporaryTrace, "Type inference failed"); + tracing.typeInferenceFailed(temporaryTrace); failedCandidates.add(candidate); } } @@ -362,11 +423,13 @@ public class CallResolver { for (JetTypeProjection typeArgument : jetTypeArguments) { if (typeArgument.getProjectionKind() != JetProjectionKind.NONE) { - temporaryTrace.getErrorHandler().genericError(typeArgument.getNode(), "Projections are not allowed on type parameters for methods"); // TODO : better positioning +// temporaryTrace.getErrorHandler().genericError(typeArgument.getNode(), "Projections are not allowed on type parameters for methods"); // TODO : better positioning + temporaryTrace.report(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(typeArgument)); } } - if (candidate.getTypeParameters().size() == jetTypeArguments.size()) { + int expectedTypeArgumentCount = candidate.getTypeParameters().size(); + if (expectedTypeArgumentCount == jetTypeArguments.size()) { List typeArguments = new ArrayList(); for (JetTypeProjection projection : jetTypeArguments) { // TODO : check that there's no projection @@ -392,7 +455,8 @@ public class CallResolver { } else { failedCandidates.add(candidate); - tracing.reportWrongTypeArguments(temporaryTrace, "Number of type arguments does not match " + DescriptorRenderer.TEXT.render(candidate)); +// tracing.reportWrongTypeArguments(temporaryTrace, "Number of type arguments does not match " + DescriptorRenderer.TEXT.render(candidate)); + tracing.wrongNumberOfTypeArguments(temporaryTrace, expectedTypeArgumentCount); } } @@ -448,7 +512,7 @@ public class CallResolver { if (receiverType != null && candidateReceiverType != null && !semanticServices.getTypeChecker().isSubtypeOf(receiverType, candidateReceiverType)) { - tracing.reportErrorOnReference(temporaryTrace, "This function requires a receiver of type " + candidateReceiverType); + tracing.missingReceiver(temporaryTrace, candidateReceiverType); return false; } return true; @@ -459,12 +523,12 @@ public class CallResolver { JetType candidateReceiverType = candidate.getReceiverType(); if (receiverType != null) { if (candidateReceiverType == null) { - tracing.reportErrorOnReference(temporaryTrace, "This function does not admit a receiver"); + tracing.noReceiverAllowed(temporaryTrace); return false; } } else if (candidateReceiverType != null) { - tracing.reportErrorOnReference(temporaryTrace, "Receiver is missing" + candidateReceiverType); + tracing.missingReceiver(temporaryTrace, candidateReceiverType); return false; } return true; @@ -492,8 +556,9 @@ public class CallResolver { Set noOverrides = filterOverrides(successfulCandidates.keySet()); if (dirtyCandidates.isEmpty()) { - tracing.reportOverallResolutionError(trace, "Overload resolution ambiguity: " - + makeErrorMessageForMultipleDescriptors(noOverrides)); +// tracing.reportOverallResolutionError(trace, "Overload resolution ambiguity: " +// + makeErrorMessageForMultipleDescriptors(noOverrides)); + tracing.ambiguity(trace, noOverrides); } tracing.recordAmbiguity(trace, noOverrides); @@ -514,8 +579,9 @@ public class CallResolver { if (failedCandidates.size() != 1) { Set noOverrides = filterOverrides(failedCandidates); if (noOverrides.size() != 1) { - tracing.reportOverallResolutionError(trace, "None of the following functions can be called with the arguments supplied: " - + makeErrorMessageForMultipleDescriptors(noOverrides)); +// tracing.reportOverallResolutionError(trace, "None of the following functions can be called with the arguments supplied: " +// + makeErrorMessageForMultipleDescriptors(noOverrides)); + tracing.noneApplicable(trace, noOverrides); tracing.recordAmbiguity(trace, noOverrides); return OverloadResolutionResult.manyFailedCandidates(noOverrides); } @@ -527,7 +593,7 @@ public class CallResolver { return OverloadResolutionResult.singleFailedCandidate(failedCandidates.iterator().next()); } else { - tracing.reportUnresolvedReference(trace); + tracing.unresolvedReference(trace); return OverloadResolutionResult.nameNotFound(); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TracingStrategy.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TracingStrategy.java index 53ffb30dfd6..117df0b9a8c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TracingStrategy.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TracingStrategy.java @@ -2,9 +2,12 @@ package org.jetbrains.jet.lang.resolve.calls; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.resolve.BindingTrace; +import org.jetbrains.jet.lang.types.JetType; import java.util.Collection; +import java.util.Set; /** * @author abreslav @@ -15,35 +18,55 @@ import java.util.Collection; public void bindReference(@NotNull BindingTrace trace, @NotNull CallableDescriptor descriptor) {} @Override - public void reportOverallResolutionError(@NotNull BindingTrace trace, @NotNull String message) {} - - @Override - public void reportWrongTypeArguments(@NotNull BindingTrace trace, @NotNull String message) {} - - @Override - public void reportWrongValueArguments(@NotNull BindingTrace trace, @NotNull String message) {} - - @Override - public void reportUnresolvedReference(@NotNull BindingTrace trace) {} - - @Override - public void reportErrorOnReference(BindingTrace trace, String message) {} + public void unresolvedReference(@NotNull BindingTrace trace) {} @Override public void recordAmbiguity(BindingTrace trace, Collection candidates) {} + + @Override + public void missingReceiver(@NotNull BindingTrace trace, @NotNull JetType candidateReceiverType) {} + + @Override + public void noReceiverAllowed(@NotNull BindingTrace trace) {} + + @Override + public void noValueForParameter(@NotNull BindingTrace trace, @NotNull ValueParameterDescriptor valueParameter) {} + + @Override + public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) {} + + @Override + public void ambiguity(@NotNull BindingTrace trace, @NotNull Set descriptors) {} + + @Override + public void noneApplicable(@NotNull BindingTrace trace, @NotNull Set descriptors) {} + + @Override + public void instantiationOfAbstractClass(@NotNull BindingTrace trace) {} + + @Override + public void typeInferenceFailed(@NotNull BindingTrace trace) {} }; void bindReference(@NotNull BindingTrace trace, @NotNull CallableDescriptor descriptor); - void reportOverallResolutionError(@NotNull BindingTrace trace, @NotNull String message); - - void reportWrongTypeArguments(@NotNull BindingTrace trace, @NotNull String message); - - void reportWrongValueArguments(@NotNull BindingTrace trace, @NotNull String message); - - void reportUnresolvedReference(@NotNull BindingTrace trace); - - void reportErrorOnReference(BindingTrace trace, String message); + void unresolvedReference(@NotNull BindingTrace trace); void recordAmbiguity(BindingTrace trace, Collection candidates); + + void missingReceiver(@NotNull BindingTrace trace, @NotNull JetType candidateReceiverType); + + void noReceiverAllowed(@NotNull BindingTrace trace); + + void noValueForParameter(@NotNull BindingTrace trace, @NotNull ValueParameterDescriptor valueParameter); + + void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount); + + void ambiguity(@NotNull BindingTrace trace, @NotNull Set descriptors); + + void noneApplicable(@NotNull BindingTrace trace, @NotNull Set descriptors); + + void instantiationOfAbstractClass(@NotNull BindingTrace trace); + + void typeInferenceFailed(@NotNull BindingTrace trace); } 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 b4bcf3e2364..dbb17dff53a 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 @@ -12,12 +12,12 @@ import org.jetbrains.jet.lang.psi.JetLabelQualifiedExpression; import org.jetbrains.jet.lang.psi.ValueArgument; import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.types.CallMaker; -import org.jetbrains.jet.resolve.DescriptorRenderer; import java.util.List; import java.util.Map; import java.util.Set; +import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; /** @@ -51,16 +51,19 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; someNamed = true; ASTNode nameNode = valueArgument.getArgumentName().getNode(); if (somePositioned) { - temporaryTrace.getErrorHandler().genericError(nameNode, "Mixing named and positioned arguments in not allowed"); +// temporaryTrace.getErrorHandler().genericError(nameNode, "Mixing named and positioned arguments in not allowed"); + temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(nameNode)); error = true; } else { ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(valueArgument.getArgumentName().getReferenceExpression().getReferencedName()); if (!usedParameters.add(valueParameterDescriptor)) { - temporaryTrace.getErrorHandler().genericError(nameNode, "An argument is already passed for this parameter"); +// temporaryTrace.getErrorHandler().genericError(nameNode, "An argument is already passed for this parameter"); + temporaryTrace.report(ARGUMENT_PASSED_TWICE.on(nameNode)); } if (valueParameterDescriptor == null) { - temporaryTrace.getErrorHandler().genericError(nameNode, "Cannot find a parameter with this name"); +// temporaryTrace.getErrorHandler().genericError(nameNode, "Cannot find a parameter with this name"); + temporaryTrace.report(NAMED_PARAMETER_NOT_FOUND.on(nameNode)); error = true; } else { @@ -72,7 +75,8 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; else { somePositioned = true; if (someNamed) { - temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), "Mixing named and positioned arguments in not allowed"); +// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), "Mixing named and positioned arguments in not allowed"); + temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(valueArgument.asElement())); error = true; } else { @@ -89,12 +93,14 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; usedParameters.add(valueParameterDescriptor); } else { - temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), getTooManyArgumentsMessage(candidate)); +// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), getTooManyArgumentsMessage(candidate)); + temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate)); error = true; } } else { - temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), getTooManyArgumentsMessage(candidate)); +// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), getTooManyArgumentsMessage(candidate)); + temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate)); error = true; } } @@ -106,7 +112,8 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; JetExpression possiblyLabeledFunctionLiteral = functionLiteralArguments.get(0); if (valueParameters.isEmpty()) { - temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), getTooManyArgumentsMessage(candidate)); +// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), getTooManyArgumentsMessage(candidate)); + temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate)); error = true; } else { JetFunctionLiteralExpression functionLiteral; @@ -120,12 +127,14 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; ValueParameterDescriptor parameterDescriptor = valueParameters.get(valueParameters.size() - 1); if (parameterDescriptor.isVararg()) { - temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), "Passing value as a vararg is only allowed inside a parenthesized argument list"); +// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), "Passing value as a vararg is only allowed inside a parenthesized argument list"); + temporaryTrace.report(VARARG_OUTSIDE_PARENTHESES.on(possiblyLabeledFunctionLiteral)); error = true; } else { if (!usedParameters.add(parameterDescriptor)) { - temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), getTooManyArgumentsMessage(candidate)); +// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), getTooManyArgumentsMessage(candidate)); + temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate)); error = true; } else { @@ -136,7 +145,8 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; for (int i = 1; i < functionLiteralArguments.size(); i++) { JetExpression argument = functionLiteralArguments.get(i); - temporaryTrace.getErrorHandler().genericError(argument.getNode(), "Only one function literal is allowed outside a parenthesized argument list"); +// temporaryTrace.getErrorHandler().genericError(argument.getNode(), "Only one function literal is allowed outside a parenthesized argument list"); + temporaryTrace.report(MANY_FUNCTION_LITERAL_ARGUMENTS.on(argument)); error = true; } } @@ -145,7 +155,8 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; for (ValueParameterDescriptor valueParameter : valueParameters) { if (!usedParameters.contains(valueParameter)) { if (!valueParameter.hasDefaultValue()) { - tracing.reportWrongValueArguments(temporaryTrace, "No value passed for parameter " + valueParameter.getName()); +// tracing.reportWrongValueArguments(temporaryTrace, "No value passed for parameter " + valueParameter.getName()); + tracing.noValueForParameter(temporaryTrace, valueParameter); error = true; } } @@ -153,7 +164,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; return error; } - private static String getTooManyArgumentsMessage(Descriptor candidate) { - return "Too many arguments for " + DescriptorRenderer.TEXT.render(candidate); - } +// private static String getTooManyArgumentsMessage(Descriptor candidate) { +// return "Too many arguments for " + DescriptorRenderer.TEXT.render(candidate); +// } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java index 452141a45a8..73504915eeb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardClasses.java @@ -4,7 +4,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.JetScope; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java index d479b05a4f1..a1f53ad71ef 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java @@ -4,7 +4,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.psi.PsiFileFactory; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index 934a0bdcf99..2f02f2fe245 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -11,12 +11,12 @@ import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetNodeTypes; -import org.jetbrains.jet.lang.CompositeErrorHandler; -import org.jetbrains.jet.lang.ErrorHandler; import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.diagnostics.CompositeErrorHandler; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.calls.CallResolver; @@ -24,11 +24,11 @@ import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResult; import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.constants.StringValue; import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.jet.resolve.DescriptorRenderer; import org.jetbrains.jet.util.slicedmap.WritableSlice; import java.util.*; +import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.BindingContext.*; /** @@ -223,14 +223,19 @@ public class JetTypeInferrer { IElementType operationSign = operationTokenNode.getElementType(); if (nullableReceiver && calleeForbidsNullableReceiver && operationSign == JetTokens.DOT) { - trace.getErrorHandler().genericError(operationTokenNode, "Only safe calls (?.) are allowed on a nullable receiver of type " + receiverType); +// trace.getErrorHandler().genericError(operationTokenNode, "Only safe calls (?.) are allowed on a nullable receiver of type " + receiverType); + trace.report(UNSAFE_CALL.on(operationTokenNode, receiverType)); } else if ((!nullableReceiver || !calleeForbidsNullableReceiver) && operationSign == JetTokens.SAFE_ACCESS) { if (namespaceType) { - trace.getErrorHandler().genericError(operationTokenNode, "Safe calls are not allowed on namespaces"); +// trace.getErrorHandler().genericError(operationTokenNode, "Safe calls are not allowed on namespaces"); + trace.report(SAFE_CALLS_ARE_NOT_ALLOWED_ON_NAMESPACES.on(operationTokenNode)); } else { - trace.getErrorHandler().genericWarning(operationTokenNode, "Unnecessary safe call on a non-null receiver of type " + receiverType); +// trace.getErrorHandler().genericWarning(operationTokenNode, "Unnecessary safe call on a non-null receiver of type " + receiverType); + + trace.report(UNNECESSARY_SAFE_CALL.on(operationTokenNode, receiverType)); + } } } @@ -270,7 +275,7 @@ public class JetTypeInferrer { // } // else if (element instanceof JetExpression) { // JetExpression expression = (JetExpression) element; - // context.trace.getErrorHandler().typeMismatch(expression, expectedReturnType, actualType); + // context.trace.report(TYPE_MISMATCH.on(expression, expectedReturnType, actualType)); // } // else { // context.trace.getErrorHandler().genericError(element.getNode(), "This function must return a value of type " + expectedReturnType); @@ -313,7 +318,8 @@ public class JetTypeInferrer { // though it'd better be reported more specifically for (JetElement element : rootUnreachableElements) { - trace.getErrorHandler().genericError(element.getNode(), "Unreachable code"); +// trace.getErrorHandler().genericError(element.getNode(), "Unreachable code"); + trace.report(UNREACHABLE_CODE.on(element)); } List returnedExpressions = Lists.newArrayList(); @@ -324,7 +330,8 @@ public class JetTypeInferrer { returnedExpressions.remove(function); // This will be the only "expression" if the body is empty if (expectedReturnType != NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(expectedReturnType) && returnedExpressions.isEmpty() && !nothingReturned) { - trace.getErrorHandler().genericError(bodyExpression.getNode(), "This function must return a value of type " + expectedReturnType); +// trace.getErrorHandler().genericError(bodyExpression.getNode(), "This function must return a value of type " + expectedReturnType); + trace.report(RETURN_TYPE_MISMATCH.on(bodyExpression, expectedReturnType)); } for (JetExpression returnedExpression : returnedExpressions) { @@ -332,7 +339,8 @@ public class JetTypeInferrer { @Override public void visitReturnExpression(JetReturnExpression expression) { if (!blockBody) { - trace.getErrorHandler().genericError(expression.getNode(), "Returns are not allowed for functions with expression body. Use block body in '{...}'"); +// trace.getErrorHandler().genericError(expression.getNode(), "Returns are not allowed for functions with expression body. Use block body in '{...}'"); + trace.report(RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY.on(expression)); } } @@ -342,7 +350,8 @@ public class JetTypeInferrer { //TODO move to pseudocode JetType type = typeInferrerVisitor.getType(expression, context.replaceExpectedType(NO_EXPECTED_TYPE)); if (type == null || !JetStandardClasses.isNothing(type)) { - trace.getErrorHandler().genericError(expression.getNode(), "A 'return' expression required in a function with a block body ('{...}')"); +// trace.getErrorHandler().genericError(expression.getNode(), "A 'return' expression required in a function with a block body ('{...}')"); + trace.report(NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY.on(expression)); } } } @@ -489,7 +498,7 @@ public class JetTypeInferrer { private JetType checkType(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull TypeInferenceContext context) { if (expressionType != null && context.expectedType != null && context.expectedType != NO_EXPECTED_TYPE) { if (!semanticServices.getTypeChecker().isSubtypeOf(expressionType, context.expectedType)) { - context.trace.getErrorHandler().typeMismatch(expression, context.expectedType, expressionType); + context.trace.report(TYPE_MISMATCH.on(expression, context.expectedType, expressionType)); } } return expressionType; @@ -520,7 +529,8 @@ public class JetTypeInferrer { } } if (!appropriateTypeFound) { - context.trace.getErrorHandler().typeMismatch(expression, context.expectedType, expressionType); +// context.trace.getErrorHandler().typeMismatch(expression, context.expectedType, expressionType); + context.trace.report(TYPE_MISMATCH.on(expression, context.expectedType, expressionType)); return expressionType; } checkAutoCast(expression, context.expectedType, variableDescriptor, context.trace); @@ -529,7 +539,8 @@ public class JetTypeInferrer { private void checkAutoCast(JetExpression expression, JetType type, VariableDescriptor variableDescriptor, BindingTrace trace) { if (variableDescriptor.isVar()) { - trace.getErrorHandler().genericError(expression.getNode(), "Automatic cast to " + type + " is impossible, because variable " + variableDescriptor.getName() + " is mutable"); +// trace.getErrorHandler().genericError(expression.getNode(), "Automatic cast to " + type + " is impossible, because variable " + variableDescriptor.getName() + " is mutable"); + trace.report(AUTOCAST_IMPOSSIBLE.on(expression, type, variableDescriptor)); } else { trace.record(BindingContext.AUTOCAST, expression, type); } @@ -696,7 +707,8 @@ public class JetTypeInferrer { } } catch (ReenteringLazyValueComputationException e) { - context.trace.getErrorHandler().genericError(expression.getNode(), "Type checking has run into a recursive problem"); // TODO : message +// context.trace.getErrorHandler().genericError(expression.getNode(), "Type checking has run into a recursive problem"); // TODO : message + context.trace.report(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM.on(expression)); result = null; } @@ -725,8 +737,9 @@ public class JetTypeInferrer { flowInformationProvider.collectDominatedExpressions(expression, dominated); Set rootExpressions = JetPsiUtil.findRootExpressions(dominated); for (JetElement rootExpression : rootExpressions) { - context.trace.getErrorHandler().genericError(rootExpression.getNode(), - "This code is unreachable, because '" + expression.getText() + "' never terminates normally"); +// context.trace.getErrorHandler().genericError(rootExpression.getNode(), +// "This code is unreachable, because '" + expression.getText() + "' never terminates normally"); + context.trace.report(UNREACHABLE_BECAUSE_OF_NOTHING.on(rootExpression, expression.getText())); } } @@ -741,7 +754,7 @@ public class JetTypeInferrer { && referencedName != null) { PropertyDescriptor property = context.scope.getPropertyByFieldReference(referencedName); if (property == null) { - context.trace.getErrorHandler().unresolvedReference(expression); + context.trace.report(UNRESOLVED_REFERENCE.on(expression)); } else { context.trace.record(REFERENCE_TARGET, expression, property); @@ -784,7 +797,7 @@ public class JetTypeInferrer { // // } // } -// context.trace.getErrorHandler().unresolvedReference(expression); +// context.trace.report(UNRESOLVED_REFERENCE.on(expression)); // } } return null; @@ -799,7 +812,8 @@ public class JetTypeInferrer { result = classObjectType; } else { - context.trace.getErrorHandler().genericError(expression.getNode(), "Classifier " + classifier.getName() + " does not have a class object"); +// context.trace.getErrorHandler().genericError(expression.getNode(), "Classifier " + classifier.getName() + " does not have a class object"); + context.trace.report(NO_CLASS_OBJECT.on(expression, classifier)); } context.trace.record(REFERENCE_TARGET, expression, classifier); if (result == null) { @@ -824,7 +838,8 @@ public class JetTypeInferrer { protected boolean furtherNameLookup(@NotNull JetSimpleNameExpression expression, @NotNull String referencedName, @NotNull JetType[] result, TypeInferenceContext context) { NamespaceType namespaceType = lookupNamespaceType(expression, referencedName, context); if (namespaceType != null) { - context.trace.getErrorHandler().genericError(expression.getNode(), "Expression expected, but a namespace name found"); +// context.trace.getErrorHandler().genericError(expression.getNode(), "Expression expected, but a namespace name found"); + context.trace.report(EXPRESSION_EXPECTED_NAMESPACE_FOUND.on(expression)); return true; } return false; @@ -910,7 +925,8 @@ public class JetTypeInferrer { type = valueParameters.get(i).getOutType(); } else { - context.trace.getErrorHandler().genericError(parameter.getNode(), "Cannot infer a type for this parameter. To specify it explicitly use the {(p : Type) => ...} notation"); +// context.trace.getErrorHandler().genericError(parameter.getNode(), "Cannot infer a type for this parameter. To specify it explicitly use the {(p : Type) => ...} notation"); + context.trace.report(CANNOT_INFER_PARAMETER_TYPE.on(parameter)); type = ErrorUtils.createErrorType("Cannot be inferred"); } } @@ -997,7 +1013,8 @@ public class JetTypeInferrer { } if (value instanceof ErrorValue) { ErrorValue errorValue = (ErrorValue) value; - context.trace.getErrorHandler().genericError(node, errorValue.getMessage()); +// context.trace.getErrorHandler().genericError(node, errorValue.getMessage()); + context.trace.report(ERROR_COMPILE_TIME_VALUE.on(node, errorValue.getMessage())); return getDefaultType(elementType); } else { @@ -1044,7 +1061,8 @@ public class JetTypeInferrer { @Override public JetType visitReturnExpression(JetReturnExpression expression, TypeInferenceContext context) { if (context.expectedReturnType == FORBIDDEN) { - context.trace.getErrorHandler().genericError(expression.getNode(), "'return' is not allowed here"); +// context.trace.getErrorHandler().genericError(expression.getNode(), "'return' is not allowed here"); + context.trace.report(RETURN_NOT_ALLOWED.on(expression)); return null; } JetExpression returnedExpression = expression.getReturnedExpression(); @@ -1055,7 +1073,8 @@ public class JetTypeInferrer { } else { if (context.expectedReturnType != NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(context.expectedReturnType)) { - context.trace.getErrorHandler().genericError(expression.getNode(), "This function must return a value of type " + context.expectedReturnType); +// context.trace.getErrorHandler().genericError(expression.getNode(), "This function must return a value of type " + context.expectedReturnType); + context.trace.report(RETURN_TYPE_MISMATCH.on(expression, context.expectedReturnType)); } } return context.services.checkType(JetStandardClasses.getNothingType(), expression, context); @@ -1124,7 +1143,8 @@ public class JetTypeInferrer { IElementType operationType = operationSign.getReferencedNameElementType(); if (operationType == JetTokens.COLON) { if (targetType != NO_EXPECTED_TYPE && !semanticServices.getTypeChecker().isSubtypeOf(actualType, targetType)) { - context.trace.getErrorHandler().typeMismatch(expression.getLeft(), targetType, actualType); +// context.trace.getErrorHandler().typeMismatch(expression.getLeft(), targetType, actualType); + context.trace.report(TYPE_MISMATCH.on(expression.getLeft(), targetType, actualType)); return false; } return true; @@ -1134,7 +1154,8 @@ public class JetTypeInferrer { return true; } else { - context.trace.getErrorHandler().genericError(operationSign.getNode(), "Unsupported binary operation"); +// context.trace.getErrorHandler().genericError(operationSign.getNode(), "Unknown binary operation");\ + context.trace.report(UNSUPPORTED.on(operationSign, "binary operation with type RHS")); return false; } } @@ -1145,16 +1166,19 @@ public class JetTypeInferrer { JetTypeChecker typeChecker = semanticServices.getTypeChecker(); if (!typeChecker.isSubtypeOf(targetType, actualType)) { if (typeChecker.isSubtypeOf(actualType, targetType)) { - context.trace.getErrorHandler().genericWarning(expression.getOperationSign().getNode(), "No cast needed, use ':' instead"); +// context.trace.getErrorHandler().genericWarning(expression.getOperationSign().getNode(), "No cast needed, use ':' instead"); + context.trace.report(USELESS_CAST_STATIC_ASSERT_IS_FINE.on(expression.getOperationSign())); } else { // See JET-58 Make 'as never succeeds' a warning, or even never check for Java (external) types - context.trace.getErrorHandler().genericWarning(expression.getOperationSign().getNode(), "This cast can never succeed"); +// context.trace.getErrorHandler().genericWarning(expression.getOperationSign().getNode(), "This cast can never succeed"); + context.trace.report(CAST_NEVER_SUCCEEDS.on(expression.getOperationSign())); } } else { if (typeChecker.isSubtypeOf(actualType, targetType)) { - context.trace.getErrorHandler().genericWarning(expression.getOperationSign().getNode(), "No cast needed"); +// context.trace.getErrorHandler().genericWarning(expression.getOperationSign().getNode(), "No cast needed"); + context.trace.report(USELESS_CAST.on(expression.getOperationSign())); } } } @@ -1218,15 +1242,16 @@ public class JetTypeInferrer { } } else { - context.trace.getErrorHandler().unresolvedReference(targetLabel); + context.trace.report(UNRESOLVED_REFERENCE.on(targetLabel)); } } else { - context.trace.getErrorHandler().unresolvedReference(targetLabel); + context.trace.report(UNRESOLVED_REFERENCE.on(targetLabel)); } } else { - context.trace.getErrorHandler().genericError(targetLabel.getNode(), "Ambiguous label"); +// context.trace.getErrorHandler().genericError(targetLabel.getNode(), "Ambiguous label"); + context.trace.report(AMBIGUOUS_LABEL.on(targetLabel)); } } else { @@ -1240,7 +1265,8 @@ public class JetTypeInferrer { if (thisType != null) { if (JetStandardClasses.isNothing(thisType)) { - context.trace.getErrorHandler().genericError(expression.getNode(), "'this' is not defined in this context"); +// context.trace.getErrorHandler().genericError(expression.getNode(), "'this' is not defined in this context"); + context.trace.report(NO_THIS.on(expression)); } else { JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier(); @@ -1263,7 +1289,8 @@ public class JetTypeInferrer { } } if (result == null) { - context.trace.getErrorHandler().genericError(superTypeElement.getNode(), "Not a superclass"); +// context.trace.getErrorHandler().genericError(superTypeElement.getNode(), "Not a superclass"); + context.trace.report(NOT_A_SUPERTYPE.on(superTypeElement)); } } } @@ -1339,7 +1366,8 @@ public class JetTypeInferrer { return semanticServices.getTypeChecker().commonSupertype(expressionTypes); } else if (expression.getEntries().isEmpty()) { - context.trace.getErrorHandler().genericError(expression.getNode(), "Entries required for when-expression"); // TODO : Scope, and maybe this should not an error +// context.trace.getErrorHandler().genericError(expression.getNode(), "Entries required for when-expression"); + context.trace.report(NO_WHEN_ENTRIES.on(expression)); } return null; } @@ -1379,7 +1407,8 @@ public class JetTypeInferrer { @Override public void visitJetElement(JetElement element) { - context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported [JetTypeInferrer] : " + element); +// context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported [JetTypeInferrer] : " + element); + context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName())); } }); return newDataFlowInfo[0]; @@ -1404,7 +1433,8 @@ public class JetTypeInferrer { TypeConstructor typeConstructor = subjectType.getConstructor(); if (!JetStandardClasses.getTuple(entries.size()).getTypeConstructor().equals(typeConstructor) || typeConstructor.getParameters().size() != entries.size()) { - context.trace.getErrorHandler().genericError(pattern.getNode(), "Type mismatch: subject is of type " + subjectType + " but the pattern is of type Tuple" + entries.size()); // TODO : message +// context.trace.getErrorHandler().genericError(pattern.getNode(), "Type mismatch: subject is of type " + subjectType + " but the pattern is of type Tuple" + entries.size()); + context.trace.report(TYPE_MISMATCH_IN_TUPLE_PATTERN.on(pattern, subjectType, entries.size())); } else { for (int i = 0, entriesSize = entries.size(); i < entriesSize; i++) { @@ -1414,7 +1444,8 @@ public class JetTypeInferrer { // TODO : is a name always allowed, ie for tuple patterns, not decomposer arg lists? ASTNode nameLabelNode = entry.getNameLabelNode(); if (nameLabelNode != null) { - context.trace.getErrorHandler().genericError(nameLabelNode, "Unsupported [JetTypeInferrer]"); +// context.trace.getErrorHandler().genericError(nameLabelNode, "Unsupported [JetTypeInferrer]"); + context.trace.report(UNSUPPORTED.on(nameLabelNode, getClass().getCanonicalName())); } JetPattern entryPattern = entry.getPattern(); @@ -1458,7 +1489,8 @@ public class JetTypeInferrer { scopeToExtend.addVariableDescriptor(variableDescriptor); if (propertyTypeRef != null) { if (!semanticServices.getTypeChecker().isSubtypeOf(subjectType, type)) { - context.trace.getErrorHandler().genericError(propertyTypeRef.getNode(), type + " must be a supertype of " + subjectType + ". Use 'is' to match against " + type); +// context.trace.getErrorHandler().genericError(propertyTypeRef.getNode(), type + " must be a supertype of " + subjectType + ". Use 'is' to match against " + type); + context.trace.report(TYPE_MISMATCH_IN_BINDING_PATTERN.on(propertyTypeRef, type, subjectType)); } } @@ -1478,13 +1510,15 @@ public class JetTypeInferrer { return; } if (TypeUtils.intersect(semanticServices.getTypeChecker(), Sets.newHashSet(type, subjectType)) == null) { - context.trace.getErrorHandler().genericError(reportErrorOn.getNode(), "Incompatible types: " + type + " and " + subjectType); +// context.trace.getErrorHandler().genericError(reportErrorOn.getNode(), "Incompatible types: " + type + " and " + subjectType); + context.trace.report(INCOMPATIBLE_TYPES.on(reportErrorOn, type, subjectType)); } } @Override public void visitJetElement(JetElement element) { - context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported [JetTypeInferrer]"); +// context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported [JetTypeInferrer]"); + context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName())); } }); return result[0]; @@ -1729,7 +1763,8 @@ public class JetTypeInferrer { JetType conditionType = getType(condition, context.replaceScope(scope)); if (conditionType != null && !isBoolean(conditionType)) { - context.trace.getErrorHandler().genericError(condition.getNode(), "Condition must be of type Boolean, but was of type " + conditionType); +// context.trace.getErrorHandler().genericError(condition.getNode(), "Condition must be of type Boolean, but was of type " + conditionType); + context.trace.report(TYPE_MISMATCH_IN_CONDITION.on(condition, conditionType)); } } } @@ -1811,7 +1846,8 @@ public class JetTypeInferrer { if (expectedParameterType != null && actualParameterType != null && !semanticServices.getTypeChecker().isSubtypeOf(expectedParameterType, actualParameterType)) { - context.trace.getErrorHandler().genericError(typeReference.getNode(), "The loop iterates over values of type " + expectedParameterType + " but the parameter is declared to be " + actualParameterType); +// context.trace.getErrorHandler().genericError(typeReference.getNode(), "The loop iterates over values of type " + expectedParameterType + " but the parameter is declared to be " + actualParameterType); + context.trace.report(TYPE_MISMATCH_IN_FOR_LOOP.on(typeReference, expectedParameterType, actualParameterType)); } } else { @@ -1847,10 +1883,12 @@ public class JetTypeInferrer { boolean hasNextPropertySupported = hasNextProperty != null; if (hasNextFunctionSupported && hasNextPropertySupported && !ErrorUtils.isErrorType(iteratorType)) { // TODO : overload resolution rules impose priorities here??? - context.trace.getErrorHandler().genericError(reportErrorsOn, "An ambiguity between 'iterator().hasNext()' function and 'iterator().hasNext' property"); +// context.trace.getErrorHandler().genericError(reportErrorsOn, "An ambiguity between 'iterator().hasNext()' function and 'iterator().hasNext' property"); + context.trace.report(HAS_NEXT_PROPERTY_AND_FUNCTION_AMBIGUITY.on(reportErrorsOn)); } else if (!hasNextFunctionSupported && !hasNextPropertySupported) { - context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().hasNext()' function or an 'iterator().hasNext' property"); +// context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().hasNext()' function or an 'iterator().hasNext' property"); + context.trace.report(HAS_NEXT_MISSING.on(reportErrorsOn)); } else { context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange, hasNextFunctionSupported ? hasNextFunction : hasNextProperty); @@ -1858,9 +1896,11 @@ public class JetTypeInferrer { OverloadResolutionResult nextResolutionResult = callResolver.resolveExactSignature(context.scope, iteratorType, "next", Collections.emptyList()); if (nextResolutionResult.isAmbiguity()) { - context.trace.getErrorHandler().genericError(reportErrorsOn, "Method 'iterator().next()' is ambiguous for this expression"); +// context.trace.getErrorHandler().genericError(reportErrorsOn, "Method 'iterator().next()' is ambiguous for this expression"); + context.trace.report(NEXT_AMBIGUITY.on(reportErrorsOn)); } else if (nextResolutionResult.isNothing()) { - context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().next()' method"); +// context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().next()' method"); + context.trace.report(NEXT_MISSING.on(reportErrorsOn)); } else { FunctionDescriptor nextFunction = nextResolutionResult.getDescriptor(); context.trace.record(LOOP_RANGE_NEXT, loopRange, nextFunction); @@ -1868,15 +1908,18 @@ public class JetTypeInferrer { } } else { - String errorMessage = "For-loop range must have an iterator() method"; if (iteratorResolutionResult.isAmbiguity()) { - StringBuffer stringBuffer = new StringBuffer("Method 'iterator()' is ambiguous for this expression: "); - for (FunctionDescriptor functionDescriptor : iteratorResolutionResult.getDescriptors()) { - stringBuffer.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" "); - } - errorMessage = "Method 'iterator()' is ambiguous for this expression: " + stringBuffer; +// StringBuffer stringBuffer = new StringBuffer("Method 'iterator()' is ambiguous for this expression: "); +// for (FunctionDescriptor functionDescriptor : iteratorResolutionResult.getDescriptors()) { +// stringBuffer.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" "); +// } +// errorMessage = stringBuffer.toString(); + context.trace.report(ITERATOR_AMBIGUITY.on(reportErrorsOn, iteratorResolutionResult.getDescriptors())); + } + else { +// context.trace.getErrorHandler().genericError(reportErrorsOn, errorMessage); + context.trace.report(ITERATOR_MISSING.on(reportErrorsOn)); } - context.trace.getErrorHandler().genericError(reportErrorsOn, errorMessage); } return null; } @@ -1885,14 +1928,16 @@ public class JetTypeInferrer { private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, TypeInferenceContext context) { OverloadResolutionResult hasNextResolutionResult = callResolver.resolveExactSignature(context.scope, iteratorType, "hasNext", Collections.emptyList()); if (hasNextResolutionResult.isAmbiguity()) { - context.trace.getErrorHandler().genericError(loopRange.getNode(), "Method 'iterator().hasNext()' is ambiguous for this expression"); +// context.trace.getErrorHandler().genericError(loopRange.getNode(), "Method 'iterator().hasNext()' is ambiguous for this expression"); + context.trace.report(HAS_NEXT_FUNCTION_AMBIGUITY.on(loopRange)); } else if (hasNextResolutionResult.isNothing()) { return null; } else { assert hasNextResolutionResult.isSuccess(); JetType hasNextReturnType = hasNextResolutionResult.getDescriptor().getReturnType(); if (!isBoolean(hasNextReturnType)) { - context.trace.getErrorHandler().genericError(loopRange.getNode(), "The 'iterator().hasNext()' method of the loop range must return Boolean, but returns " + hasNextReturnType); +// context.trace.getErrorHandler().genericError(loopRange.getNode(), "The 'iterator().hasNext()' method of the loop range must return Boolean, but returns " + hasNextReturnType); + context.trace.report(HAS_NEXT_FUNCTION_TYPE_MISMATCH.on(loopRange, hasNextReturnType)); } } return hasNextResolutionResult.getDescriptor(); @@ -1908,10 +1953,12 @@ public class JetTypeInferrer { JetType hasNextReturnType = hasNextProperty.getOutType(); if (hasNextReturnType == null) { // TODO : accessibility - context.trace.getErrorHandler().genericError(loopRange.getNode(), "The 'iterator().hasNext' property of the loop range must be readable"); +// context.trace.getErrorHandler().genericError(loopRange.getNode(), "The 'iterator().hasNext' property of the loop range must be readable"); + context.trace.report(HAS_NEXT_MUST_BE_READABLE.on(loopRange)); } else if (!isBoolean(hasNextReturnType)) { - context.trace.getErrorHandler().genericError(loopRange.getNode(), "The 'iterator().hasNext' property of the loop range must return Boolean, but returns " + hasNextReturnType); +// context.trace.getErrorHandler().genericError(loopRange.getNode(), "The 'iterator().hasNext' property of the loop range must return Boolean, but returns " + hasNextReturnType); + context.trace.report(HAS_NEXT_PROPERTY_TYPE_MISMATCH.on(loopRange, hasNextReturnType)); } } return hasNextProperty; @@ -1919,7 +1966,8 @@ public class JetTypeInferrer { @Override public JetType visitHashQualifiedExpression(JetHashQualifiedExpression expression, TypeInferenceContext context) { - context.trace.getErrorHandler().genericError(expression.getOperationTokenNode(), "Unsupported"); +// context.trace.getErrorHandler().genericError(expression.getOperationTokenNode(), "Unsupported"); + context.trace.report(UNSUPPORTED.on(expression, getClass().getCanonicalName())); return null; } @@ -1983,7 +2031,8 @@ public class JetTypeInferrer { if (expression.getOperationSign() == JetTokens.QUEST) { if (selectorReturnType != null && !isBoolean(selectorReturnType) && selectorExpression != null) { // TODO : more comprehensible error message - context.trace.getErrorHandler().typeMismatch(selectorExpression, semanticServices.getStandardLibrary().getBooleanType(), selectorReturnType); +// context.trace.getErrorHandler().typeMismatch(selectorExpression, semanticServices.getStandardLibrary().getBooleanType(), selectorReturnType); + context.trace.report(TYPE_MISMATCH.on(selectorExpression, semanticServices.getStandardLibrary().getBooleanType(), selectorReturnType)); } result = TypeUtils.makeNullable(receiverType); } @@ -2072,7 +2121,8 @@ public class JetTypeInferrer { @Override public void visitJetElement(JetElement element) { - context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported [getCalleeFunctionDescriptor]: " + element); +// context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported [getCalleeFunctionDescriptor]: " + element); + context.trace.report(UNSUPPORTED.on(element, "getCalleeFunctionDescriptor")); } }); if (result[0] == null) { @@ -2098,7 +2148,7 @@ public class JetTypeInferrer { TypeInferenceContext newContext = receiverType == null ? context : context.replaceScope(receiverType.getMemberScope()); JetType jetType = lookupNamespaceOrClassObject(nameExpression, nameExpression.getReferencedName(), newContext); if (jetType == null) { - context.trace.getErrorHandler().unresolvedReference(nameExpression); + context.trace.report(UNRESOLVED_REFERENCE.on(nameExpression)); } return context.services.checkEnrichedType(jetType, nameExpression, context); // JetScope scope = receiverType != null ? receiverType.getMemberScope() : context.scope; @@ -2114,7 +2164,8 @@ public class JetTypeInferrer { } else { // TODO : not a simple name -> resolve in scope, expect property type or a function type - context.trace.getErrorHandler().genericError(selectorExpression.getNode(), "Unsupported selector element type: " + selectorExpression); +// context.trace.getErrorHandler().genericError(selectorExpression.getNode(), "Unsupported selector element type: " + selectorExpression); + context.trace.report(UNSUPPORTED.on(selectorExpression, "getSelectorReturnType")); } return null; } @@ -2151,7 +2202,8 @@ public class JetTypeInferrer { IElementType operationType = operationSign.getReferencedNameElementType(); String name = unaryOperationNames.get(operationType); if (name == null) { - context.trace.getErrorHandler().genericError(operationSign.getNode(), "Unknown unary operation"); +// context.trace.getErrorHandler().genericError(operationSign.getNode(), "Unknown unary operation"); + context.trace.report(UNSUPPORTED.on(operationSign, "visitUnaryExpression")); return null; } JetType receiverType = getType(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(context.scope)); @@ -2175,7 +2227,8 @@ public class JetTypeInferrer { } else { if (!semanticServices.getTypeChecker().isSubtypeOf(returnType, receiverType)) { - context.trace.getErrorHandler().genericError(operationSign.getNode(), name + " must return " + receiverType + " but returns " + returnType); +// context.trace.getErrorHandler().genericError(operationSign.getNode(), name + " must return " + receiverType + " but returns " + returnType); + context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, name, receiverType, returnType)); } else { context.trace.record(BindingContext.VARIABLE_REASSIGNMENT, expression); @@ -2224,7 +2277,8 @@ public class JetTypeInferrer { if (constructor.equals(intTypeConstructor)) { result = standardLibrary.getBooleanType(); } else { - context.trace.getErrorHandler().genericError(operationSign.getNode(), "compareTo must return Int, but returns " + compareToReturnType); +// context.trace.getErrorHandler().genericError(operationSign.getNode(), "compareTo() must return Int, but returns " + compareToReturnType); + context.trace.report(COMPARE_TO_TYPE_MISMATCH.on(operationSign, compareToReturnType)); } } } @@ -2244,14 +2298,16 @@ public class JetTypeInferrer { } else { if (resolutionResult.isAmbiguity()) { - StringBuilder stringBuilder = new StringBuilder(); - for (FunctionDescriptor functionDescriptor : resolutionResult.getDescriptors()) { - stringBuilder.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" "); - } - context.trace.getErrorHandler().genericError(operationSign.getNode(), "Ambiguous function: " + stringBuilder); +// StringBuilder stringBuilder = new StringBuilder(); +// for (FunctionDescriptor functionDescriptor : resolutionResult.getDescriptors()) { +// stringBuilder.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" "); +// } +// context.trace.getErrorHandler().genericError(operationSign.getNode(), "Ambiguous function: " + stringBuilder); + context.trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(operationSign, resolutionResult.getDescriptors())); } else { - context.trace.getErrorHandler().genericError(operationSign.getNode(), "No method 'equals(Any?) : Boolean' available"); +// context.trace.getErrorHandler().genericError(operationSign.getNode(), "No method 'equals(Any?) : Boolean' available"); + context.trace.report(EQUALS_MISSING.on(operationSign)); } } } @@ -2278,10 +2334,12 @@ public class JetTypeInferrer { WritableScopeImpl rightScope = operationType == JetTokens.ANDAND ? leftScope : newWritableScopeImpl(context.scope, context.trace).setDebugName("Right scope of && or ||"); JetType rightType = right == null ? null : getType(right, context.replaceDataFlowInfo(flowInfoLeft).replaceScope(rightScope)); if (leftType != null && !isBoolean(leftType)) { - context.trace.getErrorHandler().typeMismatch(left, semanticServices.getStandardLibrary().getBooleanType(), leftType); +// context.trace.getErrorHandler().typeMismatch(left, semanticServices.getStandardLibrary().getBooleanType(), leftType); + context.trace.report(TYPE_MISMATCH.on(left, semanticServices.getStandardLibrary().getBooleanType(), leftType)); } if (rightType != null && !isBoolean(rightType)) { - context.trace.getErrorHandler().typeMismatch(right, semanticServices.getStandardLibrary().getBooleanType(), rightType); +// context.trace.getErrorHandler().typeMismatch(right, semanticServices.getStandardLibrary().getBooleanType(), rightType); + context.trace.report(TYPE_MISMATCH.on(right, semanticServices.getStandardLibrary().getBooleanType(), rightType)); } result = semanticServices.getStandardLibrary().getBooleanType(); } @@ -2290,7 +2348,8 @@ public class JetTypeInferrer { JetType rightType = right == null ? null : getType(right, contextWithExpectedType.replaceScope(context.scope)); if (leftType != null) { if (!leftType.isNullable()) { - context.trace.getErrorHandler().genericWarning(left.getNode(), "Elvis operator (?:) is always returns the left operand of non-nullable type " + leftType); +// context.trace.getErrorHandler().genericWarning(left.getNode(), "Elvis operator (?:) always returns the left operand of non-nullable type " + leftType); + context.trace.report(USELESS_ELVIS.on(left, leftType)); } if (rightType != null) { context.services.checkType(TypeUtils.makeNullableAsSpecified(leftType, rightType.isNullable()), left, contextWithExpectedType); @@ -2299,7 +2358,8 @@ public class JetTypeInferrer { } } else { - context.trace.getErrorHandler().genericError(operationSign.getNode(), "Unknown operation"); +// context.trace.getErrorHandler().genericError(operationSign.getNode(), "Unknown operation"); + context.trace.report(UNSUPPORTED.on(operationSign, "Unknown operation")); } return context.services.checkType(result, expression, contextWithExpectedType); } @@ -2330,7 +2390,8 @@ public class JetTypeInferrer { if (rightType != null) { JetType intersect = TypeUtils.intersect(semanticServices.getTypeChecker(), new HashSet(Arrays.asList(leftType, rightType))); if (intersect == null) { - context.trace.getErrorHandler().genericError(expression.getNode(), "Operator " + operationSign.getReferencedName() + " cannot be applied to " + leftType + " and " + rightType); +// context.trace.getErrorHandler().genericError(expression.getNode(), "Operator " + operationSign.getReferencedName() + " cannot be applied to " + leftType + " and " + rightType); + context.trace.report(EQUALITY_NOT_APPLICABLE.on(expression, operationSign, leftType, rightType)); } } } @@ -2345,7 +2406,8 @@ public class JetTypeInferrer { } private JetType assignmentIsNotAnExpressionError(JetBinaryExpression expression, TypeInferenceContext context) { - context.trace.getErrorHandler().genericError(expression.getNode(), "Assignments are not expressions, and only expressions are allowed in this context"); +// context.trace.getErrorHandler().genericError(expression.getNode(), "Assignments are not expressions, and only expressions are allowed in this context"); + context.trace.report(ASSIGNMENT_IN_EXPRESSION_CONTEXT.on(expression)); return null; } @@ -2357,7 +2419,8 @@ public class JetTypeInferrer { if (resultType != null) { // TODO : Relax? if (!isBoolean(resultType)) { - context.trace.getErrorHandler().genericError(operationSign.getNode(), subjectName + " must return Boolean but returns " + resultType); +// context.trace.getErrorHandler().genericError(operationSign.getNode(), subjectName + " must return Boolean but returns " + resultType); + context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, subjectName, semanticServices.getStandardLibrary().getBooleanType(), resultType)); return false; } } @@ -2407,12 +2470,14 @@ public class JetTypeInferrer { JetExpression right = binaryExpression.getRight(); String rightText = right == null ? "" : right.getText(); String leftText = binaryExpression.getLeft().getText(); - context.trace.getErrorHandler().genericError(binaryExpression.getOperationReference().getNode(), - "Infix call corresponds to a dot-qualified call '" + - leftText + "." + name + "(" + rightText + ")'" + - " which is not allowed on a nullable receiver '" + leftText + "'." + - " Use '?.'-qualified call instead"); +// context.trace.getErrorHandler().genericError(binaryExpression.getOperationReference().getNode(), +// "Infix call corresponds to a dot-qualified call '" + +// leftText + "." + name + "(" + rightText + ")'" + +// " which is not allowed on a nullable receiver '" + leftText + "'." + +// " Use '?.'-qualified call instead"); + context.trace.report(UNSAFE_INFIX_CALL.on(binaryExpression.getOperationReference(), leftText, name, rightText)); } + return functionDescriptor.getReturnType(); } @@ -2421,13 +2486,15 @@ public class JetTypeInferrer { @Override public JetType visitDeclaration(JetDeclaration dcl, TypeInferenceContext context) { - context.trace.getErrorHandler().genericError(dcl.getNode(), "Declarations are not allowed in this position"); +// context.trace.getErrorHandler().genericError(dcl.getNode(), "Declarations are not allowed in this position"); + context.trace.report(DECLARATION_IN_ILLEGAL_CONTEXT.on(dcl)); return null; } @Override public JetType visitRootNamespaceExpression(JetRootNamespaceExpression expression, TypeInferenceContext context) { - context.trace.getErrorHandler().genericError(expression.getNode(), "'namespace' is not an expression"); +// context.trace.getErrorHandler().genericError(expression.getNode(), "'namespace' is not an expression"); + context.trace.report(NAMESPACE_IS_NOT_AN_EXPRESSION.on(expression)); return null; } @@ -2463,7 +2530,8 @@ public class JetTypeInferrer { Character character = CompileTimeConstantResolver.translateEscape(escaped); if (character == null) { - context.trace.getErrorHandler().genericError(entry.getNode(), "Illegal escape sequence"); +// context.trace.getErrorHandler().genericError(entry.getNode(), "Illegal escape sequence"); + context.trace.report(ILLEGAL_ESCAPE_SEQUENCE.on(entry)); value[0] = CompileTimeConstantResolver.OUT_OF_RANGE; } else { @@ -2480,7 +2548,8 @@ public class JetTypeInferrer { @Override public JetType visitJetElement(JetElement element, TypeInferenceContext context) { - context.trace.getErrorHandler().genericError(element.getNode(), "[JetTypeInferrer] Unsupported element: " + element + " " + element.getClass().getCanonicalName()); +// context.trace.getErrorHandler().genericError(element.getNode(), "[JetTypeInferrer] Unsupported element: " + element + " " + element.getClass().getCanonicalName()); + context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName())); return null; } } @@ -2526,17 +2595,20 @@ public class JetTypeInferrer { public JetType visitProperty(JetProperty property, TypeInferenceContext context) { JetTypeReference receiverTypeRef = property.getReceiverTypeRef(); if (receiverTypeRef != null) { - context.trace.getErrorHandler().genericError(receiverTypeRef.getNode(), "Local receiver-properties are not allowed"); +// context.trace.getErrorHandler().genericError(receiverTypeRef.getNode(), "Local receiver-properties are not allowed"); + context.trace.report(LOCAL_EXTENSION_PROPERTY.on(receiverTypeRef)); } JetPropertyAccessor getter = property.getGetter(); if (getter != null) { - context.trace.getErrorHandler().genericError(getter.getNode(), "Local variables are not allowed to have getters"); +// context.trace.getErrorHandler().genericError(getter.getNode(), "Local variables are not allowed to have getters"); + context.trace.report(LOCAL_VARIABLE_WITH_GETTER.on(getter)); } JetPropertyAccessor setter = property.getSetter(); if (setter != null) { - context.trace.getErrorHandler().genericError(setter.getNode(), "Local variables are not allowed to have setters"); +// context.trace.getErrorHandler().genericError(setter.getNode(), "Local variables are not allowed to have setters"); + context.trace.report(LOCAL_VARIABLE_WITH_SETTER.on(setter)); } VariableDescriptor propertyDescriptor = context.classDescriptorResolver.resolveLocalVariableDescriptor(scope.getContainingDeclaration(), scope, property); @@ -2547,7 +2619,7 @@ public class JetTypeInferrer { // if (outType != null && // initializerType != null && // !semanticServices.getTypeChecker().isConvertibleTo(initializerType, outType)) { -// context.trace.getErrorHandler().typeMismatch(initializer, outType, initializerType); +// context.trace.report(TYPE_MISMATCH.on(initializer, outType, initializerType)); // } } @@ -2615,7 +2687,7 @@ public class JetTypeInferrer { // if (rightType != null && // leftType != null && // !semanticServices.getTypeChecker().isConvertibleTo(rightType, leftType)) { -// context.trace.getErrorHandler().typeMismatch(right, leftType, rightType); +// context.trace.report(TYPE_MISMATCH.on(right, leftType, rightType)); // } } if (left instanceof JetSimpleNameExpression) { @@ -2656,7 +2728,8 @@ public class JetTypeInferrer { @Override public JetType visitJetElement(JetElement element, TypeInferenceContext context) { - context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported element in a block: " + element + " " + element.getClass().getCanonicalName()); + context.trace.report(UNSUPPORTED.on(element, "in a block")); +// context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported element in a block: " + element + " " + element.getClass().getCanonicalName()); return null; } } diff --git a/idea/src/org/jetbrains/jet/plugin/annotations/DebugInfoAnnotator.java b/idea/src/org/jetbrains/jet/plugin/annotations/DebugInfoAnnotator.java index 9014574c050..ca49e5d995d 100644 --- a/idea/src/org/jetbrains/jet/plugin/annotations/DebugInfoAnnotator.java +++ b/idea/src/org/jetbrains/jet/plugin/annotations/DebugInfoAnnotator.java @@ -10,7 +10,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetNodeTypes; -import org.jetbrains.jet.lang.JetDiagnostic; +import org.jetbrains.jet.lang.diagnostics.JetDiagnostic; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -54,7 +54,7 @@ public class DebugInfoAnnotator implements Annotator { final BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(file); final Set unresolvedReferences = Sets.newHashSet(); - for (JetDiagnostic diagnostic : bindingContext.getDiagnostics()) { + for (JetDiagnostic diagnostic : bindingContext.getOld_Diagnostics()) { if (diagnostic instanceof JetDiagnostic.UnresolvedReferenceError) { JetDiagnostic.UnresolvedReferenceError error = (JetDiagnostic.UnresolvedReferenceError) diagnostic; unresolvedReferences.add(error.getReferenceExpression()); diff --git a/idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java b/idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java index 4db5848500a..08bb6ebc8cf 100644 --- a/idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java +++ b/idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java @@ -10,7 +10,7 @@ import com.intellij.psi.MultiRangeReference; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; diff --git a/idea/tests/org/jetbrains/jet/JetTestUtils.java b/idea/tests/org/jetbrains/jet/JetTestUtils.java index 43900be94db..f3466d5c5db 100644 --- a/idea/tests/org/jetbrains/jet/JetTestUtils.java +++ b/idea/tests/org/jetbrains/jet/JetTestUtils.java @@ -1,8 +1,9 @@ package org.jetbrains.jet; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.ErrorHandler; -import org.jetbrains.jet.lang.JetDiagnostic; +import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.JetDiagnostic; import org.jetbrains.jet.lang.psi.JetReferenceExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTrace; @@ -34,7 +35,12 @@ public class JetTestUtils { return new BindingContext() { @Override - public Collection getDiagnostics() { + public Collection getOld_Diagnostics() { + throw new UnsupportedOperationException(); // TODO + } + + @Override + public Collection getDiagnostics() { throw new UnsupportedOperationException(); // TODO } @@ -58,5 +64,10 @@ public class JetTestUtils { if (slice == BindingContext.PROCESSED) return (V) Boolean.FALSE; return null; } + + @Override + public void report(@NotNull Diagnostic diagnostic) { + throw new UnsupportedOperationException(); // TODO + } }; } diff --git a/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java b/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java index b0fafdf8d07..eb50c1bd030 100644 --- a/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java +++ b/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java @@ -5,7 +5,7 @@ import com.intellij.openapi.editor.Document; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.descriptors.*; diff --git a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index d531312e086..c5230b3a116 100644 --- a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetTestCaseBase; import org.jetbrains.jet.JetTestUtils; -import org.jetbrains.jet.lang.ErrorHandler; +import org.jetbrains.jet.lang.diagnostics.ErrorHandler; import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider; import org.jetbrains.jet.lang.descriptors.*;