182: KotlinElementActionsFactory.createAddFieldActions no more generates private @JvmField and lateinit @JvmField

This commit is contained in:
Nicolay Mitropolsky
2018-04-18 15:24:52 +03:00
parent 789a6f9c63
commit 0aa236d1ac
2 changed files with 105 additions and 18 deletions
@@ -151,7 +151,7 @@ class KotlinElementActionsFactory : JvmElementActionsFactory() {
val info = callableInfos.first() as PropertyInfo val info = callableInfos.first() as PropertyInfo
return buildString { return buildString {
append("Add '") append("Add '")
if (info.isLateinitPreferred) { if (info.isLateinitPreferred || info.modifierList?.hasModifier(KtTokens.LATEINIT_KEYWORD) == true) {
append("lateinit ") append("lateinit ")
} }
append(if (info.writable) "var" else "val") append(if (info.writable) "var" else "val")
@@ -349,30 +349,35 @@ class KotlinElementActionsFactory : JvmElementActionsFactory() {
override fun createAddFieldActions(targetClass: JvmClass, request: CreateFieldRequest): List<IntentionAction> { override fun createAddFieldActions(targetClass: JvmClass, request: CreateFieldRequest): List<IntentionAction> {
val targetContainer = targetClass.toKtClassOrFile() ?: return emptyList() val targetContainer = targetClass.toKtClassOrFile() ?: return emptyList()
val modifierBuilder = ModifierBuilder(targetContainer, allowJvmStatic = false).apply {
addJvmModifiers(request.modifiers)
addAnnotation(JVM_FIELD_ANNOTATION_FQ_NAME)
}
if (!modifierBuilder.isValid) return emptyList()
val resolutionFacade = targetContainer.getResolutionFacade() val resolutionFacade = targetContainer.getResolutionFacade()
val typeInfo = request.fieldType.toKotlinTypeInfo(resolutionFacade) val typeInfo = request.fieldType.toKotlinTypeInfo(resolutionFacade)
val writable = JvmModifier.FINAL !in request.modifiers val writable = JvmModifier.FINAL !in request.modifiers
val propertyInfo = PropertyInfo(
request.fieldName, fun propertyInfo(lateinit: Boolean) = PropertyInfo(
TypeInfo.Empty, request.fieldName,
typeInfo, TypeInfo.Empty,
writable, typeInfo,
listOf(targetContainer), writable,
isForCompanion = JvmModifier.STATIC in request.modifiers, listOf(targetContainer),
modifierList = modifierBuilder.modifierList, isLateinitPreferred = false, // Dont set it to `lateinit` because it works via templates that brings issues in batch field adding
withInitializer = true isForCompanion = JvmModifier.STATIC in request.modifiers,
modifierList = ModifierBuilder(targetContainer, allowJvmStatic = false).apply {
addJvmModifiers(request.modifiers)
if (modifierList.children.none { it.node.elementType in KtTokens.VISIBILITY_MODIFIERS })
addJvmModifier(JvmModifier.PUBLIC)
if (lateinit)
modifierList.appendModifier(KtTokens.LATEINIT_KEYWORD)
if (!request.modifiers.contains(JvmModifier.PRIVATE) && !lateinit)
addAnnotation(JVM_FIELD_ANNOTATION_FQ_NAME)
}.modifierList,
withInitializer = !lateinit
) )
val propertyInfos = if (writable) { val propertyInfos = if (writable) {
listOf(propertyInfo, propertyInfo.copyProperty(isLateinitPreferred = true)) listOf(propertyInfo(false), propertyInfo(true))
} }
else { else {
listOf(propertyInfo) listOf(propertyInfo(false))
} }
return propertyInfos.map { CreatePropertyFix(targetClass, targetContainer, it) } return propertyInfos.map { CreatePropertyFix(targetClass, targetContainer, it) }
} }
@@ -403,9 +403,68 @@ class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() {
""".trim().trimMargin(), true) """.trim().trimMargin(), true)
} }
fun testAddStringVarField() {
myFixture.configureByText(
"foo.kt", """
|class Foo<caret> {
| fun bar() {}
|}
""".trim().trimMargin()
)
myFixture.launchAction(
createFieldActions(
myFixture.atCaret(),
FieldRequest(project, emptyList(), "java.util.Date", "baz")
).findWithText("Add 'var' property 'baz' to 'Foo'")
)
myFixture.checkResult(
"""
|import java.util.Date
|
|class Foo {
| @JvmField
| var baz: Date = TODO("initialize me")
|
| fun bar() {}
|}
""".trim().trimMargin(), true
)
}
fun testAddLateInitStringVarField() {
myFixture.configureByText(
"foo.kt", """
|class Foo<caret> {
| fun bar() {}
|}
""".trim().trimMargin()
)
myFixture.launchAction(
createFieldActions(
myFixture.atCaret(),
FieldRequest(project, listOf(JvmModifier.PRIVATE), "java.lang.String", "baz")
).findWithText("Add 'lateinit var' property 'baz' to 'Foo'")
)
myFixture.checkResult(
"""
|class Foo {
| private lateinit var baz: String
|
| fun bar() {}
|}
""".trim().trimMargin(), true
)
}
private fun createPropertyActions(atCaret: JvmClass, property: MemberRequest.Property): List<IntentionAction> = private fun createPropertyActions(atCaret: JvmClass, property: MemberRequest.Property): List<IntentionAction> =
com.intellij.lang.jvm.actions.EP_NAME.extensions.flatMap { it.createAddPropertyActions(atCaret, property) } com.intellij.lang.jvm.actions.EP_NAME.extensions.flatMap { it.createAddPropertyActions(atCaret, property) }
private fun createFieldActions(atCaret: JvmClass, fieldRequest: CreateFieldRequest): List<IntentionAction> =
com.intellij.lang.jvm.actions.EP_NAME.extensions.flatMap { it.createAddFieldActions(atCaret, fieldRequest) }
fun testAddStringValProperty() { fun testAddStringValProperty() {
myFixture.configureByText("foo.kt", """ myFixture.configureByText("foo.kt", """
|class Foo<caret> { |class Foo<caret> {
@@ -452,5 +511,28 @@ class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() {
private fun List<IntentionAction>.findWithText(text: String): IntentionAction = private fun List<IntentionAction>.findWithText(text: String): IntentionAction =
this.firstOrNull { it.text == text } ?: this.firstOrNull { it.text == text } ?:
Assert.fail("intention with text '$text' was not found, only ${this.joinToString { "\"${it.text}\"" }} available") as Nothing Assert.fail("intention with text '$text' was not found, only ${this.joinToString { "\"${it.text}\"" }} available") as Nothing
class FieldRequest(
private val project: Project,
val modifiers: List<JvmModifier>,
val type: String,
val name: String
) : CreateFieldRequest {
override fun getTargetSubstitutor(): JvmSubstitutor = PsiJvmSubstitutor(project, PsiSubstitutor.EMPTY)
override fun getModifiers(): Collection<JvmModifier> = modifiers
override fun isConstant(): Boolean = false
override fun getFieldType(): List<ExpectedType> =
com.intellij.lang.jvm.actions.expectedTypes(PsiType.getTypeByName(type, project, project.allScope()))
override fun getFieldName(): String = name
override fun isValid(): Boolean = true
}
} }