PsiFiles retained in diagnostics. Line:Col messages fixed

This commit is contained in:
Andrey Breslav
2011-09-15 15:05:14 +04:00
parent 350a77cab5
commit 911d6e7fa1
22 changed files with 170 additions and 95 deletions
@@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod;
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.diagnostics.ErrorHandlerUtils;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
@@ -237,11 +237,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
DeclarationDescriptor hasNextDescriptor = bindingContext.get(BindingContext.LOOP_RANGE_HAS_NEXT, loopRange);
if(iteratorDescriptor == null)
throw new IllegalStateException("No iterator() method " + ErrorHandlerUtils.atLocation(loopRange));
throw new IllegalStateException("No iterator() method " + DiagnosticUtils.atLocation(loopRange));
if(nextDescriptor == null)
throw new IllegalStateException("No next() method " + ErrorHandlerUtils.atLocation(loopRange));
throw new IllegalStateException("No next() method " + DiagnosticUtils.atLocation(loopRange));
if(hasNextDescriptor == null)
throw new IllegalStateException("No iterator() method " + ErrorHandlerUtils.atLocation(loopRange));
throw new IllegalStateException("No iterator() method " + DiagnosticUtils.atLocation(loopRange));
final JetParameter loopParameter = expression.getLoopParameter();
final VariableDescriptor parameterDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, loopParameter);
@@ -1,25 +1,23 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import java.text.MessageFormat;
/**
* @author abreslav
*/
* @author abreslav
*/
public class AbstractDiagnosticFactory implements DiagnosticFactory {
protected final MessageFormat messageFormat;
protected final Severity severity;
public AbstractDiagnosticFactory(Severity severity, String message) {
this.severity = severity;
this.messageFormat = new MessageFormat(message);
@NotNull
@Override
public TextRange getTextRange(@NotNull Diagnostic diagnostic) {
return ((DiagnosticWithTextRange) diagnostic).getTextRange();
}
@NotNull
@Override
public TextRange getMarkerPosition(@NotNull Diagnostic diagnostic) {
return ((DiagnosticWithTextRange) diagnostic).getTextRange();
public PsiFile getPsiFile(@NotNull Diagnostic diagnostic) {
return ((DiagnosticWithTextRange) diagnostic).getPsiFile();
}
}
@@ -1,6 +1,7 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
@@ -8,5 +9,8 @@ import org.jetbrains.annotations.NotNull;
*/
public interface DiagnosticFactory {
@NotNull
TextRange getMarkerPosition(@NotNull Diagnostic diagnostic);
TextRange getTextRange(@NotNull Diagnostic diagnostic);
@NotNull
PsiFile getPsiFile(@NotNull Diagnostic diagnostic);
}
@@ -0,0 +1,16 @@
package org.jetbrains.jet.lang.diagnostics;
import java.text.MessageFormat;
/**
* @author abreslav
*/
public class DiagnosticFactoryWithMessageFormat extends DiagnosticFactoryWithSeverity {
protected final MessageFormat messageFormat;
public DiagnosticFactoryWithMessageFormat(Severity severity, String message) {
super(severity);
this.messageFormat = new MessageFormat(message);
}
}
@@ -0,0 +1,13 @@
package org.jetbrains.jet.lang.diagnostics;
/**
* @author abreslav
*/
public class DiagnosticFactoryWithSeverity extends AbstractDiagnosticFactory {
protected final Severity severity;
public DiagnosticFactoryWithSeverity(Severity severity) {
this.severity = severity;
}
}
@@ -1,5 +1,7 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
@@ -15,7 +17,9 @@ public interface DiagnosticHolder {
@Override
public void report(@NotNull Diagnostic diagnostic) {
if (diagnostic.getSeverity() == Severity.ERROR) {
throw new IllegalStateException(diagnostic.getMessage());
PsiFile psiFile = diagnostic.getFactory().getPsiFile(diagnostic);
TextRange textRange = diagnostic.getFactory().getTextRange(diagnostic);
throw new IllegalStateException(diagnostic.getMessage() + DiagnosticUtils.atLocation(psiFile, textRange));
}
}
};
@@ -0,0 +1,61 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author abreslav
*/
public class DiagnosticUtils {
public static String atLocation(@NotNull PsiElement element) {
return atLocation(element.getNode());
}
public static String atLocation(@NotNull ASTNode node) {
int startOffset = node.getStartOffset();
PsiElement element = getClosestPsiElement(node);
if (element != null) {
return atLocation(element.getContainingFile(), element.getTextRange());
}
return "' at offset " + startOffset + " (line and file unknown)";
}
@Nullable
public static PsiElement getClosestPsiElement(@NotNull ASTNode node) {
while (node != null && node.getPsi() == null) {
node = node.getTreeParent();
}
return node == null ? null : node.getPsi();
}
@NotNull
public static PsiFile getContainingFile(@NotNull ASTNode node) {
PsiElement closestPsiElement = getClosestPsiElement(node);
assert closestPsiElement != null : "This node is not contained by a file";
return closestPsiElement.getContainingFile();
}
public static String atLocation(@NotNull PsiFile file, @NotNull TextRange textRange) {
Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
int offset = textRange.getStartOffset();
VirtualFile virtualFile = file.getVirtualFile();
String pathSuffix = virtualFile == null ? "" : " in " + virtualFile.getPath();
if (document != null) {
int lineNumber = document.getLineNumber(offset);
int lineStartOffset = document.getLineStartOffset(lineNumber);
int column = offset - lineStartOffset;
return "' at line " + (lineNumber + 1) + ":" + column + pathSuffix;
}
else {
return "' at offset " + offset + " (line unknown)" + pathSuffix;
}
}
}
@@ -1,6 +1,5 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
@@ -11,7 +10,7 @@ public class DiagnosticWithPsiElement<T extends PsiElement> extends GenericDiagn
private final T psiElement;
public DiagnosticWithPsiElement(DiagnosticFactory factory, Severity severity, String message, T psiElement) {
super(factory, severity, message, psiElement.getTextRange());
super(factory, severity, message, psiElement.getContainingFile(), psiElement.getTextRange());
this.psiElement = psiElement;
}
@@ -1,6 +1,7 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
@@ -10,4 +11,7 @@ public interface DiagnosticWithTextRange extends Diagnostic {
@NotNull
TextRange getTextRange();
@NotNull
PsiFile getPsiFile();
}
@@ -1,35 +0,0 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Document;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
public class ErrorHandlerUtils {
public static String atLocation(@NotNull PsiElement element) {
return atLocation(element.getNode());
}
public static String atLocation(@NotNull ASTNode node) {
while (node.getPsi() == null) {
node = node.getTreeParent();
}
PsiElement element = node.getPsi();
Document document = PsiDocumentManager.getInstance(element.getProject()).getDocument(element.getContainingFile());
int offset = element.getTextRange().getStartOffset();
if (document != null) {
int lineNumber = document.getLineNumber(offset);
int lineStartOffset = document.getLineStartOffset(lineNumber);
int column = offset - lineStartOffset;
return "' at line " + (lineNumber+1) + ":" + column;
}
else {
return "' at offset " + offset + " (line unknown)";
}
}
}
@@ -1,6 +1,7 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
@@ -12,12 +13,14 @@ public class GenericDiagnostic implements DiagnosticWithTextRange {
private final String message;
private final DiagnosticFactory factory;
private final Severity severity;
private final PsiFile psiFile;
public GenericDiagnostic(DiagnosticFactory factory, Severity severity, String message, TextRange textRange) {
public GenericDiagnostic(DiagnosticFactory factory, Severity severity, String message, @NotNull PsiFile psiFile, @NotNull TextRange textRange) {
this.factory = factory;
this.textRange = textRange;
this.severity = severity;
this.message = message;
this.psiFile = psiFile;
}
@NotNull
@@ -31,6 +34,12 @@ public class GenericDiagnostic implements DiagnosticWithTextRange {
return textRange;
}
@NotNull
@Override
public PsiFile getPsiFile() {
return psiFile;
}
@NotNull
@Override
public String getMessage() {
@@ -3,12 +3,13 @@ package org.jetbrains.jet.lang.diagnostics;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
public class ParameterizedDiagnosticFactory1<T> extends AbstractDiagnosticFactory {
public class ParameterizedDiagnosticFactory1<T> extends DiagnosticFactoryWithMessageFormat {
public static <T> ParameterizedDiagnosticFactory1<T> create(Severity severity, String messageStub) {
return new ParameterizedDiagnosticFactory1<T>(severity, messageStub);
}
@@ -26,13 +27,13 @@ public class ParameterizedDiagnosticFactory1<T> extends AbstractDiagnosticFactor
}
@NotNull
public Diagnostic on(@NotNull TextRange range, @NotNull T argument) {
return new GenericDiagnostic(this, severity, makeMessage(argument), range);
public Diagnostic on(@NotNull PsiFile psiFile, @NotNull TextRange range, @NotNull T argument) {
return new GenericDiagnostic(this, severity, makeMessage(argument), psiFile, range);
}
@NotNull
public Diagnostic on(@NotNull ASTNode node, @NotNull T argument) {
return on(node.getTextRange(), argument);
return on(DiagnosticUtils.getContainingFile(node), node.getTextRange(), argument);
}
@NotNull
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.diagnostics;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
@@ -17,13 +18,13 @@ public class ParameterizedDiagnosticFactory2<A, B> extends PsiElementOnlyDiagnos
}
@NotNull
public Diagnostic on(@NotNull TextRange range, @NotNull A a, @NotNull B b) {
return new GenericDiagnostic(this, severity, makeMessage(a, b), range);
public Diagnostic on(@NotNull PsiFile psiFile, @NotNull TextRange range, @NotNull A a, @NotNull B b) {
return new GenericDiagnostic(this, severity, makeMessage(a, b), psiFile, range);
}
@NotNull
public Diagnostic on(@NotNull ASTNode node, @NotNull A a, @NotNull B b) {
return on(node.getTextRange(), a, b);
return on(DiagnosticUtils.getContainingFile(node), node.getTextRange(), a, b);
}
}
@@ -3,12 +3,13 @@ package org.jetbrains.jet.lang.diagnostics;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
public class ParameterizedDiagnosticFactory3<A, B, C> extends AbstractDiagnosticFactory {
public class ParameterizedDiagnosticFactory3<A, B, C> extends DiagnosticFactoryWithMessageFormat {
public static <A, B, C> ParameterizedDiagnosticFactory3<A, B, C> create(Severity severity, String messageStub) {
return new ParameterizedDiagnosticFactory3<A, B, C>(severity, messageStub);
}
@@ -34,13 +35,13 @@ public class ParameterizedDiagnosticFactory3<A, B, C> extends AbstractDiagnostic
}
@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);
public Diagnostic on(@NotNull PsiFile psiFile, @NotNull TextRange range, @NotNull A a, @NotNull B b, @NotNull C c) {
return new GenericDiagnostic(this, severity, makeMessage(a, b, c), psiFile, range);
}
@NotNull
public Diagnostic on(@NotNull ASTNode node, @NotNull A a, @NotNull B b, @NotNull C c) {
return on(node.getTextRange(), a, b, c);
return on(DiagnosticUtils.getContainingFile(node), node.getTextRange(), a, b, c);
}
@NotNull
@@ -6,7 +6,7 @@ import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
public class PsiElementOnlyDiagnosticFactory2<A, B> extends AbstractDiagnosticFactory {
public class PsiElementOnlyDiagnosticFactory2<A, B> extends DiagnosticFactoryWithMessageFormat {
public static <A, B> PsiElementOnlyDiagnosticFactory2<A, B> create(Severity severity, String message) {
return new PsiElementOnlyDiagnosticFactory2<A, B>(severity, message);
@@ -1,6 +1,7 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
@@ -19,7 +20,13 @@ public class RedeclarationDiagnosticFactory implements DiagnosticFactory {
@NotNull
@Override
public TextRange getMarkerPosition(@NotNull Diagnostic diagnostic) {
public TextRange getTextRange(@NotNull Diagnostic diagnostic) {
throw new UnsupportedOperationException(); // TODO
}
@NotNull
@Override
public PsiFile getPsiFile(@NotNull Diagnostic diagnostic) {
throw new UnsupportedOperationException(); // TODO
}
}
@@ -3,43 +3,37 @@ package org.jetbrains.jet.lang.diagnostics;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
public class SimpleDiagnosticFactory implements DiagnosticFactory {
public class SimpleDiagnosticFactory extends DiagnosticFactoryWithSeverity {
public static SimpleDiagnosticFactory create(Severity severity, String message) {
return new SimpleDiagnosticFactory(severity, message);
}
protected final String message;
protected final Severity severity;
public SimpleDiagnosticFactory(Severity severity, String message) {
super(severity);
this.message = message;
this.severity = severity;
}
@NotNull
public Diagnostic on(@NotNull TextRange range) {
return new GenericDiagnostic(this, severity, message, range);
public Diagnostic on(@NotNull PsiFile psiFile, @NotNull TextRange range) {
return new GenericDiagnostic(this, severity, message, psiFile, range);
}
@NotNull
public Diagnostic on(@NotNull ASTNode node) {
return on(node.getTextRange());
return on(DiagnosticUtils.getContainingFile(node), node.getTextRange());
}
@NotNull
public Diagnostic on(@NotNull PsiElement element) {
return new DiagnosticWithPsiElement<PsiElement>(this, severity, message, element);
}
@NotNull
@Override
public TextRange getMarkerPosition(@NotNull Diagnostic diagnostic) {
return ((DiagnosticWithTextRange) diagnostic).getTextRange();
}
}
@@ -1,5 +1,6 @@
package org.jetbrains.jet.lang.diagnostics;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
import static org.jetbrains.jet.lang.diagnostics.Severity.ERROR;
@@ -13,4 +14,9 @@ public class UnresolvedReferenceDiagnostic extends DiagnosticWithPsiElement<JetR
super(Errors.UNRESOLVED_REFERENCE, ERROR, "Unresolved reference", referenceExpression);
}
@NotNull
@Override
public String getMessage() {
return super.getMessage() + ": " + getPsiElement().getText();
}
}
@@ -1,13 +1,12 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.openapi.util.TextRange;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
/**
* @author abreslav
*/
public class UnresolvedReferenceDiagnosticFactory implements DiagnosticFactory {
public class UnresolvedReferenceDiagnosticFactory extends AbstractDiagnosticFactory {
public static final UnresolvedReferenceDiagnosticFactory INSTANCE = new UnresolvedReferenceDiagnosticFactory();
public UnresolvedReferenceDiagnosticFactory() {}
@@ -15,11 +14,4 @@ public class UnresolvedReferenceDiagnosticFactory implements DiagnosticFactory {
public UnresolvedReferenceDiagnostic on(@NotNull JetReferenceExpression reference) {
return new UnresolvedReferenceDiagnostic(reference);
}
@NotNull
@Override
public TextRange getMarkerPosition(@NotNull Diagnostic diagnostic) {
return ((UnresolvedReferenceDiagnostic) diagnostic).getTextRange();
}
}
@@ -44,7 +44,7 @@ public class AnalyzingUtils {
@Override
public void visitErrorElement(PsiErrorElement element) {
throw new IllegalArgumentException(element.getErrorDescription() + "; looking at " + element.getNode().getElementType() + " '" + element.getText() + ErrorHandlerUtils.atLocation(element));
throw new IllegalArgumentException(element.getErrorDescription() + "; looking at " + element.getNode().getElementType() + " '" + element.getText() + DiagnosticUtils.atLocation(element));
}
});
}
@@ -124,11 +124,11 @@ public class JetPsiChecker implements Annotator {
markRedeclaration(redeclarations, redeclarationDiagnostic.getB(), bindingContext, holder);
}
else {
holder.createErrorAnnotation(diagnostic.getFactory().getMarkerPosition(diagnostic), diagnostic.getMessage());
holder.createErrorAnnotation(diagnostic.getFactory().getTextRange(diagnostic), diagnostic.getMessage());
}
}
else if (diagnostic.getSeverity() == Severity.WARNING) {
holder.createWarningAnnotation(diagnostic.getFactory().getMarkerPosition(diagnostic), diagnostic.getMessage());
holder.createWarningAnnotation(diagnostic.getFactory().getTextRange(diagnostic), diagnostic.getMessage());
}
}
}
@@ -8,7 +8,7 @@ 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.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.ErrorHandlerUtils;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.diagnostics.UnresolvedReferenceDiagnostic;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -278,7 +278,7 @@ public class ExpectedResolveData {
return referenceExpression.getText() + " at " + ErrorHandlerUtils.atLocation(referenceExpression) +
return referenceExpression.getText() + " at " + DiagnosticUtils.atLocation(referenceExpression) +
" in " + statement.getText() + (declaration == null ? "" : " in " + declaration.getText());
}