Changed highlighting range for unresolved annotation name to not include '@'

#KT-11529 Fixed
This commit is contained in:
Valentin Kipyatkov
2016-03-22 18:34:59 +03:00
parent 0fdba49315
commit f0ef04a6a8
19 changed files with 51 additions and 53 deletions
@@ -24,7 +24,10 @@ import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.utils.sure import org.jetbrains.kotlin.utils.sure
object PositioningStrategies { object PositioningStrategies {
@@ -219,7 +222,7 @@ object PositioningStrategies {
return ranges return ranges
} }
} }
return listOf(element.getHighlightingRange()) return listOf(element.textRange)
} }
} }
@@ -150,23 +150,6 @@ fun KtExpression.getQualifiedExpressionForReceiverOrThis(): KtExpression {
fun KtExpression.isDotReceiver(): Boolean = fun KtExpression.isDotReceiver(): Boolean =
(parent as? KtDotQualifiedExpression)?.getReceiverExpression() == this (parent as? KtDotQualifiedExpression)?.getReceiverExpression() == this
fun KtReferenceExpression.getHighlightingRange(): TextRange {
// include '@' symbol if the reference is the first segment of KtAnnotationEntry
// if "Deprecated" is highlighted then '@' should be highlighted too in "@Deprecated"
val annotationEntry =
PsiTreeUtil.getParentOfType<KtAnnotationEntry>(
this, KtAnnotationEntry::class.java, /* strict = */false, KtValueArgumentList::class.java
)
val atSymbol = annotationEntry?.atSymbol
return if (atSymbol != null && atSymbol.endOffset == this.startOffset) {
TextRange(atSymbol.startOffset, this.endOffset)
}
else {
this.textRange
}
}
// ---------- Block expression ------------------------------------------------------------------------------------------------------------- // ---------- Block expression -------------------------------------------------------------------------------------------------------------
fun KtElement.blockExpressionsOrSingle(): Sequence<KtElement> = fun KtElement.blockExpressionsOrSingle(): Sequence<KtElement> =
@@ -6,4 +6,4 @@ package foo
// FILE: b.kt // FILE: b.kt
<!UNRESOLVED_REFERENCE!>@foo<!> fun bar(p: <!UNRESOLVED_REFERENCE!>foo<!>): <!UNRESOLVED_REFERENCE!>foo<!> = null!! @<!UNRESOLVED_REFERENCE!>foo<!> fun bar(p: <!UNRESOLVED_REFERENCE!>foo<!>): <!UNRESOLVED_REFERENCE!>foo<!> = null!!
@@ -1,5 +1,5 @@
import java.util.ArrayList import java.util.ArrayList
@<!NONE_APPLICABLE!>ArrayList<!><Int>(1, 1) fun b() {} @<!NONE_APPLICABLE!>ArrayList<!><Int>(1, 1) fun b() {}
<!UNRESOLVED_REFERENCE!>@Xoo<!>(<!UNRESOLVED_REFERENCE!>x<!>) fun c() {} @<!UNRESOLVED_REFERENCE!>Xoo<!>(<!UNRESOLVED_REFERENCE!>x<!>) fun c() {}
<!DEPRECATED_JAVA_ANNOTATION!>@java.lang.Deprecated(<!UNRESOLVED_REFERENCE, TOO_MANY_ARGUMENTS!>x<!>)<!> fun a() {} <!DEPRECATED_JAVA_ANNOTATION!>@java.lang.Deprecated(<!UNRESOLVED_REFERENCE, TOO_MANY_ARGUMENTS!>x<!>)<!> fun a() {}
@@ -1,3 +1,3 @@
// Check that there won't be "Rewrite at slice ANNOTATION key" exception - EA-36935 // Check that there won't be "Rewrite at slice ANNOTATION key" exception - EA-36935
<!UNRESOLVED_REFERENCE!>@someErrorAnnotation<!> object Test { @<!UNRESOLVED_REFERENCE!>someErrorAnnotation<!> object Test {
} }
@@ -4,19 +4,19 @@ annotation class Ann2
class C { class C {
fun foo() { fun foo() {
class Local { class Local {
<!UNRESOLVED_REFERENCE!>@Ann0<!> @<!UNRESOLVED_REFERENCE!>Ann0<!>
@Ann <!UNRESOLVED_REFERENCE!>@Ann3<!> @Ann @<!UNRESOLVED_REFERENCE!>Ann3<!>
@Ann2(<!TOO_MANY_ARGUMENTS!>1<!>) @Ann2(<!TOO_MANY_ARGUMENTS!>1<!>)
<!UNRESOLVED_REFERENCE!>@Ann4<!><!SYNTAX!><!> @<!UNRESOLVED_REFERENCE!>Ann4<!><!SYNTAX!><!>
} }
} }
<!UNRESOLVED_REFERENCE!>@Ann0<!> @<!UNRESOLVED_REFERENCE!>Ann0<!>
@Ann <!UNRESOLVED_REFERENCE!>@Ann3<!> @Ann @<!UNRESOLVED_REFERENCE!>Ann3<!>
@Ann2(<!TOO_MANY_ARGUMENTS!>1<!>) @Ann2(<!TOO_MANY_ARGUMENTS!>1<!>)
<!UNRESOLVED_REFERENCE!>@Ann4<!><!SYNTAX!><!> @<!UNRESOLVED_REFERENCE!>Ann4<!><!SYNTAX!><!>
} }
<!UNRESOLVED_REFERENCE!>@Ann0<!> @<!UNRESOLVED_REFERENCE!>Ann0<!>
@Ann <!UNRESOLVED_REFERENCE!>@Ann3<!> @Ann @<!UNRESOLVED_REFERENCE!>Ann3<!>
@Ann2(<!TOO_MANY_ARGUMENTS!>1<!>) @Ann2(<!TOO_MANY_ARGUMENTS!>1<!>)
<!UNRESOLVED_REFERENCE!>@Ann4<!SYNTAX!><!><!> @<!UNRESOLVED_REFERENCE!>Ann4<!SYNTAX!><!><!>
@@ -4,6 +4,6 @@ data class Pair(val x: Int, val y: Int)
fun foo(): Int { fun foo(): Int {
<!WRONG_ANNOTATION_TARGET!>@Ann<!> val (a, b) = Pair(12, 34) <!WRONG_ANNOTATION_TARGET!>@Ann<!> val (a, b) = Pair(12, 34)
<!UNRESOLVED_REFERENCE!>@Err<!> val (c, d) = Pair(56, 78) @<!UNRESOLVED_REFERENCE!>Err<!> val (c, d) = Pair(56, 78)
return a + b + c + d return a + b + c + d
} }
@@ -3,7 +3,7 @@ package test
// Checks that there is no rewrite error at ANNOTATION slice because of resolving annotations for object in lazy resolve and resolving // Checks that there is no rewrite error at ANNOTATION slice because of resolving annotations for object in lazy resolve and resolving
// object as property (method tries to resolve annotations too). // object as property (method tries to resolve annotations too).
<!UNRESOLVED_REFERENCE!>@BadAnnotation<!> @<!UNRESOLVED_REFERENCE!>BadAnnotation<!>
object SomeObject object SomeObject
val some = SomeObject val some = SomeObject
@@ -10,5 +10,5 @@ fun foo() {
for (<!WRONG_ANNOTATION_TARGET!>@Ann(3)<!> (x, @Ann(4) y) in bar()) {} for (<!WRONG_ANNOTATION_TARGET!>@Ann(3)<!> (x, @Ann(4) y) in bar()) {}
for (<!UNRESOLVED_REFERENCE!>@Err<!>() (x,y) in bar()) {} for (@<!UNRESOLVED_REFERENCE!>Err<!>() (x,y) in bar()) {}
} }
@@ -1,9 +1,9 @@
fun foo(<!UNRESOLVED_REFERENCE!>@varargs<!> <!UNUSED_PARAMETER!>f<!> : Int) {} fun foo(@<!UNRESOLVED_REFERENCE!>varargs<!> <!UNUSED_PARAMETER!>f<!> : Int) {}
var bar : Int = 1 var bar : Int = 1
set(<!UNRESOLVED_REFERENCE!>@varargs<!> v) {} set(@<!UNRESOLVED_REFERENCE!>varargs<!> v) {}
val x : (Int) -> Int = {<!UNRESOLVED_REFERENCE!>@varargs<!> <!TYPE_MISMATCH, UNINITIALIZED_VARIABLE!>x<!> <!SYNTAX!>: Int -> x<!>} val x : (Int) -> Int = {@<!UNRESOLVED_REFERENCE!>varargs<!> <!TYPE_MISMATCH, UNINITIALIZED_VARIABLE!>x<!> <!SYNTAX!>: Int -> x<!>}
class Hello(<!UNRESOLVED_REFERENCE!>@varargs<!> <!UNUSED_PARAMETER!>args<!>: Any) { class Hello(@<!UNRESOLVED_REFERENCE!>varargs<!> <!UNUSED_PARAMETER!>args<!>: Any) {
} }
@@ -1,11 +1,11 @@
class A { class A {
<!WRONG_ANNOTATION_TARGET!>@ann<!> init {} <!WRONG_ANNOTATION_TARGET!>@ann<!> init {}
<!WRONG_ANNOTATION_TARGET, UNRESOLVED_REFERENCE!>@aaa<!> init {} <!WRONG_ANNOTATION_TARGET!>@<!UNRESOLVED_REFERENCE!>aaa<!><!> init {}
} }
interface T { interface T {
<!ANONYMOUS_INITIALIZER_IN_INTERFACE!><!WRONG_ANNOTATION_TARGET!>@ann<!> init {}<!> <!ANONYMOUS_INITIALIZER_IN_INTERFACE!><!WRONG_ANNOTATION_TARGET!>@ann<!> init {}<!>
<!ANONYMOUS_INITIALIZER_IN_INTERFACE!><!WRONG_ANNOTATION_TARGET, UNRESOLVED_REFERENCE!>@aaa<!> init {}<!> <!ANONYMOUS_INITIALIZER_IN_INTERFACE!><!WRONG_ANNOTATION_TARGET!>@<!UNRESOLVED_REFERENCE!>aaa<!><!> init {}<!>
} }
annotation class ann annotation class ann
@@ -1,5 +1,5 @@
<!UNRESOLVED_REFERENCE!>@Ann<!> class A @<!UNRESOLVED_REFERENCE!>Ann<!> class A
<!UNRESOLVED_REFERENCE!>@Ann<!> class B @<!UNRESOLVED_REFERENCE!>Ann<!> class B
<!UNRESOLVED_REFERENCE!>@Ann<!>(1) class C @<!UNRESOLVED_REFERENCE!>Ann<!>(1) class C
@kotlin.<!UNRESOLVED_REFERENCE!>Ann<!>(1) class D @kotlin.<!UNRESOLVED_REFERENCE!>Ann<!>(1) class D
@kotlin.annotation.<!UNRESOLVED_REFERENCE!>Ann<!>(1) class E @kotlin.annotation.<!UNRESOLVED_REFERENCE!>Ann<!>(1) class E
@@ -1,5 +1,5 @@
class Test { class Test {
<!UNRESOLVED_REFERENCE!>@ClassObjectAnnotation<!> @<!UNRESOLVED_REFERENCE!>ClassObjectAnnotation<!>
@NestedAnnotation @NestedAnnotation
companion object { companion object {
annotation class ClassObjectAnnotation annotation class ClassObjectAnnotation
@@ -1,4 +1,4 @@
<!UNRESOLVED_REFERENCE!>@<!SYNTAX!><!>myAnnotation<!> <!WRONG_MODIFIER_TARGET!>public<!> package illegal_modifiers @<!UNRESOLVED_REFERENCE!><!SYNTAX!><!>myAnnotation<!> <!WRONG_MODIFIER_TARGET!>public<!> package illegal_modifiers
abstract class A() { abstract class A() {
<!INCOMPATIBLE_MODIFIERS!>abstract<!> <!INCOMPATIBLE_MODIFIERS!>final<!> fun f() <!INCOMPATIBLE_MODIFIERS!>abstract<!> <!INCOMPATIBLE_MODIFIERS!>final<!> fun f()
+1 -1
View File
@@ -1,5 +1,5 @@
// !DIAGNOSTICS: -FUNCTION_DECLARATION_WITH_NO_NAME // !DIAGNOSTICS: -FUNCTION_DECLARATION_WITH_NO_NAME
class ClassB() { class ClassB() {
private inner class ClassC: <!SYNTAX!>super<!><!SYNTAX!>.<!><!UNRESOLVED_REFERENCE!>@ClassA<!>()<!SYNTAX!><!> { private inner class ClassC: <!SYNTAX!>super<!><!SYNTAX!>.<!>@<!UNRESOLVED_REFERENCE!>ClassA<!>()<!SYNTAX!><!> {
} }
} }
@@ -20,10 +20,10 @@ import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingContext;
class TypeKindHighlightingVisitor extends AfterAnalysisHighlightingVisitor { class TypeKindHighlightingVisitor extends AfterAnalysisHighlightingVisitor {
@@ -61,8 +61,20 @@ class TypeKindHighlightingVisitor extends AfterAnalysisHighlightingVisitor {
} }
private void highlightAnnotation(@NotNull KtSimpleNameExpression expression) { private void highlightAnnotation(@NotNull KtSimpleNameExpression expression) {
TextRange toHighlight = KtPsiUtilKt.getHighlightingRange(expression); TextRange range = expression.getTextRange();
NameHighlighter.highlightName(holder, toHighlight, KotlinHighlightingColors.ANNOTATION);
// include '@' symbol if the reference is the first segment of KtAnnotationEntry
// if "Deprecated" is highlighted then '@' should be highlighted too in "@Deprecated"
KtAnnotationEntry annotationEntry = PsiTreeUtil.getParentOfType(
expression, KtAnnotationEntry.class, /* strict = */false, KtValueArgumentList.class);
if (annotationEntry != null) {
PsiElement atSymbol = annotationEntry.getAtSymbol();
if (atSymbol != null) {
range = new TextRange(atSymbol.getTextRange().getStartOffset(), expression.getTextRange().getEndOffset());
}
}
NameHighlighter.highlightName(holder, range, KotlinHighlightingColors.ANNOTATION);
} }
@Override @Override
@@ -1,3 +1,3 @@
fun <K, V> intercept(<warning>block</warning>: (<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: A"><error descr="[UNSUPPORTED] Unsupported [annotation on parameter in function type]">@A</error></error> key: K, (K) -> V) -> V) { fun <K, V> intercept(<warning>block</warning>: (<error descr="[UNSUPPORTED] Unsupported [annotation on parameter in function type]">@<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: A">A</error></error> key: K, (K) -> V) -> V) {
} }
@@ -1,4 +1,4 @@
package foo package foo
<error>@Anno</error> ({ val x: Int }) @<error>Anno</error> ({ val x: Int })
fun f() {} fun f() {}
+2 -2
View File
@@ -13,11 +13,11 @@ fun <info descr="null">foo</info>() {
<info descr="null"><info descr="null">bar</info></info> <info descr="null" textAttributesKey="KOTLIN_ANNOTATION">@Ann</info> { 1 } <info descr="null"><info descr="null">bar</info></info> <info descr="null" textAttributesKey="KOTLIN_ANNOTATION">@Ann</info> { 1 }
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: Err" textAttributesKey="WRONG_REFERENCES_ATTRIBUTES">@Err</error> @<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: Err" textAttributesKey="WRONG_REFERENCES_ATTRIBUTES">Err</error>
<warning descr="[UNUSED_EXPRESSION] The expression is unused" textAttributesKey="WARNING_ATTRIBUTES">5</warning> <warning descr="[UNUSED_EXPRESSION] The expression is unused" textAttributesKey="WARNING_ATTRIBUTES">5</warning>
} }
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: Err" textAttributesKey="WRONG_REFERENCES_ATTRIBUTES">@Err</error> class <info descr="null" textAttributesKey="KOTLIN_CLASS">Err1</info> @<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: Err" textAttributesKey="WRONG_REFERENCES_ATTRIBUTES">Err</error> class <info descr="null" textAttributesKey="KOTLIN_CLASS">Err1</info>
class <info descr="null">NotAnn</info> class <info descr="null">NotAnn</info>
<error descr="[NOT_AN_ANNOTATION_CLASS] 'NotAnn' is not an annotation class" textAttributesKey="ERRORS_ATTRIBUTES">@NotAnn</error> <error descr="[NOT_AN_ANNOTATION_CLASS] 'NotAnn' is not an annotation class" textAttributesKey="ERRORS_ATTRIBUTES">@NotAnn</error>