FIR IDE: Add quickfix for INAPPLICABLE_LATEINIT_MODIFIER.
Also changed FE1.0 checker and all related fix factories to report error on the declaration instead of the lateinit modifier. This is consistent with the direction of all checkers in FIR (no reporting on modifiers).
This commit is contained in:
committed by
Ilya Kirillov
parent
b1ab64e854
commit
4e44804c77
@@ -37,6 +37,7 @@ class MainKtQuickFixRegistrar : KtQuickFixRegistrar() {
|
||||
|
||||
private val mutability = KtQuickFixesListBuilder.registerPsiQuickFix {
|
||||
registerPsiQuickFix<PsiElement, KtFirDiagnostic.VarOverriddenByVal>(ChangeVariableMutabilityFix.VAR_OVERRIDDEN_BY_VAL_FACTORY)
|
||||
registerPsiQuickFix<KtModifierListOwner, KtFirDiagnostic.InapplicableLateinitModifier>(ChangeVariableMutabilityFix.LATEINIT_VAL_FACTORY)
|
||||
}
|
||||
|
||||
override val list: KtQuickFixesList = KtQuickFixesList.createCombined(
|
||||
|
||||
Generated
+43
@@ -19,6 +19,49 @@ import java.util.regex.Pattern;
|
||||
@SuppressWarnings("all")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class HighLevelQuickFixTestGenerated extends AbstractHighLevelQuickFixTest {
|
||||
@TestMetadata("idea/testData/quickfix/lateinit")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Lateinit extends AbstractHighLevelQuickFixTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInLateinit() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/lateinit"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("nullable.kt")
|
||||
public void testNullable() throws Exception {
|
||||
runTest("idea/testData/quickfix/lateinit/nullable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("val.kt")
|
||||
public void testVal() throws Exception {
|
||||
runTest("idea/testData/quickfix/lateinit/val.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withGetter.kt")
|
||||
public void testWithGetter() throws Exception {
|
||||
runTest("idea/testData/quickfix/lateinit/withGetter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withGetterSetter.kt")
|
||||
public void testWithGetterSetter() throws Exception {
|
||||
runTest("idea/testData/quickfix/lateinit/withGetterSetter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withInitializer.kt")
|
||||
public void testWithInitializer() throws Exception {
|
||||
runTest("idea/testData/quickfix/lateinit/withInitializer.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withSetter.kt")
|
||||
public void testWithSetter() throws Exception {
|
||||
runTest("idea/testData/quickfix/lateinit/withSetter.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/modifiers")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+1
-1
@@ -372,7 +372,7 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
abstract val candidate: KtSymbol
|
||||
}
|
||||
|
||||
abstract class InapplicableLateinitModifier : KtFirDiagnostic<PsiElement>() {
|
||||
abstract class InapplicableLateinitModifier : KtFirDiagnostic<KtModifierListOwner>() {
|
||||
override val diagnosticClass get() = InapplicableLateinitModifier::class
|
||||
abstract val reason: String
|
||||
}
|
||||
|
||||
+1
-1
@@ -596,7 +596,7 @@ internal class InapplicableLateinitModifierImpl(
|
||||
override val reason: String,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.InapplicableLateinitModifier(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
) : KtFirDiagnostic.InapplicableLateinitModifier(), KtAbstractFirDiagnostic<KtModifierListOwner> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -64,9 +64,9 @@ class ChangeVariableMutabilityFix(
|
||||
listOf(ChangeVariableMutabilityFix(psiElement, false))
|
||||
}
|
||||
|
||||
val LATEINIT_VAL_FACTORY: QuickFixesPsiBasedFactory<PsiElement> =
|
||||
quickFixesPsiBasedFactory { psiElement: PsiElement ->
|
||||
val property = psiElement.getStrictParentOfType<KtProperty>() ?: return@quickFixesPsiBasedFactory emptyList()
|
||||
val LATEINIT_VAL_FACTORY: QuickFixesPsiBasedFactory<KtModifierListOwner> =
|
||||
quickFixesPsiBasedFactory { psiElement: KtModifierListOwner ->
|
||||
val property = psiElement as? KtProperty ?: return@quickFixesPsiBasedFactory emptyList()
|
||||
if (property.valOrVarKeyword.text != "val") {
|
||||
emptyList()
|
||||
} else {
|
||||
|
||||
+1
-2
@@ -121,8 +121,7 @@ class RemoveModifierFix(
|
||||
|
||||
fun createRemoveLateinitFactory(): QuickFixesPsiBasedFactory<PsiElement> {
|
||||
return quickFixesPsiBasedFactory { psiElement: PsiElement ->
|
||||
val modifierList = psiElement.parent as? KtDeclarationModifierList ?: return@quickFixesPsiBasedFactory emptyList()
|
||||
val property = modifierList.parent as? KtProperty ?: return@quickFixesPsiBasedFactory emptyList()
|
||||
val property = psiElement as? KtProperty ?: return@quickFixesPsiBasedFactory emptyList()
|
||||
if (!property.hasModifier(KtTokens.LATEINIT_KEYWORD)) return@quickFixesPsiBasedFactory emptyList()
|
||||
listOf(RemoveModifierFix(property, KtTokens.LATEINIT_KEYWORD, isRedundant = false))
|
||||
}
|
||||
|
||||
+1
-2
@@ -40,8 +40,7 @@ class ConvertLateinitPropertyToNotNullDelegateFix(
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<KtProperty>? {
|
||||
val modifierList = diagnostic.psiElement.parent as? KtDeclarationModifierList ?: return null
|
||||
val property = modifierList.parent as? KtProperty ?: return null
|
||||
val property = diagnostic.psiElement as? KtProperty ?: return null
|
||||
if (!property.hasModifier(KtTokens.LATEINIT_KEYWORD) || !property.isVar || property.hasInitializer()) return null
|
||||
val typeReference = property.typeReference ?: return null
|
||||
val type = property.analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, typeReference] ?: return null
|
||||
|
||||
@@ -58,8 +58,7 @@ class RemoveNullableFix(
|
||||
|
||||
object LATEINIT_FACTORY : KotlinSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<KtNullableType>? {
|
||||
val lateinitElement = Errors.INAPPLICABLE_LATEINIT_MODIFIER.cast(diagnostic).psiElement
|
||||
val property = lateinitElement.getStrictParentOfType<KtProperty>() ?: return null
|
||||
val property = Errors.INAPPLICABLE_LATEINIT_MODIFIER.cast(diagnostic).psiElement as? KtProperty ?: return null
|
||||
val typeReference = property.typeReference ?: return null
|
||||
val typeElement = (typeReference.typeElement ?: return null) as? KtNullableType ?: return null
|
||||
if (typeElement.innerType == null) return null
|
||||
|
||||
@@ -118,8 +118,7 @@ open class RemovePartsFromPropertyFix(
|
||||
|
||||
object LateInitFactory : KotlinSingleIntentionActionFactory() {
|
||||
public override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<KtProperty>? {
|
||||
val element = Errors.INAPPLICABLE_LATEINIT_MODIFIER.cast(diagnostic).psiElement
|
||||
val property = PsiTreeUtil.getParentOfType(element, KtProperty::class.java) ?: return null
|
||||
val property = Errors.INAPPLICABLE_LATEINIT_MODIFIER.cast(diagnostic).psiElement as? KtProperty ?: return null
|
||||
val hasInitializer = property.hasInitializer()
|
||||
val hasGetter = property.getter?.bodyExpression != null
|
||||
val hasSetter = property.setter?.bodyExpression != null
|
||||
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
// FIR_COMPARISON
|
||||
|
||||
class C<V>() {
|
||||
<error descr="[INAPPLICABLE_LATEINIT_MODIFIER] 'lateinit' modifier is not allowed on properties of a type with nullable upper bound">lateinit</error> var item: V
|
||||
}
|
||||
+2
-1
@@ -2,4 +2,5 @@
|
||||
|
||||
class A() {
|
||||
<caret>lateinit val foo: String
|
||||
}
|
||||
}
|
||||
/* FIR_COMPARISON */
|
||||
+2
-1
@@ -2,4 +2,5 @@
|
||||
|
||||
class A() {
|
||||
<caret>lateinit var foo: String
|
||||
}
|
||||
}
|
||||
/* FIR_COMPARISON */
|
||||
Reference in New Issue
Block a user