Suggest "Add annotation target" quick fix also for field use-site

So #KT-23227 Fixed
This commit is contained in:
Toshiaki Kameyama
2018-03-13 13:12:10 +03:00
committed by Mikhail Glukhikh
parent e328d2d1ca
commit a67068d37e
10 changed files with 143 additions and 4 deletions
@@ -9,7 +9,9 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.searches.ReferencesSearch
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Errors
@@ -85,11 +87,24 @@ private fun KtAnnotationEntry.getActualTargetList(): List<KotlinTarget> {
val targetList = AnnotationChecker.getActualTargetList(annotatedElement, null, BindingTraceContext())
if (useSiteTarget == null) {
return targetList.defaultTargets
val useSiteTarget = this.useSiteTarget ?: return targetList.defaultTargets
val annotationUseSiteTarget = useSiteTarget.getAnnotationUseSiteTarget()
val target = KotlinTarget.USE_SITE_MAPPING[annotationUseSiteTarget] ?: return emptyList()
if (annotationUseSiteTarget == AnnotationUseSiteTarget.FIELD) {
if (KotlinTarget.MEMBER_PROPERTY !in targetList.defaultTargets && KotlinTarget.TOP_LEVEL_PROPERTY !in targetList.defaultTargets) {
return emptyList()
}
val property = annotatedElement as? KtProperty
if (property != null && (LightClassUtil.getLightClassPropertyMethods(property).backingField == null || property.hasDelegate())) {
return emptyList()
}
} else {
if (target !in with(targetList) { defaultTargets + canBeSubstituted + onlyWithUseSiteTarget }) {
return emptyList()
}
}
val target = KotlinTarget.USE_SITE_MAPPING[useSiteTarget?.getAnnotationUseSiteTarget()] ?: return emptyList()
if (target !in with(targetList) { defaultTargets + canBeSubstituted + onlyWithUseSiteTarget }) return emptyList()
return listOf(target)
}
@@ -0,0 +1,9 @@
// "Add annotation target" "true"
@Target
annotation class Ann
class Test {
@field:Ann<caret>
var foo = ""
}
@@ -0,0 +1,9 @@
// "Add annotation target" "true"
@Target(AnnotationTarget.FIELD)
annotation class Ann
class Test {
@field:Ann
var foo = ""
}
@@ -0,0 +1,15 @@
// "Add annotation target" "false"
// WITH_RUNTIME
// ACTION: Make internal
// ACTION: Make private
// ACTION: Make protected
// ERROR: '@field:' annotations could be applied only to properties with backing fields
// ERROR: This annotation is not applicable to target 'member property with delegate' and use site target '@field'
@Target
annotation class Ann
class Test {
@field:Ann<caret>
val baz: String by lazy { "" }
}
@@ -0,0 +1,16 @@
// "Add annotation target" "false"
// ACTION: Make internal
// ACTION: Make private
// ACTION: Make protected
// ACTION: Specify type explicitly
// ERROR: This annotation is not applicable to target 'member property without backing field or delegate' and use site target '@field'
@Target
annotation class Ann
class Test {
@field:Ann<caret>
var bar
get() = ""
set(p) {}
}
@@ -0,0 +1,7 @@
// "Add annotation target" "true"
@Target
annotation class Ann
@field:Ann<caret>
var foo = ""
@@ -0,0 +1,7 @@
// "Add annotation target" "true"
@Target(AnnotationTarget.FIELD)
annotation class Ann
@field:Ann
var foo = ""
@@ -0,0 +1,12 @@
// "Add annotation target" "false"
// WITH_RUNTIME
// ACTION: Make internal
// ACTION: Make private
// ERROR: '@field:' annotations could be applied only to properties with backing fields
// ERROR: This annotation is not applicable to target 'top level property with delegate' and use site target '@field'
@Target
annotation class Ann
@field:Ann<caret>
val baz: String by lazy { "" }
@@ -0,0 +1,13 @@
// "Add annotation target" "false"
// ACTION: Make internal
// ACTION: Make private
// ACTION: Specify type explicitly
// ERROR: This annotation is not applicable to target 'top level property without backing field or delegate' and use site target '@field'
@Target
annotation class Ann
@field:Ann<caret>
var bar
get() = ""
set(p) {}
@@ -306,6 +306,42 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
doTest(fileName);
}
@TestMetadata("use-site_field_member.kt")
public void testUse_site_field_member() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addAnnotationTarget/use-site_field_member.kt");
doTest(fileName);
}
@TestMetadata("use-site_field_member_with_delegate.kt")
public void testUse_site_field_member_with_delegate() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addAnnotationTarget/use-site_field_member_with_delegate.kt");
doTest(fileName);
}
@TestMetadata("use-site_field_member_without_backing.kt")
public void testUse_site_field_member_without_backing() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addAnnotationTarget/use-site_field_member_without_backing.kt");
doTest(fileName);
}
@TestMetadata("use-site_field_toplevel.kt")
public void testUse_site_field_toplevel() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addAnnotationTarget/use-site_field_toplevel.kt");
doTest(fileName);
}
@TestMetadata("use-site_field_toplevel_with_delegate.kt")
public void testUse_site_field_toplevel_with_delegate() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addAnnotationTarget/use-site_field_toplevel_with_delegate.kt");
doTest(fileName);
}
@TestMetadata("use-site_field_toplevel_without_backing.kt")
public void testUse_site_field_toplevel_without_backing() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addAnnotationTarget/use-site_field_toplevel_without_backing.kt");
doTest(fileName);
}
@TestMetadata("use-site_file.kt")
public void testUse_site_file() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addAnnotationTarget/use-site_file.kt");