Mark only brackets when array access expression is unresolved
This commit is contained in:
@@ -11,7 +11,6 @@ import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithTextRange;
|
||||
import org.jetbrains.jet.lang.diagnostics.Severity;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
|
||||
@@ -26,16 +25,26 @@ public class CheckerTestUtil {
|
||||
public static final Comparator<Diagnostic> DIAGNOSTIC_COMPARATOR = new Comparator<Diagnostic>() {
|
||||
@Override
|
||||
public int compare(Diagnostic o1, Diagnostic o2) {
|
||||
TextRange range1 = getTextRange(o1);
|
||||
TextRange range2 = getTextRange(o2);
|
||||
int startOffset1 = range1.getStartOffset();
|
||||
int startOffset2 = range2.getStartOffset();
|
||||
if (startOffset1 != startOffset2) {
|
||||
// Start early -- go first
|
||||
return startOffset1 - range2.getStartOffset();
|
||||
List<TextRange> ranges1 = getTextRanges(o1);
|
||||
List<TextRange> ranges2 = getTextRanges(o2);
|
||||
if (ranges1.size() != ranges2.size()) return ranges1.size() - ranges2.size();
|
||||
for (int i = 0; i < ranges1.size(); i++) {
|
||||
TextRange range1 = ranges1.get(i);
|
||||
TextRange range2 = ranges2.get(i);
|
||||
int startOffset1 = range1.getStartOffset();
|
||||
int startOffset2 = range2.getStartOffset();
|
||||
if (startOffset1 != startOffset2) {
|
||||
// Start early -- go first
|
||||
return startOffset1 - range2.getStartOffset();
|
||||
}
|
||||
int endOffset1 = range1.getEndOffset();
|
||||
int endOffset2 = range2.getEndOffset();
|
||||
if (endOffset1 != endOffset2) {
|
||||
// start at the same offset, the one who end later is the outer, i.e. goes first
|
||||
return endOffset2 - endOffset1;
|
||||
}
|
||||
}
|
||||
// start at the same offset, the one who end later is the outer, i.e. goes first
|
||||
return range2.getEndOffset() - range1.getEndOffset();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
private static final Pattern RANGE_START_OR_END_PATTERN = Pattern.compile("(<!\\w+(,\\s*\\w+)*!>)|(<!>)");
|
||||
@@ -132,8 +141,10 @@ public class CheckerTestUtil {
|
||||
private static void unexpectedDiagnostics(List<Diagnostic> actual, DiagnosticDiffCallbacks callbacks) {
|
||||
for (Diagnostic diagnostic : actual) {
|
||||
if (!diagnostic.getFactory().getPsiFile(diagnostic).equals(callbacks.getFile())) continue;
|
||||
TextRange textRange = getTextRange(diagnostic);
|
||||
callbacks.unexpectedDiagnostic(diagnostic.getFactory().getName(), textRange.getStartOffset(), textRange.getEndOffset());
|
||||
List<TextRange> textRanges = getTextRanges(diagnostic);
|
||||
for (TextRange textRange : textRanges) {
|
||||
callbacks.unexpectedDiagnostic(diagnostic.getFactory().getName(), textRange.getStartOffset(), textRange.getEndOffset());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,8 +283,8 @@ public class CheckerTestUtil {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TextRange getTextRange(@NotNull Diagnostic diagnostic) {
|
||||
return ((SyntaxErrorDiagnostic) diagnostic).textRange;
|
||||
public List<TextRange> getTextRanges(@NotNull Diagnostic diagnostic) {
|
||||
return Collections.singletonList(((SyntaxErrorDiagnostic) diagnostic).textRange);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -337,7 +348,7 @@ public class CheckerTestUtil {
|
||||
List<DiagnosticDescriptor> diagnosticDescriptors = Lists.newArrayList();
|
||||
DiagnosticDescriptor currentDiagnosticDescriptor = null;
|
||||
for (Diagnostic diagnostic : list) {
|
||||
TextRange textRange = getTextRange(diagnostic);
|
||||
TextRange textRange = getTextRanges(diagnostic).get(0);
|
||||
if (currentDiagnosticDescriptor != null && currentDiagnosticDescriptor.equalRange(textRange)) {
|
||||
currentDiagnosticDescriptor.diagnostics.add(diagnostic);
|
||||
}
|
||||
@@ -349,8 +360,8 @@ public class CheckerTestUtil {
|
||||
return diagnosticDescriptors;
|
||||
}
|
||||
|
||||
private static TextRange getTextRange(Diagnostic currentDiagnostic) {
|
||||
return currentDiagnostic.getFactory().getTextRange(currentDiagnostic);
|
||||
private static List<TextRange> getTextRanges(Diagnostic currentDiagnostic) {
|
||||
return currentDiagnostic.getFactory().getTextRanges(currentDiagnostic);
|
||||
}
|
||||
|
||||
private static class DiagnosticDescriptor {
|
||||
|
||||
+5
-2
@@ -4,6 +4,9 @@ import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
@@ -22,8 +25,8 @@ public class AbstractDiagnosticFactory implements DiagnosticFactory {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TextRange getTextRange(@NotNull Diagnostic diagnostic) {
|
||||
return ((DiagnosticWithTextRange) diagnostic).getTextRange();
|
||||
public List<TextRange> getTextRanges(@NotNull Diagnostic diagnostic) {
|
||||
return Collections.singletonList(((DiagnosticWithTextRange) diagnostic).getTextRange());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -4,12 +4,14 @@ import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface DiagnosticFactory {
|
||||
@NotNull
|
||||
TextRange getTextRange(@NotNull Diagnostic diagnostic);
|
||||
List<TextRange> getTextRanges(@NotNull Diagnostic diagnostic);
|
||||
|
||||
@NotNull
|
||||
PsiFile getPsiFile(@NotNull Diagnostic diagnostic);
|
||||
|
||||
@@ -4,6 +4,8 @@ import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
@@ -18,8 +20,8 @@ public interface DiagnosticHolder {
|
||||
public void report(@NotNull Diagnostic diagnostic) {
|
||||
if (diagnostic.getSeverity() == Severity.ERROR) {
|
||||
PsiFile psiFile = diagnostic.getFactory().getPsiFile(diagnostic);
|
||||
TextRange textRange = diagnostic.getFactory().getTextRange(diagnostic);
|
||||
throw new IllegalStateException(diagnostic.getMessage() + DiagnosticUtils.atLocation(psiFile, textRange));
|
||||
List<TextRange> textRanges = diagnostic.getFactory().getTextRanges(diagnostic);
|
||||
throw new IllegalStateException(diagnostic.getMessage() + DiagnosticUtils.atLocation(psiFile, textRanges.get(0)));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -15,7 +15,9 @@ import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Severity.ERROR;
|
||||
import static org.jetbrains.jet.lang.diagnostics.Severity.WARNING;
|
||||
@@ -193,6 +195,9 @@ public interface Errors {
|
||||
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");
|
||||
SimplePsiElementOnlyDiagnosticFactory<JetProperty> VAL_WITH_SETTER = SimplePsiElementOnlyDiagnosticFactory.create(ERROR, "A 'val'-property cannot have a setter");
|
||||
|
||||
SimpleDiagnosticFactory NO_GET_METHOD = SimpleDiagnosticFactory.create(ERROR, "No get method providing array access");
|
||||
SimpleDiagnosticFactory NO_SET_METHOD = SimpleDiagnosticFactory.create(ERROR, "No set method providing array access");
|
||||
|
||||
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");
|
||||
@@ -362,7 +367,7 @@ public interface Errors {
|
||||
ParameterizedDiagnosticFactory2<CallableMemberDescriptor, CallableMemberDescriptor> RETURN_TYPE_MISMATCH_ON_OVERRIDE = new ParameterizedDiagnosticFactory2<CallableMemberDescriptor, CallableMemberDescriptor>(ERROR, "Return type of {0} is not a subtype of the return type overridden member {1}") {
|
||||
@NotNull
|
||||
@Override
|
||||
public TextRange getTextRange(@NotNull Diagnostic diagnostic) {
|
||||
public List<TextRange> getTextRanges(@NotNull Diagnostic diagnostic) {
|
||||
PsiElement psiElement = ((DiagnosticWithPsiElement) diagnostic).getPsiElement();
|
||||
JetTypeReference returnTypeRef = null;
|
||||
ASTNode nameNode = null;
|
||||
@@ -381,9 +386,9 @@ public interface Errors {
|
||||
returnTypeRef = accessor.getReturnTypeReference();
|
||||
nameNode = accessor.getNamePlaceholder().getNode();
|
||||
}
|
||||
if (returnTypeRef != null) return returnTypeRef.getTextRange();
|
||||
if (nameNode != null) return nameNode.getTextRange();
|
||||
return super.getTextRange(diagnostic);
|
||||
if (returnTypeRef != null) return Collections.singletonList(returnTypeRef.getTextRange());
|
||||
if (nameNode != null) return Collections.singletonList(nameNode.getTextRange());
|
||||
return super.getTextRanges(diagnostic);
|
||||
}
|
||||
|
||||
private ASTNode getNameNode(JetNamedDeclaration function) {
|
||||
|
||||
+7
-4
@@ -8,6 +8,9 @@ import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetNamedDeclaration;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
@@ -38,22 +41,22 @@ public class RedeclarationDiagnosticFactory extends AbstractDiagnosticFactory {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TextRange getTextRange(@NotNull Diagnostic diagnostic) {
|
||||
public List<TextRange> getTextRanges(@NotNull Diagnostic diagnostic) {
|
||||
PsiElement redeclaration = ((RedeclarationDiagnostic) diagnostic).getPsiElement();
|
||||
if (redeclaration instanceof JetNamedDeclaration) {
|
||||
PsiElement nameIdentifier = ((JetNamedDeclaration) redeclaration).getNameIdentifier();
|
||||
if (nameIdentifier != null) {
|
||||
return nameIdentifier.getTextRange();
|
||||
return Collections.singletonList(nameIdentifier.getTextRange());
|
||||
}
|
||||
}
|
||||
else if (redeclaration instanceof JetFile) {
|
||||
JetFile file = (JetFile) redeclaration;
|
||||
PsiElement nameIdentifier = file.getNamespaceHeader().getNameIdentifier();
|
||||
if (nameIdentifier != null) {
|
||||
return nameIdentifier.getTextRange();
|
||||
return Collections.singletonList(nameIdentifier.getTextRange());
|
||||
}
|
||||
}
|
||||
return redeclaration.getTextRange();
|
||||
return Collections.singletonList(redeclaration.getTextRange());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+18
-2
@@ -1,12 +1,16 @@
|
||||
package org.jetbrains.jet.lang.diagnostics;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetArrayAccessExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
* @author abreslav
|
||||
*/
|
||||
public class UnresolvedReferenceDiagnosticFactory extends AbstractDiagnosticFactory
|
||||
implements PsiElementOnlyDiagnosticFactory<JetSimpleNameExpression> {
|
||||
|
||||
@@ -19,4 +23,16 @@ public class UnresolvedReferenceDiagnosticFactory extends AbstractDiagnosticFact
|
||||
public UnresolvedReferenceDiagnostic on(@NotNull JetReferenceExpression reference) {
|
||||
return new UnresolvedReferenceDiagnostic(reference, message);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TextRange> getTextRanges(@NotNull Diagnostic diagnostic) {
|
||||
if (diagnostic instanceof UnresolvedReferenceDiagnostic) {
|
||||
JetReferenceExpression element = ((UnresolvedReferenceDiagnostic) diagnostic).getPsiElement();
|
||||
if (element instanceof JetArrayAccessExpression) {
|
||||
return ((JetArrayAccessExpression)element).getBracketRanges();
|
||||
}
|
||||
}
|
||||
return super.getTextRanges(diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.jetbrains.jet.lang.psi;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.PsiReferenceService;
|
||||
@@ -8,6 +10,7 @@ import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -50,7 +53,14 @@ public class JetArrayAccessExpression extends JetReferenceExpression {
|
||||
return PsiTreeUtil.getChildrenOfTypeAsList(container, JetExpression.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetContainerNode getIndicesNode() {
|
||||
return (JetContainerNode) findChildByType(JetNodeTypes.INDICES);
|
||||
}
|
||||
|
||||
public List<TextRange> getBracketRanges() {
|
||||
TextRange lBracket = getIndicesNode().findChildByType(JetTokens.LBRACKET).getTextRange();
|
||||
TextRange rBracket = getIndicesNode().findChildByType(JetTokens.RBRACKET).getTextRange();
|
||||
return Lists.newArrayList(lBracket, rBracket);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ class Test() {
|
||||
(a : Array<Int>)[4]++
|
||||
(<!VARIABLE_EXPECTED!>ab.getArray()<!> : Array<Int>)[54] += 43
|
||||
|
||||
<!UNRESOLVED_REFERENCE!>this[54]<!> = 34
|
||||
this<!NO_SET_METHOD!><!UNRESOLVED_REFERENCE!>[<!>54]<!> = 34
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.jet.plugin.quickfix.JetIntentionActionFactory;
|
||||
import org.jetbrains.jet.plugin.quickfix.QuickFixes;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||
@@ -141,6 +142,7 @@ public class JetPsiChecker implements Annotator {
|
||||
@NotNull Set<PsiElement> redeclarations,
|
||||
@NotNull final AnnotationHolder holder
|
||||
) {
|
||||
List<TextRange> textRanges = diagnostic.getFactory().getTextRanges(diagnostic);
|
||||
if (diagnostic.getSeverity() == Severity.ERROR) {
|
||||
if (diagnostic instanceof UnresolvedReferenceDiagnostic) {
|
||||
UnresolvedReferenceDiagnostic unresolvedReferenceDiagnostic = (UnresolvedReferenceDiagnostic) diagnostic;
|
||||
@@ -159,9 +161,11 @@ public class JetPsiChecker implements Annotator {
|
||||
}
|
||||
}
|
||||
else {
|
||||
Annotation annotation = holder.createErrorAnnotation(referenceExpression, diagnostic.getMessage());
|
||||
registerQuickFix(annotation, diagnostic);
|
||||
annotation.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
|
||||
for (TextRange textRange : textRanges) {
|
||||
Annotation annotation = holder.createErrorAnnotation(textRange, diagnostic.getMessage());
|
||||
registerQuickFix(annotation, diagnostic);
|
||||
annotation.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -174,17 +178,19 @@ public class JetPsiChecker implements Annotator {
|
||||
}
|
||||
|
||||
// Generic annotation
|
||||
Annotation errorAnnotation = holder.createErrorAnnotation(diagnostic.getFactory().getTextRange(diagnostic), getMessage(diagnostic));
|
||||
registerQuickFix(
|
||||
errorAnnotation,
|
||||
diagnostic);
|
||||
for (TextRange textRange : textRanges) {
|
||||
Annotation errorAnnotation = holder.createErrorAnnotation(textRange, getMessage(diagnostic));
|
||||
registerQuickFix(errorAnnotation, diagnostic);
|
||||
}
|
||||
}
|
||||
else if (diagnostic.getSeverity() == Severity.WARNING) {
|
||||
Annotation annotation = holder.createWarningAnnotation(diagnostic.getFactory().getTextRange(diagnostic), getMessage(diagnostic));
|
||||
registerQuickFix(annotation, diagnostic);
|
||||
for (TextRange textRange : textRanges) {
|
||||
Annotation annotation = holder.createWarningAnnotation(textRange, getMessage(diagnostic));
|
||||
registerQuickFix(annotation, diagnostic);
|
||||
|
||||
if (diagnostic.getFactory() instanceof UnusedElementDiagnosticFactory) {
|
||||
annotation.setHighlightType(ProblemHighlightType.LIKE_UNUSED_SYMBOL);
|
||||
if (diagnostic.getFactory() instanceof UnusedElementDiagnosticFactory) {
|
||||
annotation.setHighlightType(ProblemHighlightType.LIKE_UNUSED_SYMBOL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -234,7 +240,7 @@ public class JetPsiChecker implements Annotator {
|
||||
@Nullable
|
||||
private Annotation markRedeclaration(@NotNull Set<PsiElement> redeclarations, @NotNull RedeclarationDiagnostic diagnostic, @NotNull AnnotationHolder holder) {
|
||||
if (!redeclarations.add(diagnostic.getPsiElement())) return null;
|
||||
return holder.createErrorAnnotation(diagnostic.getFactory().getTextRange(diagnostic), getMessage(diagnostic));
|
||||
return holder.createErrorAnnotation(diagnostic.getFactory().getTextRanges(diagnostic).get(0), getMessage(diagnostic));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user