check debug info errors in diagnostic tests
This commit is contained in:
@@ -30,6 +30,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.diagnostics.AbstractDiagnosticFactory;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.diagnostics.Severity;
|
||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
|
||||
@@ -75,9 +76,36 @@ public class CheckerTestUtil {
|
||||
for (PsiErrorElement errorElement : AnalyzingUtils.getSyntaxErrorRanges(root)) {
|
||||
diagnostics.add(new SyntaxErrorDiagnostic(errorElement));
|
||||
}
|
||||
final List<Diagnostic> debugAnnotations = getDebugInfoDiagnostics(root, bindingContext);
|
||||
diagnostics.addAll(debugAnnotations);
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
public static List<Diagnostic> getDebugInfoDiagnostics(@NotNull PsiElement root, @NotNull BindingContext bindingContext) {
|
||||
final List<Diagnostic> debugAnnotations = Lists.newArrayList();
|
||||
DebugInfoUtil.markDebugAnnotations(root, bindingContext, new DebugInfoUtil.DebugInfoReporter() {
|
||||
@Override
|
||||
public void reportErrorElement(@NotNull JetReferenceExpression expression) {
|
||||
newDiagnostic(expression, DebugInfoDiagnosticFactory.ERROR_ELEMENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportMissingUnresolved(@NotNull JetReferenceExpression expression) {
|
||||
newDiagnostic(expression, DebugInfoDiagnosticFactory.MISSING_UNRESOLVED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportUnresolvedWithTarget(@NotNull JetReferenceExpression expression, @NotNull String target) {
|
||||
newDiagnostic(expression, DebugInfoDiagnosticFactory.UNRESOLVED_WITH_TARGET);
|
||||
}
|
||||
|
||||
private void newDiagnostic(JetReferenceExpression expression, DebugInfoDiagnosticFactory factory) {
|
||||
debugAnnotations.add(new DebugInfoDiagnostic(expression, factory));
|
||||
}
|
||||
});
|
||||
return debugAnnotations;
|
||||
}
|
||||
|
||||
public interface DiagnosticDiffCallbacks {
|
||||
@NotNull PsiFile getFile();
|
||||
void missingDiagnostic(String type, int expectedStart, int expectedEnd);
|
||||
@@ -287,27 +315,19 @@ public class CheckerTestUtil {
|
||||
result.append("<!>");
|
||||
}
|
||||
|
||||
private static class SyntaxErrorDiagnosticFactory extends AbstractDiagnosticFactory {
|
||||
private static final SyntaxErrorDiagnosticFactory instance = new SyntaxErrorDiagnosticFactory();
|
||||
public static class AbstractDiagnosticForTests implements Diagnostic {
|
||||
private final PsiElement element;
|
||||
private final AbstractDiagnosticFactory factory;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "SYNTAX";
|
||||
}
|
||||
}
|
||||
|
||||
public static class SyntaxErrorDiagnostic implements Diagnostic {
|
||||
private final PsiErrorElement errorElement;
|
||||
|
||||
public SyntaxErrorDiagnostic(@NotNull PsiErrorElement errorElement) {
|
||||
this.errorElement = errorElement;
|
||||
public AbstractDiagnosticForTests(@NotNull PsiElement element, @NotNull AbstractDiagnosticFactory factory) {
|
||||
this.element = element;
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public AbstractDiagnosticFactory getFactory() {
|
||||
return SyntaxErrorDiagnosticFactory.instance;
|
||||
return factory;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -318,20 +338,20 @@ public class CheckerTestUtil {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiErrorElement getPsiElement() {
|
||||
return errorElement;
|
||||
public PsiElement getPsiElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TextRange> getTextRanges() {
|
||||
return Collections.singletonList(errorElement.getTextRange());
|
||||
return Collections.singletonList(element.getTextRange());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiFile getPsiFile() {
|
||||
return errorElement.getContainingFile();
|
||||
return element.getContainingFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -339,7 +359,48 @@ public class CheckerTestUtil {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class SyntaxErrorDiagnosticFactory extends AbstractDiagnosticFactory {
|
||||
public static final SyntaxErrorDiagnosticFactory INSTANCE = new SyntaxErrorDiagnosticFactory();
|
||||
|
||||
private SyntaxErrorDiagnosticFactory() {}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "SYNTAX";
|
||||
}
|
||||
}
|
||||
|
||||
public static class SyntaxErrorDiagnostic extends AbstractDiagnosticForTests {
|
||||
public SyntaxErrorDiagnostic(@NotNull PsiErrorElement errorElement) {
|
||||
super(errorElement, SyntaxErrorDiagnosticFactory.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
public static class DebugInfoDiagnosticFactory extends AbstractDiagnosticFactory {
|
||||
public static final DebugInfoDiagnosticFactory ERROR_ELEMENT = new DebugInfoDiagnosticFactory("ERROR_ELEMENT");
|
||||
public static final DebugInfoDiagnosticFactory UNRESOLVED_WITH_TARGET = new DebugInfoDiagnosticFactory("UNRESOLVED_WITH_TARGET");
|
||||
public static final DebugInfoDiagnosticFactory MISSING_UNRESOLVED = new DebugInfoDiagnosticFactory("MISSING_UNRESOLVED");
|
||||
|
||||
private final String name;
|
||||
private DebugInfoDiagnosticFactory(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "DEBUG_INFO_" + name;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DebugInfoDiagnostic extends AbstractDiagnosticForTests {
|
||||
public DebugInfoDiagnostic(@NotNull JetReferenceExpression reference, @NotNull DebugInfoDiagnosticFactory factory) {
|
||||
super(reference, factory);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<DiagnosticDescriptor> getSortedDiagnosticDescriptors(Collection<Diagnostic> diagnostics) {
|
||||
List<Diagnostic> list = Lists.newArrayList(diagnostics);
|
||||
Collections.sort(list, DIAGNOSTIC_COMPARATOR);
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.checkers;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.diagnostics.AbstractDiagnosticFactory;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.diagnostics.UnresolvedReferenceDiagnosticFactory;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.*;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.ELVIS;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.EXCLEXCL;
|
||||
|
||||
public class DebugInfoUtil {
|
||||
private static final TokenSet EXCLUDED = TokenSet.create(
|
||||
COLON, AS_KEYWORD, AS_SAFE, IS_KEYWORD, NOT_IS, OROR, ANDAND, EQ, EQEQEQ, EXCLEQEQEQ, ELVIS, EXCLEXCL, IN_KEYWORD, NOT_IN);
|
||||
|
||||
public interface DebugInfoReporter {
|
||||
|
||||
void reportErrorElement(@NotNull JetReferenceExpression expression);
|
||||
|
||||
void reportMissingUnresolved(@NotNull JetReferenceExpression expression);
|
||||
|
||||
void reportUnresolvedWithTarget(@NotNull JetReferenceExpression expression, @NotNull String target);
|
||||
}
|
||||
|
||||
public static void markDebugAnnotations(
|
||||
@NotNull PsiElement root,
|
||||
@NotNull final BindingContext bindingContext,
|
||||
@NotNull final DebugInfoReporter debugInfoReporter
|
||||
) {
|
||||
final Map<JetReferenceExpression, AbstractDiagnosticFactory> markedWithErrorElements = Maps.newHashMap();
|
||||
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
|
||||
AbstractDiagnosticFactory factory = diagnostic.getFactory();
|
||||
if (factory instanceof UnresolvedReferenceDiagnosticFactory) {
|
||||
markedWithErrorElements.put((JetReferenceExpression) diagnostic.getPsiElement(), factory);
|
||||
}
|
||||
else if (factory == Errors.SUPER_IS_NOT_AN_EXPRESSION
|
||||
|| factory == Errors.SUPER_NOT_AVAILABLE) {
|
||||
JetSuperExpression superExpression = (JetSuperExpression) diagnostic.getPsiElement();
|
||||
markedWithErrorElements.put(superExpression.getInstanceReference(), factory);
|
||||
}
|
||||
}
|
||||
|
||||
root.acceptChildren(new JetTreeVisitorVoid() {
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(JetReferenceExpression expression) {
|
||||
if (expression instanceof JetSimpleNameExpression) {
|
||||
JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) expression;
|
||||
IElementType elementType = expression.getNode().getElementType();
|
||||
if (elementType == JetNodeTypes.OPERATION_REFERENCE) {
|
||||
IElementType referencedNameElementType = nameExpression.getReferencedNameElementType();
|
||||
if (EXCLUDED.contains(referencedNameElementType)) {
|
||||
return;
|
||||
}
|
||||
if (JetTokens.LABELS.contains(referencedNameElementType)) return;
|
||||
}
|
||||
else if (nameExpression.getReferencedNameElementType() == JetTokens.THIS_KEYWORD) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String target = null;
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, expression);
|
||||
if (declarationDescriptor != null) {
|
||||
target = declarationDescriptor.toString();
|
||||
}
|
||||
if (target == null) {
|
||||
PsiElement labelTarget = bindingContext.get(LABEL_TARGET, expression);
|
||||
if (labelTarget != null) {
|
||||
target = labelTarget.getText();
|
||||
}
|
||||
}
|
||||
if (target == null) {
|
||||
Collection<? extends DeclarationDescriptor> declarationDescriptors =
|
||||
bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, expression);
|
||||
if (declarationDescriptors != null) {
|
||||
target = "[" + declarationDescriptors.size() + " descriptors]";
|
||||
}
|
||||
}
|
||||
if (target == null) {
|
||||
Collection<? extends PsiElement> labelTargets = bindingContext.get(AMBIGUOUS_LABEL_TARGET, expression);
|
||||
if (labelTargets != null) {
|
||||
target = "[" + labelTargets.size() + " elements]";
|
||||
}
|
||||
}
|
||||
|
||||
boolean resolved = target != null;
|
||||
boolean markedWithError = markedWithErrorElements.containsKey(expression);
|
||||
JetType expressionType = bindingContext.get(EXPRESSION_TYPE, expression);
|
||||
if (declarationDescriptor != null &&
|
||||
!ApplicationManager.getApplication().isUnitTestMode() &&
|
||||
(ErrorUtils.isError(declarationDescriptor) || ErrorUtils.containsErrorType(expressionType))) {
|
||||
debugInfoReporter.reportErrorElement(expression);
|
||||
}
|
||||
if (resolved && markedWithError) {
|
||||
AbstractDiagnosticFactory factory = markedWithErrorElements.get(expression);
|
||||
if (factory instanceof UnresolvedReferenceDiagnosticFactory) {
|
||||
debugInfoReporter.reportUnresolvedWithTarget(expression, target);
|
||||
}
|
||||
}
|
||||
else if (!resolved && !markedWithError) {
|
||||
debugInfoReporter.reportMissingUnresolved(expression);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -261,9 +261,8 @@ public class BindingContextUtils {
|
||||
Collection<PsiElement> targets = Lists.newArrayList();
|
||||
for (DeclarationDescriptor descriptor : declarationsByLabel) {
|
||||
PsiElement element = descriptorToDeclaration(trace.getBindingContext(), descriptor);
|
||||
if (element != null) {
|
||||
targets.add(element);
|
||||
}
|
||||
assert element != null : "Label can only point to something in the same lexical scope";
|
||||
targets.add(element);
|
||||
}
|
||||
if (!targets.isEmpty()) {
|
||||
trace.record(AMBIGUOUS_LABEL_TARGET, targetLabel, targets);
|
||||
|
||||
@@ -19,7 +19,7 @@ package foobar.a
|
||||
import java.util.*
|
||||
|
||||
val b : List<Int>? = <!TYPE_MISMATCH!>a<!>
|
||||
val b1 : <!UNRESOLVED_REFERENCE!>util<!>.List<Int>? = a
|
||||
val b1 : <!UNRESOLVED_REFERENCE!>util<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>List<!><Int>? = a
|
||||
|
||||
// FILE: b.kt
|
||||
package foobar
|
||||
|
||||
@@ -14,7 +14,7 @@ fun test(<!UNUSED_PARAMETER!>l<!> : <!PLATFORM_CLASS_MAPPED_TO_KOTLIN!>java.util
|
||||
val <!UNUSED_VARIABLE!>y<!> : <!PLATFORM_CLASS_MAPPED_TO_KOTLIN!>java.util.List<Int><!>
|
||||
val <!UNUSED_VARIABLE!>b<!> : <!PLATFORM_CLASS_MAPPED_TO_KOTLIN!>java.lang.Object<!>
|
||||
val <!UNUSED_VARIABLE!>a<!> : <!PLATFORM_CLASS_MAPPED_TO_KOTLIN!>util.List<Int><!>
|
||||
val <!UNUSED_VARIABLE!>z<!> : java.<!UNRESOLVED_REFERENCE!>utils<!>.List<Int>
|
||||
val <!UNUSED_VARIABLE!>z<!> : java.<!UNRESOLVED_REFERENCE!>utils<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>List<!><Int>
|
||||
|
||||
val <!UNUSED_VARIABLE!>f<!> : java.io.File? = null
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ package n
|
||||
// FILE: f.kt
|
||||
abstract class XXX() {
|
||||
abstract val a : Int
|
||||
abstract val a1 : <!UNSUPPORTED!>package.Int<!>
|
||||
abstract val a2 : n.B
|
||||
abstract val a3 : (A)
|
||||
abstract val a31 : (n.B)
|
||||
|
||||
@@ -5,7 +5,7 @@ fun sum(a : IntArray) : Int {
|
||||
// Write your solution here
|
||||
<!UNRESOLVED_REFERENCE!>res<!> = 0
|
||||
for (e in a)
|
||||
res +=<!SYNTAX!><!>
|
||||
<!DEBUG_INFO_MISSING_UNRESOLVED!>res<!> <!DEBUG_INFO_MISSING_UNRESOLVED!>+=<!><!SYNTAX!><!>
|
||||
}
|
||||
fun main(args : Array<String>) {
|
||||
test(0)
|
||||
|
||||
@@ -7,13 +7,13 @@ import b.ext //extension function
|
||||
import b.value //property
|
||||
import b.C.<!CANNOT_BE_IMPORTED!>bar<!> //function from class object
|
||||
import b.C.<!CANNOT_BE_IMPORTED!>cValue<!> //property from class object
|
||||
import b.<!CANNOT_IMPORT_FROM_ELEMENT!>constant<!>.fff //function from val
|
||||
import b.<!CANNOT_IMPORT_FROM_ELEMENT!>constant<!>.dValue //property from val
|
||||
import b.<!CANNOT_IMPORT_FROM_ELEMENT!>constant<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>fff<!> //function from val
|
||||
import b.<!CANNOT_IMPORT_FROM_ELEMENT!>constant<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>dValue<!> //property from val
|
||||
import b.constant
|
||||
import b.E.<!CANNOT_BE_IMPORTED!>f<!> //val from class object
|
||||
import <!UNRESOLVED_REFERENCE!>smth<!>.illegal
|
||||
import b.C.<!UNRESOLVED_REFERENCE!>smth<!>.illegal
|
||||
import b.<!CANNOT_IMPORT_FROM_ELEMENT!>bar<!>.smth
|
||||
import <!UNRESOLVED_REFERENCE!>smth<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>illegal<!>
|
||||
import b.C.<!UNRESOLVED_REFERENCE!>smth<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>illegal<!>
|
||||
import b.<!CANNOT_IMPORT_FROM_ELEMENT!>bar<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>smth<!>
|
||||
import b.<!CANNOT_IMPORT_FROM_ELEMENT!>bar<!>.*
|
||||
|
||||
fun test(arg: B) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
package kt1080
|
||||
|
||||
import <!UNRESOLVED_REFERENCE!>reflect<!>.Constructor
|
||||
import <!UNRESOLVED_REFERENCE!>reflect<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>Constructor<!>
|
||||
|
||||
import b.*
|
||||
import <!UNRESOLVED_REFERENCE!>d<!>
|
||||
@@ -12,4 +12,4 @@ import b.d
|
||||
|
||||
//FILE:b.kt
|
||||
|
||||
package b.d
|
||||
package b.d
|
||||
@@ -3,10 +3,10 @@ package d
|
||||
//import from objects before properties resolve
|
||||
|
||||
import d.<!CANNOT_IMPORT_FROM_ELEMENT!>A<!>.*
|
||||
import d.<!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.R
|
||||
import d.<!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.R.bar
|
||||
import d.<!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.T
|
||||
import d.<!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.Y
|
||||
import d.<!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>R<!>
|
||||
import d.<!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>R<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>bar<!>
|
||||
import d.<!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>T<!>
|
||||
import d.<!CANNOT_IMPORT_FROM_ELEMENT!>M<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>Y<!>
|
||||
|
||||
var r: T = <!UNRESOLVED_REFERENCE!>T<!>()
|
||||
val y: T = <!UNRESOLVED_REFERENCE!>Y<!>
|
||||
|
||||
@@ -35,7 +35,7 @@ object N {
|
||||
//FILE:b.kt
|
||||
package b
|
||||
|
||||
import b.<!CANNOT_IMPORT_FROM_ELEMENT!>N<!>.M
|
||||
import b.<!CANNOT_IMPORT_FROM_ELEMENT!>N<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>M<!>
|
||||
import b.A.P
|
||||
import b.A.B
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class A<E>() : C(), T {
|
||||
|
||||
fun test() {
|
||||
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>
|
||||
<!SUPER_IS_NOT_AN_EXPRESSION!>super<T><!>
|
||||
<!SUPER_IS_NOT_AN_EXPRESSION!>super<<!DEBUG_INFO_MISSING_UNRESOLVED!>T<!>><!>
|
||||
<!AMBIGUOUS_SUPER!>super<!>.foo()
|
||||
super<T>.foo()
|
||||
super<C>.bar()
|
||||
@@ -23,8 +23,8 @@ class A<E>() : C(), T {
|
||||
super<<!SYNTAX!><!>>.foo()
|
||||
super<<!NOT_A_SUPERTYPE!>() -> Unit<!>>.foo()
|
||||
super<<!NOT_A_SUPERTYPE!>Unit<!>>.foo()
|
||||
super<T><!UNRESOLVED_REFERENCE!>@B<!>.foo()
|
||||
super<C><!UNRESOLVED_REFERENCE!>@B<!>.bar()
|
||||
<!DEBUG_INFO_MISSING_UNRESOLVED!>super<!><<!DEBUG_INFO_MISSING_UNRESOLVED!>T<!>><!UNRESOLVED_REFERENCE!>@B<!>.foo()
|
||||
<!DEBUG_INFO_MISSING_UNRESOLVED!>super<!><<!DEBUG_INFO_MISSING_UNRESOLVED!>C<!>><!UNRESOLVED_REFERENCE!>@B<!>.bar()
|
||||
}
|
||||
|
||||
class B : T {
|
||||
@@ -37,7 +37,7 @@ class A<E>() : C(), T {
|
||||
super<<!NOT_A_SUPERTYPE!>C<!>>@B.foo()
|
||||
super.foo()
|
||||
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>
|
||||
<!SUPER_IS_NOT_AN_EXPRESSION!>super<T><!>
|
||||
<!SUPER_IS_NOT_AN_EXPRESSION!>super<<!DEBUG_INFO_MISSING_UNRESOLVED!>T<!>><!>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fun foo() {
|
||||
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>
|
||||
<!SUPER_NOT_AVAILABLE!>super<!>.foo()
|
||||
<!SUPER_NOT_AVAILABLE!>super<Nothing><!>.foo()
|
||||
<!SUPER_NOT_AVAILABLE!>super<<!DEBUG_INFO_MISSING_UNRESOLVED!>Nothing<!>><!>.foo()
|
||||
}
|
||||
@@ -16,33 +16,19 @@
|
||||
|
||||
package org.jetbrains.jet.plugin.highlighter;
|
||||
|
||||
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.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.diagnostics.UnresolvedReferenceDiagnosticFactory;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.checkers.DebugInfoUtil;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.*;
|
||||
|
||||
/**
|
||||
* Quick showing possible problems with jet internals in IDEA with a tooltips
|
||||
*
|
||||
@@ -50,8 +36,6 @@ import static org.jetbrains.jet.lexer.JetTokens.*;
|
||||
*/
|
||||
public class DebugInfoAnnotator implements Annotator {
|
||||
|
||||
public static final TokenSet EXCLUDED = TokenSet.create(COLON, AS_KEYWORD, AS_SAFE, IS_KEYWORD, NOT_IS, OROR, ANDAND, EQ, EQEQEQ, EXCLEQEQEQ, ELVIS, EXCLEXCL);
|
||||
|
||||
public static boolean isDebugInfoEnabled() {
|
||||
return ApplicationManager.getApplication().isInternal();
|
||||
}
|
||||
@@ -69,67 +53,24 @@ public class DebugInfoAnnotator implements Annotator {
|
||||
JetFile file = (JetFile) element;
|
||||
try {
|
||||
final BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file).getBindingContext();
|
||||
|
||||
final Set<JetReferenceExpression> unresolvedReferences = Sets.newHashSet();
|
||||
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
|
||||
if (diagnostic.getFactory() instanceof UnresolvedReferenceDiagnosticFactory) {
|
||||
unresolvedReferences.add((JetReferenceExpression)diagnostic.getPsiElement());
|
||||
}
|
||||
}
|
||||
|
||||
file.acceptChildren(new JetVisitorVoid() {
|
||||
|
||||
DebugInfoUtil.markDebugAnnotations(file, bindingContext, new DebugInfoUtil.DebugInfoReporter() {
|
||||
@Override
|
||||
public void visitReferenceExpression(JetReferenceExpression expression) {
|
||||
if (expression instanceof JetSimpleNameExpression) {
|
||||
JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) expression;
|
||||
IElementType elementType = expression.getNode().getElementType();
|
||||
if (elementType == JetNodeTypes.OPERATION_REFERENCE) {
|
||||
IElementType referencedNameElementType = nameExpression.getReferencedNameElementType();
|
||||
if (EXCLUDED.contains(referencedNameElementType)) {
|
||||
return;
|
||||
}
|
||||
if (JetTokens.LABELS.contains(referencedNameElementType)) return;
|
||||
}
|
||||
else if (nameExpression.getReferencedNameElementType() == JetTokens.THIS_KEYWORD) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String target = null;
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, expression);
|
||||
if (declarationDescriptor != null) {
|
||||
target = declarationDescriptor.toString();
|
||||
}
|
||||
else {
|
||||
PsiElement labelTarget = bindingContext.get(LABEL_TARGET, expression);
|
||||
if (labelTarget != null) {
|
||||
target = labelTarget.getText();
|
||||
}
|
||||
else {
|
||||
Collection<? extends DeclarationDescriptor> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, expression);
|
||||
if (declarationDescriptors != null) {
|
||||
target = "[" + declarationDescriptors.size() + " descriptors]";
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean resolved = target != null;
|
||||
boolean unresolved = unresolvedReferences.contains(expression);
|
||||
JetType expressionType = bindingContext.get(EXPRESSION_TYPE, expression);
|
||||
if (declarationDescriptor != null && !ApplicationManager.getApplication().isUnitTestMode() && (ErrorUtils.isError(declarationDescriptor) || ErrorUtils.containsErrorType(expressionType))) {
|
||||
holder.createErrorAnnotation(expression, "[DEBUG] Resolved to error element").setTextAttributes(JetHighlightingColors.RESOLVED_TO_ERROR);
|
||||
}
|
||||
if (resolved && unresolved) {
|
||||
holder.createErrorAnnotation(expression, "[DEBUG] Reference marked as unresolved is actually resolved to " + target).setTextAttributes(JetHighlightingColors.DEBUG_INFO);
|
||||
}
|
||||
else if (!resolved && !unresolved) {
|
||||
holder.createErrorAnnotation(expression, "[DEBUG] Reference is not resolved to anything, but is not marked unresolved").setTextAttributes(JetHighlightingColors.DEBUG_INFO);
|
||||
}
|
||||
public void reportErrorElement(@NotNull JetReferenceExpression expression) {
|
||||
holder.createErrorAnnotation(expression, "[DEBUG] Resolved to error element")
|
||||
.setTextAttributes(JetHighlightingColors.RESOLVED_TO_ERROR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJetElement(JetElement element) {
|
||||
element.acceptChildren(this);
|
||||
public void reportMissingUnresolved(@NotNull JetReferenceExpression expression) {
|
||||
holder.createErrorAnnotation(expression,
|
||||
"[DEBUG] Reference is not resolved to anything, but is not marked unresolved")
|
||||
.setTextAttributes(JetHighlightingColors.DEBUG_INFO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportUnresolvedWithTarget(@NotNull JetReferenceExpression expression, @NotNull String target) {
|
||||
holder.createErrorAnnotation(expression, "[DEBUG] Reference marked as unresolved is actually resolved to " + target)
|
||||
.setTextAttributes(JetHighlightingColors.DEBUG_INFO);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -144,4 +85,5 @@ public class DebugInfoAnnotator implements Annotator {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user