diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 3e7739c9d4e..6fbcc23d4b6 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -38,6 +38,7 @@
+
diff --git a/idea/src/org/jetbrains/jet/lang/JetDiagnostic.java b/idea/src/org/jetbrains/jet/lang/JetDiagnostic.java
index f05a8465266..068d101b13f 100644
--- a/idea/src/org/jetbrains/jet/lang/JetDiagnostic.java
+++ b/idea/src/org/jetbrains/jet/lang/JetDiagnostic.java
@@ -1,7 +1,7 @@
package org.jetbrains.jet.lang;
import com.intellij.lang.ASTNode;
-import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
@@ -16,14 +16,19 @@ public abstract class JetDiagnostic {
private final JetReferenceExpression referenceExpression;
- public UnresolvedReferenceError(@NonNls JetReferenceExpression referenceExpression) {
+ public UnresolvedReferenceError(@NotNull JetReferenceExpression referenceExpression) {
this.referenceExpression = referenceExpression;
}
@Override
- public void acceptHandler(@NonNls ErrorHandler handler) {
+ public void acceptHandler(@NotNull ErrorHandler handler) {
handler.unresolvedReference(referenceExpression);
}
+
+ @NotNull
+ public JetReferenceExpression getReferenceExpression() {
+ return referenceExpression;
+ }
}
public static class GenericError extends JetDiagnostic {
@@ -31,13 +36,13 @@ public abstract class JetDiagnostic {
private final ASTNode node;
private final String message;
- public GenericError(@NonNls ASTNode node, @NonNls String message) {
+ public GenericError(@NotNull ASTNode node, @NotNull String message) {
this.node = node;
this.message = message;
}
@Override
- public void acceptHandler(@NonNls ErrorHandler handler) {
+ public void acceptHandler(@NotNull ErrorHandler handler) {
handler.genericError(node, message);
}
}
@@ -48,14 +53,14 @@ public abstract class JetDiagnostic {
private final JetType expectedType;
private final JetType actualType;
- public TypeMismatchError(@NonNls JetExpression expression, @NonNls JetType expectedType, @NonNls JetType actualType) {
+ public TypeMismatchError(@NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull JetType actualType) {
this.expression = expression;
this.expectedType = expectedType;
this.actualType = actualType;
}
@Override
- public void acceptHandler(@NonNls ErrorHandler handler) {
+ public void acceptHandler(@NotNull ErrorHandler handler) {
handler.typeMismatch(expression, expectedType, actualType);
}
}
@@ -65,13 +70,13 @@ public abstract class JetDiagnostic {
private final DeclarationDescriptor existingDescriptor;
private final DeclarationDescriptor redeclaredDescriptor;
- public RedeclarationError(@NonNls DeclarationDescriptor existingDescriptor, @NonNls DeclarationDescriptor redeclaredDescriptor) {
+ public RedeclarationError(@NotNull DeclarationDescriptor existingDescriptor, @NotNull DeclarationDescriptor redeclaredDescriptor) {
this.existingDescriptor = existingDescriptor;
this.redeclaredDescriptor = redeclaredDescriptor;
}
@Override
- public void acceptHandler(@NonNls ErrorHandler handler) {
+ public void acceptHandler(@NotNull ErrorHandler handler) {
handler.redeclaration(existingDescriptor, redeclaredDescriptor);
}
}
@@ -81,13 +86,13 @@ public abstract class JetDiagnostic {
private final ASTNode node;
private final String message;
- public GenericWarning(@NonNls ASTNode node, @NonNls String message) {
+ public GenericWarning(@NotNull ASTNode node, @NotNull String message) {
this.message = message;
this.node = node;
}
@Override
- public void acceptHandler(@NonNls ErrorHandler handler) {
+ public void acceptHandler(@NotNull ErrorHandler handler) {
handler.genericWarning(node, message);
}
}
@@ -102,5 +107,5 @@ public abstract class JetDiagnostic {
// return stackTrace;
// }
- public abstract void acceptHandler(@NonNls ErrorHandler handler);
+ public abstract void acceptHandler(@NotNull ErrorHandler handler);
}
diff --git a/idea/src/org/jetbrains/jet/plugin/JetHighlighter.java b/idea/src/org/jetbrains/jet/plugin/JetHighlighter.java
index dd5ab7174bc..5e971f21cab 100644
--- a/idea/src/org/jetbrains/jet/plugin/JetHighlighter.java
+++ b/idea/src/org/jetbrains/jet/plugin/JetHighlighter.java
@@ -7,6 +7,7 @@ import com.intellij.lexer.Lexer;
import com.intellij.openapi.editor.HighlighterColors;
import com.intellij.openapi.editor.SyntaxHighlighterColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
import com.intellij.psi.TokenType;
@@ -96,6 +97,15 @@ public class JetHighlighter extends SyntaxHighlighterBase {
JET_AUTO_CAST_EXPRESSION = TextAttributesKey.createTextAttributesKey("JET.AUTO.CAST.EXPRESSION", clone);
}
+ public static final TextAttributesKey JET_DEBUG_INFO;
+
+ static {
+ TextAttributes textAttributes = new TextAttributes();
+ textAttributes.setEffectType(EffectType.ROUNDED_BOX);
+ textAttributes.setEffectColor(Color.BLACK);
+ JET_DEBUG_INFO = TextAttributesKey.createTextAttributesKey("JET.DEBUG.INFO", textAttributes);
+ }
+
@NotNull
public Lexer getHighlightingLexer() {
return new JetLexer();
diff --git a/idea/src/org/jetbrains/jet/plugin/annotations/DebugInfoAnnotator.java b/idea/src/org/jetbrains/jet/plugin/annotations/DebugInfoAnnotator.java
new file mode 100644
index 00000000000..0ce7336449d
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/annotations/DebugInfoAnnotator.java
@@ -0,0 +1,90 @@
+package org.jetbrains.jet.plugin.annotations;
+
+import com.google.common.collect.Sets;
+import com.intellij.lang.annotation.AnnotationHolder;
+import com.intellij.lang.annotation.Annotator;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.lang.JetDiagnostic;
+import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
+import org.jetbrains.jet.lang.psi.JetElement;
+import org.jetbrains.jet.lang.psi.JetFile;
+import org.jetbrains.jet.lang.psi.JetReferenceExpression;
+import org.jetbrains.jet.lang.psi.JetVisitorVoid;
+import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
+import org.jetbrains.jet.lang.resolve.BindingContext;
+import org.jetbrains.jet.plugin.JetHighlighter;
+
+import java.util.Set;
+
+import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
+
+/**
+ * @author abreslav
+ */
+public class DebugInfoAnnotator implements Annotator {
+
+ private static volatile boolean debugInfoEnabled = !ApplicationManager.getApplication().isUnitTestMode();
+
+ public static void setDebugInfoEnabled(boolean value) {
+ debugInfoEnabled = value;
+ }
+
+ public static boolean isDebugInfoEnabled() {
+ return debugInfoEnabled;
+ }
+
+ @Override
+ public void annotate(@NotNull PsiElement element, @NotNull final AnnotationHolder holder) {
+ if (!debugInfoEnabled) {
+ return;
+ }
+
+ if (element instanceof JetFile) {
+ JetFile file = (JetFile) element;
+ try {
+ final BindingContext bindingContext = AnalyzingUtils.analyzeFileWithCache(file);
+
+ final Set unresolvedReferences = Sets.newHashSet();
+ for (JetDiagnostic diagnostic : bindingContext.getDiagnostics()) {
+ if (diagnostic instanceof JetDiagnostic.UnresolvedReferenceError) {
+ JetDiagnostic.UnresolvedReferenceError error = (JetDiagnostic.UnresolvedReferenceError) diagnostic;
+ unresolvedReferences.add(error.getReferenceExpression());
+ }
+ }
+
+ file.acceptChildren(new JetVisitorVoid() {
+
+ @Override
+ public void visitReferenceExpression(JetReferenceExpression expression) {
+ DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, expression);
+ boolean resolved = declarationDescriptor != null;
+ boolean unresolved = unresolvedReferences.contains(expression);
+ if (resolved && unresolved) {
+ holder.createErrorAnnotation(expression, "Reference marked as unresolved is actually resolved to " + declarationDescriptor).setTextAttributes(JetHighlighter.JET_DEBUG_INFO);
+ }
+ else if (!resolved && !unresolved) {
+ holder.createErrorAnnotation(expression, "Reference is not resolved to anything, but is not marked unresolved").setTextAttributes(JetHighlighter.JET_DEBUG_INFO);
+ }
+ }
+
+ @Override
+ public void visitJetElement(JetElement element) {
+ element.acceptChildren(this);
+ }
+ });
+ }
+ catch (ProcessCanceledException e) {
+ throw e;
+ }
+ catch (Throwable e) {
+ // TODO
+ holder.createErrorAnnotation(element, e.getClass().getCanonicalName() + ": " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+ }
+
+}