Change deprecation rules for annotations in brackets

Also adjust quickfix for deprecated syntax
This commit is contained in:
Denis Zharkov
2015-05-15 13:47:14 +03:00
parent e4f54b5d2e
commit 89337ff51e
12 changed files with 45 additions and 27 deletions
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub;
import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes;
@@ -40,13 +41,15 @@ public class JetAnnotation extends JetElementImplStub<KotlinPlaceHolderStub<JetA
}
public boolean isDeprecated() {
PsiElement parent = getParentByStub();
if (parent instanceof JetFileAnnotationList) return false;
if (!(parent instanceof JetModifierList)) return true;
return !(((JetModifierList) parent).getOwner() instanceof JetPrimaryConstructor);
if (getStub() != null) return false;
return findChildByType(JetTokens.AT) == null;
}
public List<JetAnnotationEntry> getEntries() {
return getStubOrPsiChildrenAsList(JetStubElementTypes.ANNOTATION_ENTRY);
}
public boolean hasFileKeyword() {
return findChildByType(JetTokens.FILE_KEYWORD) != null;
}
}
@@ -53,6 +53,7 @@ public class DeclarationResolver {
public fun resolveAnnotationsOnFiles(c: TopDownAnalysisContext, scopeProvider: FileScopeProvider) {
val filesToScope = c.getFiles().keysToMap { scopeProvider.getFileScope(it) }
for ((file, fileScope) in filesToScope) {
AnnotationResolver.reportDeprecatedAnnotationSyntax(file.getAnnotations(), _trace)
_annotationResolver.resolveAnnotationsWithArguments(fileScope, file.getAnnotationEntries(), _trace)
_annotationResolver.resolveAnnotationsWithArguments(fileScope, file.getDanglingAnnotations(), _trace)
}
@@ -1,7 +1,7 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
annotation class Ann(val x: Int = 6)
@Ann(1) @Ann(2) @Ann(3) @private class A [Ann] constructor() {
@Ann(1) @Ann(2) @Ann(3) @private class A @Ann constructor() {
@Ann(x = 5) fun foo() {
1 + @Ann(1) 1 * @Ann(<!TYPE_MISMATCH!>""<!>) 6
@@ -1,5 +1,6 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
[file: Ann]
<!DEPRECATED_ANNOTATION_SYNTAX!>[file: Ann]<!>
@file:[Ann]
annotation class Ann(val arg: Int = 1)
fun bar(block: () -> Int) = block()
@@ -8,7 +9,7 @@ data class Q(val x: Int, val y: Int)
fun bar2(): Array<Q> = null!!
<!DEPRECATED_ANNOTATION_SYNTAX!>[Ann Ann]<!> class A [Ann] constructor(<!DEPRECATED_ANNOTATION_SYNTAX!>[Ann]<!> val prop: Int) {
<!DEPRECATED_ANNOTATION_SYNTAX!>[Ann Ann]<!> class A <!DEPRECATED_ANNOTATION_SYNTAX!>[Ann]<!> constructor(<!DEPRECATED_ANNOTATION_SYNTAX!>[Ann]<!> val prop: Int) {
<!DEPRECATED_ANNOTATION_SYNTAX!>[Ann]<!> val x = 1
<!DEPRECATED_ANNOTATION_SYNTAX!>[Ann]<!> fun foo(<!DEPRECATED_ANNOTATION_SYNTAX!>[Ann]<!> x: Int) {
<!DEPRECATED_ANNOTATION_SYNTAX!>[Ann]<!> class B
@@ -4,7 +4,7 @@ open class Obsolete {
}
deprecated("Class")
open class Obsolete2 [deprecated("Constructor")] constructor() {
open class Obsolete2 deprecated("Constructor") constructor() {
fun use() {}
}
@@ -32,7 +32,7 @@ var vardef: Int = 1
set
<!INAPPLICABLE_ANNOTATION!>@platformName("C")<!>
class C [<!INAPPLICABLE_ANNOTATION!>platformName("primary")<!>] constructor() {
class C <!INAPPLICABLE_ANNOTATION!>platformName("primary")<!> constructor() {
<!INAPPLICABLE_ANNOTATION!>platformName("ctr")<!> constructor(x: Int): this() {}
<!INAPPLICABLE_ANNOTATION!>@platformName("a")<!>
fun foo() {}
@@ -6,4 +6,4 @@ class A {
}
}
class C <!PLATFORM_STATIC_ILLEGAL_USAGE!>[platformStatic] constructor()<!>
class C <!PLATFORM_STATIC_ILLEGAL_USAGE!>platformStatic constructor()<!>
@@ -7,4 +7,4 @@ class A {
<!INAPPLICABLE_ANNOTATION!>native constructor(<!UNUSED_PARAMETER!>x<!>: Int)
<!>}
class C <!INAPPLICABLE_ANNOTATION!>[native] constructor()<!>
class C <!INAPPLICABLE_ANNOTATION!>native constructor()<!>
@@ -22,10 +22,12 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.quickfix.quickfixUtil.addConstructorKeyword
import org.jetbrains.kotlin.idea.quickfix.quickfixUtil.createIntentionFactory
import org.jetbrains.kotlin.idea.quickfix.quickfixUtil.createIntentionForFirstParentOfType
import org.jetbrains.kotlin.psi.JetAnnotation
import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.psi.JetPrimaryConstructor
import org.jetbrains.kotlin.psi.JetPsiFactory
public class DeprecatedAnnotationSyntaxFix(element: JetAnnotation) : JetIntentionAction<JetAnnotation>(element) {
@@ -51,11 +53,15 @@ public class DeprecatedAnnotationSyntaxFix(element: JetAnnotation) : JetIntentio
private fun replaceWithAtAnnotationEntries(annotation: JetAnnotation) {
val psiFactory = JetPsiFactory(annotation)
val hasFileKeyword = annotation.hasFileKeyword()
val parent = annotation.getParent()
val owner = parent.getParent()
var prevElement: PsiElement = annotation
for (entry in annotation.getEntries()) {
val newEntry = psiFactory.createAnnotationEntry("@" + entry.getText())
val newEntry = if (hasFileKeyword) createFileAnnotationEntry(psiFactory, entry.getText())
else psiFactory.createAnnotationEntry("@" + entry.getText())
val added = parent.addAfter(newEntry, prevElement)
if (prevElement != annotation) {
@@ -65,7 +71,14 @@ public class DeprecatedAnnotationSyntaxFix(element: JetAnnotation) : JetIntentio
prevElement = added
}
if (owner is JetPrimaryConstructor) {
owner.addConstructorKeyword()
}
annotation.delete()
}
private fun createFileAnnotationEntry(psiFactory: JetPsiFactory, text: String) =
psiFactory.createFile("@file:$text").getAnnotationEntries().first()
}
}
+12 -12
View File
@@ -1,18 +1,18 @@
[file: kotlin.deprecated("message")]
[file: suppress(<error>BAR</error>)]
[file: suppress(BAZ)]
@file:kotlin.deprecated("message")
@file:suppress(<error>BAR</error>)
@file:suppress(BAZ)
[<error>k</error>otlin.deprecated("message")]
[<error>s</error>uppress(<error>BAR</error>)]
[<error>s</error>uppress(BAZ)]
@<error>k</error>otlin.deprecated("message")
@<error>s</error>uppress(<error>BAR</error>)
@<error>s</error>uppress(BAZ)
[file: myAnnotation(1, "string")]
[file: boo.myAnnotation(1, <error>BAR</error>)]
[file: myAnnotation(N, BAZ)]
@file:myAnnotation(1, "string")
@file:boo.myAnnotation(1, <error>BAR</error>)
@file:myAnnotation(N, BAZ)
[<error>m</error>yAnnotation(1, "string")]
[<error>b</error>oo.myAnnotation(1, "string")]
[<error>m</error>yAnnotation(N, BAZ)]
@<error>m</error>yAnnotation(1, "string")
@<error>b</error>oo.myAnnotation(1, "string")
@<error>m</error>yAnnotation(N, BAZ)
package boo
@@ -15,7 +15,7 @@ fun testVisibility() {
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: ClassInM2">ClassInM2</error>()
}
public open class A internal () {
public open class A internal constructor() {
private fun pri() {
}
fun int() {
@@ -1,3 +1,3 @@
[file: Ann]
@file:Ann
@Ann class B [Ann(1)]()
@Ann class B @Ann(1) constructor()