Migrate PyConvertImportIntentionActio and ReplaceListComprehensionWithForIntention to ModCommand

PY-65297

GitOrigin-RevId: e5aa826a816c3d302a7f70f005ba6688449bde10
This commit is contained in:
Georgii Ustinov
2024-01-12 10:16:18 +02:00
committed by intellij-monorepo-bot
parent fb31a3e184
commit 183c37f41e
4 changed files with 59 additions and 61 deletions

View File

@@ -1,9 +1,10 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.jetbrains.python.codeInsight.intentions
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import com.intellij.modcommand.ActionContext
import com.intellij.modcommand.ModPsiUpdater
import com.intellij.modcommand.Presentation
import com.intellij.psi.PsiElement
import com.jetbrains.python.codeInsight.imports.PyRelativeImportData
import com.jetbrains.python.psi.PyFile
import com.jetbrains.python.psi.resolve.QualifiedNameFinder
@@ -15,22 +16,21 @@ import com.jetbrains.python.psi.resolve.QualifiedNameFinder
* @author Aleksei.Kniazev
*/
class PyAbsoluteToRelativeImportIntention : PyConvertImportIntentionAction("INTN.convert.absolute.to.relative") {
override fun getPresentation(context: ActionContext, element: PsiElement): Presentation? {
if (context.file !is PyFile) return null
val statement = findStatement(element) ?: return null
if (statement.relativeLevel != 0) return null
override fun doInvoke(project: Project, editor: Editor, file: PsiFile) {
val statement = findStatement(file, editor) ?: return
val targetPath = statement.importSourceQName ?: return
val importData = PyRelativeImportData.fromString(targetPath.toString(), file as PyFile) ?: return
replaceImportStatement(statement, file, importData.locationWithDots)
val targetPath = statement.importSourceQName ?: return null
val filePath = QualifiedNameFinder.findCanonicalImportPath(context.file, null) ?: return null
return if(targetPath.firstComponent == filePath.firstComponent) super.getPresentation(context, element) else null
}
override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean {
if (file !is PyFile) return false
val statement = findStatement(file, editor) ?: return false
if (statement.relativeLevel != 0) return false
override fun invoke(context: ActionContext, element: PsiElement, updater: ModPsiUpdater) {
val statement = findStatement(element) ?: return
val targetPath = statement.importSourceQName ?: return
val importData = PyRelativeImportData.fromString(targetPath.toString(), context.file as PyFile) ?: return
val targetPath = statement.importSourceQName ?: return false
val filePath = QualifiedNameFinder.findCanonicalImportPath(file, null) ?: return false
return targetPath.firstComponent == filePath.firstComponent
replaceImportStatement(statement, context.file, importData.locationWithDots)
}
}

View File

@@ -1,7 +1,9 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.jetbrains.python.codeInsight.intentions
import com.intellij.openapi.editor.Editor
import com.intellij.codeInspection.util.IntentionFamilyName
import com.intellij.modcommand.PsiUpdateModCommandAction
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.codeStyle.CodeStyleManager
import com.intellij.psi.util.PsiTreeUtil
@@ -12,13 +14,11 @@ import com.jetbrains.python.psi.PyFromImportStatement
import com.jetbrains.python.psi.PyStatement
import org.jetbrains.annotations.PropertyKey
abstract class PyConvertImportIntentionAction(@PropertyKey(resourceBundle = PyPsiBundle.BUNDLE) intentionText: String) : PyBaseIntentionAction() {
abstract class PyConvertImportIntentionAction(
@IntentionFamilyName @PropertyKey(resourceBundle = PyPsiBundle.BUNDLE) private val intentionText: String
) : PsiUpdateModCommandAction<PsiElement>(PsiElement::class.java) {
init {
text = PyPsiBundle.message(intentionText)
}
override fun getFamilyName(): String = text
override fun getFamilyName(): String = PyPsiBundle.message(intentionText)
fun replaceImportStatement(statement: PyFromImportStatement, file: PsiFile, path: String) {
val imported = statement.importElements.joinToString(", ") { it.text }
@@ -30,9 +30,7 @@ abstract class PyConvertImportIntentionAction(@PropertyKey(resourceBundle = PyPs
statement.replace(formattedStatement)
}
fun findStatement(file: PsiFile, editor: Editor): PyFromImportStatement? {
val position = file.findElementAt(editor.caretModel.offset)
return PsiTreeUtil.getParentOfType(position, PyFromImportStatement::class.java, true, PyStatement::class.java)
}
fun findStatement(element: PsiElement): PyFromImportStatement? =
PsiTreeUtil.getParentOfType(element, PyFromImportStatement::class.java, true, PyStatement::class.java)
}

View File

@@ -1,9 +1,10 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.jetbrains.python.codeInsight.intentions
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import com.intellij.modcommand.ActionContext
import com.intellij.modcommand.ModPsiUpdater
import com.intellij.modcommand.Presentation
import com.intellij.psi.PsiElement
import com.jetbrains.python.extensions.getQName
import com.jetbrains.python.psi.PyFile
@@ -14,18 +15,17 @@ import com.jetbrains.python.psi.PyFile
* @author Aleksei.Kniazev
*/
class PyRelativeToAbsoluteImportIntention : PyConvertImportIntentionAction("INTN.convert.relative.to.absolute") {
override fun getPresentation(context: ActionContext, element: PsiElement): Presentation? {
if (context.file !is PyFile) return null
val statement = findStatement(element) ?: return null
return if (statement.relativeLevel > 0) super.getPresentation(context, element) else null
}
override fun doInvoke(project: Project, editor: Editor, file: PsiFile) {
val statement = findStatement(file, editor) ?: return
override fun invoke(context: ActionContext, element: PsiElement, updater: ModPsiUpdater) {
val statement = findStatement(element) ?: return
val source = statement.resolveImportSource() ?: return
val qName = source.getQName()
replaceImportStatement(statement, file, qName.toString())
}
override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean {
if (file !is PyFile) return false
val statement = findStatement(file, editor) ?: return false
return statement.relativeLevel > 0
replaceImportStatement(statement, context.file, qName.toString())
}
}

View File

@@ -1,24 +1,23 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.jetbrains.python.codeInsight.intentions;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.modcommand.ActionContext;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.modcommand.Presentation;
import com.intellij.modcommand.PsiUpdateModCommandAction;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.PyPsiBundle;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyStatementListImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public final class ReplaceListComprehensionWithForIntention extends PyBaseIntentionAction {
@Override
@NotNull
public String getText() {
return PyPsiBundle.message("INTN.replace.list.comprehensions.with.for");
public final class ReplaceListComprehensionWithForIntention extends PsiUpdateModCommandAction<PsiElement> {
ReplaceListComprehensionWithForIntention() {
super(PsiElement.class);
}
@Override
@@ -27,40 +26,41 @@ public final class ReplaceListComprehensionWithForIntention extends PyBaseIntent
return PyPsiBundle.message("INTN.replace.list.comprehensions.with.for");
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
if (!(file instanceof PyFile)) {
return false;
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiElement element) {
if (!(context.file() instanceof PyFile)) {
return null;
}
PyListCompExpression expression =
PsiTreeUtil.getTopmostParentOfType(file.findElementAt(editor.getCaretModel().getOffset()), PyListCompExpression.class);
PsiTreeUtil.getTopmostParentOfType(element, PyListCompExpression.class);
if (expression == null) {
return false;
return null;
}
if (expression.getComponents().isEmpty()) return false;
if (expression.getComponents().isEmpty()) return null;
PsiElement parent = expression.getParent();
if (parent instanceof PyAssignmentStatement || parent instanceof PyPrintStatement) {
return true;
return super.getPresentation(context, element);
}
return false;
return null;
}
@Override
public void doInvoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
PyListCompExpression expression = PsiTreeUtil.getTopmostParentOfType(
file.findElementAt(editor.getCaretModel().getOffset()), PyListCompExpression.class);
protected void invoke(@NotNull ActionContext context, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PyListCompExpression expression = PsiTreeUtil.getTopmostParentOfType(element, PyListCompExpression.class);
if (expression == null) {
return;
}
PsiElement parent = expression.getParent();
PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project);
PyElementGenerator elementGenerator = PyElementGenerator.getInstance(context.project());
if (parent instanceof PyAssignmentStatement) {
final PsiElement leftExpr = ((PyAssignmentStatement)parent).getLeftHandSideExpression();
if (leftExpr == null) return;
PyAssignmentStatement initAssignment = elementGenerator.createFromText(LanguageLevel.forElement(expression), PyAssignmentStatement.class,
leftExpr.getText() + " = []");
leftExpr.getText() + " = []");
PyForStatement forStatement = createForLoop(expression, elementGenerator,
leftExpr.getText() + ".append("+ expression.getResultExpression().getText() +")");