KT-19126 Add convert property initializer to getter in interfaces (#1224)

This commit is contained in:
Andrius Semionovas
2017-08-07 12:53:37 +03:00
committed by Dmitry Jemerov
parent 2536615e0e
commit 666c241479
12 changed files with 122 additions and 2 deletions
@@ -261,6 +261,15 @@ class KtPsiFactory @JvmOverloads constructor(private val project: Project, val m
return getter
}
fun createPropertySetter(expression: KtExpression): KtPropertyAccessor {
val property = createProperty("val x get() = 1\nset(value) = TODO()")
val setter = property.setter!!
val bodyExpression = setter.bodyExpression!!
bodyExpression.replace(expression)
return setter
}
fun createDestructuringDeclaration(text: String): KtDestructuringDeclaration {
return (createFunction("fun foo() {$text}").bodyExpression as KtBlockExpression).statements.first() as KtDestructuringDeclaration
}
@@ -16,9 +16,12 @@
package org.jetbrains.kotlin.idea.intentions
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtPsiFactory
@@ -43,7 +46,11 @@ class ConvertPropertyInitializerToGetterIntention : SelfTargetingRangeIntention<
convertPropertyInitializerToGetter(element, editor)
}
companion object {
companion object : KotlinSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
return ConvertPropertyInitializerToGetterIntention()
}
fun convertPropertyInitializerToGetter(property: KtProperty, editor: Editor?) {
val type = SpecifyTypeExplicitlyIntention.getTypeForDeclaration(property)
SpecifyTypeExplicitlyIntention.addTypeAnnotation(editor, property, type)
@@ -55,6 +62,12 @@ class ConvertPropertyInitializerToGetterIntention : SelfTargetingRangeIntention<
if (setter != null) {
property.addBefore(getter, setter)
}
else if (property.isVar) {
property.add(getter)
val notImplemented = KtPsiFactory(property).createExpression("TODO()")
val notImplementedSetter = KtPsiFactory(property).createPropertySetter(notImplemented)
property.add(notImplementedSetter)
}
else {
property.add(getter)
}
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementAsConstructorPa
import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler
import org.jetbrains.kotlin.idea.inspections.*
import org.jetbrains.kotlin.idea.intentions.AddValVarToConstructorParameterAction
import org.jetbrains.kotlin.idea.intentions.ConvertPropertyInitializerToGetterIntention
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.*
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClassFromCallWithConstructorCalleeActionFactory
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClassFromConstructorCallActionFactory
@@ -69,7 +70,7 @@ class QuickFixRegistrar : QuickFixContributor {
ABSTRACT_PROPERTY_WITH_GETTER.registerFactory(removeAbstractModifierFactory, removePartsFromPropertyFactory)
ABSTRACT_PROPERTY_WITH_SETTER.registerFactory(removeAbstractModifierFactory, removePartsFromPropertyFactory)
PROPERTY_INITIALIZER_IN_INTERFACE.registerFactory(removePartsFromPropertyFactory)
PROPERTY_INITIALIZER_IN_INTERFACE.registerFactory(removePartsFromPropertyFactory, ConvertPropertyInitializerToGetterIntention)
MUST_BE_INITIALIZED_OR_BE_ABSTRACT.registerFactory(addAbstractModifierFactory)
ABSTRACT_MEMBER_NOT_IMPLEMENTED.registerFactory(addAbstractModifierFactory)
@@ -0,0 +1,7 @@
// "Convert property initializer to getter" "true"
fun String.foo() = "bar"
interface A {
val name = <caret>"The quick brown fox jumps over the lazy dog".foo()
}
@@ -0,0 +1,8 @@
// "Convert property initializer to getter" "true"
fun String.foo() = "bar"
interface A {
val name: String
get() = "The quick brown fox jumps over the lazy dog".foo()
}
@@ -0,0 +1,8 @@
// "Convert property initializer to getter" "true"
// WITH_RUNTIME
fun String.foo() = "bar"
interface A {
var name = <caret>"The quick brown fox jumps over the lazy dog".foo()
}
@@ -0,0 +1,10 @@
// "Convert property initializer to getter" "true"
// WITH_RUNTIME
fun String.foo() = "bar"
interface A {
var name: String
get() = "The quick brown fox jumps over the lazy dog".foo()
set(value) = TODO()
}
@@ -0,0 +1,11 @@
// "Convert property initializer to getter" "true"
fun String.foo() = "bar"
fun nop() {
}
interface A {
var name = <caret>"The quick brown fox jumps over the lazy dog".foo()
set(value) = nop()
}
@@ -0,0 +1,12 @@
// "Convert property initializer to getter" "true"
fun String.foo() = "bar"
fun nop() {
}
interface A {
var name: String
get() = "The quick brown fox jumps over the lazy dog".foo()
set(value) = nop()
}
@@ -0,0 +1,3 @@
// "Convert extension property initializer to getter" "true"
// WITH_RUNTIME
var String.foo: Int = 0<caret>
@@ -0,0 +1,5 @@
// "Convert extension property initializer to getter" "true"
// WITH_RUNTIME
var String.foo: Int
get() = 0
set(value) = TODO()
@@ -1422,6 +1422,33 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
}
}
@TestMetadata("idea/testData/quickfix/convertPropertyInitializerToGetter")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class ConvertPropertyInitializerToGetter extends AbstractQuickFixTest {
public void testAllFilesPresentInConvertPropertyInitializerToGetter() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/convertPropertyInitializerToGetter"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("val.kt")
public void testVal() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/convertPropertyInitializerToGetter/val.kt");
doTest(fileName);
}
@TestMetadata("var.kt")
public void testVar() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/convertPropertyInitializerToGetter/var.kt");
doTest(fileName);
}
@TestMetadata("varWithSetter.kt")
public void testVarWithSetter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/convertPropertyInitializerToGetter/varWithSetter.kt");
doTest(fileName);
}
}
@TestMetadata("idea/testData/quickfix/createFromUsage")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -8287,6 +8314,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
doTest(fileName);
}
@TestMetadata("baseCaseVar.kt")
public void testBaseCaseVar() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/properties/extensionPropertyInitializerToGetter/baseCaseVar.kt");
doTest(fileName);
}
@TestMetadata("baseCaseWithoutTypeAnnotation.kt")
public void testBaseCaseWithoutTypeAnnotation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/properties/extensionPropertyInitializerToGetter/baseCaseWithoutTypeAnnotation.kt");