Suggest "Add annotation target" quick fix also for field use-site
So #KT-23227 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
e328d2d1ca
commit
a67068d37e
@@ -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 = ""
|
||||
}
|
||||
+15
@@ -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 { "" }
|
||||
}
|
||||
+16
@@ -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 = ""
|
||||
+12
@@ -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 { "" }
|
||||
+13
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user