Fix invalid FakeJvmFieldConstant inspection for UL classes

Test MultiFileInspectionTestGenerated.testFakeJvmFieldConstant_FakeJvmFieldConstant now correctly works with ultra-light annotation classes.
This commit is contained in:
Igor Yakovlev
2019-07-03 16:09:28 +03:00
parent a9aa60491e
commit 0602a6da72
8 changed files with 29 additions and 17 deletions
@@ -175,7 +175,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
this.classOrObject.companionObjects.firstOrNull()?.let { companion -> this.classOrObject.companionObjects.firstOrNull()?.let { companion ->
result.add( result.add(
KtUltraLightField( KtUltraLightFieldForSourceDeclaration(
companion, companion,
membersBuilder.generateUniqueFieldName(companion.name.orEmpty(), usedNames), membersBuilder.generateUniqueFieldName(companion.name.orEmpty(), usedNames),
this, this,
@@ -211,7 +211,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
if (isNamedObject()) { if (isNamedObject()) {
result.add( result.add(
KtUltraLightField( KtUltraLightFieldForSourceDeclaration(
this.classOrObject, this.classOrObject,
JvmAbi.INSTANCE_FIELD, JvmAbi.INSTANCE_FIELD,
this, this,
@@ -14,7 +14,7 @@ internal class KtUltraLightEnumEntry(
containingClass: KtLightClass, containingClass: KtLightClass,
support: KtUltraLightSupport, support: KtUltraLightSupport,
modifiers: Set<String> modifiers: Set<String>
) : KtUltraLightField(declaration, name, containingClass, support, modifiers), PsiEnumConstant { ) : KtUltraLightFieldImpl(declaration, name, containingClass, support, modifiers), PsiEnumConstant {
private val enumEntry get() = declaration as KtEnumEntry private val enumEntry get() = declaration as KtEnumEntry
@@ -12,10 +12,7 @@ import com.intellij.psi.util.TypeConversionUtil
import org.jetbrains.annotations.NonNls import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.elements.KtLightElement import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightSimpleModifierList
import org.jetbrains.kotlin.asJava.elements.KtUltraLightSimpleModifierList
import org.jetbrains.kotlin.codegen.PropertyCodegen import org.jetbrains.kotlin.codegen.PropertyCodegen
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
@@ -54,7 +51,16 @@ private class KtUltraLightSimpleModifierListField(
override fun copy() = KtUltraLightSimpleModifierListField(support, declaration, owner, modifiers) override fun copy() = KtUltraLightSimpleModifierListField(support, declaration, owner, modifiers)
} }
internal open class KtUltraLightField( internal class KtUltraLightFieldForSourceDeclaration(
declaration: KtNamedDeclaration,
name: String,
containingClass: KtLightClass,
support: KtUltraLightSupport,
modifiers: Set<String>
) : KtUltraLightFieldImpl(declaration, name, containingClass, support, modifiers),
KtLightFieldForSourceDeclarationSupport
internal open class KtUltraLightFieldImpl protected constructor(
protected val declaration: KtNamedDeclaration, protected val declaration: KtNamedDeclaration,
name: String, name: String,
private val containingClass: KtLightClass, private val containingClass: KtLightClass,
@@ -91,7 +91,7 @@ internal class UltraLightMembersCreator(
modifiers.add(PsiModifier.STATIC) modifiers.add(PsiModifier.STATIC)
} }
return KtUltraLightField(variable, fieldName, containingClass, support, modifiers) return KtUltraLightFieldForSourceDeclaration(variable, fieldName, containingClass, support, modifiers)
} }
private fun hasBackingField(property: KtProperty): Boolean { private fun hasBackingField(property: KtProperty): Boolean {
@@ -48,6 +48,10 @@ interface KtLightMember<out D : PsiMember> : PsiMember, KtLightDeclaration<KtDec
interface KtLightField : PsiField, KtLightMember<PsiField>, PsiVariableEx interface KtLightField : PsiField, KtLightMember<PsiField>, PsiVariableEx
interface KtLightFieldForSourceDeclarationSupport : PsiField {
val kotlinOrigin: KtDeclaration?
}
interface KtLightMethod : PsiAnnotationMethod, KtLightMember<PsiMethod> { interface KtLightMethod : PsiAnnotationMethod, KtLightMember<PsiMethod> {
val isDelegated: Boolean val isDelegated: Boolean
get() = lightMemberOrigin?.originKind == JvmDeclarationOriginKind.DELEGATION get() = lightMemberOrigin?.originKind == JvmDeclarationOriginKind.DELEGATION
@@ -102,13 +102,14 @@ sealed class KtLightFieldImpl<D : PsiField>(
override fun resolveMethodGenerics() = clsDelegate.resolveMethodGenerics() override fun resolveMethodGenerics() = clsDelegate.resolveMethodGenerics()
} }
class KtLightFieldForDeclaration(origin: LightMemberOrigin?, computeDelegate: () -> PsiField, containingClass: KtLightClass, dummyDelegate: PsiField?) : class KtLightFieldForSourceDeclaration(origin: LightMemberOrigin?, computeDelegate: () -> PsiField, containingClass: KtLightClass, dummyDelegate: PsiField?) :
KtLightFieldImpl<PsiField>(origin, computeDelegate, containingClass, dummyDelegate) KtLightFieldImpl<PsiField>(origin, computeDelegate, containingClass, dummyDelegate),
KtLightFieldForSourceDeclarationSupport
companion object Factory { companion object Factory {
fun create(origin: LightMemberOrigin?, delegate: PsiField, containingClass: KtLightClass): KtLightField = when (delegate) { fun create(origin: LightMemberOrigin?, delegate: PsiField, containingClass: KtLightClass): KtLightField = when (delegate) {
is PsiEnumConstant -> KtLightEnumConstant(origin, { delegate }, containingClass, null) is PsiEnumConstant -> KtLightEnumConstant(origin, { delegate }, containingClass, null)
else -> KtLightFieldForDeclaration(origin, { delegate }, containingClass, null) else -> KtLightFieldForSourceDeclaration(origin, { delegate }, containingClass, null)
} }
fun lazy( fun lazy(
@@ -121,7 +122,7 @@ sealed class KtLightFieldImpl<D : PsiField>(
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return KtLightEnumConstant(origin, computeRealDelegate as () -> PsiEnumConstant, containingClass, dummyDelegate) return KtLightEnumConstant(origin, computeRealDelegate as () -> PsiEnumConstant, containingClass, dummyDelegate)
} }
return KtLightFieldForDeclaration(origin, computeRealDelegate, containingClass, dummyDelegate) return KtLightFieldForSourceDeclaration(origin, computeRealDelegate, containingClass, dummyDelegate)
} }
fun fromClsFields(delegateClass: PsiClass, containingClass: KtLightClass) = delegateClass.fields.map { fun fromClsFields(delegateClass: PsiClass, containingClass: KtLightClass) = delegateClass.fields.map {
@@ -21,7 +21,7 @@ import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemHighlightType import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.* import com.intellij.psi.*
import org.jetbrains.kotlin.asJava.elements.KtLightFieldImpl.KtLightFieldForDeclaration import org.jetbrains.kotlin.asJava.elements.KtLightFieldForSourceDeclarationSupport
import org.jetbrains.kotlin.idea.inspections.MayBeConstantInspection.Status.* import org.jetbrains.kotlin.idea.inspections.MayBeConstantInspection.Status.*
import org.jetbrains.kotlin.idea.quickfix.AddConstModifierFix import org.jetbrains.kotlin.idea.quickfix.AddConstModifierFix
import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtProperty
@@ -80,7 +80,8 @@ class FakeJvmFieldConstantInspection : AbstractKotlinInspection() {
holder: ProblemsHolder, holder: ProblemsHolder,
additionalTypeCheck: (PsiType) -> Boolean = { true } additionalTypeCheck: (PsiType) -> Boolean = { true }
) { ) {
val resolvedLightField = (valueExpression as? PsiReference)?.resolve() as? KtLightFieldForDeclaration ?: return val resolvedLightField = (valueExpression as? PsiReference)?.resolve() as? KtLightFieldForSourceDeclarationSupport
?: return
val resolvedProperty = resolvedLightField.kotlinOrigin as? KtProperty ?: return val resolvedProperty = resolvedLightField.kotlinOrigin as? KtProperty ?: return
with(MayBeConstantInspection) { with(MayBeConstantInspection) {
if (resolvedProperty.annotationEntries.isEmpty()) return if (resolvedProperty.annotationEntries.isEmpty()) return
@@ -284,7 +284,7 @@ class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() {
TestCase.assertEquals( TestCase.assertEquals(
"KtUltraLightMethodForSourceDeclaration -> org.jetbrains.annotations.NotNull," + "KtUltraLightMethodForSourceDeclaration -> org.jetbrains.annotations.NotNull," +
" KtUltraLightField -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull", " KtUltraLightFieldForSourceDeclaration -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java)) annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java))
) )
} }
@@ -336,7 +336,7 @@ class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() {
TestCase.assertEquals( TestCase.assertEquals(
"KtUltraLightMethodForSourceDeclaration -> org.jetbrains.annotations.NotNull," + "KtUltraLightMethodForSourceDeclaration -> org.jetbrains.annotations.NotNull," +
" KtUltraLightField -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull", " KtUltraLightFieldForSourceDeclaration -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java)) annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java))
) )
} }