KotlinElementActionsFactory.createAddAnnotationActions: adding @field annotation target for targetless annotations (KT-18459)
This commit is contained in:
+40
-10
@@ -29,6 +29,7 @@ import com.intellij.openapi.util.text.StringUtilRt
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo
|
||||
import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl
|
||||
import com.intellij.psi.util.PropertyUtil
|
||||
import com.intellij.psi.util.PropertyUtilBase
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||
@@ -36,14 +37,14 @@ import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||
import org.jetbrains.kotlin.asJava.unwrapped
|
||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
import org.jetbrains.kotlin.idea.core.appendModifier
|
||||
import org.jetbrains.kotlin.idea.quickfix.AddModifierFix
|
||||
@@ -52,6 +53,7 @@ import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.CreateCallableFromUsageFix
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.approximateFlexibleTypes
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.load.java.components.TypeUsage
|
||||
@@ -70,7 +72,9 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
||||
import org.jetbrains.kotlin.resolve.AnnotationChecker
|
||||
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -449,11 +453,21 @@ class KotlinElementActionsFactory : JvmElementActionsFactory() {
|
||||
override fun createAddAnnotationActions(target: JvmModifiersOwner, request: AnnotationRequest): List<IntentionAction> {
|
||||
val declaration = (target as? KtLightElement<*, *>)?.kotlinOrigin as? KtModifierListOwner ?: return emptyList()
|
||||
if (declaration.language != KotlinLanguage.INSTANCE) return emptyList()
|
||||
return listOf(CreateAnnotationAction(declaration, request))
|
||||
val annotationUseSiteTarget = when (target) {
|
||||
is JvmField -> AnnotationUseSiteTarget.FIELD
|
||||
is JvmMethod -> when {
|
||||
PropertyUtil.isSimplePropertySetter(target as? PsiMethod) -> AnnotationUseSiteTarget.PROPERTY_SETTER
|
||||
PropertyUtil.isSimplePropertyGetter(target as? PsiMethod) -> AnnotationUseSiteTarget.PROPERTY_GETTER
|
||||
else -> null
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
return listOf(CreateAnnotationAction(declaration, annotationUseSiteTarget, request))
|
||||
}
|
||||
|
||||
private class CreateAnnotationAction(
|
||||
target: KtModifierListOwner,
|
||||
val annotationTarget: AnnotationUseSiteTarget?,
|
||||
val request: AnnotationRequest
|
||||
) : IntentionAction {
|
||||
|
||||
@@ -471,14 +485,30 @@ class KotlinElementActionsFactory : JvmElementActionsFactory() {
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
|
||||
val target = pointer.element ?: return
|
||||
val kotlinAnnotation = JavaPsiFacade.getInstance(project).findClass(
|
||||
request.qualifiedName,
|
||||
target.resolveScope
|
||||
)?.language == KotlinLanguage.INSTANCE
|
||||
val annotationClass = JavaPsiFacade.getInstance(project).findClass(request.qualifiedName, target.resolveScope)
|
||||
|
||||
val kotlinAnnotation = annotationClass?.language == KotlinLanguage.INSTANCE
|
||||
|
||||
val annotationUseSiteTargetPrefix = run prefixEvaluation@{
|
||||
if (annotationTarget == null) return@prefixEvaluation ""
|
||||
|
||||
val moduleDescriptor = (target as? KtDeclaration)?.resolveToDescriptorIfAny()?.module ?: return@prefixEvaluation ""
|
||||
val annotationClassDescriptor = moduleDescriptor.resolveClassByFqName(
|
||||
FqName(request.qualifiedName), NoLookupLocation.FROM_IDE
|
||||
) ?: return@prefixEvaluation ""
|
||||
|
||||
val applicableTargetSet =
|
||||
AnnotationChecker.applicableTargetSet(annotationClassDescriptor) ?: KotlinTarget.DEFAULT_TARGET_SET
|
||||
|
||||
if (KotlinTarget.PROPERTY !in applicableTargetSet) return@prefixEvaluation ""
|
||||
|
||||
"${annotationTarget.renderName}:"
|
||||
}
|
||||
|
||||
val entry = target.addAnnotationEntry(
|
||||
KtPsiFactory(target)
|
||||
.createAnnotationEntry(
|
||||
"@${request.qualifiedName}${
|
||||
"@$annotationUseSiteTargetPrefix${request.qualifiedName}${
|
||||
request.attributes.mapIndexed { i, p ->
|
||||
if (!kotlinAnnotation && i == 0 && p.name == "value")
|
||||
renderAttributeValue(p.value).toString()
|
||||
|
||||
+40
-14
@@ -20,10 +20,7 @@ import com.intellij.codeInsight.daemon.QuickFixBundle
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory
|
||||
import com.intellij.lang.java.beans.PropertyKind
|
||||
import com.intellij.lang.jvm.JvmClass
|
||||
import com.intellij.lang.jvm.JvmElement
|
||||
import com.intellij.lang.jvm.JvmModifier
|
||||
import com.intellij.lang.jvm.JvmModifiersOwner
|
||||
import com.intellij.lang.jvm.*
|
||||
import com.intellij.lang.jvm.actions.*
|
||||
import com.intellij.lang.jvm.types.JvmType
|
||||
import com.intellij.openapi.editor.Editor
|
||||
@@ -32,6 +29,7 @@ import com.intellij.openapi.util.text.StringUtilRt
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo
|
||||
import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl
|
||||
import com.intellij.psi.util.PropertyUtil
|
||||
import com.intellij.psi.util.PropertyUtilBase
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||
@@ -39,14 +37,14 @@ import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||
import org.jetbrains.kotlin.asJava.unwrapped
|
||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
import org.jetbrains.kotlin.idea.core.appendModifier
|
||||
import org.jetbrains.kotlin.idea.quickfix.AddModifierFix
|
||||
@@ -55,6 +53,7 @@ import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.CreateCallableFromUsageFix
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.approximateFlexibleTypes
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.load.java.components.TypeUsage
|
||||
@@ -73,7 +72,9 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
||||
import org.jetbrains.kotlin.resolve.AnnotationChecker
|
||||
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -452,11 +453,21 @@ class KotlinElementActionsFactory : JvmElementActionsFactory() {
|
||||
override fun createAddAnnotationActions(target: JvmModifiersOwner, request: AnnotationRequest): List<IntentionAction> {
|
||||
val declaration = (target as? KtLightElement<*, *>)?.kotlinOrigin as? KtModifierListOwner ?: return emptyList()
|
||||
if (declaration.language != KotlinLanguage.INSTANCE) return emptyList()
|
||||
return listOf(CreateAnnotationAction(declaration, request))
|
||||
val annotationUseSiteTarget = when (target) {
|
||||
is JvmField -> AnnotationUseSiteTarget.FIELD
|
||||
is JvmMethod -> when {
|
||||
PropertyUtil.isSimplePropertySetter(target as? PsiMethod) -> AnnotationUseSiteTarget.PROPERTY_SETTER
|
||||
PropertyUtil.isSimplePropertyGetter(target as? PsiMethod) -> AnnotationUseSiteTarget.PROPERTY_GETTER
|
||||
else -> null
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
return listOf(CreateAnnotationAction(declaration, annotationUseSiteTarget, request))
|
||||
}
|
||||
|
||||
private class CreateAnnotationAction(
|
||||
target: KtModifierListOwner,
|
||||
val annotationTarget: AnnotationUseSiteTarget?,
|
||||
val request: AnnotationRequest
|
||||
) : IntentionAction {
|
||||
|
||||
@@ -474,14 +485,29 @@ class KotlinElementActionsFactory : JvmElementActionsFactory() {
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
|
||||
val target = pointer.element ?: return
|
||||
val kotlinAnnotation = JavaPsiFacade.getInstance(project).findClass(
|
||||
request.qualifiedName,
|
||||
target.resolveScope
|
||||
)?.language == KotlinLanguage.INSTANCE
|
||||
val annotationClass = JavaPsiFacade.getInstance(project).findClass(request.qualifiedName, target.resolveScope)
|
||||
|
||||
val kotlinAnnotation = annotationClass?.language == KotlinLanguage.INSTANCE
|
||||
|
||||
val annotationUseSiteTargetPrefix = run prefixEvaluation@{
|
||||
if (annotationTarget == null) return@prefixEvaluation ""
|
||||
|
||||
val moduleDescriptor = (target as? KtDeclaration)?.resolveToDescriptorIfAny()?.module ?: return@prefixEvaluation ""
|
||||
val annotationClassDescriptor = moduleDescriptor.resolveClassByFqName(
|
||||
FqName(request.qualifiedName), NoLookupLocation.FROM_IDE
|
||||
) ?: return@prefixEvaluation ""
|
||||
|
||||
val applicableTargetSet = AnnotationChecker.applicableTargetSet(annotationClassDescriptor) ?: KotlinTarget.DEFAULT_TARGET_SET
|
||||
|
||||
if (KotlinTarget.PROPERTY !in applicableTargetSet) return@prefixEvaluation ""
|
||||
|
||||
"${annotationTarget.renderName}:"
|
||||
}
|
||||
|
||||
val entry = target.addAnnotationEntry(
|
||||
KtPsiFactory(target)
|
||||
.createAnnotationEntry(
|
||||
"@${request.qualifiedName}${
|
||||
"@$annotationUseSiteTargetPrefix${request.qualifiedName}${
|
||||
request.attributes.mapIndexed { i, p ->
|
||||
if (!kotlinAnnotation && i == 0 && p.name == "value")
|
||||
renderAttributeValue(p.value).toString()
|
||||
|
||||
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.idea.quickfix
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.lang.jvm.JvmClass
|
||||
import com.intellij.lang.jvm.JvmElement
|
||||
import com.intellij.lang.jvm.JvmMethod
|
||||
import com.intellij.lang.jvm.JvmModifier
|
||||
import com.intellij.lang.jvm.actions.*
|
||||
import com.intellij.lang.jvm.types.JvmSubstitutor
|
||||
@@ -19,6 +18,7 @@ import com.intellij.psi.*
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo
|
||||
import com.intellij.testFramework.fixtures.CodeInsightTestFixture
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.asJava.toLightElements
|
||||
import org.jetbrains.kotlin.idea.search.allScope
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
@@ -240,6 +240,113 @@ class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() {
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun testAddJavaAnnotationOnFieldWithoutTarget() {
|
||||
|
||||
myFixture.addFileToProject(
|
||||
"pkg/myannotation/JavaAnnotation.java", """
|
||||
package pkg.myannotation
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
//no @Target
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface JavaAnnotation {
|
||||
String value();
|
||||
int param() default 0;
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """class Foo {
|
||||
| val bar: String = null
|
||||
|}""".trim().trimMargin()
|
||||
)
|
||||
|
||||
myFixture.launchAction(
|
||||
createAddAnnotationActions(
|
||||
myFixture.findElementByText("bar", KtModifierListOwner::class.java).toLightElements().single { it is PsiField } as PsiField,
|
||||
annotationRequest("pkg.myannotation.JavaAnnotation")
|
||||
).single()
|
||||
)
|
||||
|
||||
myFixture.checkResult(
|
||||
"""
|
||||
import pkg.myannotation.JavaAnnotation
|
||||
|
||||
class Foo {
|
||||
@field:JavaAnnotation()
|
||||
val bar: String = null
|
||||
}
|
||||
""".trimIndent(), true
|
||||
)
|
||||
|
||||
TestCase.assertEquals(
|
||||
"KtLightMethodImpl -> org.jetbrains.annotations.NotNull," +
|
||||
" KtLightFieldForDeclaration -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
|
||||
annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun testAddJavaAnnotationOnField() {
|
||||
|
||||
myFixture.addFileToProject(
|
||||
"pkg/myannotation/JavaAnnotation.java", """
|
||||
package pkg.myannotation
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface JavaAnnotation {
|
||||
String value();
|
||||
int param() default 0;
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """class Foo {
|
||||
| val bar: String = null
|
||||
|}""".trim().trimMargin()
|
||||
)
|
||||
|
||||
myFixture.launchAction(
|
||||
createAddAnnotationActions(
|
||||
myFixture.findElementByText("bar", KtModifierListOwner::class.java).toLightElements().single { it is PsiField } as PsiField,
|
||||
annotationRequest("pkg.myannotation.JavaAnnotation")
|
||||
).single()
|
||||
)
|
||||
|
||||
myFixture.checkResult(
|
||||
"""
|
||||
import pkg.myannotation.JavaAnnotation
|
||||
|
||||
class Foo {
|
||||
@JavaAnnotation()
|
||||
val bar: String = null
|
||||
}
|
||||
""".trimIndent(), true
|
||||
)
|
||||
|
||||
TestCase.assertEquals(
|
||||
"KtLightMethodImpl -> org.jetbrains.annotations.NotNull," +
|
||||
" KtLightFieldForDeclaration -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
|
||||
annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java))
|
||||
)
|
||||
}
|
||||
|
||||
private fun annotationsString(findElementByText: KtModifierListOwner) = findElementByText.toLightElements()
|
||||
.joinToString { elem -> "${elem.javaClass.simpleName} -> ${(elem as PsiModifierListOwner).annotations.joinToString { it.qualifiedName!! }}" }
|
||||
|
||||
fun testDontMakePublicPublic() {
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """class Foo {
|
||||
|
||||
@@ -13,13 +13,11 @@ import com.intellij.lang.jvm.actions.*
|
||||
import com.intellij.lang.jvm.types.JvmSubstitutor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Pair.pair
|
||||
import com.intellij.psi.PsiJvmSubstitutor
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiSubstitutor
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo
|
||||
import com.intellij.testFramework.fixtures.CodeInsightTestFixture
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.asJava.toLightElements
|
||||
import org.jetbrains.kotlin.idea.search.allScope
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
@@ -238,6 +236,113 @@ class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() {
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun testAddJavaAnnotationOnFieldWithoutTarget() {
|
||||
|
||||
myFixture.addFileToProject(
|
||||
"pkg/myannotation/JavaAnnotation.java", """
|
||||
package pkg.myannotation
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
//no @Target
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface JavaAnnotation {
|
||||
String value();
|
||||
int param() default 0;
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """class Foo {
|
||||
| val bar: String = null
|
||||
|}""".trim().trimMargin()
|
||||
)
|
||||
|
||||
myFixture.launchAction(
|
||||
createAddAnnotationActions(
|
||||
myFixture.findElementByText("bar", KtModifierListOwner::class.java).toLightElements().single { it is PsiField } as PsiField,
|
||||
annotationRequest("pkg.myannotation.JavaAnnotation")
|
||||
).single()
|
||||
)
|
||||
|
||||
myFixture.checkResult(
|
||||
"""
|
||||
import pkg.myannotation.JavaAnnotation
|
||||
|
||||
class Foo {
|
||||
@field:JavaAnnotation()
|
||||
val bar: String = null
|
||||
}
|
||||
""".trimIndent(), true
|
||||
)
|
||||
|
||||
TestCase.assertEquals(
|
||||
"KtLightMethodImpl -> org.jetbrains.annotations.NotNull," +
|
||||
" KtLightFieldForDeclaration -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
|
||||
annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun testAddJavaAnnotationOnField() {
|
||||
|
||||
myFixture.addFileToProject(
|
||||
"pkg/myannotation/JavaAnnotation.java", """
|
||||
package pkg.myannotation
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface JavaAnnotation {
|
||||
String value();
|
||||
int param() default 0;
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """class Foo {
|
||||
| val bar: String = null
|
||||
|}""".trim().trimMargin()
|
||||
)
|
||||
|
||||
myFixture.launchAction(
|
||||
createAddAnnotationActions(
|
||||
myFixture.findElementByText("bar", KtModifierListOwner::class.java).toLightElements().single { it is PsiField } as PsiField,
|
||||
annotationRequest("pkg.myannotation.JavaAnnotation")
|
||||
).single()
|
||||
)
|
||||
|
||||
myFixture.checkResult(
|
||||
"""
|
||||
import pkg.myannotation.JavaAnnotation
|
||||
|
||||
class Foo {
|
||||
@JavaAnnotation()
|
||||
val bar: String = null
|
||||
}
|
||||
""".trimIndent(), true
|
||||
)
|
||||
|
||||
TestCase.assertEquals(
|
||||
"KtLightMethodImpl -> org.jetbrains.annotations.NotNull," +
|
||||
" KtLightFieldForDeclaration -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
|
||||
annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java))
|
||||
)
|
||||
}
|
||||
|
||||
private fun annotationsString(findElementByText: KtModifierListOwner) = findElementByText.toLightElements()
|
||||
.joinToString { elem -> "${elem.javaClass.simpleName} -> ${(elem as PsiModifierListOwner).annotations.joinToString { it.qualifiedName!! }}" }
|
||||
|
||||
fun testDontMakePublicPublic() {
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """class Foo {
|
||||
|
||||
Reference in New Issue
Block a user