Add quick fix for INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER

#KT-34533 Fixed
This commit is contained in:
Toshiaki Kameyama
2019-10-22 23:31:21 +09:00
committed by Yan Zhulanow
parent 9f192ba85e
commit 75e8849c94
13 changed files with 79 additions and 5 deletions
@@ -34,6 +34,7 @@ open class KtClass : KtClassOrObject {
fun isData(): Boolean = hasModifier(KtTokens.DATA_KEYWORD)
fun isSealed(): Boolean = hasModifier(KtTokens.SEALED_KEYWORD)
fun isInner(): Boolean = hasModifier(KtTokens.INNER_KEYWORD)
fun isInline(): Boolean = hasModifier(KtTokens.INLINE_KEYWORD)
override fun getCompanionObjects(): List<KtObjectDeclaration> = body?.allCompanionObjects.orEmpty()
@@ -1583,6 +1583,7 @@ looking.for.usages.in.java.files=Looking for usages in Java files...
add.return.at.0=Add return@{0}
add.0.to.argument=Add ''{0} ='' to argument
add.val.var.to.parameter.0=Add val/var to parameter ''{0}''
add.val.to.parameter.0=Add val to parameter ''{0}''
add.val.var.to.primary.constructor.parameter=Add val/var to primary constructor parameter
make.primary.constructor.0=Make primary constructor {0}
change.visibility.modifier=Change visibility modifier
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.idea.refactoring.ValVarExpression
import org.jetbrains.kotlin.idea.util.isExpectDeclaration
import org.jetbrains.kotlin.idea.util.mustHaveValOrVar
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClass
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.startOffset
@@ -33,7 +34,7 @@ interface AddValVarToConstructorParameterAction {
element.addBefore(KtPsiFactory(project).createValKeyword(), element.nameIdentifier)
if (editor == null) return
if (element.containingClass()?.isInline() == true || editor == null) return
val parameter = element.createSmartPointer().let {
PsiDocumentManager.getInstance(project).commitAllDocuments()
@@ -55,7 +56,8 @@ interface AddValVarToConstructorParameterAction {
), AddValVarToConstructorParameterAction {
override fun applicabilityRange(element: KtParameter): TextRange? {
if (!canInvoke(element)) return null
if (element.getStrictParentOfType<KtClass>()?.isData() == true) return null
val containingClass = element.getStrictParentOfType<KtClass>()
if (containingClass?.isData() == true || containingClass?.isInline() == true) return null
setTextGetter(KotlinBundle.lazyMessage("add.val.var.to.parameter.0", element.name ?: ""))
return element.nameIdentifier?.textRange
}
@@ -66,7 +68,11 @@ interface AddValVarToConstructorParameterAction {
class QuickFix(parameter: KtParameter) :
KotlinQuickFixAction<KtParameter>(parameter),
AddValVarToConstructorParameterAction {
override fun getText() = element?.let { KotlinBundle.message("add.val.var.to.parameter.0", it.name ?: "") } ?: ""
override fun getText() = element?.let {
val key =
if (it.getStrictParentOfType<KtClass>()?.isInline() == true) "add.val.to.parameter.0" else "add.val.var.to.parameter.0"
KotlinBundle.message(key, it.name ?: "")
} ?: ""
override fun getFamilyName() = KotlinBundle.message("add.val.var.to.primary.constructor.parameter")
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.quickfix
import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.idea.intentions.AddValVarToConstructorParameterAction
object InlineClassConstructorNotValParameterFactory : KotlinSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
val parameter = Errors.INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER.cast(diagnostic).psiElement
return if (parameter.isMutable)
ChangeVariableMutabilityFix(parameter, false)
else
AddValVarToConstructorParameterAction.QuickFix(parameter)
}
}
@@ -658,5 +658,7 @@ class QuickFixRegistrar : QuickFixContributor {
MISSING_EXCEPTION_IN_THROWS_ON_SUSPEND.registerFactory(AddExceptionToThrowsFix)
THROWS_LIST_EMPTY.registerFactory(RemoveAnnotationFix)
INCOMPATIBLE_THROWS_OVERRIDE.registerFactory(RemoveAnnotationFix)
INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER.registerFactory(InlineClassConstructorNotValParameterFactory)
}
}
@@ -1,2 +1,3 @@
// IS_APPLICABLE: false
// DISABLE-ERRORS
expect inline class A(<caret>a: Int)
@@ -1,2 +0,0 @@
// DISABLE-ERRORS
expect inline class A(val a: Int)
@@ -0,0 +1,2 @@
// "Add val to parameter 'x'" "true"
inline class Foo(<caret>x: Int)
@@ -0,0 +1,2 @@
// "Add val to parameter 'x'" "true"
inline class Foo(val x: Int)
@@ -0,0 +1,2 @@
// "Change to val" "true"
inline class Foo(<caret>var x: Int)
@@ -0,0 +1,2 @@
// "Change to val" "true"
inline class Foo(val x: Int)
@@ -3048,6 +3048,19 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
}
}
@TestMetadata("idea/testData/quickfix/inlineClassConstructorNotValParameter")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class InlineClassConstructorNotValParameter extends AbstractQuickFixMultiFileTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTestWithExtraFile, this, testDataFilePath);
}
public void testAllFilesPresentInInlineClassConstructorNotValParameter() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/inlineClassConstructorNotValParameter"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), null, true);
}
}
@TestMetadata("idea/testData/quickfix/inlineTypeParameterFix")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -8503,6 +8503,29 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
}
}
@TestMetadata("idea/testData/quickfix/inlineClassConstructorNotValParameter")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class InlineClassConstructorNotValParameter extends AbstractQuickFixTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInInlineClassConstructorNotValParameter() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/inlineClassConstructorNotValParameter"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), null, true);
}
@TestMetadata("basic.kt")
public void testBasic() throws Exception {
runTest("idea/testData/quickfix/inlineClassConstructorNotValParameter/basic.kt");
}
@TestMetadata("var.kt")
public void testVar() throws Exception {
runTest("idea/testData/quickfix/inlineClassConstructorNotValParameter/var.kt");
}
}
@TestMetadata("idea/testData/quickfix/inlineTypeParameterFix")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)