mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[mod-commands] IDEA-333040 Convert CompositeIntentionQuickFix to ModCommand
GitOrigin-RevId: 67fd2853544b99e94e442566d29d874990292d9f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c86d97746e
commit
83ad94ff1f
@@ -6,8 +6,21 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface ChangeModifierRequest extends ActionRequest {
|
||||
|
||||
/**
|
||||
* @return the modifier which should be changed
|
||||
*/
|
||||
@NotNull
|
||||
JvmModifier getModifier();
|
||||
|
||||
/**
|
||||
* @return true if the modifier should be added, false if it should be removed
|
||||
*/
|
||||
boolean shouldBePresent();
|
||||
|
||||
/**
|
||||
* @return true if it's desired to process hierarchy when applicable (e.g., update overriding methods correspondingly)
|
||||
*/
|
||||
default boolean processHierarchy() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@ package com.intellij.lang.jvm.actions
|
||||
|
||||
import com.intellij.lang.jvm.JvmModifier
|
||||
|
||||
fun modifierRequest(modifier: JvmModifier, shouldBePresent: Boolean): ChangeModifierRequest = object : ChangeModifierRequest {
|
||||
@JvmOverloads
|
||||
fun modifierRequest(modifier: JvmModifier, shouldBePresent: Boolean, processHierarchy: Boolean = true): ChangeModifierRequest = object : ChangeModifierRequest {
|
||||
override fun isValid(): Boolean = true
|
||||
override fun getModifier(): JvmModifier = modifier
|
||||
override fun shouldBePresent(): Boolean = shouldBePresent
|
||||
override fun processHierarchy(): Boolean = processHierarchy
|
||||
}
|
||||
@@ -37,6 +37,7 @@ public class ModifierFix extends LocalQuickFixAndIntentionActionOnPsiElement imp
|
||||
@PsiModifier.ModifierConstant private final String myModifier;
|
||||
private final boolean myShouldHave;
|
||||
private final boolean myShowContainingClass;
|
||||
private final boolean myProcessHierarchy;
|
||||
private volatile @IntentionName String myName;
|
||||
private final boolean myStartInWriteAction;
|
||||
|
||||
@@ -49,6 +50,7 @@ public class ModifierFix extends LocalQuickFixAndIntentionActionOnPsiElement imp
|
||||
myShouldHave = shouldHave;
|
||||
myShowContainingClass = showContainingClass;
|
||||
myName = format(null, modifierList, myShowContainingClass);
|
||||
myProcessHierarchy = true;
|
||||
myStartInWriteAction = !(modifierList.getParent() instanceof PsiMethod) || AccessModifier.fromPsiModifier(modifier) == null;
|
||||
}
|
||||
|
||||
@@ -56,13 +58,21 @@ public class ModifierFix extends LocalQuickFixAndIntentionActionOnPsiElement imp
|
||||
@PsiModifier.ModifierConstant @NotNull String modifier,
|
||||
boolean shouldHave,
|
||||
boolean showContainingClass) {
|
||||
this(owner, modifier, shouldHave, showContainingClass, true);
|
||||
}
|
||||
|
||||
public ModifierFix(@NotNull PsiModifierListOwner owner,
|
||||
@PsiModifier.ModifierConstant @NotNull String modifier,
|
||||
boolean shouldHave,
|
||||
boolean showContainingClass, boolean processHierarchy) {
|
||||
super(owner);
|
||||
myModifier = modifier;
|
||||
myShouldHave = shouldHave;
|
||||
myShowContainingClass = showContainingClass;
|
||||
myProcessHierarchy = processHierarchy;
|
||||
PsiVariable variable = owner instanceof PsiVariable ? (PsiVariable)owner : null;
|
||||
myName = format(variable, owner.getModifierList(), myShowContainingClass);
|
||||
myStartInWriteAction = !(owner instanceof PsiMethod) || AccessModifier.fromPsiModifier(modifier) == null;
|
||||
myStartInWriteAction = !myProcessHierarchy || !(owner instanceof PsiMethod) || AccessModifier.fromPsiModifier(modifier) == null;
|
||||
}
|
||||
|
||||
private @IntentionName @NotNull String format(PsiVariable variable, PsiModifierList modifierList, boolean showContainingClass) {
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ class JavaElementActionsFactory : JvmElementActionsFactory() {
|
||||
|
||||
internal class ChangeModifierFix(declaration: PsiModifierListOwner,
|
||||
@FileModifier.SafeFieldForPreview val request: ChangeModifierRequest) :
|
||||
ModifierFix(declaration, request.modifier.toPsiModifier(), request.shouldBePresent(), true) {
|
||||
ModifierFix(declaration, request.modifier.toPsiModifier(), request.shouldBePresent(), true, request.processHierarchy()) {
|
||||
override fun isAvailable(): Boolean = request.isValid && super.isAvailable()
|
||||
|
||||
override fun isAvailable(project: Project,
|
||||
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInspection.fix
|
||||
|
||||
import com.intellij.codeInsight.FileModificationService
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewUtils
|
||||
import com.intellij.codeInspection.LocalQuickFix
|
||||
import com.intellij.codeInspection.ProblemDescriptor
|
||||
import com.intellij.codeInspection.nonPreviewElement
|
||||
import com.intellij.lang.jvm.JvmModifiersOwner
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.SmartPointerManager
|
||||
import com.intellij.util.asSafely
|
||||
|
||||
/**
|
||||
* A quickfix that can call multiple JVM intention actions and bundle them into a single quick fix.
|
||||
*/
|
||||
abstract class CompositeIntentionQuickFix : LocalQuickFix {
|
||||
override fun startInWriteAction(): Boolean = false
|
||||
|
||||
protected fun generatePreviews(project: Project, previewDescriptor: ProblemDescriptor, element: PsiElement): IntentionPreviewInfo {
|
||||
val containingFile = previewDescriptor.startElement.containingFile ?: return IntentionPreviewInfo.EMPTY
|
||||
val editor = IntentionPreviewUtils.getPreviewEditor() ?: return IntentionPreviewInfo.EMPTY
|
||||
val target = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(element)
|
||||
getActions(project, previewDescriptor).forEach { factory ->
|
||||
val actions = factory(target.element?.nonPreviewElement ?: return@forEach)
|
||||
actions.forEach { action ->
|
||||
action.generatePreview(project, editor, containingFile)
|
||||
}
|
||||
}
|
||||
return IntentionPreviewInfo.DIFF
|
||||
}
|
||||
|
||||
protected fun applyFixes(project: Project, descriptor: ProblemDescriptor, element: PsiElement) {
|
||||
val containingFile = descriptor.psiElement.containingFile ?: return
|
||||
val target = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(element)
|
||||
if (!FileModificationService.getInstance().prepareFileForWrite(element.containingFile)) return
|
||||
getActions(project, descriptor).forEach { factory ->
|
||||
val actions = factory(target.element.asSafely<JvmModifiersOwner>() ?: return@forEach)
|
||||
actions.forEach { action ->
|
||||
if (action.startInWriteAction()) {
|
||||
runWriteAction { action.invoke(project, null, containingFile) }
|
||||
} else {
|
||||
action.invoke(project, null, containingFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun getActions(project: Project, descriptor: ProblemDescriptor): List<(JvmModifiersOwner) -> List<IntentionAction>>
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInspection.fix
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.lang.jvm.JvmModifiersOwner
|
||||
import com.intellij.modcommand.PsiUpdateModCommandQuickFix
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.SmartPointerManager
|
||||
import com.intellij.util.asSafely
|
||||
|
||||
/**
|
||||
* A quickfix that can call multiple JVM intention actions and bundle them into a single quick fix.
|
||||
* It's assumed that all the JVM intention actions are well-behaving: they only modify the single PSI file
|
||||
* and don't do anything else like starting template.
|
||||
*/
|
||||
abstract class CompositeModCommandQuickFix : PsiUpdateModCommandQuickFix() {
|
||||
protected fun applyFixes(project: Project, element: PsiElement, containingFile: PsiFile) {
|
||||
val target = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(element)
|
||||
getActions(project).forEach { factory ->
|
||||
val actions = factory(target.element.asSafely<JvmModifiersOwner>() ?: return@forEach)
|
||||
actions.forEach { action ->
|
||||
action.invoke(project, null, containingFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun getActions(project: Project): List<(JvmModifiersOwner) -> List<IntentionAction>>
|
||||
}
|
||||
+26
-39
@@ -8,10 +8,9 @@ import com.intellij.codeInsight.MetaAnnotationUtil
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil
|
||||
import com.intellij.codeInsight.intention.FileModifier.SafeFieldForPreview
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
|
||||
import com.intellij.codeInsight.options.JavaClassValidator
|
||||
import com.intellij.codeInspection.*
|
||||
import com.intellij.codeInspection.fix.CompositeIntentionQuickFix
|
||||
import com.intellij.codeInspection.fix.CompositeModCommandQuickFix
|
||||
import com.intellij.codeInspection.options.OptPane
|
||||
import com.intellij.codeInspection.options.OptPane.pane
|
||||
import com.intellij.codeInspection.options.OptPane.stringList
|
||||
@@ -24,6 +23,7 @@ import com.intellij.lang.jvm.JvmModifiersOwner
|
||||
import com.intellij.lang.jvm.actions.*
|
||||
import com.intellij.lang.jvm.types.JvmPrimitiveTypeKind
|
||||
import com.intellij.lang.jvm.types.JvmType
|
||||
import com.intellij.modcommand.ModPsiUpdater
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
@@ -333,8 +333,8 @@ private class JUnitMalformedSignatureVisitor(
|
||||
) {
|
||||
override fun getName(): String = JvmAnalysisBundle.message("jvm.inspections.junit.malformed.fix.class.signature.multi")
|
||||
|
||||
override fun getActions(project: Project, descriptor: ProblemDescriptor): List<(JvmModifiersOwner) -> List<IntentionAction>> {
|
||||
val list = super.getActions(project, descriptor).toMutableList()
|
||||
override fun getActions(project: Project): List<(JvmModifiersOwner) -> List<IntentionAction>> {
|
||||
val list = super.getActions(project).toMutableList()
|
||||
list.add { owner ->
|
||||
val outerClass = owner.sourceElement?.toUElementOfType<UClass>()?.nestedClassHierarchy()?.last()!!
|
||||
val request = annotationRequest(ORG_JUNIT_RUNNER_RUN_WITH, classAttribute("value", ORG_JUNIT_EXPERIMENTAL_RUNNERS_ENCLOSED))
|
||||
@@ -345,9 +345,10 @@ private class JUnitMalformedSignatureVisitor(
|
||||
|
||||
override fun getFamilyName(): String = JvmAnalysisBundle.message("jvm.inspections.junit.malformed.fix.class.signature.multi")
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val uClass = getUParentForIdentifier(descriptor.psiElement)?.asSafely<UClass>() ?: return
|
||||
applyFixes(project, descriptor, uClass.javaPsi.asSafely<PsiClass>() ?: return)
|
||||
override fun applyFix(project: Project, element: PsiElement, updater: ModPsiUpdater) {
|
||||
val uClass = getUParentForIdentifier(element)?.asSafely<UClass>() ?: return
|
||||
applyFixes(project, uClass.javaPsi.asSafely<PsiClass>() ?: return,
|
||||
element.containingFile ?: return)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1118,22 +1119,18 @@ private class JUnitMalformedSignatureVisitor(
|
||||
private val makeStatic: Boolean? = null,
|
||||
private val makePublic: Boolean? = null,
|
||||
private val annotation: String? = null
|
||||
) : CompositeIntentionQuickFix() {
|
||||
) : CompositeModCommandQuickFix() {
|
||||
override fun getFamilyName(): String = JvmAnalysisBundle.message("jvm.inspections.junit.malformed.fix.class.signature")
|
||||
|
||||
override fun getName(): String = JvmAnalysisBundle.message("jvm.inspections.junit.malformed.fix.class.signature.descriptor", name)
|
||||
|
||||
override fun generatePreview(project: Project, previewDescriptor: ProblemDescriptor): IntentionPreviewInfo {
|
||||
val javaDeclaration = getUParentForIdentifier(previewDescriptor.psiElement)?.asSafely<UClass>() ?: return IntentionPreviewInfo.EMPTY
|
||||
return generatePreviews(project, previewDescriptor, javaDeclaration.javaPsi.asSafely<PsiClass>() ?: return IntentionPreviewInfo.EMPTY)
|
||||
override fun applyFix(project: Project, element: PsiElement, updater: ModPsiUpdater) {
|
||||
val javaDeclaration = getUParentForIdentifier(element)?.asSafely<UClass>() ?: return
|
||||
applyFixes(project, javaDeclaration.javaPsi.asSafely<PsiClass>() ?: return,
|
||||
element.containingFile ?: return)
|
||||
}
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val javaDeclaration = getUParentForIdentifier(descriptor.psiElement)?.asSafely<UClass>() ?: return
|
||||
applyFixes(project, descriptor, javaDeclaration.javaPsi.asSafely<PsiClass>() ?: return)
|
||||
}
|
||||
|
||||
override fun getActions(project: Project, descriptor: ProblemDescriptor): List<(JvmModifiersOwner) -> List<IntentionAction>> {
|
||||
override fun getActions(project: Project): List<(JvmModifiersOwner) -> List<IntentionAction>> {
|
||||
val actions = mutableListOf<(JvmModifiersOwner) -> List<IntentionAction>>()
|
||||
if (makeStatic != null) {
|
||||
actions.add { jvmClass -> createModifierActions(jvmClass, modifierRequest(JvmModifier.STATIC, makeStatic)) }
|
||||
@@ -1152,22 +1149,17 @@ private class JUnitMalformedSignatureVisitor(
|
||||
private val name: @NlsSafe String,
|
||||
private val makeStatic: Boolean?,
|
||||
private val newVisibility: JvmModifier? = null
|
||||
) : CompositeIntentionQuickFix() {
|
||||
) : CompositeModCommandQuickFix() {
|
||||
override fun getFamilyName(): String = JvmAnalysisBundle.message("jvm.inspections.junit.malformed.fix.field.signature")
|
||||
|
||||
override fun getName(): String = JvmAnalysisBundle.message("jvm.inspections.junit.malformed.fix.field.signature.descriptor", name)
|
||||
|
||||
override fun generatePreview(project: Project, previewDescriptor: ProblemDescriptor): IntentionPreviewInfo {
|
||||
val javaDeclaration = getUParentForIdentifier(previewDescriptor.psiElement)?.asSafely<UField>() ?: return IntentionPreviewInfo.EMPTY
|
||||
return generatePreviews(project, previewDescriptor, javaDeclaration.javaPsi ?: return IntentionPreviewInfo.EMPTY)
|
||||
override fun applyFix(project: Project, element: PsiElement, updater: ModPsiUpdater) {
|
||||
val javaDeclaration = getUParentForIdentifier(element)?.asSafely<UField>() ?: return
|
||||
applyFixes(project, javaDeclaration.javaPsi ?: return, element.containingFile ?: return)
|
||||
}
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val javaDeclaration = getUParentForIdentifier(descriptor.psiElement)?.asSafely<UField>() ?: return
|
||||
applyFixes(project, descriptor, javaDeclaration.javaPsi ?: return)
|
||||
}
|
||||
|
||||
override fun getActions(project: Project, descriptor: ProblemDescriptor): List<(JvmModifiersOwner) -> List<IntentionAction>> {
|
||||
override fun getActions(project: Project): List<(JvmModifiersOwner) -> List<IntentionAction>> {
|
||||
val actions = mutableListOf<(JvmModifiersOwner) -> List<IntentionAction>>()
|
||||
if (newVisibility != null) {
|
||||
actions.add { jvmField -> createModifierActions(jvmField, modifierRequest(newVisibility, true)) }
|
||||
@@ -1185,22 +1177,17 @@ private class JUnitMalformedSignatureVisitor(
|
||||
private val shouldBeVoidType: Boolean? = null,
|
||||
private val newVisibility: JvmModifier? = null,
|
||||
@SafeFieldForPreview private val inCorrectParams: Map<String, JvmType>? = null
|
||||
) : CompositeIntentionQuickFix() {
|
||||
) : CompositeModCommandQuickFix() {
|
||||
override fun getFamilyName(): String = JvmAnalysisBundle.message("jvm.inspections.junit.malformed.fix.method.signature")
|
||||
|
||||
override fun getName(): String = JvmAnalysisBundle.message("jvm.inspections.junit.malformed.fix.method.signature.descriptor", name)
|
||||
|
||||
override fun generatePreview(project: Project, previewDescriptor: ProblemDescriptor): IntentionPreviewInfo {
|
||||
val javaDeclaration = getUParentForIdentifier(previewDescriptor.psiElement)?.asSafely<UMethod>() ?: return IntentionPreviewInfo.EMPTY
|
||||
return generatePreviews(project, previewDescriptor, javaDeclaration.javaPsi)
|
||||
override fun applyFix(project: Project, element: PsiElement, updater: ModPsiUpdater) {
|
||||
val javaDeclaration = getUParentForIdentifier(element)?.asSafely<UMethod>() ?: return
|
||||
applyFixes(project, javaDeclaration.javaPsi, element.containingFile ?: return)
|
||||
}
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val javaDeclaration = getUParentForIdentifier(descriptor.psiElement)?.asSafely<UMethod>() ?: return
|
||||
applyFixes(project, descriptor, javaDeclaration.javaPsi)
|
||||
}
|
||||
|
||||
override fun getActions(project: Project, descriptor: ProblemDescriptor): List<(JvmModifiersOwner) -> List<IntentionAction>> {
|
||||
override fun getActions(project: Project): List<(JvmModifiersOwner) -> List<IntentionAction>> {
|
||||
val actions = mutableListOf<(JvmModifiersOwner) -> List<IntentionAction>>()
|
||||
if (shouldBeVoidType == true) {
|
||||
actions.add { jvmMethod -> createChangeTypeActions(
|
||||
@@ -1209,7 +1196,7 @@ private class JUnitMalformedSignatureVisitor(
|
||||
) }
|
||||
}
|
||||
if (newVisibility != null) {
|
||||
actions.add { jvmMethod -> createModifierActions(jvmMethod, modifierRequest(newVisibility, true)) }
|
||||
actions.add { jvmMethod -> createModifierActions(jvmMethod, modifierRequest(newVisibility, true, false)) }
|
||||
}
|
||||
if (inCorrectParams != null) {
|
||||
actions.add { jvmMethod -> createChangeParametersActions(
|
||||
@@ -1218,7 +1205,7 @@ private class JUnitMalformedSignatureVisitor(
|
||||
) }
|
||||
}
|
||||
if (makeStatic != null) {
|
||||
actions.add { jvmMethod -> createModifierActions(jvmMethod, modifierRequest(JvmModifier.STATIC, makeStatic)) }
|
||||
actions.add { jvmMethod -> createModifierActions(jvmMethod, modifierRequest(JvmModifier.STATIC, makeStatic, false)) }
|
||||
}
|
||||
return actions
|
||||
}
|
||||
|
||||
+2
-1
@@ -20,7 +20,8 @@ abstract class KotlinQuickFixAction<out T : PsiElement>(element: T) : QuickFixAc
|
||||
|
||||
final override fun invoke(project: Project, editor: Editor?, file: PsiFile) {
|
||||
val element = element ?: return
|
||||
if (file is KtFile && IntentionPreviewUtils.prepareElementForWrite(element)) {
|
||||
if (file is KtFile &&
|
||||
(startInWriteAction() && getElementToMakeWritable(file) == file || IntentionPreviewUtils.prepareElementForWrite(element))) {
|
||||
invoke(project, editor, file)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -15,7 +15,8 @@ abstract class KotlinCrossLanguageQuickFixAction<out T : PsiElement>(element: T)
|
||||
|
||||
final override fun invoke(project: Project, editor: Editor?, file: PsiFile) {
|
||||
val element = element
|
||||
if (element != null && IntentionPreviewUtils.prepareElementForWrite(element)) {
|
||||
if (element != null &&
|
||||
(startInWriteAction() && getElementToMakeWritable(file) == file || IntentionPreviewUtils.prepareElementForWrite(element))) {
|
||||
invokeImpl(project, editor, file)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.kotlin.idea.quickfix
|
||||
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.idea.base.psi.getOrCreateCompanionObject
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.classic.quickfixes.KotlinQuickFixAction
|
||||
import org.jetbrains.kotlin.idea.intentions.AddJvmStaticIntention
|
||||
import org.jetbrains.kotlin.idea.intentions.MoveMemberToCompanionObjectIntention
|
||||
import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively
|
||||
import org.jetbrains.kotlin.idea.util.addAnnotation
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -24,61 +18,23 @@ import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
|
||||
class MakeMemberStaticFix(declaration: KtNamedDeclaration) : KotlinQuickFixAction<KtNamedDeclaration>(declaration) {
|
||||
override fun startInWriteAction(): Boolean = false
|
||||
|
||||
override fun generatePreview(project: Project, editor: Editor, file: PsiFile): IntentionPreviewInfo {
|
||||
val declaration = element ?: return IntentionPreviewInfo.EMPTY
|
||||
if (declaration is KtClass) {
|
||||
if (declaration.hasModifier(KtTokens.INNER_KEYWORD)) declaration.removeModifier(KtTokens.INNER_KEYWORD)
|
||||
return IntentionPreviewInfo.DIFF
|
||||
}
|
||||
val copyDeclaration = PsiTreeUtil.findSameElementInCopy(declaration, file)
|
||||
val containingClass = copyDeclaration.containingClassOrObject ?: return IntentionPreviewInfo.EMPTY
|
||||
val copyDeclarationInCompanion = if (containingClass is KtClass) {
|
||||
val companionObject = containingClass.getOrCreateCompanionObject()
|
||||
MoveMemberToCompanionObjectIntention.Factory.removeModifiers(copyDeclaration)
|
||||
val newDeclaration = companionObject.addDeclaration(copyDeclaration)
|
||||
copyDeclaration.delete()
|
||||
newDeclaration
|
||||
} else copyDeclaration
|
||||
if (AddJvmStaticIntention().applicabilityRange(copyDeclarationInCompanion) != null) {
|
||||
copyDeclarationInCompanion.addAnnotation(JVM_STATIC_FQ_NAME)
|
||||
CodeStyleManager.getInstance(declaration.project).reformat(copyDeclarationInCompanion, true)
|
||||
}
|
||||
return IntentionPreviewInfo.DIFF
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
fun makeStaticAndReformat(declaration: KtNamedDeclaration, editor: Editor?) {
|
||||
val intention = AddJvmStaticIntention()
|
||||
if (intention.applicabilityRange(declaration) != null) {
|
||||
intention.applyTo(declaration, editor)
|
||||
runWriteAction { CodeStyleManager.getInstance(declaration.project).reformat(declaration, true) }
|
||||
}
|
||||
}
|
||||
val declaration = element ?: return
|
||||
var declaration = element ?: return
|
||||
if (declaration is KtClass) {
|
||||
if (declaration.hasModifier(KtTokens.INNER_KEYWORD)) declaration.removeModifier(KtTokens.INNER_KEYWORD)
|
||||
return
|
||||
}
|
||||
val containingClass = declaration.containingClassOrObject ?: return
|
||||
if (containingClass is KtClass) {
|
||||
val moveMemberToCompanionObjectIntention = MoveMemberToCompanionObjectIntention()
|
||||
val (conflicts, externalUsages, outerInstanceUsages) =
|
||||
moveMemberToCompanionObjectIntention.retrieveConflictsAndUsages(project, editor, declaration, containingClass)
|
||||
?: return
|
||||
|
||||
project.checkConflictsInteractively(conflicts) {
|
||||
ApplicationManagerEx.getApplicationEx().runWriteActionWithNonCancellableProgressInDispatchThread(
|
||||
KotlinBundle.message("making.member.static"), project, null
|
||||
) {
|
||||
val movedDeclaration = moveMemberToCompanionObjectIntention.doMove(
|
||||
it, declaration, externalUsages, outerInstanceUsages, editor
|
||||
)
|
||||
makeStaticAndReformat(movedDeclaration, editor)
|
||||
}
|
||||
} else {
|
||||
val containingClass = declaration.containingClassOrObject ?: return
|
||||
if (containingClass is KtClass) {
|
||||
val moveMemberToCompanionObjectIntention = MoveMemberToCompanionObjectIntention()
|
||||
declaration = moveMemberToCompanionObjectIntention.doMove(
|
||||
EmptyProgressIndicator(), declaration, listOf(), listOf(), editor
|
||||
)
|
||||
}
|
||||
} else makeStaticAndReformat(declaration, editor)
|
||||
}
|
||||
if (AddJvmStaticIntention().applicabilityRange(declaration) != null) {
|
||||
declaration.addAnnotation(JVM_STATIC_FQ_NAME)
|
||||
CodeStyleManager.getInstance(project).reformat(declaration, true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getText(): String = KotlinBundle.message("make.member.static.quickfix", element?.name ?: "")
|
||||
|
||||
Reference in New Issue
Block a user