Refactored RemoveModifierFix + some psi API refactoring
#EA-69237 Fixed
This commit is contained in:
@@ -20,10 +20,6 @@ make.class.annotation.class.family=Make Class an Annotation Class
|
||||
add.star.projections=Add ''{0}''
|
||||
change.to.star.projection=Change type arguments to {0}
|
||||
change.to.star.projection.family=Change to Star Projection
|
||||
make.element.not.modifier=Make {0} not {1}
|
||||
remove.modifier=Remove ''{0}'' modifier
|
||||
remove.modifier.family=Remove Modifier
|
||||
remove.redundant.modifier=Remove redundant ''{0}'' modifier
|
||||
remove.parts.from.property=Remove {0} from property
|
||||
remove.parts.from.property.family=Remove Parts from Property
|
||||
remove.psi.element.family=Remove Element
|
||||
|
||||
@@ -16,16 +16,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.quickfix
|
||||
|
||||
import com.intellij.extapi.psi.ASTDelegatePsiElement
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.JetBundle
|
||||
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil
|
||||
import org.jetbrains.kotlin.lexer.JetKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.JetFile
|
||||
import org.jetbrains.kotlin.psi.JetModifierListOwner
|
||||
import org.jetbrains.kotlin.psi.JetTypeParameter
|
||||
import org.jetbrains.kotlin.psi.JetTypeProjection
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
public class RemoveModifierFix(
|
||||
@@ -34,53 +36,37 @@ public class RemoveModifierFix(
|
||||
private val isRedundant: Boolean
|
||||
) : JetIntentionAction<JetModifierListOwner>(element) {
|
||||
|
||||
override fun getFamilyName() = JetBundle.message("remove.modifier.family")
|
||||
private val text = run {
|
||||
val modifierText = modifier.value
|
||||
when {
|
||||
isRedundant ->
|
||||
"Remove redundant '$modifierText' modifier"
|
||||
modifier === JetTokens.ABSTRACT_KEYWORD || modifier === JetTokens.OPEN_KEYWORD ->
|
||||
"Make ${AddModifierFix.getElementName(element)} not $modifierText"
|
||||
else ->
|
||||
"Remove '$modifierText' modifier"
|
||||
}
|
||||
}
|
||||
|
||||
override fun getText() = makeText(element, modifier, isRedundant)
|
||||
override fun getFamilyName() = "Remove modifier"
|
||||
|
||||
override fun getText() = text
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile)
|
||||
= super.isAvailable(project, editor, file) && element.hasModifier(modifier)
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: JetFile) {
|
||||
invoke()
|
||||
}
|
||||
|
||||
public fun invoke() {
|
||||
//TODO: without this copy&replace we get bad formatting on removing last modifier
|
||||
val newElement = element.copy() as JetModifierListOwner
|
||||
element.replace(removeModifier(newElement, modifier))
|
||||
newElement.removeModifier(modifier)
|
||||
element.replace(newElement)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun makeText(element: JetModifierListOwner?, modifier: JetKeywordToken, isRedundant: Boolean): String {
|
||||
if (isRedundant) {
|
||||
return JetBundle.message("remove.redundant.modifier", modifier.value)
|
||||
}
|
||||
if (element != null && (modifier === JetTokens.ABSTRACT_KEYWORD || modifier === JetTokens.OPEN_KEYWORD)) {
|
||||
return JetBundle.message("make.element.not.modifier", AddModifierFix.getElementName(element), modifier.value)
|
||||
}
|
||||
return JetBundle.message("remove.modifier", modifier.value)
|
||||
}
|
||||
|
||||
private fun <T : JetModifierListOwner> removeModifier(element: T, modifier: JetModifierKeywordToken): T {
|
||||
val modifierList = element.modifierList!!
|
||||
removeModifierFromList(modifierList, modifier)
|
||||
if (modifierList.firstChild == null) {
|
||||
val whiteSpace = modifierList.nextSibling
|
||||
assert(element is ASTDelegatePsiElement)
|
||||
(element as ASTDelegatePsiElement).deleteChildInternal(modifierList.node)
|
||||
QuickFixUtil.removePossiblyWhiteSpace(element, whiteSpace)
|
||||
}
|
||||
return element
|
||||
}
|
||||
|
||||
private fun removeModifierFromList(modifierList: JetModifierList, modifier: JetModifierKeywordToken): JetModifierList {
|
||||
val modifierNode = modifierList.getModifierNode(modifier)!!
|
||||
val whiteSpace = modifierNode.psi.nextSibling
|
||||
val wsRemoved = QuickFixUtil.removePossiblyWhiteSpace(modifierList, whiteSpace)
|
||||
modifierList.deleteChildInternal(modifierNode)
|
||||
if (!wsRemoved) {
|
||||
QuickFixUtil.removePossiblyWhiteSpace(modifierList, modifierList.lastChild)
|
||||
}
|
||||
return modifierList
|
||||
}
|
||||
|
||||
public fun createRemoveModifierFromListOwnerFactory(modifier: JetModifierKeywordToken, isRedundant: Boolean = false): JetSingleIntentionActionFactory {
|
||||
return object : JetSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): JetIntentionAction<JetModifierListOwner>? {
|
||||
@@ -93,10 +79,9 @@ public class RemoveModifierFix(
|
||||
public fun createRemoveModifierFactory(isRedundant: Boolean = false): JetSingleIntentionActionFactory {
|
||||
return object : JetSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): JetIntentionAction<JetModifierListOwner>? {
|
||||
val modifierListOwner = QuickFixUtil.getParentElementOfType(diagnostic, javaClass<JetModifierListOwner>()) ?: return null
|
||||
val psiElement = diagnostic.psiElement
|
||||
val elementType = psiElement.node.elementType
|
||||
if (elementType !is JetModifierKeywordToken) return null
|
||||
val elementType = psiElement.node.elementType as? JetModifierKeywordToken ?: return null
|
||||
val modifierListOwner = psiElement.getStrictParentOfType<JetModifierListOwner>() ?: return null
|
||||
return RemoveModifierFix(modifierListOwner, elementType, isRedundant)
|
||||
}
|
||||
}
|
||||
@@ -105,10 +90,8 @@ public class RemoveModifierFix(
|
||||
public fun createRemoveProjectionFactory(isRedundant: Boolean): JetSingleIntentionActionFactory {
|
||||
return object : JetSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): JetIntentionAction<JetModifierListOwner>? {
|
||||
val projection = QuickFixUtil.getParentElementOfType(diagnostic, javaClass<JetTypeProjection>()) ?: return null
|
||||
val projectionAstNode = projection.projectionNode ?: return null
|
||||
val elementType = projectionAstNode.elementType
|
||||
if (elementType !is JetModifierKeywordToken) return null
|
||||
val projection = diagnostic.psiElement as JetTypeProjection
|
||||
val elementType = projection.projectionToken?.node?.elementType as? JetModifierKeywordToken ?: return null
|
||||
return RemoveModifierFix(projection, elementType, isRedundant)
|
||||
}
|
||||
}
|
||||
@@ -117,17 +100,13 @@ public class RemoveModifierFix(
|
||||
public fun createRemoveVarianceFactory(): JetSingleIntentionActionFactory {
|
||||
return object : JetSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): JetIntentionAction<JetModifierListOwner>? {
|
||||
val modifierListOwner = QuickFixUtil.getParentElementOfType(diagnostic, javaClass<JetModifierListOwner>()) ?: return null
|
||||
val psiElement = diagnostic.psiElement
|
||||
if (psiElement !is JetTypeParameter) return null
|
||||
val variance = psiElement.variance
|
||||
val modifier: JetModifierKeywordToken
|
||||
when (variance) {
|
||||
Variance.IN_VARIANCE -> modifier = JetTokens.IN_KEYWORD
|
||||
Variance.OUT_VARIANCE -> modifier = JetTokens.OUT_KEYWORD
|
||||
val psiElement = diagnostic.psiElement as JetTypeParameter
|
||||
val modifier = when (psiElement.variance) {
|
||||
Variance.IN_VARIANCE -> JetTokens.IN_KEYWORD
|
||||
Variance.OUT_VARIANCE -> JetTokens.OUT_KEYWORD
|
||||
else -> return null
|
||||
}
|
||||
return RemoveModifierFix(modifierListOwner, modifier, false)
|
||||
return RemoveModifierFix(psiElement, modifier, isRedundant = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user