From 0cf6f55486d04dceb818d041d976cb496b613861 Mon Sep 17 00:00:00 2001 From: UNV Date: Fri, 10 Oct 2025 13:30:09 +0300 Subject: [PATCH] Localizing inspection, intentions and quick fixes (part 2). --- .../PyProtectedMemberInspection.java | 324 +++--- .../PyUnusedLocalInspectionVisitor.java | 972 ++++++++---------- .../quickfix/AddMethodQuickFix.java | 24 +- .../inspections/quickfix/AddSelfQuickFix.java | 64 +- .../quickfix/AugmentedAssignmentQuickFix.java | 107 +- .../quickfix/ChainedComparisonsQuickFix.java | 246 ++--- .../quickfix/ComparisonWithNoneQuickFix.java | 63 +- .../CompatibilityPrintCallQuickFix.java | 52 +- .../quickfix/ConvertDictCompQuickFix.java | 144 ++- .../quickfix/ConvertDocstringQuickFix.java | 81 +- .../quickfix/ConvertIndentsFix.java | 67 +- .../quickfix/ConvertSetLiteralQuickFix.java | 66 +- .../quickfix/CreateClassQuickFix.java | 95 +- .../quickfix/DictCreationQuickFix.java | 147 +-- .../quickfix/DocstringQuickFix.java | 161 ++- .../quickfix/ListCreationQuickFix.java | 70 +- .../MoveFromFutureImportQuickFix.java | 47 +- .../PyAddExceptionSuperClassQuickFix.java | 91 +- .../PyAddPropertyForFieldQuickFix.java | 113 +- .../quickfix/PyChangeBaseClassQuickFix.java | 51 +- .../quickfix/PyChangeSignatureQuickFix.java | 118 +-- .../quickfix/PyConvertToNewStyleQuickFix.java | 72 +- .../quickfix/PyCreatePropertyQuickFix.java | 90 +- .../quickfix/PyDefaultArgumentQuickFix.java | 112 +- .../quickfix/PyImplementMethodsQuickFix.java | 94 +- .../PyMakeFunctionFromMethodQuickFix.java | 317 +++--- .../quickfix/PyMakeMethodStaticQuickFix.java | 180 ++-- .../quickfix/PyMakePublicQuickFix.java | 88 +- .../PyMoveAttributeToInitQuickFix.java | 74 +- .../quickfix/PyMoveExceptQuickFix.java | 112 +- .../quickfix/PyRemoveArgumentQuickFix.java | 64 +- .../quickfix/PyRemoveParameterQuickFix.java | 114 +- .../quickfix/PyRemoveStatementQuickFix.java | 40 +- ...eUnderscoresInNumericLiteralsQuickFix.java | 50 +- .../PyRenameUnresolvedRefQuickFix.java | 274 ++--- .../PyUpdatePropertySignatureQuickFix.java | 79 +- .../RedundantParenthesesQuickFix.java | 93 +- .../inspections/quickfix/ReformatFix.java | 65 +- .../quickfix/RemoveDecoratorQuickFix.java | 35 +- .../quickfix/RemoveTrailingLQuickFix.java | 50 +- .../quickfix/ReplaceBuiltinsQuickFix.java | 72 +- .../quickfix/ReplaceExceptPartQuickFix.java | 71 +- .../ReplaceListComprehensionsQuickFix.java | 53 +- .../ReplaceNotEqOperatorQuickFix.java | 56 +- .../StatementEffectFunctionCallQuickFix.java | 112 +- .../UnresolvedRefAddFutureImportQuickFix.java | 56 +- .../UnresolvedRefTrueFalseQuickFix.java | 64 +- .../validation/Pep8ExternalAnnotator.java | 690 +++++++------ .../ConfigureTemplateDirectoriesAction.java | 39 +- .../rest/quickfixes/AddIgnoredRoleFix.java | 68 +- 50 files changed, 3013 insertions(+), 3374 deletions(-) diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/PyProtectedMemberInspection.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/PyProtectedMemberInspection.java index be7a0831..80d6fd69 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/PyProtectedMemberInspection.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/PyProtectedMemberInspection.java @@ -36,190 +36,168 @@ import consulo.language.psi.PsiElementVisitor; import consulo.language.psi.PsiReference; import consulo.language.psi.util.PsiTreeUtil; +import consulo.localize.LocalizeValue; +import consulo.python.impl.localize.PyLocalize; import consulo.util.lang.StringUtil; -import org.jetbrains.annotations.Nls; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; + import java.util.ArrayList; import java.util.Collection; import java.util.List; /** - * User: ktisha - *

* Inspection to detect situations, where * protected member (i.e. class member with a name beginning with an underscore) * is access outside the class or a descendant of the class where it's defined. + * + * @author ktisha */ @ExtensionImpl -public class PyProtectedMemberInspection extends PyInspection -{ - @Nonnull - @Override - public InspectionToolState createStateProvider() - { - return new PyProtectedMemberInspectionState(); - } - - @Nls - @Nonnull - @Override - public String getDisplayName() - { - return PyBundle.message("INSP.NAME.protected.member.access"); - } - - @Nonnull - @Override - public PsiElementVisitor buildVisitor(@Nonnull ProblemsHolder holder, - boolean isOnTheFly, - @Nonnull LocalInspectionToolSession session, - Object state) - { - PyProtectedMemberInspectionState inspectionState = (PyProtectedMemberInspectionState) state; - return new Visitor(holder, session, inspectionState); - } - - - private class Visitor extends PyInspectionVisitor - { - private final PyProtectedMemberInspectionState myState; - - public Visitor(@Nullable ProblemsHolder holder, @Nonnull LocalInspectionToolSession session, PyProtectedMemberInspectionState inspectionState) - { - super(holder, session); - myState = inspectionState; - } - - @Override - public void visitPyImportElement(PyImportElement node) - { - final PyStatement statement = node.getContainingImportStatement(); - if(!(statement instanceof PyFromImportStatement)) - { - return; - } - final PyReferenceExpression importReferenceExpression = node.getImportReferenceExpression(); - final PyReferenceExpression importSource = ((PyFromImportStatement) statement).getImportSource(); - if(importReferenceExpression != null && importSource != null && !isImportFromTheSamePackage(importSource)) - { - checkReference(importReferenceExpression, importSource); - } - } - - private boolean isImportFromTheSamePackage(PyReferenceExpression importSource) - { - PsiDirectory directory = importSource.getContainingFile().getContainingDirectory(); - if(directory != null && PyUtil.isPackage(directory, true, importSource.getContainingFile()) && - directory.getName().equals(importSource.getName())) - { - return true; - } - return false; - } - - @Override - public void visitPyReferenceExpression(PyReferenceExpression node) - { - final PyExpression qualifier = node.getQualifier(); - if(myState.ignoreAnnotations && PsiTreeUtil.getParentOfType(node, PyAnnotation.class) != null) - { - return; - } - if(qualifier == null || PyNames.CANONICAL_SELF.equals(qualifier.getText())) - { - return; - } - checkReference(node, qualifier); - } - - private void checkReference(@Nonnull final PyReferenceExpression node, @Nonnull final PyExpression qualifier) - { - if(myTypeEvalContext.getType(qualifier) instanceof PyNamedTupleType) - { - return; - } - final String name = node.getName(); - final List quickFixes = new ArrayList<>(); - quickFixes.add(new PyRenameElementQuickFix()); - - if(name != null && name.startsWith("_") && !name.startsWith("__") && !name.endsWith("__")) - { - final PsiReference reference = node.getReference(getResolveContext()); - for(final PyInspectionExtension inspectionExtension : PyInspectionExtension.EP_NAME.getExtensions()) - { - if(inspectionExtension.ignoreProtectedSymbol(node, myTypeEvalContext)) - { - return; - } - } - final PsiElement resolvedExpression = reference.resolve(); - final PyClass resolvedClass = getClassOwner(resolvedExpression); - if(resolvedExpression instanceof PyTargetExpression) - { - final String newName = StringUtil.trimLeading(name, '_'); - if(resolvedClass != null) - { - final String qFixName = - resolvedClass.getProperties().containsKey(newName) ? PyBundle.message("QFIX.use.property") : PyBundle.message( - "QFIX.add.property"); - quickFixes.add(new PyAddPropertyForFieldQuickFix(qFixName)); - - final Collection usedNames = PyRefactoringUtil.collectUsedNames(resolvedClass); - if(!usedNames.contains(newName)) - { - quickFixes.add(new PyMakePublicQuickFix()); - } - } - } - - final PyClass parentClass = getClassOwner(node); - if(parentClass != null) - { - if(PyTestUtil.isPyTestClass(parentClass, null) && myState.ignoreTestFunctions) - { - return; - } - - if(parentClass.isSubclass(resolvedClass, myTypeEvalContext)) - { - return; - } - - PyClass outerClass = getClassOwner(parentClass); - while(outerClass != null) - { - if(outerClass.isSubclass(resolvedClass, myTypeEvalContext)) - { - return; - } - - outerClass = getClassOwner(outerClass); - } - } - final PyType type = myTypeEvalContext.getType(qualifier); - final String bundleKey = - type instanceof PyModuleType ? "INSP.protected.member.$0.access.module" : "INSP.protected.member.$0.access"; - registerProblem(node, - PyBundle.message(bundleKey, name), - ProblemHighlightType.GENERIC_ERROR_OR_WARNING, - null, - quickFixes.toArray(new LocalQuickFix[quickFixes.size() - 1])); - } - } - - @Nullable - private PyClass getClassOwner(@Nullable PsiElement element) - { - for(ScopeOwner owner = ScopeUtil.getScopeOwner(element); owner != null; owner = ScopeUtil.getScopeOwner(owner)) - { - if(owner instanceof PyClass) - { - return (PyClass) owner; - } - } - return null; - } - } +public class PyProtectedMemberInspection extends PyInspection { + @Nonnull + @Override + public InspectionToolState createStateProvider() { + return new PyProtectedMemberInspectionState(); + } + + @Nonnull + @Override + public LocalizeValue getDisplayName() { + return PyLocalize.inspNameProtectedMemberAccess(); + } + + @Nonnull + @Override + public PsiElementVisitor buildVisitor( + @Nonnull ProblemsHolder holder, + boolean isOnTheFly, + @Nonnull LocalInspectionToolSession session, + Object state + ) { + PyProtectedMemberInspectionState inspectionState = (PyProtectedMemberInspectionState) state; + return new Visitor(holder, session, inspectionState); + } + + + private class Visitor extends PyInspectionVisitor { + private final PyProtectedMemberInspectionState myState; + + public Visitor( + @Nullable ProblemsHolder holder, + @Nonnull LocalInspectionToolSession session, + PyProtectedMemberInspectionState inspectionState + ) { + super(holder, session); + myState = inspectionState; + } + + @Override + public void visitPyImportElement(PyImportElement node) { + final PyStatement statement = node.getContainingImportStatement(); + if (!(statement instanceof PyFromImportStatement)) { + return; + } + final PyReferenceExpression importReferenceExpression = node.getImportReferenceExpression(); + final PyReferenceExpression importSource = ((PyFromImportStatement) statement).getImportSource(); + if (importReferenceExpression != null && importSource != null && !isImportFromTheSamePackage(importSource)) { + checkReference(importReferenceExpression, importSource); + } + } + + private boolean isImportFromTheSamePackage(PyReferenceExpression importSource) { + PsiDirectory directory = importSource.getContainingFile().getContainingDirectory(); + if (directory != null && PyUtil.isPackage(directory, true, importSource.getContainingFile()) && + directory.getName().equals(importSource.getName())) { + return true; + } + return false; + } + + @Override + public void visitPyReferenceExpression(PyReferenceExpression node) { + final PyExpression qualifier = node.getQualifier(); + if (myState.ignoreAnnotations && PsiTreeUtil.getParentOfType(node, PyAnnotation.class) != null) { + return; + } + if (qualifier == null || PyNames.CANONICAL_SELF.equals(qualifier.getText())) { + return; + } + checkReference(node, qualifier); + } + + private void checkReference(@Nonnull final PyReferenceExpression node, @Nonnull final PyExpression qualifier) { + if (myTypeEvalContext.getType(qualifier) instanceof PyNamedTupleType) { + return; + } + final String name = node.getName(); + final List quickFixes = new ArrayList<>(); + quickFixes.add(new PyRenameElementQuickFix()); + + if (name != null && name.startsWith("_") && !name.startsWith("__") && !name.endsWith("__")) { + final PsiReference reference = node.getReference(getResolveContext()); + for (final PyInspectionExtension inspectionExtension : PyInspectionExtension.EP_NAME.getExtensions()) { + if (inspectionExtension.ignoreProtectedSymbol(node, myTypeEvalContext)) { + return; + } + } + final PsiElement resolvedExpression = reference.resolve(); + final PyClass resolvedClass = getClassOwner(resolvedExpression); + if (resolvedExpression instanceof PyTargetExpression) { + final String newName = StringUtil.trimLeading(name, '_'); + if (resolvedClass != null) { + LocalizeValue qFixName = resolvedClass.getProperties().containsKey(newName) + ? PyLocalize.qfixUseProperty() + : PyLocalize.qfixAddProperty(); + quickFixes.add(new PyAddPropertyForFieldQuickFix(qFixName)); + + final Collection usedNames = PyRefactoringUtil.collectUsedNames(resolvedClass); + if (!usedNames.contains(newName)) { + quickFixes.add(new PyMakePublicQuickFix()); + } + } + } + + final PyClass parentClass = getClassOwner(node); + if (parentClass != null) { + if (PyTestUtil.isPyTestClass(parentClass, null) && myState.ignoreTestFunctions) { + return; + } + + if (parentClass.isSubclass(resolvedClass, myTypeEvalContext)) { + return; + } + + PyClass outerClass = getClassOwner(parentClass); + while (outerClass != null) { + if (outerClass.isSubclass(resolvedClass, myTypeEvalContext)) { + return; + } + + outerClass = getClassOwner(outerClass); + } + } + final PyType type = myTypeEvalContext.getType(qualifier); + final String bundleKey = + type instanceof PyModuleType ? "INSP.protected.member.$0.access.module" : "INSP.protected.member.$0.access"; + registerProblem( + node, + PyBundle.message(bundleKey, name), + ProblemHighlightType.GENERIC_ERROR_OR_WARNING, + null, + quickFixes.toArray(new LocalQuickFix[quickFixes.size() - 1]) + ); + } + } + + @Nullable + private PyClass getClassOwner(@Nullable PsiElement element) { + for (ScopeOwner owner = ScopeUtil.getScopeOwner(element); owner != null; owner = ScopeUtil.getScopeOwner(owner)) { + if (owner instanceof PyClass) { + return (PyClass) owner; + } + } + return null; + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/PyUnusedLocalInspectionVisitor.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/PyUnusedLocalInspectionVisitor.java index 4431a150..20983d04 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/PyUnusedLocalInspectionVisitor.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/PyUnusedLocalInspectionVisitor.java @@ -47,12 +47,15 @@ import consulo.language.psi.PsiElement; import consulo.language.psi.PsiFile; import consulo.language.psi.util.PsiTreeUtil; +import consulo.localize.LocalizeValue; import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import consulo.undoRedo.CommandProcessor; import consulo.util.lang.Pair; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; + import java.util.*; import static com.jetbrains.python.impl.psi.PyUtil.as; @@ -60,520 +63,457 @@ /** * @author oleg */ -public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor -{ - private final boolean myIgnoreTupleUnpacking; - private final boolean myIgnoreLambdaParameters; - private final boolean myIgnoreRangeIterationVariables; - private final HashSet myUnusedElements; - private final HashSet myUsedElements; - - public PyUnusedLocalInspectionVisitor(@Nonnull ProblemsHolder holder, - @Nonnull LocalInspectionToolSession session, - boolean ignoreTupleUnpacking, - boolean ignoreLambdaParameters, - boolean ignoreRangeIterationVariables) - { - super(holder, session); - myIgnoreTupleUnpacking = ignoreTupleUnpacking; - myIgnoreLambdaParameters = ignoreLambdaParameters; - myIgnoreRangeIterationVariables = ignoreRangeIterationVariables; - myUnusedElements = new HashSet<>(); - myUsedElements = new HashSet<>(); - } - - @Override - public void visitPyFunction(final PyFunction node) - { - processScope(node); - } - - @Override - public void visitPyLambdaExpression(final PyLambdaExpression node) - { - processScope(node); - } - - @Override - public void visitPyClass(PyClass node) - { - processScope(node); - } - - private void processScope(final ScopeOwner owner) - { - if(owner.getContainingFile() instanceof PyExpressionCodeFragment || callsLocals(owner)) - { - return; - } - if(!(owner instanceof PyClass)) - { - collectAllWrites(owner); - } - collectUsedReads(owner); - } - - @Override - public void visitPyStringLiteralExpression(PyStringLiteralExpression pyString) - { - final ScopeOwner owner = ScopeUtil.getScopeOwner(pyString); - if(owner != null && !(owner instanceof PsiFile)) - { - final PyStatement instrAnchor = PsiTreeUtil.getParentOfType(pyString, PyStatement.class); - if(instrAnchor == null) - { - return; - } - final Instruction[] instructions = ControlFlowCache.getControlFlow(owner).getInstructions(); - final int startInstruction = ControlFlowUtil.findInstructionNumberByElement(instructions, instrAnchor); - if(startInstruction < 0) - { - return; - } - final Project project = pyString.getProject(); - final List> pairs = InjectedLanguageManager.getInstance(project).getInjectedPsiFiles(pyString); - if(pairs != null) - { - for(Pair pair : pairs) - { - pair.getFirst().accept(new PyRecursiveElementVisitor() - { - @Override - public void visitPyReferenceExpression(PyReferenceExpression expr) - { - final PyExpression qualifier = expr.getQualifier(); - if(qualifier != null) - { - qualifier.accept(this); - return; - } - final String name = expr.getName(); - if(name != null) - { - analyzeReadsInScope(name, owner, instructions, startInstruction, pyString); - } - } - }); - } - } - } - } - - private void collectAllWrites(ScopeOwner owner) - { - final Instruction[] instructions = ControlFlowCache.getControlFlow(owner).getInstructions(); - for(Instruction instruction : instructions) - { - final PsiElement element = instruction.getElement(); - if(element instanceof PyFunction && owner instanceof PyFunction) - { - if(PyKnownDecoratorUtil.hasUnknownDecorator((PyFunction) element, myTypeEvalContext)) - { - continue; - } - if(!myUsedElements.contains(element)) - { - myUnusedElements.add(element); - } - } - else if(instruction instanceof ReadWriteInstruction) - { - final ReadWriteInstruction readWriteInstruction = (ReadWriteInstruction) instruction; - final ReadWriteInstruction.ACCESS access = readWriteInstruction.getAccess(); - if(!access.isWriteAccess()) - { - continue; - } - final String name = readWriteInstruction.getName(); - // Ignore empty, wildcards, global and nonlocal names - final Scope scope = ControlFlowCache.getScope(owner); - if(name == null || "_".equals(name) || scope.isGlobal(name) || scope.isNonlocal(name)) - { - continue; - } - // Ignore elements out of scope - if(element == null || !PsiTreeUtil.isAncestor(owner, element, false)) - { - continue; - } - // Ignore arguments of import statement - if(PyImportStatementNavigator.getImportStatementByElement(element) != null) - { - continue; - } - if(PyAugAssignmentStatementNavigator.getStatementByTarget(element) != null) - { - continue; - } - if(parameterInMethodWithFixedSignature(owner, element)) - { - continue; - } - if(!myUsedElements.contains(element)) - { - myUnusedElements.add(element); - } - } - } - } - - private static boolean parameterInMethodWithFixedSignature(@Nonnull ScopeOwner owner, @Nonnull PsiElement element) - { - if(owner instanceof PyFunction && element instanceof PyParameter) - { - final PyFunction function = (PyFunction) owner; - final String functionName = function.getName(); - - return !PyNames.INIT.equals(functionName) && - function.getContainingClass() != null && - PyNames.getBuiltinMethods(LanguageLevel.forElement(function)).containsKey(functionName); - } - - return false; - } - - private void collectUsedReads(final ScopeOwner owner) - { - final Instruction[] instructions = ControlFlowCache.getControlFlow(owner).getInstructions(); - for(int i = 0; i < instructions.length; i++) - { - final Instruction instruction = instructions[i]; - if(instruction instanceof ReadWriteInstruction) - { - final ReadWriteInstruction readWriteInstruction = (ReadWriteInstruction) instruction; - final ReadWriteInstruction.ACCESS access = readWriteInstruction.getAccess(); - if(!access.isReadAccess()) - { - continue; - } - final String name = readWriteInstruction.getName(); - if(name == null) - { - continue; - } - final PsiElement element = instruction.getElement(); - // Ignore elements out of scope - if(element == null || !PsiTreeUtil.isAncestor(owner, element, false)) - { - continue; - } - final int startInstruction; - if(access.isWriteAccess()) - { - final PyAugAssignmentStatement augAssignmentStatement = PyAugAssignmentStatementNavigator.getStatementByTarget(element); - startInstruction = ControlFlowUtil.findInstructionNumberByElement(instructions, augAssignmentStatement); - } - else - { - startInstruction = i; - } - analyzeReadsInScope(name, owner, instructions, startInstruction, as(element, PyReferenceExpression.class)); - } - } - } - - private void analyzeReadsInScope(@Nonnull String name, @Nonnull ScopeOwner owner, @Nonnull Instruction[] instructions, int startInstruction, @Nullable PsiElement scopeAnchor) - { - // Check if the element is declared out of scope, mark all out of scope write accesses as used - if(scopeAnchor != null) - { - final ScopeOwner declOwner = ScopeUtil.getDeclarationScopeOwner(scopeAnchor, name); - if(declOwner != null && declOwner != owner) - { - final Collection writeElements = ScopeUtil.getReadWriteElements(name, declOwner, false, true); - for(PsiElement e : writeElements) - { - myUsedElements.add(e); - myUnusedElements.remove(e); - } - } - } - ControlFlowUtil.iteratePrev(startInstruction, instructions, inst -> { - final PsiElement instElement = inst.getElement(); - // Mark function as used - if(instElement instanceof PyFunction) - { - if(name.equals(((PyFunction) instElement).getName())) - { - myUsedElements.add(instElement); - myUnusedElements.remove(instElement); - return ControlFlowUtil.Operation.CONTINUE; - } - } - // Mark write access as used - else if(inst instanceof ReadWriteInstruction) - { - final ReadWriteInstruction rwInstruction = (ReadWriteInstruction) inst; - if(rwInstruction.getAccess().isWriteAccess() && name.equals(rwInstruction.getName())) - { - // For elements in scope - if(instElement != null && PsiTreeUtil.isAncestor(owner, instElement, false)) - { - myUsedElements.add(instElement); - myUnusedElements.remove(instElement); - } - return ControlFlowUtil.Operation.CONTINUE; - } - } - return ControlFlowUtil.Operation.NEXT; - }); - } - - static class DontPerformException extends RuntimeException - { - } - - private static boolean callsLocals(final ScopeOwner owner) - { - try - { - owner.acceptChildren(new PyRecursiveElementVisitor() - { - @Override - public void visitPyCallExpression(final PyCallExpression node) - { - final PyExpression callee = node.getCallee(); - if(callee != null && "locals".equals(callee.getName())) - { - throw new DontPerformException(); - } - node.acceptChildren(this); // look at call expr in arguments - } - - @Override - public void visitPyFunction(final PyFunction node) - { - // stop here - } - }); - } - catch(DontPerformException e) - { - return true; - } - return false; - } - - void registerProblems() - { - final PyInspectionExtension[] filters = Extensions.getExtensions(PyInspectionExtension.EP_NAME); - // Register problems - - final Set functionsWithInheritors = new HashSet<>(); - final Map emptyFunctions = new HashMap<>(); - - for(PsiElement element : myUnusedElements) - { - boolean ignoreUnused = false; - for(PyInspectionExtension filter : filters) - { - if(filter.ignoreUnused(element)) - { - ignoreUnused = true; - } - } - if(ignoreUnused) - { - continue; - } - - if(element instanceof PyFunction) - { - // Local function - final PsiElement nameIdentifier = ((PyFunction) element).getNameIdentifier(); - registerWarning(nameIdentifier == null ? element : nameIdentifier, PyBundle.message("INSP.unused.locals.local.function.isnot.used", ((PyFunction) element).getName()), new - PyRemoveStatementQuickFix()); - } - else if(element instanceof PyClass) - { - // Local class - final PyClass cls = (PyClass) element; - final PsiElement name = cls.getNameIdentifier(); - registerWarning(name != null ? name : element, PyBundle.message("INSP.unused.locals.local.class.isnot.used", cls.getName()), new PyRemoveStatementQuickFix()); - } - else - { - // Local variable or parameter - String name = element.getText(); - if(element instanceof PyNamedParameter || element.getParent() instanceof PyNamedParameter) - { - PyNamedParameter namedParameter = element instanceof PyNamedParameter ? (PyNamedParameter) element : (PyNamedParameter) element.getParent(); - name = namedParameter.getName(); - // When function is inside a class, first parameter may be either self or cls which is always 'used'. - if(namedParameter.isSelf()) - { - continue; - } - if(myIgnoreLambdaParameters && PsiTreeUtil.getParentOfType(element, PyCallable.class) instanceof PyLambdaExpression) - { - continue; - } - boolean mayBeField = false; - PyClass containingClass = null; - PyParameterList paramList = PsiTreeUtil.getParentOfType(element, PyParameterList.class); - if(paramList != null && paramList.getParent() instanceof PyFunction) - { - final PyFunction func = (PyFunction) paramList.getParent(); - containingClass = func.getContainingClass(); - if(PyNames.INIT.equals(func.getName()) && containingClass != null && !namedParameter.isKeywordContainer() && !namedParameter.isPositionalContainer()) - { - mayBeField = true; - } - else if(ignoreUnusedParameters(func, functionsWithInheritors)) - { - continue; - } - if(func.asMethod() != null) - { - Boolean isEmpty = emptyFunctions.get(func); - if(isEmpty == null) - { - isEmpty = PyUtil.isEmptyFunction(func); - emptyFunctions.put(func, isEmpty); - } - if(isEmpty && !mayBeField) - { - continue; - } - } - } - boolean canRemove = !(PsiTreeUtil.getPrevSiblingOfType(element, PyParameter.class) instanceof PySingleStarParameter) || PsiTreeUtil.getNextSiblingOfType(element, PyParameter - .class) != null; - - final List fixes = new ArrayList<>(); - if(mayBeField) - { - fixes.add(new AddFieldQuickFix(name, name, containingClass.getName(), false)); - } - if(canRemove) - { - fixes.add(new PyRemoveParameterQuickFix()); - } - registerWarning(element, PyBundle.message("INSP.unused.locals.parameter.isnot.used", name), fixes.toArray(new LocalQuickFix[fixes.size()])); - } - else - { - if(myIgnoreTupleUnpacking && isTupleUnpacking(element)) - { - continue; - } - final PyForStatement forStatement = PyForStatementNavigator.getPyForStatementByIterable(element); - if(forStatement != null) - { - if(!myIgnoreRangeIterationVariables || !isRangeIteration(forStatement)) - { - registerProblem(element, PyBundle.message("INSP.unused.locals.local.variable.isnot.used", name), ProblemHighlightType.LIKE_UNUSED_SYMBOL, null, new ReplaceWithWildCard()); - } - } - else - { - registerWarning(element, PyBundle.message("INSP.unused.locals.local.variable.isnot.used", name), new PyRemoveStatementQuickFix()); - } - } - } - } - } - - private boolean isRangeIteration(PyForStatement forStatement) - { - final PyExpression source = forStatement.getForPart().getSource(); - if(!(source instanceof PyCallExpression)) - { - return false; - } - PyCallExpression expr = (PyCallExpression) source; - if(expr.isCalleeText("range", "xrange")) - { - final PyCallable callee = expr.resolveCalleeFunction(PyResolveContext.noImplicits().withTypeEvalContext(myTypeEvalContext)); - if(callee != null && PyBuiltinCache.getInstance(forStatement).isBuiltin(callee)) - { - return true; - } - } - return false; - } - - private boolean ignoreUnusedParameters(PyFunction func, Set functionsWithInheritors) - { - if(functionsWithInheritors.contains(func)) - { - return true; - } - if(!PyNames.INIT.equals(func.getName()) && PySuperMethodsSearch.search(func, myTypeEvalContext).findFirst() != null || PyOverridingMethodsSearch.search(func, true).findFirst() != null) - { - functionsWithInheritors.add(func); - return true; - } - return false; - } - - private boolean isTupleUnpacking(PsiElement element) - { - if(!(element instanceof PyTargetExpression)) - { - return false; - } - // Handling of the star expressions - PsiElement parent = element.getParent(); - if(parent instanceof PyStarExpression) - { - element = parent; - parent = element.getParent(); - } - if(parent instanceof PyTupleExpression) - { - // if all the items of the tuple are unused, we still highlight all of them; if some are unused, we ignore - final PyTupleExpression tuple = (PyTupleExpression) parent; - for(PyExpression expression : tuple.getElements()) - { - if(expression instanceof PyStarExpression) - { - if(!myUnusedElements.contains(((PyStarExpression) expression).getExpression())) - { - return true; - } - } - else if(!myUnusedElements.contains(expression)) - { - return true; - } - } - } - return false; - } - - private void registerWarning(@Nonnull final PsiElement element, final String msg, LocalQuickFix... quickfixes) - { - registerProblem(element, msg, ProblemHighlightType.LIKE_UNUSED_SYMBOL, null, quickfixes); - } - - private static class ReplaceWithWildCard implements LocalQuickFix - { - @Nonnull - public String getFamilyName() - { - return PyBundle.message("INSP.unused.locals.replace.with.wildcard"); - } - - public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) - { - if(!FileModificationService.getInstance().preparePsiElementForWrite(descriptor.getPsiElement())) - { - return; - } - replace(descriptor.getPsiElement()); - } - - private void replace(final PsiElement psiElement) - { - final PyFile pyFile = (PyFile) PyElementGenerator.getInstance(psiElement.getProject()).createDummyFile(LanguageLevel.getDefault(), "for _ in tuples:\n pass"); - final PyExpression target = ((PyForStatement) pyFile.getStatements().get(0)).getForPart().getTarget(); - CommandProcessor.getInstance().executeCommand(psiElement.getProject(), () -> ApplicationManager.getApplication().runWriteAction(() -> { - if(target != null) - { - psiElement.replace(target); - } - }), getName(), null); - } - } +public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor { + private final boolean myIgnoreTupleUnpacking; + private final boolean myIgnoreLambdaParameters; + private final boolean myIgnoreRangeIterationVariables; + private final HashSet myUnusedElements; + private final HashSet myUsedElements; + + public PyUnusedLocalInspectionVisitor( + @Nonnull ProblemsHolder holder, + @Nonnull LocalInspectionToolSession session, + boolean ignoreTupleUnpacking, + boolean ignoreLambdaParameters, + boolean ignoreRangeIterationVariables + ) { + super(holder, session); + myIgnoreTupleUnpacking = ignoreTupleUnpacking; + myIgnoreLambdaParameters = ignoreLambdaParameters; + myIgnoreRangeIterationVariables = ignoreRangeIterationVariables; + myUnusedElements = new HashSet<>(); + myUsedElements = new HashSet<>(); + } + + @Override + public void visitPyFunction(final PyFunction node) { + processScope(node); + } + + @Override + public void visitPyLambdaExpression(final PyLambdaExpression node) { + processScope(node); + } + + @Override + public void visitPyClass(PyClass node) { + processScope(node); + } + + private void processScope(final ScopeOwner owner) { + if (owner.getContainingFile() instanceof PyExpressionCodeFragment || callsLocals(owner)) { + return; + } + if (!(owner instanceof PyClass)) { + collectAllWrites(owner); + } + collectUsedReads(owner); + } + + @Override + public void visitPyStringLiteralExpression(PyStringLiteralExpression pyString) { + final ScopeOwner owner = ScopeUtil.getScopeOwner(pyString); + if (owner != null && !(owner instanceof PsiFile)) { + final PyStatement instrAnchor = PsiTreeUtil.getParentOfType(pyString, PyStatement.class); + if (instrAnchor == null) { + return; + } + final Instruction[] instructions = ControlFlowCache.getControlFlow(owner).getInstructions(); + final int startInstruction = ControlFlowUtil.findInstructionNumberByElement(instructions, instrAnchor); + if (startInstruction < 0) { + return; + } + final Project project = pyString.getProject(); + final List> pairs = InjectedLanguageManager.getInstance(project).getInjectedPsiFiles(pyString); + if (pairs != null) { + for (Pair pair : pairs) { + pair.getFirst().accept(new PyRecursiveElementVisitor() { + @Override + public void visitPyReferenceExpression(PyReferenceExpression expr) { + final PyExpression qualifier = expr.getQualifier(); + if (qualifier != null) { + qualifier.accept(this); + return; + } + final String name = expr.getName(); + if (name != null) { + analyzeReadsInScope(name, owner, instructions, startInstruction, pyString); + } + } + }); + } + } + } + } + + private void collectAllWrites(ScopeOwner owner) { + final Instruction[] instructions = ControlFlowCache.getControlFlow(owner).getInstructions(); + for (Instruction instruction : instructions) { + final PsiElement element = instruction.getElement(); + if (element instanceof PyFunction && owner instanceof PyFunction) { + if (PyKnownDecoratorUtil.hasUnknownDecorator((PyFunction) element, myTypeEvalContext)) { + continue; + } + if (!myUsedElements.contains(element)) { + myUnusedElements.add(element); + } + } + else if (instruction instanceof ReadWriteInstruction) { + final ReadWriteInstruction readWriteInstruction = (ReadWriteInstruction) instruction; + final ReadWriteInstruction.ACCESS access = readWriteInstruction.getAccess(); + if (!access.isWriteAccess()) { + continue; + } + final String name = readWriteInstruction.getName(); + // Ignore empty, wildcards, global and nonlocal names + final Scope scope = ControlFlowCache.getScope(owner); + if (name == null || "_".equals(name) || scope.isGlobal(name) || scope.isNonlocal(name)) { + continue; + } + // Ignore elements out of scope + if (element == null || !PsiTreeUtil.isAncestor(owner, element, false)) { + continue; + } + // Ignore arguments of import statement + if (PyImportStatementNavigator.getImportStatementByElement(element) != null) { + continue; + } + if (PyAugAssignmentStatementNavigator.getStatementByTarget(element) != null) { + continue; + } + if (parameterInMethodWithFixedSignature(owner, element)) { + continue; + } + if (!myUsedElements.contains(element)) { + myUnusedElements.add(element); + } + } + } + } + + private static boolean parameterInMethodWithFixedSignature(@Nonnull ScopeOwner owner, @Nonnull PsiElement element) { + if (owner instanceof PyFunction && element instanceof PyParameter) { + final PyFunction function = (PyFunction) owner; + final String functionName = function.getName(); + + return !PyNames.INIT.equals(functionName) && + function.getContainingClass() != null && + PyNames.getBuiltinMethods(LanguageLevel.forElement(function)).containsKey(functionName); + } + + return false; + } + + private void collectUsedReads(final ScopeOwner owner) { + final Instruction[] instructions = ControlFlowCache.getControlFlow(owner).getInstructions(); + for (int i = 0; i < instructions.length; i++) { + final Instruction instruction = instructions[i]; + if (instruction instanceof ReadWriteInstruction) { + final ReadWriteInstruction readWriteInstruction = (ReadWriteInstruction) instruction; + final ReadWriteInstruction.ACCESS access = readWriteInstruction.getAccess(); + if (!access.isReadAccess()) { + continue; + } + final String name = readWriteInstruction.getName(); + if (name == null) { + continue; + } + final PsiElement element = instruction.getElement(); + // Ignore elements out of scope + if (element == null || !PsiTreeUtil.isAncestor(owner, element, false)) { + continue; + } + final int startInstruction; + if (access.isWriteAccess()) { + final PyAugAssignmentStatement augAssignmentStatement = PyAugAssignmentStatementNavigator.getStatementByTarget(element); + startInstruction = ControlFlowUtil.findInstructionNumberByElement(instructions, augAssignmentStatement); + } + else { + startInstruction = i; + } + analyzeReadsInScope(name, owner, instructions, startInstruction, as(element, PyReferenceExpression.class)); + } + } + } + + private void analyzeReadsInScope( + @Nonnull String name, + @Nonnull ScopeOwner owner, + @Nonnull Instruction[] instructions, + int startInstruction, + @Nullable PsiElement scopeAnchor + ) { + // Check if the element is declared out of scope, mark all out of scope write accesses as used + if (scopeAnchor != null) { + final ScopeOwner declOwner = ScopeUtil.getDeclarationScopeOwner(scopeAnchor, name); + if (declOwner != null && declOwner != owner) { + final Collection writeElements = ScopeUtil.getReadWriteElements(name, declOwner, false, true); + for (PsiElement e : writeElements) { + myUsedElements.add(e); + myUnusedElements.remove(e); + } + } + } + ControlFlowUtil.iteratePrev(startInstruction, instructions, inst -> { + final PsiElement instElement = inst.getElement(); + // Mark function as used + if (instElement instanceof PyFunction) { + if (name.equals(((PyFunction) instElement).getName())) { + myUsedElements.add(instElement); + myUnusedElements.remove(instElement); + return ControlFlowUtil.Operation.CONTINUE; + } + } + // Mark write access as used + else if (inst instanceof ReadWriteInstruction) { + final ReadWriteInstruction rwInstruction = (ReadWriteInstruction) inst; + if (rwInstruction.getAccess().isWriteAccess() && name.equals(rwInstruction.getName())) { + // For elements in scope + if (instElement != null && PsiTreeUtil.isAncestor(owner, instElement, false)) { + myUsedElements.add(instElement); + myUnusedElements.remove(instElement); + } + return ControlFlowUtil.Operation.CONTINUE; + } + } + return ControlFlowUtil.Operation.NEXT; + }); + } + + static class DontPerformException extends RuntimeException { + } + + private static boolean callsLocals(final ScopeOwner owner) { + try { + owner.acceptChildren(new PyRecursiveElementVisitor() { + @Override + public void visitPyCallExpression(final PyCallExpression node) { + final PyExpression callee = node.getCallee(); + if (callee != null && "locals".equals(callee.getName())) { + throw new DontPerformException(); + } + node.acceptChildren(this); // look at call expr in arguments + } + + @Override + public void visitPyFunction(final PyFunction node) { + // stop here + } + }); + } + catch (DontPerformException e) { + return true; + } + return false; + } + + void registerProblems() { + final PyInspectionExtension[] filters = Extensions.getExtensions(PyInspectionExtension.EP_NAME); + // Register problems + + final Set functionsWithInheritors = new HashSet<>(); + final Map emptyFunctions = new HashMap<>(); + + for (PsiElement element : myUnusedElements) { + boolean ignoreUnused = false; + for (PyInspectionExtension filter : filters) { + if (filter.ignoreUnused(element)) { + ignoreUnused = true; + } + } + if (ignoreUnused) { + continue; + } + + if (element instanceof PyFunction) { + // Local function + final PsiElement nameIdentifier = ((PyFunction) element).getNameIdentifier(); + registerWarning( + nameIdentifier == null ? element : nameIdentifier, + PyBundle.message("INSP.unused.locals.local.function.isnot.used", ((PyFunction) element).getName()), + new + PyRemoveStatementQuickFix() + ); + } + else if (element instanceof PyClass) { + // Local class + final PyClass cls = (PyClass) element; + final PsiElement name = cls.getNameIdentifier(); + registerWarning( + name != null ? name : element, + PyBundle.message("INSP.unused.locals.local.class.isnot.used", cls.getName()), + new PyRemoveStatementQuickFix() + ); + } + else { + // Local variable or parameter + String name = element.getText(); + if (element instanceof PyNamedParameter || element.getParent() instanceof PyNamedParameter) { + PyNamedParameter namedParameter = + element instanceof PyNamedParameter ? (PyNamedParameter) element : (PyNamedParameter) element.getParent(); + name = namedParameter.getName(); + // When function is inside a class, first parameter may be either self or cls which is always 'used'. + if (namedParameter.isSelf()) { + continue; + } + if (myIgnoreLambdaParameters && PsiTreeUtil.getParentOfType(element, PyCallable.class) instanceof PyLambdaExpression) { + continue; + } + boolean mayBeField = false; + PyClass containingClass = null; + PyParameterList paramList = PsiTreeUtil.getParentOfType(element, PyParameterList.class); + if (paramList != null && paramList.getParent() instanceof PyFunction) { + final PyFunction func = (PyFunction) paramList.getParent(); + containingClass = func.getContainingClass(); + if (PyNames.INIT.equals(func.getName()) && containingClass != null && !namedParameter.isKeywordContainer() && !namedParameter.isPositionalContainer()) { + mayBeField = true; + } + else if (ignoreUnusedParameters(func, functionsWithInheritors)) { + continue; + } + if (func.asMethod() != null) { + Boolean isEmpty = emptyFunctions.get(func); + if (isEmpty == null) { + isEmpty = PyUtil.isEmptyFunction(func); + emptyFunctions.put(func, isEmpty); + } + if (isEmpty && !mayBeField) { + continue; + } + } + } + boolean canRemove = !(PsiTreeUtil.getPrevSiblingOfType( + element, + PyParameter.class + ) instanceof PySingleStarParameter) || PsiTreeUtil.getNextSiblingOfType(element, PyParameter + .class) != null; + + final List fixes = new ArrayList<>(); + if (mayBeField) { + fixes.add(new AddFieldQuickFix(name, name, containingClass.getName(), false)); + } + if (canRemove) { + fixes.add(new PyRemoveParameterQuickFix()); + } + registerWarning( + element, + PyLocalize.inspUnusedLocalsParameterIsnotUsed(name).get(), + fixes.toArray(new LocalQuickFix[fixes.size()]) + ); + } + else { + if (myIgnoreTupleUnpacking && isTupleUnpacking(element)) { + continue; + } + final PyForStatement forStatement = PyForStatementNavigator.getPyForStatementByIterable(element); + if (forStatement != null) { + if (!myIgnoreRangeIterationVariables || !isRangeIteration(forStatement)) { + registerProblem( + element, + PyLocalize.inspUnusedLocalsLocalVariableIsnotUsed(name).get(), + ProblemHighlightType.LIKE_UNUSED_SYMBOL, + null, + new ReplaceWithWildCard() + ); + } + } + else { + registerWarning( + element, + PyLocalize.inspUnusedLocalsLocalVariableIsnotUsed(name).get(), + new PyRemoveStatementQuickFix() + ); + } + } + } + } + } + + private boolean isRangeIteration(PyForStatement forStatement) { + final PyExpression source = forStatement.getForPart().getSource(); + if (!(source instanceof PyCallExpression)) { + return false; + } + PyCallExpression expr = (PyCallExpression) source; + if (expr.isCalleeText("range", "xrange")) { + final PyCallable callee = expr.resolveCalleeFunction(PyResolveContext.noImplicits().withTypeEvalContext(myTypeEvalContext)); + if (callee != null && PyBuiltinCache.getInstance(forStatement).isBuiltin(callee)) { + return true; + } + } + return false; + } + + private boolean ignoreUnusedParameters(PyFunction func, Set functionsWithInheritors) { + if (functionsWithInheritors.contains(func)) { + return true; + } + if (!PyNames.INIT.equals(func.getName()) && PySuperMethodsSearch.search(func, myTypeEvalContext) + .findFirst() != null || PyOverridingMethodsSearch.search(func, true).findFirst() != null) { + functionsWithInheritors.add(func); + return true; + } + return false; + } + + private boolean isTupleUnpacking(PsiElement element) { + if (!(element instanceof PyTargetExpression)) { + return false; + } + // Handling of the star expressions + PsiElement parent = element.getParent(); + if (parent instanceof PyStarExpression) { + element = parent; + parent = element.getParent(); + } + if (parent instanceof PyTupleExpression) { + // if all the items of the tuple are unused, we still highlight all of them; if some are unused, we ignore + final PyTupleExpression tuple = (PyTupleExpression) parent; + for (PyExpression expression : tuple.getElements()) { + if (expression instanceof PyStarExpression) { + if (!myUnusedElements.contains(((PyStarExpression) expression).getExpression())) { + return true; + } + } + else if (!myUnusedElements.contains(expression)) { + return true; + } + } + } + return false; + } + + private void registerWarning(@Nonnull final PsiElement element, final String msg, LocalQuickFix... quickfixes) { + registerProblem(element, msg, ProblemHighlightType.LIKE_UNUSED_SYMBOL, null, quickfixes); + } + + private static class ReplaceWithWildCard implements LocalQuickFix { + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.inspUnusedLocalsReplaceWithWildcard(); + } + + public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { + if (!FileModificationService.getInstance().preparePsiElementForWrite(descriptor.getPsiElement())) { + return; + } + replace(descriptor.getPsiElement()); + } + + private void replace(final PsiElement psiElement) { + final PyFile pyFile = (PyFile) PyElementGenerator.getInstance(psiElement.getProject()) + .createDummyFile(LanguageLevel.getDefault(), "for _ in tuples:\n pass"); + final PyExpression target = ((PyForStatement) pyFile.getStatements().get(0)).getForPart().getTarget(); + CommandProcessor.getInstance().newCommand() + .project(psiElement.getProject()) + .name(getName()) + .inWriteAction() + .run(() -> { + if (target != null) { + psiElement.replace(target); + } + }); + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/AddMethodQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/AddMethodQuickFix.java index 46999006..efdd90a8 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/AddMethodQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/AddMethodQuickFix.java @@ -15,14 +15,14 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import com.jetbrains.python.impl.PyBundle; import com.jetbrains.python.PyNames; +import com.jetbrains.python.impl.PyBundle; import com.jetbrains.python.impl.psi.PyUtil; -import com.jetbrains.python.psi.*; import com.jetbrains.python.impl.psi.impl.ParamHelper; import com.jetbrains.python.impl.psi.impl.PyFunctionBuilder; -import com.jetbrains.python.psi.types.PyClassType; import com.jetbrains.python.impl.psi.types.PyClassTypeImpl; +import com.jetbrains.python.psi.*; +import com.jetbrains.python.psi.types.PyClassType; import com.jetbrains.python.psi.types.PyType; import com.jetbrains.python.psi.types.TypeEvalContext; import consulo.codeEditor.Editor; @@ -37,19 +37,21 @@ import consulo.language.psi.PsiFile; import consulo.language.psi.util.PsiTreeUtil; import consulo.language.util.IncorrectOperationException; +import consulo.localize.LocalizeValue; import consulo.navigation.OpenFileDescriptorFactory; import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import consulo.ui.NotificationType; import consulo.virtualFileSystem.VirtualFile; - import jakarta.annotation.Nonnull; import static com.jetbrains.python.impl.psi.PyUtil.sure; /** * Adds a method foo to class X if X.foo() is unresolved. - * User: dcheryasov - * Date: Apr 5, 2009 6:51:26 PM + * + * @author dcheryasov + * @since 2009-04-05 */ public class AddMethodQuickFix implements LocalQuickFix { @@ -64,13 +66,9 @@ public AddMethodQuickFix(String identifier, String className, boolean replaceUsa } @Nonnull - public String getName() { - return PyBundle.message("QFIX.NAME.add.method.$0.to.class.$1", myIdentifier, myClassName); - } - - @Nonnull - public String getFamilyName() { - return "Add method to class"; + @Override + public LocalizeValue getName() { + return PyLocalize.qfixNameAddMethod$0ToClass$1(myIdentifier, myClassName); } public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/AddSelfQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/AddSelfQuickFix.java index 2b93ee59..23dc70eb 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/AddSelfQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/AddSelfQuickFix.java @@ -13,54 +13,48 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.psi.PyElementGenerator; +import com.jetbrains.python.psi.PyNamedParameter; +import com.jetbrains.python.psi.PyParameterList; import consulo.language.editor.FileModificationService; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.PyElementGenerator; -import com.jetbrains.python.psi.PyNamedParameter; -import com.jetbrains.python.psi.PyParameterList; -import org.jetbrains.annotations.NonNls; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; /** * Insert 'self' in a method that lacks any arguments - * User: dcheryasov - * Date: Nov 19, 2008 + * + * @author dcheryasov + * @since 2008-11-19 */ public class AddSelfQuickFix implements LocalQuickFix { - private final String myParamName; - - public AddSelfQuickFix(String paramName) { - myParamName = paramName; - } + private final String myParamName; - @Nonnull - public String getName() { - return PyBundle.message("QFIX.add.parameter.self", myParamName); - } + public AddSelfQuickFix(String paramName) { + myParamName = paramName; + } - @NonNls - @Nonnull - public String getFamilyName() { - return "Add parameter"; - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixAddParameterSelf(myParamName); + } - public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { - PsiElement problem_elt = descriptor.getPsiElement(); - if (problem_elt instanceof PyParameterList) { - final PyParameterList param_list = (PyParameterList)problem_elt; - if (!FileModificationService.getInstance().preparePsiElementForWrite(problem_elt)) { - return; - } - PyNamedParameter new_param = PyElementGenerator.getInstance(project).createParameter(myParamName); - param_list.addParameter(new_param); + public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { + PsiElement problem_elt = descriptor.getPsiElement(); + if (problem_elt instanceof PyParameterList) { + final PyParameterList param_list = (PyParameterList) problem_elt; + if (!FileModificationService.getInstance().preparePsiElementForWrite(problem_elt)) { + return; + } + PyNamedParameter new_param = PyElementGenerator.getInstance(project).createParameter(myParamName); + param_list.addParameter(new_param); + } } - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/AugmentedAssignmentQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/AugmentedAssignmentQuickFix.java index cfb68bb5..9d2feddd 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/AugmentedAssignmentQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/AugmentedAssignmentQuickFix.java @@ -13,79 +13,82 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; +import com.jetbrains.python.impl.psi.impl.PyAugAssignmentStatementImpl; +import com.jetbrains.python.psi.*; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiComment; import consulo.language.psi.PsiElement; import consulo.language.psi.util.PsiTreeUtil; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.*; -import com.jetbrains.python.impl.psi.impl.PyAugAssignmentStatementImpl; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import jakarta.annotation.Nonnull; import java.util.List; /** - * User: catherine - * * QuickFix to replace assignment that can be replaced with augmented assignment. * for instance, i = i + 1 --> i +=1 + * + * @author catherine */ public class AugmentedAssignmentQuickFix implements LocalQuickFix { - @Nonnull - public String getName() { - return PyBundle.message("QFIX.augment.assignment"); - } - - @Nonnull - public String getFamilyName() { - return getName(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixAugmentAssignment(); + } - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement element = descriptor.getPsiElement(); + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement element = descriptor.getPsiElement(); - if (element instanceof PyAssignmentStatement && element.isWritable()) { - final PyAssignmentStatement statement = (PyAssignmentStatement)element; + if (element instanceof PyAssignmentStatement && element.isWritable()) { + final PyAssignmentStatement statement = (PyAssignmentStatement) element; - final PyExpression target = statement.getLeftHandSideExpression(); - final PyBinaryExpression expression = (PyBinaryExpression)statement.getAssignedValue(); - if (expression == null) return; - PyExpression leftExpression = expression.getLeftExpression(); - PyExpression rightExpression = expression.getRightExpression(); - if (rightExpression instanceof PyParenthesizedExpression) - rightExpression = ((PyParenthesizedExpression)rightExpression).getContainedExpression(); - if (target != null && rightExpression != null) { - final String targetText = target.getText(); - final String rightText = rightExpression.getText(); - if (rightText.equals(targetText)) { - final PyExpression tmp = rightExpression; - rightExpression = leftExpression; - leftExpression = tmp; - } - final List comments = PsiTreeUtil.getChildrenOfTypeAsList(statement, PsiComment.class); + final PyExpression target = statement.getLeftHandSideExpression(); + final PyBinaryExpression expression = (PyBinaryExpression) statement.getAssignedValue(); + if (expression == null) { + return; + } + PyExpression leftExpression = expression.getLeftExpression(); + PyExpression rightExpression = expression.getRightExpression(); + if (rightExpression instanceof PyParenthesizedExpression) { + rightExpression = ((PyParenthesizedExpression) rightExpression).getContainedExpression(); + } + if (target != null && rightExpression != null) { + final String targetText = target.getText(); + final String rightText = rightExpression.getText(); + if (rightText.equals(targetText)) { + final PyExpression tmp = rightExpression; + rightExpression = leftExpression; + leftExpression = tmp; + } + final List comments = PsiTreeUtil.getChildrenOfTypeAsList(statement, PsiComment.class); - if ((leftExpression instanceof PyReferenceExpression || leftExpression instanceof PySubscriptionExpression)) { - if (leftExpression.getText().equals(targetText)) { - final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - final StringBuilder stringBuilder = new StringBuilder(); - final PsiElement psiOperator = expression.getPsiOperator(); - if (psiOperator == null) return; - stringBuilder.append(targetText).append(" "). - append(psiOperator.getText()).append("= ").append(rightExpression.getText()); - final PyAugAssignmentStatementImpl augAssignment = elementGenerator.createFromText(LanguageLevel.forElement(element), - PyAugAssignmentStatementImpl.class, stringBuilder.toString()); - for (PsiComment comment : comments) - augAssignment.add(comment); - statement.replace(augAssignment); - } + if ((leftExpression instanceof PyReferenceExpression || leftExpression instanceof PySubscriptionExpression)) { + if (leftExpression.getText().equals(targetText)) { + final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + final StringBuilder stringBuilder = new StringBuilder(); + final PsiElement psiOperator = expression.getPsiOperator(); + if (psiOperator == null) { + return; + } + stringBuilder.append(targetText).append(" "). + append(psiOperator.getText()).append("= ").append(rightExpression.getText()); + final PyAugAssignmentStatementImpl augAssignment = + elementGenerator.createFromText(LanguageLevel.forElement(element), + PyAugAssignmentStatementImpl.class, stringBuilder.toString() + ); + for (PsiComment comment : comments) + augAssignment.add(comment); + statement.replace(augAssignment); + } + } + } } - } } - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ChainedComparisonsQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ChainedComparisonsQuickFix.java index 2e131bfb..38d0703c 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ChainedComparisonsQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ChainedComparisonsQuickFix.java @@ -13,157 +13,163 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; +import com.jetbrains.python.PyTokenTypes; +import com.jetbrains.python.psi.PyBinaryExpression; +import com.jetbrains.python.psi.PyElementGenerator; +import com.jetbrains.python.psi.PyExpression; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.PyTokenTypes; -import com.jetbrains.python.psi.*; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; /** - * User: catherine - * * QuickFix to replace chained comparisons with more simple version * For instance, a < b and b < c --> a < b < c + * + * @author catherine */ public class ChainedComparisonsQuickFix implements LocalQuickFix { - boolean myIsLeftLeft; - boolean myIsRightLeft; - boolean getInnerRight; + boolean myIsLeftLeft; + boolean myIsRightLeft; + boolean getInnerRight; - public ChainedComparisonsQuickFix(boolean isLeft, boolean isRight, boolean getInner) { - myIsLeftLeft = isLeft; - myIsRightLeft = isRight; - getInnerRight = getInner; - } - - @Nonnull - public String getName() { - return PyBundle.message("QFIX.chained.comparison"); - } + public ChainedComparisonsQuickFix(boolean isLeft, boolean isRight, boolean getInner) { + myIsLeftLeft = isLeft; + myIsRightLeft = isRight; + getInnerRight = getInner; + } - @Nonnull - public String getFamilyName() { - return getName(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixChainedComparison(); + } - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement expression = descriptor.getPsiElement(); - if (expression != null && expression.isWritable()) { - if (expression instanceof PyBinaryExpression) { - PyExpression leftExpression = ((PyBinaryExpression)expression).getLeftExpression(); - PyExpression rightExpression = ((PyBinaryExpression)expression).getRightExpression(); - if (rightExpression instanceof PyBinaryExpression && leftExpression instanceof PyBinaryExpression) { - if (((PyBinaryExpression)expression).getOperator() == PyTokenTypes.AND_KEYWORD) { - if (getInnerRight && ((PyBinaryExpression)leftExpression).getRightExpression() instanceof PyBinaryExpression - && PyTokenTypes.AND_KEYWORD == ((PyBinaryExpression)leftExpression).getOperator()) { - leftExpression = ((PyBinaryExpression)leftExpression).getRightExpression(); + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement expression = descriptor.getPsiElement(); + if (expression != null && expression.isWritable()) { + if (expression instanceof PyBinaryExpression) { + PyExpression leftExpression = ((PyBinaryExpression) expression).getLeftExpression(); + PyExpression rightExpression = ((PyBinaryExpression) expression).getRightExpression(); + if (rightExpression instanceof PyBinaryExpression && leftExpression instanceof PyBinaryExpression) { + if (((PyBinaryExpression) expression).getOperator() == PyTokenTypes.AND_KEYWORD) { + if (getInnerRight && ((PyBinaryExpression) leftExpression).getRightExpression() instanceof PyBinaryExpression + && PyTokenTypes.AND_KEYWORD == ((PyBinaryExpression) leftExpression).getOperator()) { + leftExpression = ((PyBinaryExpression) leftExpression).getRightExpression(); + } + checkOperator((PyBinaryExpression) leftExpression, (PyBinaryExpression) rightExpression, project); + } + } } - checkOperator((PyBinaryExpression)leftExpression, (PyBinaryExpression)rightExpression, project); - } } - } } - } - private void checkOperator(final PyBinaryExpression leftExpression, - final PyBinaryExpression rightExpression, final Project project) { - final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - if (myIsLeftLeft) { - final PyExpression newLeftExpression = invertExpression(leftExpression, elementGenerator); + private void checkOperator( + final PyBinaryExpression leftExpression, + final PyBinaryExpression rightExpression, final Project project + ) { + final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + if (myIsLeftLeft) { + final PyExpression newLeftExpression = invertExpression(leftExpression, elementGenerator); - if (myIsRightLeft) { - final PsiElement operator = getLeftestOperator(rightExpression); - final PyBinaryExpression binaryExpression = elementGenerator.createBinaryExpression( + if (myIsRightLeft) { + final PsiElement operator = getLeftestOperator(rightExpression); + final PyBinaryExpression binaryExpression = elementGenerator.createBinaryExpression( operator.getText(), newLeftExpression, getLargeRightExpression(rightExpression, project)); - leftExpression.replace(binaryExpression); - rightExpression.delete(); - } - else { - final String operator = invertOperator(rightExpression.getPsiOperator()); - final PyBinaryExpression binaryExpression = elementGenerator.createBinaryExpression( + leftExpression.replace(binaryExpression); + rightExpression.delete(); + } + else { + final String operator = invertOperator(rightExpression.getPsiOperator()); + final PyBinaryExpression binaryExpression = elementGenerator.createBinaryExpression( operator, newLeftExpression, rightExpression.getLeftExpression()); - leftExpression.replace(binaryExpression); - rightExpression.delete(); - } - } - else { - if (myIsRightLeft) { - final PsiElement operator = getLeftestOperator(rightExpression); - final PyBinaryExpression binaryExpression = elementGenerator.createBinaryExpression( + leftExpression.replace(binaryExpression); + rightExpression.delete(); + } + } + else { + if (myIsRightLeft) { + final PsiElement operator = getLeftestOperator(rightExpression); + final PyBinaryExpression binaryExpression = elementGenerator.createBinaryExpression( operator.getText(), leftExpression, getLargeRightExpression(rightExpression, project)); - leftExpression.replace(binaryExpression); - rightExpression.delete(); - } - else { - PyExpression expression = rightExpression.getLeftExpression(); - if (expression instanceof PyBinaryExpression) - expression = invertExpression((PyBinaryExpression)expression, elementGenerator); - final String operator = invertOperator(rightExpression.getPsiOperator()); - final PyBinaryExpression binaryExpression = elementGenerator.createBinaryExpression( + leftExpression.replace(binaryExpression); + rightExpression.delete(); + } + else { + PyExpression expression = rightExpression.getLeftExpression(); + if (expression instanceof PyBinaryExpression) { + expression = invertExpression((PyBinaryExpression) expression, elementGenerator); + } + final String operator = invertOperator(rightExpression.getPsiOperator()); + final PyBinaryExpression binaryExpression = elementGenerator.createBinaryExpression( operator, leftExpression, expression); - leftExpression.replace(binaryExpression); - rightExpression.delete(); - } - } - - } + leftExpression.replace(binaryExpression); + rightExpression.delete(); + } + } - private PsiElement getLeftestOperator(PyBinaryExpression expression) { - PsiElement op = expression.getPsiOperator(); - while (expression.getLeftExpression() instanceof PyBinaryExpression) { - expression = (PyBinaryExpression)expression.getLeftExpression(); - op = expression.getPsiOperator(); } - assert op != null; - return op; - } - private PyExpression invertExpression(PyBinaryExpression leftExpression, PyElementGenerator elementGenerator) { - final PsiElement operator = leftExpression.getPsiOperator(); - final PyExpression right = leftExpression.getRightExpression(); - PyExpression left = leftExpression.getLeftExpression(); - if (left instanceof PyBinaryExpression){ - left = invertExpression((PyBinaryExpression)left, elementGenerator); + private PsiElement getLeftestOperator(PyBinaryExpression expression) { + PsiElement op = expression.getPsiOperator(); + while (expression.getLeftExpression() instanceof PyBinaryExpression) { + expression = (PyBinaryExpression) expression.getLeftExpression(); + op = expression.getPsiOperator(); + } + assert op != null; + return op; } - final String newOperator = invertOperator(operator); - return elementGenerator.createBinaryExpression( - newOperator, right, left); - } - private String invertOperator(PsiElement op) { - if (op.getText().equals(">")) - return "<"; - if (op.getText().equals("<")) - return ">"; - if (op.getText().equals(">=")) - return "<="; - if (op.getText().equals("<=")) - return ">="; - return op.getText(); - } + private PyExpression invertExpression(PyBinaryExpression leftExpression, PyElementGenerator elementGenerator) { + final PsiElement operator = leftExpression.getPsiOperator(); + final PyExpression right = leftExpression.getRightExpression(); + PyExpression left = leftExpression.getLeftExpression(); + if (left instanceof PyBinaryExpression) { + left = invertExpression((PyBinaryExpression) left, elementGenerator); + } + final String newOperator = invertOperator(operator); + return elementGenerator.createBinaryExpression( + newOperator, right, left); + } - @Nullable - static private PyExpression getLargeRightExpression(PyBinaryExpression expression, Project project) { - final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - PyExpression left = expression.getLeftExpression(); - PyExpression right = expression.getRightExpression(); - PsiElement operator = expression.getPsiOperator(); - while (left instanceof PyBinaryExpression) { - assert operator != null; - right = elementGenerator.createBinaryExpression(operator.getText(), - ((PyBinaryExpression)left).getRightExpression(), - right); - operator = ((PyBinaryExpression)left).getPsiOperator(); - left = ((PyBinaryExpression)left).getLeftExpression(); + private String invertOperator(PsiElement op) { + if (op.getText().equals(">")) { + return "<"; + } + if (op.getText().equals("<")) { + return ">"; + } + if (op.getText().equals(">=")) { + return "<="; + } + if (op.getText().equals("<=")) { + return ">="; + } + return op.getText(); } - return right; - } + @Nullable + static private PyExpression getLargeRightExpression(PyBinaryExpression expression, Project project) { + final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + PyExpression left = expression.getLeftExpression(); + PyExpression right = expression.getRightExpression(); + PsiElement operator = expression.getPsiOperator(); + while (left instanceof PyBinaryExpression) { + assert operator != null; + right = elementGenerator.createBinaryExpression( + operator.getText(), + ((PyBinaryExpression) left).getRightExpression(), + right + ); + operator = ((PyBinaryExpression) left).getPsiOperator(); + left = ((PyBinaryExpression) left).getLeftExpression(); + } + return right; + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ComparisonWithNoneQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ComparisonWithNoneQuickFix.java index 9ba941c6..e169a4ba 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ComparisonWithNoneQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ComparisonWithNoneQuickFix.java @@ -13,51 +13,46 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - -import consulo.language.editor.inspection.LocalQuickFix; -import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; -import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; import com.jetbrains.python.PyTokenTypes; import com.jetbrains.python.psi.PyBinaryExpression; import com.jetbrains.python.psi.PyElementGenerator; import com.jetbrains.python.psi.PyElementType; import com.jetbrains.python.psi.PyExpression; +import consulo.language.editor.inspection.LocalQuickFix; +import consulo.language.editor.inspection.ProblemDescriptor; +import consulo.language.psi.PsiElement; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; /** - * Created by IntelliJ IDEA. - * Author: Alexey.Ivanov - * Date: 24.03.2010 - * Time: 22:00:49 + * @author Alexey.Ivanov + * @since 2010-03-24 */ public class ComparisonWithNoneQuickFix implements LocalQuickFix { - @Nonnull - public String getName() { - return PyBundle.message("QFIX.replace.equality"); - } - - @Nonnull - public String getFamilyName() { - return getName(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixReplaceEquality(); + } - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement problemElement = descriptor.getPsiElement(); - if (problemElement instanceof PyBinaryExpression) { - PyBinaryExpression binaryExpression = (PyBinaryExpression)problemElement; - PyElementType operator = binaryExpression.getOperator(); - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - String temp; - temp = (operator == PyTokenTypes.EQEQ) ? "is" : "is not"; - PyExpression expression = elementGenerator.createBinaryExpression(temp, - binaryExpression.getLeftExpression(), - binaryExpression.getRightExpression()); - binaryExpression.replace(expression); + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement problemElement = descriptor.getPsiElement(); + if (problemElement instanceof PyBinaryExpression) { + PyBinaryExpression binaryExpression = (PyBinaryExpression) problemElement; + PyElementType operator = binaryExpression.getOperator(); + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + String temp; + temp = (operator == PyTokenTypes.EQEQ) ? "is" : "is not"; + PyExpression expression = elementGenerator.createBinaryExpression( + temp, + binaryExpression.getLeftExpression(), + binaryExpression.getRightExpression() + ); + binaryExpression.replace(expression); + } } - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/CompatibilityPrintCallQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/CompatibilityPrintCallQuickFix.java index 00a835f3..c27b3796 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/CompatibilityPrintCallQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/CompatibilityPrintCallQuickFix.java @@ -13,10 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import com.jetbrains.python.impl.PyBundle; import com.jetbrains.python.psi.LanguageLevel; import com.jetbrains.python.psi.PyElementGenerator; import com.jetbrains.python.psi.PyExpression; @@ -24,43 +22,41 @@ import consulo.language.editor.inspection.ProblemDescriptor; import consulo.language.psi.PsiElement; import consulo.language.psi.util.PsiTreeUtil; +import consulo.localize.LocalizeValue; import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import consulo.util.lang.StringUtil; - import jakarta.annotation.Nonnull; /** - * User: catherine - * * QuickFix to replace statement that has no effect with function call + * + * @author catherine */ public class CompatibilityPrintCallQuickFix implements LocalQuickFix { - @Nonnull - public String getName() { - return PyBundle.message("QFIX.statement.effect"); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixStatementEffect(); + } - @Nonnull - public String getFamilyName() { - return getName(); - } + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement expression = descriptor.getPsiElement(); + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + replacePrint(expression, elementGenerator); + } - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement expression = descriptor.getPsiElement(); - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - replacePrint(expression, elementGenerator); - } + private static void replacePrint(PsiElement expression, PyElementGenerator elementGenerator) { + StringBuilder stringBuilder = new StringBuilder("print("); - private static void replacePrint(PsiElement expression, PyElementGenerator elementGenerator) { - StringBuilder stringBuilder = new StringBuilder("print("); + PyExpression[] target = PsiTreeUtil.getChildrenOfType(expression, PyExpression.class); + if (target != null) { + stringBuilder.append(StringUtil.join(target, o -> o.getText(), ", ")); + } - PyExpression[] target = PsiTreeUtil.getChildrenOfType(expression, PyExpression.class); - if (target != null) { - stringBuilder.append(StringUtil.join(target, o -> o.getText(), ", ")); + stringBuilder.append(")"); + expression.replace(elementGenerator.createFromText(LanguageLevel.forElement(expression), PyExpression.class, + stringBuilder.toString() + )); } - - stringBuilder.append(")"); - expression.replace(elementGenerator.createFromText(LanguageLevel.forElement(expression), PyExpression.class, - stringBuilder.toString())); - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertDictCompQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertDictCompQuickFix.java index 836cdb9b..fdd58b16 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertDictCompQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertDictCompQuickFix.java @@ -15,98 +15,74 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import java.util.List; - -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.psi.*; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.LanguageLevel; -import com.jetbrains.python.psi.PyComprehensionComponent; -import com.jetbrains.python.psi.PyComprehensionForComponent; -import com.jetbrains.python.psi.PyComprehensionIfComponent; -import com.jetbrains.python.psi.PyDictCompExpression; -import com.jetbrains.python.psi.PyElementGenerator; -import com.jetbrains.python.psi.PyExpression; -import com.jetbrains.python.psi.PyExpressionStatement; -import com.jetbrains.python.psi.PyKeyValueExpression; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; + +import java.util.List; /** - * Created by IntelliJ IDEA. - * User: Alexey.Ivanov - * Date: 20.02.2010 - * Time: 15:49:35 + * @author Alexey.Ivanov + * @since 2010-02-20 */ -public class ConvertDictCompQuickFix implements LocalQuickFix -{ - @Nonnull - @Override - public String getName() - { - return PyBundle.message("INTN.convert.dict.comp.to"); - } - - @Nonnull - public String getFamilyName() - { - return PyBundle.message("INTN.Family.convert.dict.comp.expression"); - } - - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) - { - PsiElement element = descriptor.getPsiElement(); - if(!LanguageLevel.forElement(element).isPy3K() && element instanceof PyDictCompExpression) - { - replaceComprehension(project, (PyDictCompExpression) element); - } - } +public class ConvertDictCompQuickFix implements LocalQuickFix { + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.intnConvertDictCompTo(); + } - private static void replaceComprehension(Project project, PyDictCompExpression expression) - { - if(expression.getResultExpression() instanceof PyKeyValueExpression) - { - final PyKeyValueExpression keyValueExpression = (PyKeyValueExpression) expression.getResultExpression(); - final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - assert keyValueExpression.getValue() != null; + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement element = descriptor.getPsiElement(); + if (!LanguageLevel.forElement(element).isPy3K() && element instanceof PyDictCompExpression) { + replaceComprehension(project, (PyDictCompExpression) element); + } + } - final List components = expression.getComponents(); - final StringBuilder replacement = new StringBuilder("dict([(" + keyValueExpression.getKey().getText() + ", " + - keyValueExpression.getValue().getText() + ")"); - int slashNum = 1; - for(PyComprehensionComponent component : components) - { - if(component instanceof PyComprehensionForComponent) - { - replacement.append("for "); - replacement.append(((PyComprehensionForComponent) component).getIteratorVariable().getText()); - replacement.append(" in "); - replacement.append(((PyComprehensionForComponent) component).getIteratedList().getText()); - replacement.append(" "); - } - if(component instanceof PyComprehensionIfComponent) - { - final PyExpression test = ((PyComprehensionIfComponent) component).getTest(); - if(test != null) - { - replacement.append("if "); - replacement.append(test.getText()); - replacement.append(" "); - } - } - for(int i = 0; i != slashNum; ++i) - { - replacement.append("\t"); - } - ++slashNum; - } - replacement.append("])"); + private static void replaceComprehension(Project project, PyDictCompExpression expression) { + if (expression.getResultExpression() instanceof PyKeyValueExpression) { + final PyKeyValueExpression keyValueExpression = (PyKeyValueExpression) expression.getResultExpression(); + final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + assert keyValueExpression.getValue() != null; - expression.replace(elementGenerator.createFromText(LanguageLevel.getDefault(), PyExpressionStatement.class, replacement.toString())); - } - } + final List components = expression.getComponents(); + final StringBuilder replacement = new StringBuilder("dict([(" + keyValueExpression.getKey().getText() + ", " + + keyValueExpression.getValue().getText() + ")"); + int slashNum = 1; + for (PyComprehensionComponent component : components) { + if (component instanceof PyComprehensionForComponent) { + replacement.append("for "); + replacement.append(((PyComprehensionForComponent) component).getIteratorVariable().getText()); + replacement.append(" in "); + replacement.append(((PyComprehensionForComponent) component).getIteratedList().getText()); + replacement.append(" "); + } + if (component instanceof PyComprehensionIfComponent) { + final PyExpression test = ((PyComprehensionIfComponent) component).getTest(); + if (test != null) { + replacement.append("if "); + replacement.append(test.getText()); + replacement.append(" "); + } + } + for (int i = 0; i != slashNum; ++i) { + replacement.append("\t"); + } + ++slashNum; + } + replacement.append("])"); + expression.replace(elementGenerator.createFromText( + LanguageLevel.getDefault(), + PyExpressionStatement.class, + replacement.toString() + )); + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertDocstringQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertDocstringQuickFix.java index 1287ae35..cf89196d 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertDocstringQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertDocstringQuickFix.java @@ -13,62 +13,59 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.impl.psi.impl.PyStringLiteralExpressionImpl; +import com.jetbrains.python.psi.PyElementGenerator; +import com.jetbrains.python.psi.PyExpression; +import com.jetbrains.python.psi.PyStringLiteralExpression; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; +import consulo.language.psi.PsiElement; +import consulo.localize.LocalizeValue; import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import consulo.util.lang.StringUtil; -import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.PyElementGenerator; -import com.jetbrains.python.psi.PyExpression; -import com.jetbrains.python.psi.PyStringLiteralExpression; -import com.jetbrains.python.impl.psi.impl.PyStringLiteralExpressionImpl; +import jakarta.annotation.Nonnull; /** - * User: catherine - * * QuickFix to convert docstrings to the common form according to PEP-257 * For consistency, always use """triple double quotes""" around docstrings. + * + * @author catherine */ public class ConvertDocstringQuickFix implements LocalQuickFix { - @Nonnull - public String getName() { - return PyBundle.message("QFIX.convert.single.quoted.docstring"); - } - - @Nonnull - public String getFamilyName() { - return getName(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixConvertSingleQuotedDocstring(); + } - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement expression = descriptor.getPsiElement(); - if (expression instanceof PyStringLiteralExpression && expression.isWritable()) { - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement expression = descriptor.getPsiElement(); + if (expression instanceof PyStringLiteralExpression && expression.isWritable()) { + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - String stringText = expression.getText(); - int prefixLength = PyStringLiteralExpressionImpl - .getPrefixLength(stringText); - String prefix = stringText.substring(0, prefixLength); - String content = stringText.substring(prefixLength); - if (content.startsWith("'''") ) { - content = content.substring(3, content.length()-3); - } else if (content.startsWith("\"\"\"")) - return; - else { - content = content.length() == 1 ? "" : content.substring(1, content.length()-1); - } - if (content.endsWith("\"")) - content = StringUtil.replaceSubstring(content, content.length()-1, content.length(), "\\\""); + String stringText = expression.getText(); + int prefixLength = PyStringLiteralExpressionImpl + .getPrefixLength(stringText); + String prefix = stringText.substring(0, prefixLength); + String content = stringText.substring(prefixLength); + if (content.startsWith("'''")) { + content = content.substring(3, content.length() - 3); + } + else if (content.startsWith("\"\"\"")) { + return; + } + else { + content = content.length() == 1 ? "" : content.substring(1, content.length() - 1); + } + if (content.endsWith("\"")) { + content = StringUtil.replaceSubstring(content, content.length() - 1, content.length(), "\\\""); + } - PyExpression newString = elementGenerator.createDocstring(prefix+"\"\"\"" + content + "\"\"\"").getExpression(); - expression.replace(newString); + PyExpression newString = elementGenerator.createDocstring(prefix + "\"\"\"" + content + "\"\"\"").getExpression(); + expression.replace(newString); + } } - } - } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertIndentsFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertIndentsFix.java index 1e31a854..7b01132e 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertIndentsFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertIndentsFix.java @@ -13,56 +13,49 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - -import consulo.language.editor.inspection.LocalQuickFix; -import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.ide.impl.idea.codeStyle.CodeStyleFacade; import consulo.document.Document; -import consulo.ide.impl.idea.openapi.editor.actions.ConvertIndentsActionBase; -import consulo.project.Project; import consulo.document.util.TextRange; +import consulo.ide.impl.idea.codeStyle.CodeStyleFacade; +import consulo.ide.impl.idea.openapi.editor.actions.ConvertIndentsActionBase; +import consulo.language.editor.inspection.LocalQuickFix; +import consulo.language.editor.inspection.ProblemDescriptor; import consulo.language.psi.PsiDocumentManager; import consulo.language.psi.PsiFile; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import jakarta.annotation.Nonnull; /** * @author yole */ public class ConvertIndentsFix implements LocalQuickFix { - private final boolean myToSpaces; - - public ConvertIndentsFix(boolean toSpaces) { - myToSpaces = toSpaces; - } + private final boolean myToSpaces; - @Nonnull - @Override - public String getName() { - return myToSpaces ? "Convert indents to spaces" : "Convert indents to tabs"; - } + public ConvertIndentsFix(boolean toSpaces) { + myToSpaces = toSpaces; + } - @Nonnull - @Override - public String getFamilyName() { - return "Convert indents"; - } + @Nonnull + @Override + public LocalizeValue getName() { + return myToSpaces ? LocalizeValue.localizeTODO("Convert indents to spaces") : LocalizeValue.localizeTODO("Convert indents to tabs"); + } - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiFile file = descriptor.getPsiElement().getContainingFile(); - Document document = PsiDocumentManager.getInstance(project).getDocument(file); - if (document != null) { - int tabSize = CodeStyleFacade.getInstance(project).getIndentSize(file.getFileType()); - TextRange allDoc = new TextRange(0, document.getTextLength()); - if (myToSpaces) { - ConvertIndentsActionBase.convertIndentsToSpaces(document, tabSize, allDoc); - } - else { - ConvertIndentsActionBase.convertIndentsToTabs(document, tabSize, allDoc); - } + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiFile file = descriptor.getPsiElement().getContainingFile(); + Document document = PsiDocumentManager.getInstance(project).getDocument(file); + if (document != null) { + int tabSize = CodeStyleFacade.getInstance(project).getIndentSize(file.getFileType()); + TextRange allDoc = new TextRange(0, document.getTextLength()); + if (myToSpaces) { + ConvertIndentsActionBase.convertIndentsToSpaces(document, tabSize, allDoc); + } + else { + ConvertIndentsActionBase.convertIndentsToTabs(document, tabSize, allDoc); + } + } } - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertSetLiteralQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertSetLiteralQuickFix.java index 22c90ebd..de0dc28c 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertSetLiteralQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ConvertSetLiteralQuickFix.java @@ -13,50 +13,46 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.psi.*; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.*; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; /** - * Created by IntelliJ IDEA. - * User: Alexey.Ivanov - * Date: 16.02.2010 - * Time: 21:33:28 + * @author Alexey.Ivanov + * @since 2010-02-16 */ public class ConvertSetLiteralQuickFix implements LocalQuickFix { - @Nonnull - @Override - public String getName() { - return PyBundle.message("INTN.convert.set.literal.to"); - } - - @Nonnull - public String getFamilyName() { - return PyBundle.message("INTN.Family.convert.set.literal"); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.intnConvertSetLiteralTo(); + } - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement setLiteral = descriptor.getPsiElement(); - if (setLiteral instanceof PySetLiteralExpression) { - PyExpression[] expressions = ((PySetLiteralExpression)setLiteral).getElements(); - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - assert expressions.length != 0; - StringBuilder stringBuilder = new StringBuilder(expressions[0].getText()); - for (int i = 1; i < expressions.length; ++i) { - stringBuilder.append(", "); - stringBuilder.append(expressions[i].getText()); - } - PyStatement newElement = elementGenerator.createFromText(LanguageLevel.getDefault(), PyExpressionStatement.class, "set([" + stringBuilder.toString() + "])"); - setLiteral.replace(newElement); + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement setLiteral = descriptor.getPsiElement(); + if (setLiteral instanceof PySetLiteralExpression) { + PyExpression[] expressions = ((PySetLiteralExpression) setLiteral).getElements(); + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + assert expressions.length != 0; + StringBuilder stringBuilder = new StringBuilder(expressions[0].getText()); + for (int i = 1; i < expressions.length; ++i) { + stringBuilder.append(", "); + stringBuilder.append(expressions[i].getText()); + } + PyStatement newElement = elementGenerator.createFromText( + LanguageLevel.getDefault(), + PyExpressionStatement.class, + "set([" + stringBuilder.toString() + "])" + ); + setLiteral.replace(newElement); + } } - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/CreateClassQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/CreateClassQuickFix.java index 46e33bf2..15a5019a 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/CreateClassQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/CreateClassQuickFix.java @@ -13,72 +13,67 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import consulo.language.editor.CodeInsightUtilCore; -import consulo.language.editor.template.TemplateBuilder; -import consulo.language.editor.template.TemplateBuilderFactory; -import consulo.language.editor.inspection.LocalQuickFix; -import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; -import consulo.language.psi.PsiElement; import com.jetbrains.python.PyNames; import com.jetbrains.python.psi.LanguageLevel; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElementGenerator; import com.jetbrains.python.psi.PyFile; - +import consulo.language.editor.CodeInsightUtilCore; +import consulo.language.editor.inspection.LocalQuickFix; +import consulo.language.editor.inspection.ProblemDescriptor; +import consulo.language.editor.template.TemplateBuilder; +import consulo.language.editor.template.TemplateBuilderFactory; +import consulo.language.psi.PsiElement; +import consulo.localize.LocalizeValue; +import consulo.project.Project; import jakarta.annotation.Nonnull; /** * @author yole */ public class CreateClassQuickFix implements LocalQuickFix { - private final String myClassName; - private final PsiElement myAnchor; - - public CreateClassQuickFix(String className, PsiElement anchor) { - myClassName = className; - myAnchor = anchor; - } + private final String myClassName; + private final PsiElement myAnchor; - @Nonnull - public String getName() { - if (myAnchor instanceof PyFile) { - return "Create class '" + myClassName + "' in module " + ((PyFile)myAnchor).getName(); + public CreateClassQuickFix(String className, PsiElement anchor) { + myClassName = className; + myAnchor = anchor; } - return "Create class '" + myClassName + "'"; - } - @Nonnull - public String getFamilyName() { - return "Create Class"; - } - - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement anchor = myAnchor; - if (!anchor.isValid()) { - return; - } - if (!(anchor instanceof PyFile)) { - while(!(anchor.getParent() instanceof PyFile)) { - anchor = anchor.getParent(); - } - } - PyClass pyClass = PyElementGenerator.getInstance(project).createFromText(LanguageLevel.getDefault(), PyClass.class, - "class " + myClassName + "(object):\n pass"); - if (anchor instanceof PyFile) { - pyClass = (PyClass) anchor.add(pyClass); + @Nonnull + @Override + public LocalizeValue getName() { + if (myAnchor instanceof PyFile) { + return LocalizeValue.localizeTODO("Create class '" + myClassName + "' in module " + ((PyFile) myAnchor).getName()); + } + return LocalizeValue.localizeTODO("Create class '" + myClassName + "'"); } - else { - pyClass = (PyClass) anchor.getParent().addBefore(pyClass, anchor); - } - pyClass = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(pyClass); - TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(pyClass); - builder.replaceElement(pyClass.getSuperClassExpressions() [0], "object"); - builder.replaceElement(pyClass.getStatementList(), PyNames.PASS); - builder.run(); - } + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement anchor = myAnchor; + if (!anchor.isValid()) { + return; + } + if (!(anchor instanceof PyFile)) { + while (!(anchor.getParent() instanceof PyFile)) { + anchor = anchor.getParent(); + } + } + PyClass pyClass = PyElementGenerator.getInstance(project).createFromText(LanguageLevel.getDefault(), PyClass.class, + "class " + myClassName + "(object):\n pass" + ); + if (anchor instanceof PyFile) { + pyClass = (PyClass) anchor.add(pyClass); + } + else { + pyClass = (PyClass) anchor.getParent().addBefore(pyClass, anchor); + } + pyClass = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(pyClass); + TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(pyClass); + builder.replaceElement(pyClass.getSuperClassExpressions()[0], "object"); + builder.replaceElement(pyClass.getStatementList(), PyNames.PASS); + builder.run(); + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/DictCreationQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/DictCreationQuickFix.java index 37774fa7..9c182b95 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/DictCreationQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/DictCreationQuickFix.java @@ -13,101 +13,104 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.jetbrains.python.impl.inspections.PyDictCreationInspection; +import com.jetbrains.python.psi.*; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; +import consulo.language.psi.util.PsiTreeUtil; +import consulo.localize.LocalizeValue; import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import consulo.util.lang.Pair; import consulo.util.lang.StringUtil; -import consulo.language.psi.util.PsiTreeUtil; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.impl.inspections.PyDictCreationInspection; -import com.jetbrains.python.psi.*; import jakarta.annotation.Nonnull; import java.util.List; import java.util.Map; /** - * Created by IntelliJ IDEA. - * User: Alexey.Ivanov - * Date: 26.02.2010 - * Time: 13:29:02 + * @author Alexey.Ivanov + * @since 2010-02-26 */ public class DictCreationQuickFix implements LocalQuickFix { - private final PyAssignmentStatement myStatement; - public DictCreationQuickFix(@Nonnull final PyAssignmentStatement statement) { - myStatement = statement; - } + private final PyAssignmentStatement myStatement; - @Override - @Nonnull - public String getName() { - return PyBundle.message("QFIX.dict.creation"); - } + public DictCreationQuickFix(@Nonnull final PyAssignmentStatement statement) { + myStatement = statement; + } - @Override - @Nonnull - public String getFamilyName() { - return getName(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixDictCreation(); + } - @Override - public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { - final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - final Map statementsMap = Maps.newLinkedHashMap(); - final PyExpression assignedValue = myStatement.getAssignedValue(); - if (assignedValue instanceof PyDictLiteralExpression) { - for (PyKeyValueExpression expression: ((PyDictLiteralExpression)assignedValue).getElements()) { - final PyExpression value = expression.getValue(); - if (value != null) - statementsMap.put(expression.getKey().getText(), value.getText()); - } + @Override + public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { + final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + final Map statementsMap = Maps.newLinkedHashMap(); + final PyExpression assignedValue = myStatement.getAssignedValue(); + if (assignedValue instanceof PyDictLiteralExpression) { + for (PyKeyValueExpression expression : ((PyDictLiteralExpression) assignedValue).getElements()) { + final PyExpression value = expression.getValue(); + if (value != null) { + statementsMap.put(expression.getKey().getText(), value.getText()); + } + } - PyStatement statement = PsiTreeUtil.getNextSiblingOfType(myStatement, PyStatement.class); - while (statement instanceof PyAssignmentStatement) { - final PyAssignmentStatement assignmentStatement = (PyAssignmentStatement)statement; - final PyExpression target = myStatement.getTargets()[0]; - final String targetName = target.getName(); - if (targetName != null) { - final List> targetsToValues = - PyDictCreationInspection.getDictTargets(target, targetName, assignmentStatement); - final PyStatement nextStatement = PsiTreeUtil.getNextSiblingOfType(statement, PyStatement.class); - if (targetsToValues == null || targetsToValues.isEmpty()) break; - for (Pair targetToValue : targetsToValues) { - final PySubscriptionExpression subscription = (PySubscriptionExpression)targetToValue.first; - final PyExpression indexExpression = subscription.getIndexExpression(); - assert indexExpression != null; - final String indexText; - if (indexExpression instanceof PyTupleExpression) - indexText = "("+indexExpression.getText()+")"; - else - indexText = indexExpression.getText(); + PyStatement statement = PsiTreeUtil.getNextSiblingOfType(myStatement, PyStatement.class); + while (statement instanceof PyAssignmentStatement) { + final PyAssignmentStatement assignmentStatement = (PyAssignmentStatement) statement; + final PyExpression target = myStatement.getTargets()[0]; + final String targetName = target.getName(); + if (targetName != null) { + final List> targetsToValues = + PyDictCreationInspection.getDictTargets(target, targetName, assignmentStatement); + final PyStatement nextStatement = PsiTreeUtil.getNextSiblingOfType(statement, PyStatement.class); + if (targetsToValues == null || targetsToValues.isEmpty()) { + break; + } + for (Pair targetToValue : targetsToValues) { + final PySubscriptionExpression subscription = (PySubscriptionExpression) targetToValue.first; + final PyExpression indexExpression = subscription.getIndexExpression(); + assert indexExpression != null; + final String indexText; + if (indexExpression instanceof PyTupleExpression) { + indexText = "(" + indexExpression.getText() + ")"; + } + else { + indexText = indexExpression.getText(); + } - final String valueText; - if (targetToValue.second instanceof PyTupleExpression) - valueText = "("+targetToValue.second.getText()+")"; - else - valueText = targetToValue.second.getText(); + final String valueText; + if (targetToValue.second instanceof PyTupleExpression) { + valueText = "(" + targetToValue.second.getText() + ")"; + } + else { + valueText = targetToValue.second.getText(); + } - statementsMap.put(indexText, valueText); - statement.delete(); - } - statement = nextStatement; + statementsMap.put(indexText, valueText); + statement.delete(); + } + statement = nextStatement; + } + } + List statements = Lists.newArrayList(); + for (Map.Entry entry : statementsMap.entrySet()) { + statements.add(entry.getKey() + ": " + entry.getValue()); + } + final PyExpression expression = elementGenerator.createExpressionFromText( + LanguageLevel.forElement(myStatement), + "{" + StringUtil.join(statements, ", ") + "}" + ); + if (expression != null) { + assignedValue.replace(expression); + } } - } - List statements = Lists.newArrayList(); - for (Map.Entry entry : statementsMap.entrySet()) { - statements.add(entry.getKey() + ": " + entry.getValue()); - } - final PyExpression expression = elementGenerator.createExpressionFromText(LanguageLevel.forElement(myStatement), - "{" + StringUtil.join(statements, ", ") + "}"); - if (expression != null) - assignedValue.replace(expression); } - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/DocstringQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/DocstringQuickFix.java index 64b9a740..3722a4a7 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/DocstringQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/DocstringQuickFix.java @@ -15,110 +15,85 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; -import jakarta.annotation.Nullable; +import com.jetbrains.python.impl.codeInsight.intentions.PyGenerateDocstringIntention; +import com.jetbrains.python.impl.documentation.docstrings.PyDocstringGenerator; +import com.jetbrains.python.psi.*; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.SmartPointerManager; import consulo.language.psi.SmartPsiElementPointer; import consulo.language.psi.util.PsiTreeUtil; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.impl.codeInsight.intentions.PyGenerateDocstringIntention; -import com.jetbrains.python.impl.documentation.docstrings.PyDocstringGenerator; -import com.jetbrains.python.psi.PyClass; -import com.jetbrains.python.psi.PyDocStringOwner; -import com.jetbrains.python.psi.PyFunction; -import com.jetbrains.python.psi.PyNamedParameter; -import com.jetbrains.python.psi.PyStringLiteralExpression; import consulo.language.util.IncorrectOperationException; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; /** - * User : catherine + * @author catherine */ -public class DocstringQuickFix implements LocalQuickFix -{ - private final SmartPsiElementPointer myMissingParam; - private final String myUnexpectedParamName; - - public DocstringQuickFix(@Nullable PyNamedParameter missing, @Nullable String unexpectedParamName) - { - if(missing != null) - { - myMissingParam = SmartPointerManager.getInstance(missing.getProject()).createSmartPsiElementPointer(missing); - } - else - { - myMissingParam = null; - } - myUnexpectedParamName = unexpectedParamName; - } +public class DocstringQuickFix implements LocalQuickFix { + private final SmartPsiElementPointer myMissingParam; + private final String myUnexpectedParamName; - @Nonnull - public String getName() - { - if(myMissingParam != null) - { - final PyNamedParameter param = myMissingParam.getElement(); - if(param == null) - { - throw new IncorrectOperationException("Parameter was invalidates before quickfix is called"); - } - return PyBundle.message("QFIX.docstring.add.$0", param.getName()); - } - else if(myUnexpectedParamName != null) - { - return PyBundle.message("QFIX.docstring.remove.$0", myUnexpectedParamName); - } - else - { - return PyBundle.message("QFIX.docstring.insert.stub"); - } - } + public DocstringQuickFix(@Nullable PyNamedParameter missing, @Nullable String unexpectedParamName) { + if (missing != null) { + myMissingParam = SmartPointerManager.getInstance(missing.getProject()).createSmartPsiElementPointer(missing); + } + else { + myMissingParam = null; + } + myUnexpectedParamName = unexpectedParamName; + } - @Nonnull - public String getFamilyName() - { - return "Fix docstring"; - } + @Nonnull + @Override + public LocalizeValue getName() { + if (myMissingParam != null) { + final PyNamedParameter param = myMissingParam.getElement(); + if (param == null) { + throw new IncorrectOperationException("Parameter was invalidates before quickfix is called"); + } + return PyLocalize.qfixDocstringAdd$0(param.getName()); + } + else if (myUnexpectedParamName != null) { + return PyLocalize.qfixDocstringRemove$0(myUnexpectedParamName); + } + else { + return PyLocalize.qfixDocstringInsertStub(); + } + } - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) - { - PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PyDocStringOwner.class); - if(docStringOwner == null) - { - return; - } - PyStringLiteralExpression docStringExpression = docStringOwner.getDocStringExpression(); - if(docStringExpression == null && myMissingParam == null && myUnexpectedParamName == null) - { - addEmptyDocstring(docStringOwner); - return; - } - if(docStringExpression != null) - { - final PyDocstringGenerator generator = PyDocstringGenerator.forDocStringOwner(docStringOwner); - if(myMissingParam != null) - { - final PyNamedParameter param = myMissingParam.getElement(); - if(param != null) - { - generator.withParam(param); - } - } - else if(myUnexpectedParamName != null) - { - generator.withoutParam(myUnexpectedParamName.trim()); - } - generator.buildAndInsert(); - } - } + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PyDocStringOwner.class); + if (docStringOwner == null) { + return; + } + PyStringLiteralExpression docStringExpression = docStringOwner.getDocStringExpression(); + if (docStringExpression == null && myMissingParam == null && myUnexpectedParamName == null) { + addEmptyDocstring(docStringOwner); + return; + } + if (docStringExpression != null) { + final PyDocstringGenerator generator = PyDocstringGenerator.forDocStringOwner(docStringOwner); + if (myMissingParam != null) { + final PyNamedParameter param = myMissingParam.getElement(); + if (param != null) { + generator.withParam(param); + } + } + else if (myUnexpectedParamName != null) { + generator.withoutParam(myUnexpectedParamName.trim()); + } + generator.buildAndInsert(); + } + } - private static void addEmptyDocstring(@Nonnull PyDocStringOwner docStringOwner) - { - if(docStringOwner instanceof PyFunction || docStringOwner instanceof PyClass && ((PyClass) docStringOwner).findInitOrNew(false, null) != null) - { - PyGenerateDocstringIntention.generateDocstring(docStringOwner, PyQuickFixUtil.getEditor(docStringOwner)); - } - } + private static void addEmptyDocstring(@Nonnull PyDocStringOwner docStringOwner) { + if (docStringOwner instanceof PyFunction + || docStringOwner instanceof PyClass pyClass && pyClass.findInitOrNew(false, null) != null) { + PyGenerateDocstringIntention.generateDocstring(docStringOwner, PyQuickFixUtil.getEditor(docStringOwner)); + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ListCreationQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ListCreationQuickFix.java index 8e9fa589..d8dabd3a 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ListCreationQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ListCreationQuickFix.java @@ -13,59 +13,57 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; +import com.jetbrains.python.psi.*; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; +import consulo.localize.LocalizeValue; import consulo.project.Project; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.*; +import consulo.python.impl.localize.PyLocalize; import jakarta.annotation.Nonnull; import java.util.ArrayList; import java.util.List; /** - * User : catherine + * @author catherine */ public class ListCreationQuickFix implements LocalQuickFix { - private final PyAssignmentStatement myStatement; - private final List myStatements = new ArrayList(); - - public ListCreationQuickFix(PyAssignmentStatement statement) { - myStatement = statement; - } + private final PyAssignmentStatement myStatement; + private final List myStatements = new ArrayList(); - public void addStatement(PyExpressionStatement statement) { - myStatements.add(statement); - } + public ListCreationQuickFix(PyAssignmentStatement statement) { + myStatement = statement; + } - @Nonnull - public String getName() { - return PyBundle.message("QFIX.list.creation"); - } + public void addStatement(PyExpressionStatement statement) { + myStatements.add(statement); + } - @Nonnull - public String getFamilyName() { - return getName(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixListCreation(); + } - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - StringBuilder stringBuilder = new StringBuilder(); - final PyExpression assignedValue = myStatement.getAssignedValue(); - if (assignedValue == null) return; + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + StringBuilder stringBuilder = new StringBuilder(); + final PyExpression assignedValue = myStatement.getAssignedValue(); + if (assignedValue == null) { + return; + } - for (PyExpression expression : ((PyListLiteralExpression)assignedValue).getElements()) { - stringBuilder.append(expression.getText()).append(", "); - } - for (PyExpressionStatement statement: myStatements) { - for (PyExpression expr : ((PyCallExpression)statement.getExpression()).getArguments()) - stringBuilder.append(expr.getText()).append(", "); - statement.delete(); + for (PyExpression expression : ((PyListLiteralExpression) assignedValue).getElements()) { + stringBuilder.append(expression.getText()).append(", "); + } + for (PyExpressionStatement statement : myStatements) { + for (PyExpression expr : ((PyCallExpression) statement.getExpression()).getArguments()) + stringBuilder.append(expr.getText()).append(", "); + statement.delete(); + } + assignedValue.replace( + elementGenerator.createExpressionFromText("[" + stringBuilder.substring(0, stringBuilder.length() - 2) + "]")); } - assignedValue.replace( - elementGenerator.createExpressionFromText("[" + stringBuilder.substring(0, stringBuilder.length() - 2) + "]")); - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/MoveFromFutureImportQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/MoveFromFutureImportQuickFix.java index 440241c3..150f82b9 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/MoveFromFutureImportQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/MoveFromFutureImportQuickFix.java @@ -13,43 +13,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.psi.PyFile; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiFile; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.PyFile; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; /** - * Created by IntelliJ IDEA. - * Author: Alexey.Ivanov - * Date: 24.03.2010 - * Time: 20:15:23 + * @author Alexey.Ivanov + * @since 2010-03-24 */ public class MoveFromFutureImportQuickFix implements LocalQuickFix { - @Nonnull - public String getName() { - return PyBundle.message("QFIX.move.from.future.import"); - } - - @Nonnull - public String getFamilyName() { - return getName(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixMoveFromFutureImport(); + } - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement problemElement = descriptor.getPsiElement(); - PsiFile psiFile = problemElement.getContainingFile(); - if (psiFile instanceof PyFile) { - PyFile file = (PyFile)psiFile; - file.addBefore(problemElement, file.getStatements().get(0)); - problemElement.delete(); + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement problemElement = descriptor.getPsiElement(); + PsiFile psiFile = problemElement.getContainingFile(); + if (psiFile instanceof PyFile) { + PyFile file = (PyFile) psiFile; + file.addBefore(problemElement, file.getStatements().get(0)); + problemElement.delete(); + } } - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyAddExceptionSuperClassQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyAddExceptionSuperClassQuickFix.java index 542fcf36..527100d1 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyAddExceptionSuperClassQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyAddExceptionSuperClassQuickFix.java @@ -15,62 +15,49 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.psi.*; +import consulo.language.ast.ASTNode; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.language.ast.ASTNode; -import consulo.project.Project; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiPolyVariantReference; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.LanguageLevel; -import com.jetbrains.python.psi.PyArgumentList; -import com.jetbrains.python.psi.PyCallExpression; -import com.jetbrains.python.psi.PyClass; -import com.jetbrains.python.psi.PyElementGenerator; -import com.jetbrains.python.psi.PyExpression; -import com.jetbrains.python.psi.PyReferenceExpression; - -public class PyAddExceptionSuperClassQuickFix implements LocalQuickFix -{ - - @Nonnull - public String getFamilyName() - { - return PyBundle.message("QFIX.NAME.add.exception.base"); - } +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) - { - final PsiElement element = descriptor.getPsiElement(); - if(element instanceof PyCallExpression) - { - PyExpression callee = ((PyCallExpression) element).getCallee(); - if(callee instanceof PyReferenceExpression) - { - final PsiPolyVariantReference reference = ((PyReferenceExpression) callee).getReference(); - PsiElement psiElement = reference.resolve(); - if(psiElement instanceof PyClass) - { - final PyElementGenerator generator = PyElementGenerator.getInstance(project); - final PyArgumentList list = ((PyClass) psiElement).getSuperClassExpressionList(); - if(list != null) - { - final PyExpression exception = generator.createExpressionFromText(LanguageLevel.forElement(element), "Exception"); - list.addArgument(exception); - } - else - { - final PyArgumentList expressionList = generator.createFromText(LanguageLevel.forElement(element), PyClass.class, "class A(Exception): pass").getSuperClassExpressionList(); - assert expressionList != null; - final ASTNode nameNode = ((PyClass) psiElement).getNameNode(); - assert nameNode != null; - psiElement.addAfter(expressionList, nameNode.getPsi()); - } - } - } - } - } +public class PyAddExceptionSuperClassQuickFix implements LocalQuickFix { + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixNameAddExceptionBase(); + } + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + if (element instanceof PyCallExpression) { + PyExpression callee = ((PyCallExpression) element).getCallee(); + if (callee instanceof PyReferenceExpression) { + final PsiPolyVariantReference reference = ((PyReferenceExpression) callee).getReference(); + PsiElement psiElement = reference.resolve(); + if (psiElement instanceof PyClass) { + final PyElementGenerator generator = PyElementGenerator.getInstance(project); + final PyArgumentList list = ((PyClass) psiElement).getSuperClassExpressionList(); + if (list != null) { + final PyExpression exception = generator.createExpressionFromText(LanguageLevel.forElement(element), "Exception"); + list.addArgument(exception); + } + else { + final PyArgumentList expressionList = + generator.createFromText(LanguageLevel.forElement(element), PyClass.class, "class A(Exception): pass") + .getSuperClassExpressionList(); + assert expressionList != null; + final ASTNode nameNode = ((PyClass) psiElement).getNameNode(); + assert nameNode != null; + psiElement.addAfter(expressionList, nameNode.getPsi()); + } + } + } + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyAddPropertyForFieldQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyAddPropertyForFieldQuickFix.java index f7b23bb2..e8f29107 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyAddPropertyForFieldQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyAddPropertyForFieldQuickFix.java @@ -15,74 +15,65 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import java.util.Map; - -import jakarta.annotation.Nonnull; - import com.jetbrains.python.impl.psi.PyUtil; +import com.jetbrains.python.psi.*; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; -import consulo.util.lang.StringUtil; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiReference; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.*; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.util.lang.StringUtil; +import jakarta.annotation.Nonnull; + +import java.util.Map; -public class PyAddPropertyForFieldQuickFix implements LocalQuickFix -{ - private String myName = PyBundle.message("QFIX.add.property"); +public class PyAddPropertyForFieldQuickFix implements LocalQuickFix { + private final LocalizeValue myName; - public PyAddPropertyForFieldQuickFix(String name) - { - myName = name; - } + public PyAddPropertyForFieldQuickFix(LocalizeValue name) { + myName = name; + } - @Nonnull - public String getFamilyName() - { - return myName; - } + @Nonnull + @Override + public LocalizeValue getName() { + return myName; + } - public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) - { - final PsiElement element = descriptor.getPsiElement(); - if(element instanceof PyReferenceExpression) - { - final PsiReference reference = element.getReference(); - if(reference == null) - { - return; - } - final PsiElement resolved = reference.resolve(); - if(resolved instanceof PyTargetExpression) - { - PyTargetExpression target = (PyTargetExpression) resolved; - final PyClass containingClass = target.getContainingClass(); - if(containingClass != null) - { - final String name = target.getName(); - if(name == null) - { - return; - } - String propertyName = StringUtil.trimStart(name, "_"); - final Map properties = containingClass.getProperties(); - final PyElementGenerator generator = PyElementGenerator.getInstance(project); - if(!properties.containsKey(propertyName)) - { - final PyFunction property = generator.createProperty(LanguageLevel.forElement(containingClass), propertyName, name, AccessDirection.READ); - PyUtil.addElementToStatementList(property, containingClass.getStatementList(), false); - } - final PyExpression qualifier = ((PyReferenceExpression) element).getQualifier(); - if(qualifier != null) - { - String newElementText = qualifier.getText() + "." + propertyName; - final PyExpression newElement = generator.createExpressionFromText(LanguageLevel.forElement(containingClass), newElementText); - element.replace(newElement); - } - } - } - } - } + public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + if (element instanceof PyReferenceExpression) { + final PsiReference reference = element.getReference(); + if (reference == null) { + return; + } + final PsiElement resolved = reference.resolve(); + if (resolved instanceof PyTargetExpression) { + PyTargetExpression target = (PyTargetExpression) resolved; + final PyClass containingClass = target.getContainingClass(); + if (containingClass != null) { + final String name = target.getName(); + if (name == null) { + return; + } + String propertyName = StringUtil.trimStart(name, "_"); + final Map properties = containingClass.getProperties(); + final PyElementGenerator generator = PyElementGenerator.getInstance(project); + if (!properties.containsKey(propertyName)) { + final PyFunction property = + generator.createProperty(LanguageLevel.forElement(containingClass), propertyName, name, AccessDirection.READ); + PyUtil.addElementToStatementList(property, containingClass.getStatementList(), false); + } + final PyExpression qualifier = ((PyReferenceExpression) element).getQualifier(); + if (qualifier != null) { + String newElementText = qualifier.getText() + "." + propertyName; + final PyExpression newElement = + generator.createExpressionFromText(LanguageLevel.forElement(containingClass), newElementText); + element.replace(newElement); + } + } + } + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyChangeBaseClassQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyChangeBaseClassQuickFix.java index 4ef08ef0..10474863 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyChangeBaseClassQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyChangeBaseClassQuickFix.java @@ -15,7 +15,6 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import com.jetbrains.python.impl.PyBundle; import com.jetbrains.python.psi.PyArgumentList; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyExpression; @@ -27,38 +26,38 @@ import consulo.language.editor.template.TemplateBuilderFactory; import consulo.language.psi.PsiElement; import consulo.language.psi.util.PsiTreeUtil; +import consulo.localize.LocalizeValue; import consulo.navigation.OpenFileDescriptorFactory; import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import consulo.virtualFileSystem.VirtualFile; - import jakarta.annotation.Nonnull; public class PyChangeBaseClassQuickFix implements LocalQuickFix { - @Nonnull - @Override - public String getFamilyName() { - return PyBundle.message("QFIX.change.base.class"); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixChangeBaseClass(); + } - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement element = descriptor.getPsiElement(); - final PyClass pyClass = PsiTreeUtil.getParentOfType(element, PyClass.class); - assert pyClass != null; + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement element = descriptor.getPsiElement(); + final PyClass pyClass = PsiTreeUtil.getParentOfType(element, PyClass.class); + assert pyClass != null; - final PyArgumentList expressionList = pyClass.getSuperClassExpressionList(); - if (expressionList != null && expressionList.getArguments().length != 0) { - final PyExpression argument = expressionList.getArguments()[0]; - final TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(argument); - builder.replaceElement(argument, argument.getText()); - final VirtualFile virtualFile = element.getContainingFile().getVirtualFile(); - if (virtualFile != null) { - final Editor editor = FileEditorManager.getInstance(project) - .openTextEditor(OpenFileDescriptorFactory.getInstance(project).builder(virtualFile).build(), - true); - assert editor != null; - builder.run(editor, false); - } + final PyArgumentList expressionList = pyClass.getSuperClassExpressionList(); + if (expressionList != null && expressionList.getArguments().length != 0) { + final PyExpression argument = expressionList.getArguments()[0]; + final TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(argument); + builder.replaceElement(argument, argument.getText()); + final VirtualFile virtualFile = element.getContainingFile().getVirtualFile(); + if (virtualFile != null) { + final Editor editor = FileEditorManager.getInstance(project) + .openTextEditor(OpenFileDescriptorFactory.getInstance(project).builder(virtualFile).build(), true); + assert editor != null; + builder.run(editor, false); + } + } } - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyChangeSignatureQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyChangeSignatureQuickFix.java index 638fd972..102a809c 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyChangeSignatureQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyChangeSignatureQuickFix.java @@ -15,77 +15,73 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import java.util.List; - -import jakarta.annotation.Nonnull; - -import consulo.language.editor.inspection.LocalQuickFix; -import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; -import consulo.language.psi.util.PsiTreeUtil; -import com.jetbrains.python.impl.PyBundle; import com.jetbrains.python.PyNames; -import com.jetbrains.python.psi.PyClass; -import com.jetbrains.python.psi.PyFunction; import com.jetbrains.python.impl.psi.search.PySuperMethodsSearch; -import com.jetbrains.python.psi.types.TypeEvalContext; import com.jetbrains.python.impl.refactoring.changeSignature.PyChangeSignatureDialog; import com.jetbrains.python.impl.refactoring.changeSignature.PyMethodDescriptor; import com.jetbrains.python.impl.refactoring.changeSignature.PyParameterInfo; +import com.jetbrains.python.psi.PyClass; +import com.jetbrains.python.psi.PyFunction; +import com.jetbrains.python.psi.types.TypeEvalContext; +import consulo.language.editor.inspection.LocalQuickFix; +import consulo.language.editor.inspection.ProblemDescriptor; +import consulo.language.psi.util.PsiTreeUtil; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; -public class PyChangeSignatureQuickFix implements LocalQuickFix -{ +import java.util.List; - private final boolean myOverridenMethod; +public class PyChangeSignatureQuickFix implements LocalQuickFix { + private final boolean myOverridenMethod; - public PyChangeSignatureQuickFix(boolean overriddenMethod) - { - myOverridenMethod = overriddenMethod; - } + public PyChangeSignatureQuickFix(boolean overriddenMethod) { + myOverridenMethod = overriddenMethod; + } - @Nonnull - public String getFamilyName() - { - return PyBundle.message("QFIX.NAME.change.signature"); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixNameChangeSignature(); + } - public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) - { - final PyFunction function = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PyFunction.class); - if(function == null) - { - return; - } - final PyClass cls = function.getContainingClass(); - assert cls != null; - final String functionName = function.getName(); - final String complementaryName = PyNames.NEW.equals(functionName) ? PyNames.INIT : PyNames.NEW; - final TypeEvalContext context = TypeEvalContext.userInitiated(project, descriptor.getEndElement().getContainingFile()); - final PyFunction complementaryMethod = myOverridenMethod ? (PyFunction) PySuperMethodsSearch.search(function, context).findFirst() : cls.findMethodByName(complementaryName, true, null); + public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { + final PyFunction function = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PyFunction.class); + if (function == null) { + return; + } + final PyClass cls = function.getContainingClass(); + assert cls != null; + final String functionName = function.getName(); + final String complementaryName = PyNames.NEW.equals(functionName) ? PyNames.INIT : PyNames.NEW; + final TypeEvalContext context = TypeEvalContext.userInitiated(project, descriptor.getEndElement().getContainingFile()); + final PyFunction complementaryMethod = + myOverridenMethod ? (PyFunction) PySuperMethodsSearch.search(function, context).findFirst() : cls.findMethodByName( + complementaryName, + true, + null + ); - assert complementaryMethod != null; - final PyMethodDescriptor methodDescriptor = new PyMethodDescriptor(function) - { - @Override - public List getParameters() - { - final List parameterInfos = super.getParameters(); - final int paramLength = function.getParameterList().getParameters().length; - final int complementaryParamLength = complementaryMethod.getParameterList().getParameters().length; - if(complementaryParamLength > paramLength) - { - parameterInfos.add(new PyParameterInfo(-1, "**kwargs", "", false)); - } - return parameterInfos; - } - }; - final PyChangeSignatureDialog dialog = new PyChangeSignatureDialog(project, methodDescriptor); - dialog.show(); - } + assert complementaryMethod != null; + final PyMethodDescriptor methodDescriptor = new PyMethodDescriptor(function) { + @Override + public List getParameters() { + final List parameterInfos = super.getParameters(); + final int paramLength = function.getParameterList().getParameters().length; + final int complementaryParamLength = complementaryMethod.getParameterList().getParameters().length; + if (complementaryParamLength > paramLength) { + parameterInfos.add(new PyParameterInfo(-1, "**kwargs", "", false)); + } + return parameterInfos; + } + }; + final PyChangeSignatureDialog dialog = new PyChangeSignatureDialog(project, methodDescriptor); + dialog.show(); + } - //@Override - public boolean startInWriteAction() - { - return false; - } + //@Override + public boolean startInWriteAction() { + return false; + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyConvertToNewStyleQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyConvertToNewStyleQuickFix.java index 4f29ea3c..57c11543 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyConvertToNewStyleQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyConvertToNewStyleQuickFix.java @@ -15,51 +15,43 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.psi.*; +import consulo.language.ast.ASTNode; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.language.ast.ASTNode; -import consulo.project.Project; import consulo.language.psi.PsiElement; import consulo.language.psi.util.PsiTreeUtil; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.LanguageLevel; -import com.jetbrains.python.psi.PyArgumentList; -import com.jetbrains.python.psi.PyClass; -import com.jetbrains.python.psi.PyElementGenerator; -import com.jetbrains.python.psi.PyExpression; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; -public class PyConvertToNewStyleQuickFix implements LocalQuickFix -{ - @Nonnull - @Override - public String getFamilyName() - { - return PyBundle.message("QFIX.convert.to.new.style"); - } +public class PyConvertToNewStyleQuickFix implements LocalQuickFix { + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixConvertToNewStyle(); + } - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) - { - PsiElement element = descriptor.getPsiElement(); - final PyClass pyClass = PsiTreeUtil.getParentOfType(element, PyClass.class); - assert pyClass != null; + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement element = descriptor.getPsiElement(); + final PyClass pyClass = PsiTreeUtil.getParentOfType(element, PyClass.class); + assert pyClass != null; - final PyElementGenerator generator = PyElementGenerator.getInstance(project); - final PyArgumentList expressionList = pyClass.getSuperClassExpressionList(); - if(expressionList != null) - { - final PyExpression object = generator.createExpressionFromText(LanguageLevel.forElement(element), "object"); - expressionList.addArgumentFirst(object); - } - else - { - final PyArgumentList list = generator.createFromText(LanguageLevel.forElement(element), PyClass.class, "class A(object):pass").getSuperClassExpressionList(); - assert list != null; - final ASTNode node = pyClass.getNameNode(); - assert node != null; - pyClass.addAfter(list, node.getPsi()); - } - } + final PyElementGenerator generator = PyElementGenerator.getInstance(project); + final PyArgumentList expressionList = pyClass.getSuperClassExpressionList(); + if (expressionList != null) { + final PyExpression object = generator.createExpressionFromText(LanguageLevel.forElement(element), "object"); + expressionList.addArgumentFirst(object); + } + else { + final PyArgumentList list = generator.createFromText(LanguageLevel.forElement(element), PyClass.class, "class A(object):pass") + .getSuperClassExpressionList(); + assert list != null; + final ASTNode node = pyClass.getNameNode(); + assert node != null; + pyClass.addAfter(list, node.getPsi()); + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyCreatePropertyQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyCreatePropertyQuickFix.java index 1e15bcd6..13b4bf2b 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyCreatePropertyQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyCreatePropertyQuickFix.java @@ -15,63 +15,51 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - -import consulo.language.editor.inspection.LocalQuickFix; -import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; -import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.AccessDirection; -import com.jetbrains.python.psi.LanguageLevel; -import com.jetbrains.python.psi.PyClass; -import com.jetbrains.python.psi.PyElementGenerator; -import com.jetbrains.python.psi.PyExpression; -import com.jetbrains.python.psi.PyFunction; -import com.jetbrains.python.psi.PyQualifiedExpression; import com.jetbrains.python.impl.psi.PyUtil; +import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.types.PyClassType; import com.jetbrains.python.psi.types.PyType; import com.jetbrains.python.psi.types.TypeEvalContext; +import consulo.language.editor.inspection.LocalQuickFix; +import consulo.language.editor.inspection.ProblemDescriptor; +import consulo.language.psi.PsiElement; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; -public class PyCreatePropertyQuickFix implements LocalQuickFix -{ - private final AccessDirection myAccessDirection; +public class PyCreatePropertyQuickFix implements LocalQuickFix { + private final AccessDirection myAccessDirection; - public PyCreatePropertyQuickFix(AccessDirection dir) - { - myAccessDirection = dir; - } + public PyCreatePropertyQuickFix(AccessDirection dir) { + myAccessDirection = dir; + } - @Nonnull - public String getFamilyName() - { - return PyBundle.message("QFIX.create.property"); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixCreateProperty(); + } - public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) - { - final PsiElement element = descriptor.getPsiElement(); - if(element instanceof PyQualifiedExpression) - { - final PyExpression qualifier = ((PyQualifiedExpression) element).getQualifier(); - if(qualifier != null) - { - final PyType type = TypeEvalContext.codeAnalysis(element.getProject(), element.getContainingFile()).getType(qualifier); - if(type instanceof PyClassType) - { - final PyClass cls = ((PyClassType) type).getPyClass(); - final String propertyName = ((PyQualifiedExpression) element).getName(); - if(propertyName == null) - { - return; - } - final String fieldName = "_" + propertyName; - final PyElementGenerator generator = PyElementGenerator.getInstance(project); - final PyFunction property = generator.createProperty(LanguageLevel.forElement(cls), propertyName, fieldName, myAccessDirection); - PyUtil.addElementToStatementList(property, cls.getStatementList(), myAccessDirection == AccessDirection.READ); - } - } - } - } + public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + if (element instanceof PyQualifiedExpression) { + final PyExpression qualifier = ((PyQualifiedExpression) element).getQualifier(); + if (qualifier != null) { + final PyType type = TypeEvalContext.codeAnalysis(element.getProject(), element.getContainingFile()).getType(qualifier); + if (type instanceof PyClassType) { + final PyClass cls = ((PyClassType) type).getPyClass(); + final String propertyName = ((PyQualifiedExpression) element).getName(); + if (propertyName == null) { + return; + } + final String fieldName = "_" + propertyName; + final PyElementGenerator generator = PyElementGenerator.getInstance(project); + final PyFunction property = + generator.createProperty(LanguageLevel.forElement(cls), propertyName, fieldName, myAccessDirection); + PyUtil.addElementToStatementList(property, cls.getStatementList(), myAccessDirection == AccessDirection.READ); + } + } + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyDefaultArgumentQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyDefaultArgumentQuickFix.java index 31c2f4cc..d611b74a 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyDefaultArgumentQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyDefaultArgumentQuickFix.java @@ -13,80 +13,80 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.psi.*; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; import consulo.language.psi.util.PsiTreeUtil; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.*; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; /** - * User: catherine - * * QuickFix to replace mutable default argument. For instance, * def foo(args=[]): - pass + * pass * replace with: * def foo(args=None): - if not args: args = [] - pass + * if not args: args = [] + * pass + * + * @author catherine */ public class PyDefaultArgumentQuickFix implements LocalQuickFix { - @Override - @Nonnull - public String getName() { - return PyBundle.message("QFIX.default.argument"); - } + @Override + @Nonnull + public LocalizeValue getName() { + return PyLocalize.qfixDefaultArgument(); + } - @Override - @Nonnull - public String getFamilyName() { - return getName(); - } + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement defaultValue = descriptor.getPsiElement(); + PsiElement param = PsiTreeUtil.getParentOfType(defaultValue, PyNamedParameter.class); + PyFunction function = PsiTreeUtil.getParentOfType(defaultValue, PyFunction.class); + String defName = PsiTreeUtil.getParentOfType(defaultValue, PyNamedParameter.class).getName(); + if (function != null) { + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + PyStatementList list = function.getStatementList(); + if (list != null) { + PyParameterList paramList = function.getParameterList(); - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement defaultValue = descriptor.getPsiElement(); - PsiElement param = PsiTreeUtil.getParentOfType(defaultValue, PyNamedParameter.class); - PyFunction function = PsiTreeUtil.getParentOfType(defaultValue, PyFunction.class); - String defName = PsiTreeUtil.getParentOfType(defaultValue, PyNamedParameter.class).getName(); - if (function != null) { - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - PyStatementList list = function.getStatementList(); - if (list != null) { - PyParameterList paramList = function.getParameterList(); + StringBuilder str = new StringBuilder("def foo("); + int size = paramList.getParameters().length; + for (int i = 0; i != size; ++i) { + PyParameter p = paramList.getParameters()[i]; + if (p == param) { + str.append(defName).append("=None"); + } + else { + str.append(p.getText()); + } + if (i != size - 1) { + str.append(", "); + } + } + str.append("):\n\tpass"); + PyIfStatement ifStatement = elementGenerator.createFromText(LanguageLevel.forElement(function), PyIfStatement.class, + "if not " + defName + ": " + defName + " = " + defaultValue.getText() + ); - StringBuilder str = new StringBuilder("def foo("); - int size = paramList.getParameters().length; - for (int i = 0; i != size; ++i) { - PyParameter p = paramList.getParameters()[i]; - if (p == param) - str.append(defName).append("=None"); - else - str.append(p.getText()); - if (i != size-1) - str.append(", "); + PyStatement firstStatement = list.getStatements()[0]; + PyStringLiteralExpression docString = function.getDocStringExpression(); + if (docString != null) { + list.addAfter(ifStatement, firstStatement); + } + else { + list.addBefore(ifStatement, firstStatement); + } + paramList.replace(elementGenerator.createFromText(LanguageLevel.forElement(defaultValue), + PyFunction.class, str.toString() + ).getParameterList()); + } } - str.append("):\n\tpass"); - PyIfStatement ifStatement = elementGenerator.createFromText(LanguageLevel.forElement(function), PyIfStatement.class, - "if not " + defName + ": " + defName + " = " + defaultValue.getText()); - - PyStatement firstStatement = list.getStatements()[0]; - PyStringLiteralExpression docString = function.getDocStringExpression(); - if (docString != null) - list.addAfter(ifStatement, firstStatement); - else - list.addBefore(ifStatement, firstStatement); - paramList.replace(elementGenerator.createFromText(LanguageLevel.forElement(defaultValue), - PyFunction.class, str.toString()).getParameterList()); - } } - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyImplementMethodsQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyImplementMethodsQuickFix.java index 3cce3742..f26c6a59 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyImplementMethodsQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyImplementMethodsQuickFix.java @@ -13,69 +13,71 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import consulo.language.editor.inspection.LocalQuickFix; -import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.document.Document; +import com.jetbrains.python.impl.codeInsight.override.PyOverrideImplementUtil; +import com.jetbrains.python.psi.PyClass; +import com.jetbrains.python.psi.PyFunction; import consulo.codeEditor.Editor; import consulo.codeEditor.EditorFactory; -import consulo.project.Project; +import consulo.document.Document; +import consulo.language.editor.inspection.LocalQuickFix; +import consulo.language.editor.inspection.ProblemDescriptor; import consulo.language.psi.PsiDocumentManager; import consulo.language.psi.PsiFile; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.impl.codeInsight.override.PyOverrideImplementUtil; -import com.jetbrains.python.psi.PyClass; -import com.jetbrains.python.psi.PyFunction; -import org.jetbrains.annotations.NonNls; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; import java.util.Set; /** - * User: ktisha + * @author ktisha */ public class PyImplementMethodsQuickFix implements LocalQuickFix { + private final PyClass myClass; + private final Set myToImplement; - private final PyClass myClass; - private final Set myToImplement; - - public PyImplementMethodsQuickFix(PyClass aClass, Set toBeImplemented) { - myClass = aClass; - myToImplement = toBeImplemented; - } - - @Nonnull - public String getName() { - return PyBundle.message("QFIX.NAME.implement.methods"); - } - - @NonNls - @Nonnull - public String getFamilyName() { - return getName(); - } + public PyImplementMethodsQuickFix(PyClass aClass, Set toBeImplemented) { + myClass = aClass; + myToImplement = toBeImplemented; + } - public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { - final Editor editor = getEditor(project, descriptor.getPsiElement().getContainingFile()); - if (editor != null) - PyOverrideImplementUtil.chooseAndOverrideOrImplementMethods(project, editor, myClass, myToImplement, "Select Methods to Implement", true); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixNameImplementMethods(); + } - @Nullable - private static Editor getEditor(Project project, PsiFile file) { - Document document = PsiDocumentManager.getInstance(project).getDocument(file); - if (document != null) { - final EditorFactory instance = EditorFactory.getInstance(); - if (instance == null) return null; - Editor[] editors = instance.getEditors(document); - if (editors.length > 0) { - return editors[0]; - } + public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { + final Editor editor = getEditor(project, descriptor.getPsiElement().getContainingFile()); + if (editor != null) { + PyOverrideImplementUtil.chooseAndOverrideOrImplementMethods( + project, + editor, + myClass, + myToImplement, + "Select Methods to Implement", + true + ); + } } - return null; - } + @Nullable + private static Editor getEditor(Project project, PsiFile file) { + Document document = PsiDocumentManager.getInstance(project).getDocument(file); + if (document != null) { + final EditorFactory instance = EditorFactory.getInstance(); + if (instance == null) { + return null; + } + Editor[] editors = instance.getEditors(document); + if (editors.length > 0) { + return editors[0]; + } + } + return null; + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMakeFunctionFromMethodQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMakeFunctionFromMethodQuickFix.java index bb35e69d..2c4dc2fa 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMakeFunctionFromMethodQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMakeFunctionFromMethodQuickFix.java @@ -15,190 +15,161 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import java.util.Collections; -import java.util.List; - -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.PyNames; +import com.jetbrains.python.impl.codeInsight.imports.AddImportHelper; +import com.jetbrains.python.impl.inspections.unresolvedReference.PyUnresolvedReferencesInspection; import com.jetbrains.python.impl.psi.PyUtil; +import com.jetbrains.python.impl.refactoring.PyRefactoringUtil; +import com.jetbrains.python.psi.*; import consulo.language.editor.inspection.LocalInspectionToolSession; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiFile; import consulo.language.psi.PsiNamedElement; import consulo.language.psi.PsiReference; import consulo.language.psi.util.PsiTreeUtil; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import consulo.usage.UsageInfo; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.PyNames; -import com.jetbrains.python.impl.codeInsight.imports.AddImportHelper; -import com.jetbrains.python.impl.inspections.unresolvedReference.PyUnresolvedReferencesInspection; -import com.jetbrains.python.psi.*; -import com.jetbrains.python.impl.refactoring.PyRefactoringUtil; +import jakarta.annotation.Nonnull; + +import java.util.Collections; +import java.util.List; /** - * User: ktisha + * @author ktisha */ -public class PyMakeFunctionFromMethodQuickFix implements LocalQuickFix -{ - public PyMakeFunctionFromMethodQuickFix() - { - } - - @Nonnull - public String getFamilyName() - { - return PyBundle.message("QFIX.NAME.make.function"); - } - - public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) - { - final PsiElement element = descriptor.getPsiElement(); - final PyFunction problemFunction = PsiTreeUtil.getParentOfType(element, PyFunction.class); - if(problemFunction == null) - { - return; - } - final PyClass containingClass = problemFunction.getContainingClass(); - if(containingClass == null) - { - return; - } - - final List usages = PyRefactoringUtil.findUsages(problemFunction, false); - final PyParameter[] parameters = problemFunction.getParameterList().getParameters(); - if(parameters.length > 0) - { - parameters[0].delete(); - } - - PsiElement copy = problemFunction.copy(); - problemFunction.delete(); - final PsiElement parent = containingClass.getParent(); - PyClass aClass = PsiTreeUtil.getTopmostParentOfType(containingClass, PyClass.class); - if(aClass == null) - { - aClass = containingClass; - } - copy = parent.addBefore(copy, aClass); - - for(UsageInfo usage : usages) - { - final PsiElement usageElement = usage.getElement(); - if(usageElement instanceof PyReferenceExpression) - { - final PsiFile usageFile = usageElement.getContainingFile(); - updateUsage(copy, (PyReferenceExpression) usageElement, usageFile, !usageFile.equals(parent)); - } - } - } - - private static void updateUsage(@Nonnull final PsiElement finalElement, @Nonnull final PyReferenceExpression element, @Nonnull final PsiFile usageFile, boolean addImport) - { - final PyExpression qualifier = element.getQualifier(); - if(qualifier == null) - { - return; - } - if(qualifier.getText().equals(PyNames.CANONICAL_SELF)) - { - PyUtil.removeQualifier(element); - return; - } - if(qualifier instanceof PyCallExpression) - { // remove qualifier A().m() - if(addImport) - { - AddImportHelper.addImport((PsiNamedElement) finalElement, usageFile, element); - } - - PyUtil.removeQualifier(element); - removeFormerImport(usageFile, addImport); - } - else - { - final PsiReference reference = qualifier.getReference(); - if(reference == null) - { - return; - } - - final PsiElement resolved = reference.resolve(); - if(resolved instanceof PyTargetExpression) - { // qualifier came from assignment a = A(); a.m() - updateAssignment(element, resolved); - } - else if(resolved instanceof PyClass) - { //call with first instance argument A.m(A()) - PyUtil.removeQualifier(element); - updateArgumentList(element); - } - } - } - - private static void removeFormerImport(@Nonnull final PsiFile usageFile, boolean addImport) - { - if(usageFile instanceof PyFile && addImport) - { - final LocalInspectionToolSession session = new LocalInspectionToolSession(usageFile, 0, usageFile.getTextLength()); - final PyUnresolvedReferencesInspection.Visitor visitor = new PyUnresolvedReferencesInspection.Visitor(null, session, Collections.emptyList()); - usageFile.accept(new PyRecursiveElementVisitor() - { - @Override - public void visitPyElement(PyElement node) - { - super.visitPyElement(node); - node.accept(visitor); - } - }); - - visitor.optimizeImports(); - } - } - - private static void updateAssignment(PyReferenceExpression element, @Nonnull final PsiElement resolved) - { - final PsiElement parent = resolved.getParent(); - if(parent instanceof PyAssignmentStatement) - { - final PyExpression value = ((PyAssignmentStatement) parent).getAssignedValue(); - if(value instanceof PyCallExpression) - { - final PyExpression callee = ((PyCallExpression) value).getCallee(); - if(callee instanceof PyReferenceExpression) - { - final PyExpression calleeQualifier = ((PyReferenceExpression) callee).getQualifier(); - if(calleeQualifier != null) - { - value.replace(calleeQualifier); - } - else - { - PyUtil.removeQualifier(element); - } - } - } - } - } - - private static void updateArgumentList(@Nonnull final PyReferenceExpression element) - { - final PyCallExpression callExpression = PsiTreeUtil.getParentOfType(element, PyCallExpression.class); - if(callExpression == null) - { - return; - } - final PyArgumentList argumentList = callExpression.getArgumentList(); - if(argumentList == null) - { - return; - } - final PyExpression[] arguments = argumentList.getArguments(); - if(arguments.length > 0) - { - arguments[0].delete(); - } - } +public class PyMakeFunctionFromMethodQuickFix implements LocalQuickFix { + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixNameMakeFunction(); + } + + public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + final PyFunction problemFunction = PsiTreeUtil.getParentOfType(element, PyFunction.class); + if (problemFunction == null) { + return; + } + final PyClass containingClass = problemFunction.getContainingClass(); + if (containingClass == null) { + return; + } + + final List usages = PyRefactoringUtil.findUsages(problemFunction, false); + final PyParameter[] parameters = problemFunction.getParameterList().getParameters(); + if (parameters.length > 0) { + parameters[0].delete(); + } + + PsiElement copy = problemFunction.copy(); + problemFunction.delete(); + final PsiElement parent = containingClass.getParent(); + PyClass aClass = PsiTreeUtil.getTopmostParentOfType(containingClass, PyClass.class); + if (aClass == null) { + aClass = containingClass; + } + copy = parent.addBefore(copy, aClass); + + for (UsageInfo usage : usages) { + final PsiElement usageElement = usage.getElement(); + if (usageElement instanceof PyReferenceExpression) { + final PsiFile usageFile = usageElement.getContainingFile(); + updateUsage(copy, (PyReferenceExpression) usageElement, usageFile, !usageFile.equals(parent)); + } + } + } + + private static void updateUsage( + @Nonnull final PsiElement finalElement, + @Nonnull final PyReferenceExpression element, + @Nonnull final PsiFile usageFile, + boolean addImport + ) { + final PyExpression qualifier = element.getQualifier(); + if (qualifier == null) { + return; + } + if (qualifier.getText().equals(PyNames.CANONICAL_SELF)) { + PyUtil.removeQualifier(element); + return; + } + if (qualifier instanceof PyCallExpression) { // remove qualifier A().m() + if (addImport) { + AddImportHelper.addImport((PsiNamedElement) finalElement, usageFile, element); + } + + PyUtil.removeQualifier(element); + removeFormerImport(usageFile, addImport); + } + else { + final PsiReference reference = qualifier.getReference(); + if (reference == null) { + return; + } + + final PsiElement resolved = reference.resolve(); + if (resolved instanceof PyTargetExpression) { // qualifier came from assignment a = A(); a.m() + updateAssignment(element, resolved); + } + else if (resolved instanceof PyClass) { //call with first instance argument A.m(A()) + PyUtil.removeQualifier(element); + updateArgumentList(element); + } + } + } + + private static void removeFormerImport(@Nonnull final PsiFile usageFile, boolean addImport) { + if (usageFile instanceof PyFile && addImport) { + final LocalInspectionToolSession session = new LocalInspectionToolSession(usageFile, 0, usageFile.getTextLength()); + final PyUnresolvedReferencesInspection.Visitor visitor = + new PyUnresolvedReferencesInspection.Visitor(null, session, Collections.emptyList()); + usageFile.accept(new PyRecursiveElementVisitor() { + @Override + public void visitPyElement(PyElement node) { + super.visitPyElement(node); + node.accept(visitor); + } + }); + + visitor.optimizeImports(); + } + } + + private static void updateAssignment(PyReferenceExpression element, @Nonnull final PsiElement resolved) { + final PsiElement parent = resolved.getParent(); + if (parent instanceof PyAssignmentStatement) { + final PyExpression value = ((PyAssignmentStatement) parent).getAssignedValue(); + if (value instanceof PyCallExpression) { + final PyExpression callee = ((PyCallExpression) value).getCallee(); + if (callee instanceof PyReferenceExpression) { + final PyExpression calleeQualifier = ((PyReferenceExpression) callee).getQualifier(); + if (calleeQualifier != null) { + value.replace(calleeQualifier); + } + else { + PyUtil.removeQualifier(element); + } + } + } + } + } + + private static void updateArgumentList(@Nonnull final PyReferenceExpression element) { + final PyCallExpression callExpression = PsiTreeUtil.getParentOfType(element, PyCallExpression.class); + if (callExpression == null) { + return; + } + final PyArgumentList argumentList = callExpression.getArgumentList(); + if (argumentList == null) { + return; + } + final PyExpression[] arguments = argumentList.getArguments(); + if (arguments.length > 0) { + arguments[0].delete(); + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMakeMethodStaticQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMakeMethodStaticQuickFix.java index 9c694379..978cdb3d 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMakeMethodStaticQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMakeMethodStaticQuickFix.java @@ -15,121 +15,99 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import java.util.ArrayList; -import java.util.List; - -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.impl.refactoring.PyRefactoringUtil; +import com.jetbrains.python.psi.*; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiReference; import consulo.language.psi.util.PsiTreeUtil; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import consulo.usage.UsageInfo; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.*; -import com.jetbrains.python.impl.refactoring.PyRefactoringUtil; +import jakarta.annotation.Nonnull; + +import java.util.ArrayList; +import java.util.List; /** - * User: ktisha + * @author ktisha */ -public class PyMakeMethodStaticQuickFix implements LocalQuickFix -{ - public PyMakeMethodStaticQuickFix() - { - } - - @Nonnull - public String getFamilyName() - { - return PyBundle.message("QFIX.NAME.make.static"); - } +public class PyMakeMethodStaticQuickFix implements LocalQuickFix { + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixNameMakeStatic(); + } - public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) - { - final PsiElement element = descriptor.getPsiElement(); - final PyFunction problemFunction = PsiTreeUtil.getParentOfType(element, PyFunction.class); - if(problemFunction == null) - { - return; - } - final List usages = PyRefactoringUtil.findUsages(problemFunction, false); + public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + final PyFunction problemFunction = PsiTreeUtil.getParentOfType(element, PyFunction.class); + if (problemFunction == null) { + return; + } + final List usages = PyRefactoringUtil.findUsages(problemFunction, false); - final PyParameter[] parameters = problemFunction.getParameterList().getParameters(); - if(parameters.length > 0) - { - parameters[0].delete(); - } - final PyDecoratorList problemDecoratorList = problemFunction.getDecoratorList(); - List decoTexts = new ArrayList<>(); - decoTexts.add("@staticmethod"); - if(problemDecoratorList != null) - { - final PyDecorator[] decorators = problemDecoratorList.getDecorators(); - for(PyDecorator deco : decorators) - { - decoTexts.add(deco.getText()); - } - } + final PyParameter[] parameters = problemFunction.getParameterList().getParameters(); + if (parameters.length > 0) { + parameters[0].delete(); + } + final PyDecoratorList problemDecoratorList = problemFunction.getDecoratorList(); + List decoTexts = new ArrayList<>(); + decoTexts.add("@staticmethod"); + if (problemDecoratorList != null) { + final PyDecorator[] decorators = problemDecoratorList.getDecorators(); + for (PyDecorator deco : decorators) { + decoTexts.add(deco.getText()); + } + } - PyElementGenerator generator = PyElementGenerator.getInstance(project); - final PyDecoratorList decoratorList = generator.createDecoratorList(decoTexts.toArray(new String[decoTexts.size()])); + PyElementGenerator generator = PyElementGenerator.getInstance(project); + final PyDecoratorList decoratorList = generator.createDecoratorList(decoTexts.toArray(new String[decoTexts.size()])); - if(problemDecoratorList != null) - { - problemDecoratorList.replace(decoratorList); - } - else - { - problemFunction.addBefore(decoratorList, problemFunction.getFirstChild()); - } + if (problemDecoratorList != null) { + problemDecoratorList.replace(decoratorList); + } + else { + problemFunction.addBefore(decoratorList, problemFunction.getFirstChild()); + } - for(UsageInfo usage : usages) - { - final PsiElement usageElement = usage.getElement(); - if(usageElement instanceof PyReferenceExpression) - { - updateUsage((PyReferenceExpression) usageElement); - } - } - } + for (UsageInfo usage : usages) { + final PsiElement usageElement = usage.getElement(); + if (usageElement instanceof PyReferenceExpression) { + updateUsage((PyReferenceExpression) usageElement); + } + } + } - private static void updateUsage(@Nonnull final PyReferenceExpression element) - { - final PyExpression qualifier = element.getQualifier(); - if(qualifier == null) - { - return; - } - final PsiReference reference = qualifier.getReference(); - if(reference == null) - { - return; - } - final PsiElement resolved = reference.resolve(); - if(resolved instanceof PyClass) - { //call with first instance argument A.m(A()) - updateArgumentList(element); - } - } + private static void updateUsage(@Nonnull final PyReferenceExpression element) { + final PyExpression qualifier = element.getQualifier(); + if (qualifier == null) { + return; + } + final PsiReference reference = qualifier.getReference(); + if (reference == null) { + return; + } + final PsiElement resolved = reference.resolve(); + if (resolved instanceof PyClass) { //call with first instance argument A.m(A()) + updateArgumentList(element); + } + } - private static void updateArgumentList(@Nonnull final PyReferenceExpression element) - { - final PyCallExpression callExpression = PsiTreeUtil.getParentOfType(element, PyCallExpression.class); - if(callExpression == null) - { - return; - } - final PyArgumentList argumentList = callExpression.getArgumentList(); - if(argumentList == null) - { - return; - } - final PyExpression[] arguments = argumentList.getArguments(); - if(arguments.length > 0) - { - arguments[0].delete(); - } - } + private static void updateArgumentList(@Nonnull final PyReferenceExpression element) { + final PyCallExpression callExpression = PsiTreeUtil.getParentOfType(element, PyCallExpression.class); + if (callExpression == null) { + return; + } + final PyArgumentList argumentList = callExpression.getArgumentList(); + if (argumentList == null) { + return; + } + final PyExpression[] arguments = argumentList.getArguments(); + if (arguments.length > 0) { + arguments[0].delete(); + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMakePublicQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMakePublicQuickFix.java index 6ededb85..7e3f8784 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMakePublicQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMakePublicQuickFix.java @@ -15,62 +15,52 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.psi.PyReferenceExpression; +import com.jetbrains.python.psi.PyTargetExpression; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; import consulo.language.editor.refactoring.rename.RenameProcessor; +import consulo.language.psi.PsiElement; +import consulo.language.psi.PsiReference; +import consulo.localize.LocalizeValue; import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import consulo.util.lang.StringUtil; import consulo.virtualFileSystem.VirtualFile; -import consulo.language.psi.PsiElement; -import consulo.language.psi.PsiReference; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.PyReferenceExpression; -import com.jetbrains.python.psi.PyTargetExpression; - -public class PyMakePublicQuickFix implements LocalQuickFix -{ +import jakarta.annotation.Nonnull; - @Nonnull - @Override - public String getFamilyName() - { - return PyBundle.message("QFIX.make.public"); - } +public class PyMakePublicQuickFix implements LocalQuickFix { + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixMakePublic(); + } - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) - { - PsiElement element = descriptor.getPsiElement(); - if(element instanceof PyReferenceExpression) - { - final PsiReference reference = element.getReference(); - if(reference == null) - { - return; - } - element = reference.resolve(); - } - if(element instanceof PyTargetExpression) - { - final String name = ((PyTargetExpression) element).getName(); - if(name == null) - { - return; - } - final VirtualFile virtualFile = element.getContainingFile().getVirtualFile(); - if(virtualFile != null) - { - final String publicName = StringUtil.trimLeading(name, '_'); - new RenameProcessor(project, element, publicName, false, false).run(); - } - } - } + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement element = descriptor.getPsiElement(); + if (element instanceof PyReferenceExpression) { + final PsiReference reference = element.getReference(); + if (reference == null) { + return; + } + element = reference.resolve(); + } + if (element instanceof PyTargetExpression) { + final String name = ((PyTargetExpression) element).getName(); + if (name == null) { + return; + } + final VirtualFile virtualFile = element.getContainingFile().getVirtualFile(); + if (virtualFile != null) { + final String publicName = StringUtil.trimLeading(name, '_'); + new RenameProcessor(project, element, publicName, false, false).run(); + } + } + } - //@Override - public boolean startInWriteAction() - { - return false; - } + //@Override + public boolean startInWriteAction() { + return false; + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMoveAttributeToInitQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMoveAttributeToInitQuickFix.java index 166d10df..c5f07674 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMoveAttributeToInitQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMoveAttributeToInitQuickFix.java @@ -13,64 +13,60 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import com.jetbrains.python.impl.PyBundle; import com.jetbrains.python.psi.*; import consulo.ide.impl.idea.util.FunctionUtil; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; import consulo.language.psi.PsiElement; import consulo.language.psi.util.PsiTreeUtil; +import consulo.localize.LocalizeValue; import consulo.project.Project; -import org.jetbrains.annotations.NonNls; - +import consulo.python.impl.localize.PyLocalize; import jakarta.annotation.Nonnull; + import java.util.function.Function; /** - * User: ktisha + * @author ktisha */ public class PyMoveAttributeToInitQuickFix implements LocalQuickFix { + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixMoveAttribute(); + } - public PyMoveAttributeToInitQuickFix() { - } - - @Nonnull - public String getName() { - return PyBundle.message("QFIX.move.attribute"); - } - - @NonNls - @Nonnull - public String getFamilyName() { - return getName(); - } - - public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { - final PsiElement element = descriptor.getPsiElement(); - if (!(element instanceof PyTargetExpression)) return; - final PyTargetExpression targetExpression = (PyTargetExpression)element; + public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + if (!(element instanceof PyTargetExpression)) { + return; + } + final PyTargetExpression targetExpression = (PyTargetExpression) element; - final PyClass containingClass = targetExpression.getContainingClass(); - final PyAssignmentStatement assignment = PsiTreeUtil.getParentOfType(element, PyAssignmentStatement.class); - if (containingClass == null || assignment == null) return; + final PyClass containingClass = targetExpression.getContainingClass(); + final PyAssignmentStatement assignment = PsiTreeUtil.getParentOfType(element, PyAssignmentStatement.class); + if (containingClass == null || assignment == null) { + return; + } - final Function callback = FunctionUtil.constant(assignment); - AddFieldQuickFix.addFieldToInit(project, containingClass, ((PyTargetExpression)element).getName(), callback); - removeDefinition(assignment); - } + final Function callback = FunctionUtil.constant(assignment); + AddFieldQuickFix.addFieldToInit(project, containingClass, ((PyTargetExpression) element).getName(), callback); + removeDefinition(assignment); + } - private static boolean removeDefinition(PyAssignmentStatement assignment) { - final PyStatementList statementList = PsiTreeUtil.getParentOfType(assignment, PyStatementList.class); - if (statementList == null) return false; + private static boolean removeDefinition(PyAssignmentStatement assignment) { + final PyStatementList statementList = PsiTreeUtil.getParentOfType(assignment, PyStatementList.class); + if (statementList == null) { + return false; + } - if (statementList.getStatements().length == 1) { - final PyPassStatement passStatement = PyElementGenerator.getInstance(assignment.getProject()).createPassStatement(); - statementList.addBefore(passStatement, assignment); + if (statementList.getStatements().length == 1) { + final PyPassStatement passStatement = PyElementGenerator.getInstance(assignment.getProject()).createPassStatement(); + statementList.addBefore(passStatement, assignment); + } + assignment.delete(); + return true; } - assignment.delete(); - return true; - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMoveExceptQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMoveExceptQuickFix.java index 344c258a..cfcfddb0 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMoveExceptQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyMoveExceptQuickFix.java @@ -15,76 +15,64 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import java.util.ArrayList; - -import jakarta.annotation.Nonnull; import com.google.common.collect.Lists; +import com.jetbrains.python.psi.*; +import com.jetbrains.python.psi.resolve.PyResolveContext; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; import consulo.language.psi.util.PsiTreeUtil; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.PyClass; -import com.jetbrains.python.psi.PyExceptPart; -import com.jetbrains.python.psi.PyExpression; -import com.jetbrains.python.psi.PyReferenceExpression; -import com.jetbrains.python.psi.PyTryExceptStatement; -import com.jetbrains.python.psi.resolve.PyResolveContext; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; -public class PyMoveExceptQuickFix implements LocalQuickFix -{ +import java.util.ArrayList; - @Nonnull - public String getFamilyName() - { - return PyBundle.message("QFIX.NAME.move.except.up"); - } +public class PyMoveExceptQuickFix implements LocalQuickFix { + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixNameMoveExceptUp(); + } - public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) - { - final PsiElement element = descriptor.getPsiElement(); - final PyExceptPart part = PsiTreeUtil.getParentOfType(element, PyExceptPart.class); - if(part == null) - { - return; - } - final PyExpression exceptClassExpression = part.getExceptClass(); - if(exceptClassExpression == null) - { - return; - } + public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + final PyExceptPart part = PsiTreeUtil.getParentOfType(element, PyExceptPart.class); + if (part == null) { + return; + } + final PyExpression exceptClassExpression = part.getExceptClass(); + if (exceptClassExpression == null) { + return; + } - final PsiElement exceptClass = ((PyReferenceExpression) exceptClassExpression).followAssignmentsChain(PyResolveContext.noImplicits()).getElement(); - if(exceptClass instanceof PyClass) - { - final PyTryExceptStatement statement = PsiTreeUtil.getParentOfType(part, PyTryExceptStatement.class); - if(statement == null) - { - return; - } + final PsiElement exceptClass = + ((PyReferenceExpression) exceptClassExpression).followAssignmentsChain(PyResolveContext.noImplicits()).getElement(); + if (exceptClass instanceof PyClass) { + final PyTryExceptStatement statement = PsiTreeUtil.getParentOfType(part, PyTryExceptStatement.class); + if (statement == null) { + return; + } - PyExceptPart prevExceptPart = PsiTreeUtil.getPrevSiblingOfType(part, PyExceptPart.class); - final ArrayList superClasses = Lists.newArrayList(((PyClass) exceptClass).getSuperClasses(null)); - while(prevExceptPart != null) - { - final PyExpression classExpression = prevExceptPart.getExceptClass(); - if(classExpression == null) - { - return; - } - final PsiElement aClass = ((PyReferenceExpression) classExpression).followAssignmentsChain(PyResolveContext.noImplicits()).getElement(); - if(aClass instanceof PyClass) - { - if(superClasses.contains(aClass)) - { - statement.addBefore(part, prevExceptPart); - part.delete(); - return; - } - } - prevExceptPart = PsiTreeUtil.getPrevSiblingOfType(prevExceptPart, PyExceptPart.class); - } - } - } + PyExceptPart prevExceptPart = PsiTreeUtil.getPrevSiblingOfType(part, PyExceptPart.class); + final ArrayList superClasses = Lists.newArrayList(((PyClass) exceptClass).getSuperClasses(null)); + while (prevExceptPart != null) { + final PyExpression classExpression = prevExceptPart.getExceptClass(); + if (classExpression == null) { + return; + } + final PsiElement aClass = + ((PyReferenceExpression) classExpression).followAssignmentsChain(PyResolveContext.noImplicits()).getElement(); + if (aClass instanceof PyClass) { + if (superClasses.contains(aClass)) { + statement.addBefore(part, prevExceptPart); + part.delete(); + return; + } + } + prevExceptPart = PsiTreeUtil.getPrevSiblingOfType(prevExceptPart, PyExceptPart.class); + } + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveArgumentQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveArgumentQuickFix.java index c166c4f1..d21cf4f8 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveArgumentQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveArgumentQuickFix.java @@ -15,47 +15,41 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.PyTokenTypes; +import com.jetbrains.python.psi.PyExpression; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiWhiteSpace; import consulo.language.psi.util.PsiTreeUtil; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.PyTokenTypes; -import com.jetbrains.python.psi.PyExpression; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; //TODO: Remove pydoc aswell -public class PyRemoveArgumentQuickFix implements LocalQuickFix -{ - - @Nonnull - public String getFamilyName() - { - return PyBundle.message("QFIX.NAME.remove.argument"); - } +public class PyRemoveArgumentQuickFix implements LocalQuickFix { + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixNameRemoveArgument(); + } - public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) - { - final PsiElement element = descriptor.getPsiElement(); - if(!(element instanceof PyExpression)) - { - return; - } - final PyExpression expression = (PyExpression) element; - final PsiElement nextSibling = PsiTreeUtil.skipSiblingsForward(expression, PsiWhiteSpace.class); - final PsiElement prevSibling = PsiTreeUtil.skipSiblingsBackward(expression, PsiWhiteSpace.class); - expression.delete(); - if(nextSibling != null && nextSibling.getNode().getElementType().equals(PyTokenTypes.COMMA)) - { - nextSibling.delete(); - return; - } - if(prevSibling != null && prevSibling.getNode().getElementType().equals(PyTokenTypes.COMMA)) - { - prevSibling.delete(); - } - } + public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + if (!(element instanceof PyExpression)) { + return; + } + final PyExpression expression = (PyExpression) element; + final PsiElement nextSibling = PsiTreeUtil.skipSiblingsForward(expression, PsiWhiteSpace.class); + final PsiElement prevSibling = PsiTreeUtil.skipSiblingsBackward(expression, PsiWhiteSpace.class); + expression.delete(); + if (nextSibling != null && nextSibling.getNode().getElementType().equals(PyTokenTypes.COMMA)) { + nextSibling.delete(); + return; + } + if (prevSibling != null && prevSibling.getNode().getElementType().equals(PyTokenTypes.COMMA)) { + prevSibling.delete(); + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveParameterQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveParameterQuickFix.java index 7d345cc3..3ecc4dc9 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveParameterQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveParameterQuickFix.java @@ -15,79 +15,63 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import java.util.List; -import java.util.Map; - -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.impl.documentation.docstrings.PyDocstringGenerator; +import com.jetbrains.python.impl.refactoring.PyRefactoringUtil; +import com.jetbrains.python.psi.*; +import com.jetbrains.python.psi.resolve.PyResolveContext; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; import consulo.language.psi.util.PsiTreeUtil; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import consulo.usage.UsageInfo; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.impl.documentation.docstrings.PyDocstringGenerator; -import com.jetbrains.python.psi.PyArgumentList; -import com.jetbrains.python.psi.PyCallExpression; -import com.jetbrains.python.psi.PyExpression; -import com.jetbrains.python.psi.PyFunction; -import com.jetbrains.python.psi.PyNamedParameter; -import com.jetbrains.python.psi.PyParameter; -import com.jetbrains.python.psi.PyStringLiteralExpression; -import com.jetbrains.python.psi.resolve.PyResolveContext; -import com.jetbrains.python.impl.refactoring.PyRefactoringUtil; +import jakarta.annotation.Nonnull; -public class PyRemoveParameterQuickFix implements LocalQuickFix -{ +import java.util.List; +import java.util.Map; - @Nonnull - public String getFamilyName() - { - return PyBundle.message("QFIX.NAME.remove.parameter"); - } +public class PyRemoveParameterQuickFix implements LocalQuickFix { + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixNameRemoveParameter(); + } - public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) - { - final PsiElement element = descriptor.getPsiElement(); - assert element instanceof PyParameter; + public void applyFix(@Nonnull final Project project, @Nonnull final ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + assert element instanceof PyParameter; - final PyFunction pyFunction = PsiTreeUtil.getParentOfType(element, PyFunction.class); + final PyFunction pyFunction = PsiTreeUtil.getParentOfType(element, PyFunction.class); - if(pyFunction != null) - { - final List usages = PyRefactoringUtil.findUsages(pyFunction, false); - for(UsageInfo usage : usages) - { - final PsiElement usageElement = usage.getElement(); - if(usageElement != null) - { - final PsiElement callExpression = usageElement.getParent(); - if(callExpression instanceof PyCallExpression) - { - final PyArgumentList argumentList = ((PyCallExpression) callExpression).getArgumentList(); - if(argumentList != null) - { - final PyResolveContext resolveContext = PyResolveContext.noImplicits(); - final PyCallExpression.PyArgumentsMapping mapping = ((PyCallExpression) callExpression).mapArguments(resolveContext); - for(Map.Entry parameterEntry : mapping.getMappedParameters().entrySet()) - { - if(parameterEntry.getValue().equals(element)) - { - parameterEntry.getKey().delete(); - } - } - } - } - } - } - final PyStringLiteralExpression expression = pyFunction.getDocStringExpression(); - final String paramName = ((PyParameter) element).getName(); - if(expression != null && paramName != null) - { - PyDocstringGenerator.forDocStringOwner(pyFunction).withoutParam(paramName).buildAndInsert(); - } - } - element.delete(); - } + if (pyFunction != null) { + final List usages = PyRefactoringUtil.findUsages(pyFunction, false); + for (UsageInfo usage : usages) { + final PsiElement usageElement = usage.getElement(); + if (usageElement != null) { + final PsiElement callExpression = usageElement.getParent(); + if (callExpression instanceof PyCallExpression) { + final PyArgumentList argumentList = ((PyCallExpression) callExpression).getArgumentList(); + if (argumentList != null) { + final PyResolveContext resolveContext = PyResolveContext.noImplicits(); + final PyCallExpression.PyArgumentsMapping mapping = + ((PyCallExpression) callExpression).mapArguments(resolveContext); + for (Map.Entry parameterEntry : mapping.getMappedParameters().entrySet()) { + if (parameterEntry.getValue().equals(element)) { + parameterEntry.getKey().delete(); + } + } + } + } + } + } + final PyStringLiteralExpression expression = pyFunction.getDocStringExpression(); + final String paramName = ((PyParameter) element).getName(); + if (expression != null && paramName != null) { + PyDocstringGenerator.forDocStringOwner(pyFunction).withoutParam(paramName).buildAndInsert(); + } + } + element.delete(); + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveStatementQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveStatementQuickFix.java index 15746602..1302d081 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveStatementQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveStatementQuickFix.java @@ -15,31 +15,27 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.psi.PyStatement; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.util.PsiTreeUtil; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.PyStatement; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; -public class PyRemoveStatementQuickFix implements LocalQuickFix -{ - @Nonnull - @Override - public String getFamilyName() - { - return PyBundle.message("QFIX.NAME.remove.statement"); - } +public class PyRemoveStatementQuickFix implements LocalQuickFix { + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixNameRemoveStatement(); + } - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) - { - final PyStatement statement = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PyStatement.class, false); - if(statement != null) - { - statement.delete(); - } - } + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + final PyStatement statement = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PyStatement.class, false); + if (statement != null) { + statement.delete(); + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveUnderscoresInNumericLiteralsQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveUnderscoresInNumericLiteralsQuickFix.java index c765c398..d3918dda 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveUnderscoresInNumericLiteralsQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRemoveUnderscoresInNumericLiteralsQuickFix.java @@ -15,38 +15,32 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import org.jetbrains.annotations.Nls; -import jakarta.annotation.Nonnull; -import consulo.language.editor.inspection.LocalQuickFix; -import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; -import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; import com.jetbrains.python.psi.LanguageLevel; import com.jetbrains.python.psi.PyElementGenerator; import com.jetbrains.python.psi.PyNumericLiteralExpression; +import consulo.language.editor.inspection.LocalQuickFix; +import consulo.language.editor.inspection.ProblemDescriptor; +import consulo.language.psi.PsiElement; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; -public class PyRemoveUnderscoresInNumericLiteralsQuickFix implements LocalQuickFix -{ - - @Nls - @Nonnull - @Override - public String getFamilyName() - { - return PyBundle.message("QFIX.NAME.remove.underscores.in.numeric"); - } +public class PyRemoveUnderscoresInNumericLiteralsQuickFix implements LocalQuickFix { + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixNameRemoveUnderscoresInNumeric(); + } - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) - { - final PsiElement element = descriptor.getPsiElement(); - if(element instanceof PyNumericLiteralExpression) - { - final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - final String text = element.getText(); + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + if (element instanceof PyNumericLiteralExpression) { + final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + final String text = element.getText(); - element.replace(elementGenerator.createExpressionFromText(LanguageLevel.forElement(element), text.replaceAll("_", ""))); - } - } + element.replace(elementGenerator.createExpressionFromText(LanguageLevel.forElement(element), text.replaceAll("_", ""))); + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRenameUnresolvedRefQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRenameUnresolvedRefQuickFix.java index 482cc806..8c006752 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRenameUnresolvedRefQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyRenameUnresolvedRefQuickFix.java @@ -1,4 +1,3 @@ - /* * Copyright 2000-2013 JetBrains s.r.o. * @@ -14,16 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import com.jetbrains.python.impl.PyBundle; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.impl.codeInsight.dataflow.scope.ScopeUtil; -import com.jetbrains.python.psi.PyRecursiveElementVisitor; -import com.jetbrains.python.psi.PyReferenceExpression; import com.jetbrains.python.impl.psi.impl.references.PyReferenceImpl; import com.jetbrains.python.impl.refactoring.PyRefactoringUtil; +import com.jetbrains.python.psi.PyRecursiveElementVisitor; +import com.jetbrains.python.psi.PyReferenceExpression; import consulo.codeEditor.Editor; import consulo.fileEditor.FileEditorManager; import consulo.language.editor.completion.lookup.LookupElement; @@ -36,162 +33,177 @@ import consulo.language.psi.PsiReference; import consulo.language.psi.ResolveResult; import consulo.language.psi.util.PsiTreeUtil; +import consulo.localize.LocalizeValue; import consulo.navigation.OpenFileDescriptorFactory; import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import consulo.virtualFileSystem.VirtualFile; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; + import java.util.*; /** - * User : ktisha - *

* Quick fix to rename unresolved references + * + * @author ktisha */ public class PyRenameUnresolvedRefQuickFix implements LocalQuickFix { - @Nonnull - @Override - public String getName() { - return PyBundle.message("QFIX.rename.unresolved.reference"); - } - - @Override - @Nonnull - public String getFamilyName() { - return PyBundle.message("QFIX.rename.unresolved.reference"); - } - - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - final PsiElement element = descriptor.getPsiElement(); - final PyReferenceExpression referenceExpression = PsiTreeUtil.getParentOfType(element, PyReferenceExpression.class); - if (referenceExpression == null) return; - - ScopeOwner parentScope = ScopeUtil.getScopeOwner(referenceExpression); - if (parentScope == null) return; - - List refs = collectExpressionsToRename(referenceExpression, parentScope); - - LookupElement[] items = collectLookupItems(parentScope); - final String name = referenceExpression.getReferencedName(); - - ReferenceNameExpression refExpr = new ReferenceNameExpression(items, name); - TemplateBuilder builder = TemplateBuilderFactory.getInstance(). - createTemplateBuilder(parentScope); - for (PyReferenceExpression expr : refs) { - if (!expr.equals(referenceExpression)) { - builder.replaceElement(expr, name, name, false); - } - else { - builder.replaceElement(expr, name, refExpr, true); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixRenameUnresolvedReference(); } - Editor editor = getEditor(project, element.getContainingFile(), parentScope.getTextRange().getStartOffset()); - if (editor != null) { - Template template = builder.buildInlineTemplate(); - TemplateManager.getInstance(project).startTemplate(editor, template); - } - } - - public static boolean isValidReference(final PsiReference reference) { - if (!(reference instanceof PyReferenceImpl)) return false; - ResolveResult[] results = ((PyReferenceImpl)reference).multiResolve(true); - if (results.length == 0) return false; - for (ResolveResult result : results) { - if (!result.isValidResult()) return false; - } - return true; - } + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + final PyReferenceExpression referenceExpression = PsiTreeUtil.getParentOfType(element, PyReferenceExpression.class); + if (referenceExpression == null) { + return; + } + ScopeOwner parentScope = ScopeUtil.getScopeOwner(referenceExpression); + if (parentScope == null) { + return; + } - private static List collectExpressionsToRename(@Nonnull final PyReferenceExpression expression, - @Nonnull final ScopeOwner parentScope) { + List refs = collectExpressionsToRename(referenceExpression, parentScope); + + LookupElement[] items = collectLookupItems(parentScope); + final String name = referenceExpression.getReferencedName(); + + ReferenceNameExpression refExpr = new ReferenceNameExpression(items, name); + TemplateBuilder builder = TemplateBuilderFactory.getInstance(). + createTemplateBuilder(parentScope); + for (PyReferenceExpression expr : refs) { + if (!expr.equals(referenceExpression)) { + builder.replaceElement(expr, name, name, false); + } + else { + builder.replaceElement(expr, name, refExpr, true); + } + } - final List result = new ArrayList(); - PyRecursiveElementVisitor visitor = new PyRecursiveElementVisitor() { - @Override - public void visitPyReferenceExpression(PyReferenceExpression node) { - if (node.textMatches(expression) && !isValidReference(node.getReference())) { - result.add(node); + Editor editor = getEditor(project, element.getContainingFile(), parentScope.getTextRange().getStartOffset()); + if (editor != null) { + Template template = builder.buildInlineTemplate(); + TemplateManager.getInstance(project).startTemplate(editor, template); } - super.visitPyReferenceExpression(node); - } - }; - - parentScope.accept(visitor); - return result; - } - - @Nullable - private static Editor getEditor(@Nonnull final Project project, @Nonnull final PsiFile file, int offset) { - final VirtualFile virtualFile = file.getVirtualFile(); - if (virtualFile != null) { - return FileEditorManager.getInstance(project).openTextEditor( - OpenFileDescriptorFactory.getInstance(project).builder(virtualFile).offset(offset).build(), true - ); } - return null; - } - private static LookupElement[] collectLookupItems(@Nonnull final ScopeOwner parentScope) { - Set items = new LinkedHashSet(); + public static boolean isValidReference(final PsiReference reference) { + if (!(reference instanceof PyReferenceImpl)) { + return false; + } + ResolveResult[] results = ((PyReferenceImpl) reference).multiResolve(true); + if (results.length == 0) { + return false; + } + for (ResolveResult result : results) { + if (!result.isValidResult()) { + return false; + } + } + return true; + } + - final Collection usedNames = PyRefactoringUtil.collectUsedNames(parentScope); - for (String name : usedNames) { - if (name != null) - items.add(LookupElementBuilder.create(name)); + private static List collectExpressionsToRename( + @Nonnull final PyReferenceExpression expression, + @Nonnull final ScopeOwner parentScope + ) { + + final List result = new ArrayList(); + PyRecursiveElementVisitor visitor = new PyRecursiveElementVisitor() { + @Override + public void visitPyReferenceExpression(PyReferenceExpression node) { + if (node.textMatches(expression) && !isValidReference(node.getReference())) { + result.add(node); + } + super.visitPyReferenceExpression(node); + } + }; + + parentScope.accept(visitor); + return result; } - return items.toArray(new LookupElement[items.size()]); - } - - private class ReferenceNameExpression extends Expression { - class HammingComparator implements Comparator { - @Override - public int compare(LookupElement lookupItem1, LookupElement lookupItem2) { - String s1 = lookupItem1.getLookupString(); - String s2 = lookupItem2.getLookupString(); - int diff1 = 0; - for (int i = 0; i < Math.min(s1.length(), myOldReferenceName.length()); i++) { - if (s1.charAt(i) != myOldReferenceName.charAt(i)) diff1++; - } - int diff2 = 0; - for (int i = 0; i < Math.min(s2.length(), myOldReferenceName.length()); i++) { - if (s2.charAt(i) != myOldReferenceName.charAt(i)) diff2++; + @Nullable + private static Editor getEditor(@Nonnull final Project project, @Nonnull final PsiFile file, int offset) { + final VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile != null) { + return FileEditorManager.getInstance(project).openTextEditor( + OpenFileDescriptorFactory.getInstance(project).builder(virtualFile).offset(offset).build(), true + ); } - return diff1 - diff2; - } + return null; } - ReferenceNameExpression(LookupElement[] items, String oldReferenceName) { - myItems = items; - myOldReferenceName = oldReferenceName; - Arrays.sort(myItems, new HammingComparator()); - } + private static LookupElement[] collectLookupItems(@Nonnull final ScopeOwner parentScope) { + Set items = new LinkedHashSet(); - LookupElement[] myItems; - private final String myOldReferenceName; + final Collection usedNames = PyRefactoringUtil.collectUsedNames(parentScope); + for (String name : usedNames) { + if (name != null) { + items.add(LookupElementBuilder.create(name)); + } + } - @Override - public Result calculateResult(ExpressionContext context) { - if (myItems == null || myItems.length == 0) { - return new TextResult(myOldReferenceName); - } - return new TextResult(myItems[0].getLookupString()); + return items.toArray(new LookupElement[items.size()]); } - @Override - public Result calculateQuickResult(ExpressionContext context) { - return null; - } + private class ReferenceNameExpression extends Expression { + class HammingComparator implements Comparator { + @Override + public int compare(LookupElement lookupItem1, LookupElement lookupItem2) { + String s1 = lookupItem1.getLookupString(); + String s2 = lookupItem2.getLookupString(); + int diff1 = 0; + for (int i = 0; i < Math.min(s1.length(), myOldReferenceName.length()); i++) { + if (s1.charAt(i) != myOldReferenceName.charAt(i)) { + diff1++; + } + } + int diff2 = 0; + for (int i = 0; i < Math.min(s2.length(), myOldReferenceName.length()); i++) { + if (s2.charAt(i) != myOldReferenceName.charAt(i)) { + diff2++; + } + } + return diff1 - diff2; + } + } - @Override - public LookupElement[] calculateLookupItems(ExpressionContext context) { - if (myItems == null || myItems.length == 1) return null; - return myItems; + ReferenceNameExpression(LookupElement[] items, String oldReferenceName) { + myItems = items; + myOldReferenceName = oldReferenceName; + Arrays.sort(myItems, new HammingComparator()); + } + + LookupElement[] myItems; + private final String myOldReferenceName; + + @Override + public Result calculateResult(ExpressionContext context) { + if (myItems == null || myItems.length == 0) { + return new TextResult(myOldReferenceName); + } + return new TextResult(myItems[0].getLookupString()); + } + + @Override + public Result calculateQuickResult(ExpressionContext context) { + return null; + } + + @Override + public LookupElement[] calculateLookupItems(ExpressionContext context) { + if (myItems == null || myItems.length == 1) { + return null; + } + return myItems; + } } - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyUpdatePropertySignatureQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyUpdatePropertySignatureQuickFix.java index abbf6db7..6e467f16 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyUpdatePropertySignatureQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/PyUpdatePropertySignatureQuickFix.java @@ -15,57 +15,48 @@ */ package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.PyNames; +import com.jetbrains.python.psi.*; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; import consulo.language.psi.util.PsiTreeUtil; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.PyNames; -import com.jetbrains.python.psi.LanguageLevel; -import com.jetbrains.python.psi.PyCallable; -import com.jetbrains.python.psi.PyElementGenerator; -import com.jetbrains.python.psi.PyFunction; -import com.jetbrains.python.psi.PyParameter; -import com.jetbrains.python.psi.PyParameterList; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; -public class PyUpdatePropertySignatureQuickFix implements LocalQuickFix -{ - private final boolean myHasValue; +public class PyUpdatePropertySignatureQuickFix implements LocalQuickFix { + private final boolean myHasValue; - public PyUpdatePropertySignatureQuickFix(boolean hasValue) - { - myHasValue = hasValue; - } + public PyUpdatePropertySignatureQuickFix(boolean hasValue) { + myHasValue = hasValue; + } - @Nonnull - @Override - public String getFamilyName() - { - return PyBundle.message("QFIX.NAME.update.parameters"); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixNameUpdateParameters(); + } - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) - { - final PsiElement element = descriptor.getPsiElement(); - final PyCallable function = PsiTreeUtil.getParentOfType(element, PyCallable.class, false); - assert function != null; - final PyParameterList parameterList = function.getParameterList(); - final PyParameter[] parameters = parameterList.getParameters(); - final PyElementGenerator generator = PyElementGenerator.getInstance(project); - String selfText = parameters.length != 0 ? parameters[0].getText() : PyNames.CANONICAL_SELF; - final StringBuilder functionText = new StringBuilder("def foo(" + selfText); - if(myHasValue) - { - String valueText = parameters.length > 1 ? parameters[1].getText() : "value"; - functionText.append(", ").append(valueText); - } - functionText.append("): pass"); + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + final PyCallable function = PsiTreeUtil.getParentOfType(element, PyCallable.class, false); + assert function != null; + final PyParameterList parameterList = function.getParameterList(); + final PyParameter[] parameters = parameterList.getParameters(); + final PyElementGenerator generator = PyElementGenerator.getInstance(project); + String selfText = parameters.length != 0 ? parameters[0].getText() : PyNames.CANONICAL_SELF; + final StringBuilder functionText = new StringBuilder("def foo(" + selfText); + if (myHasValue) { + String valueText = parameters.length > 1 ? parameters[1].getText() : "value"; + functionText.append(", ").append(valueText); + } + functionText.append("): pass"); - final PyParameterList list = generator.createFromText(LanguageLevel.forElement(element), PyFunction.class, functionText.toString()).getParameterList(); - parameterList.replace(list); - } + final PyParameterList list = + generator.createFromText(LanguageLevel.forElement(element), PyFunction.class, functionText.toString()).getParameterList(); + parameterList.replace(list); + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/RedundantParenthesesQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/RedundantParenthesesQuickFix.java index 6deb6949..64736e28 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/RedundantParenthesesQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/RedundantParenthesesQuickFix.java @@ -13,69 +13,64 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.psi.PyBinaryExpression; +import com.jetbrains.python.psi.PyExpression; +import com.jetbrains.python.psi.PyParenthesizedExpression; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; import consulo.language.psi.util.PsiTreeUtil; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.PyBinaryExpression; -import com.jetbrains.python.psi.PyExpression; -import com.jetbrains.python.psi.PyParenthesizedExpression; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; /** - * User: catherine - * * QuickFix to remove redundant parentheses from if/while/except statement + * + * @author catherine */ public class RedundantParenthesesQuickFix implements LocalQuickFix { - @Nonnull - public String getName() { - return PyBundle.message("QFIX.redundant.parentheses"); - } - - @Nonnull - public String getFamilyName() { - return getName(); - } - - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement element = descriptor.getPsiElement(); - PsiElement binaryExpression = ((PyParenthesizedExpression)element).getContainedExpression(); - PyBinaryExpression parent = PsiTreeUtil.getParentOfType(element, PyBinaryExpression.class); - if (binaryExpression instanceof PyBinaryExpression && parent != null) { - if (!replaceBinaryExpression((PyBinaryExpression)binaryExpression)) { - element.replace(binaryExpression); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixRedundantParentheses(); } - else { - while (element instanceof PyParenthesizedExpression) { - PyExpression expression = ((PyParenthesizedExpression)element).getContainedExpression(); - if (expression != null) { - element = element.replace(expression); + + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement element = descriptor.getPsiElement(); + PsiElement binaryExpression = ((PyParenthesizedExpression) element).getContainedExpression(); + PyBinaryExpression parent = PsiTreeUtil.getParentOfType(element, PyBinaryExpression.class); + if (binaryExpression instanceof PyBinaryExpression && parent != null) { + if (!replaceBinaryExpression((PyBinaryExpression) binaryExpression)) { + element.replace(binaryExpression); + } + } + else { + while (element instanceof PyParenthesizedExpression) { + PyExpression expression = ((PyParenthesizedExpression) element).getContainedExpression(); + if (expression != null) { + element = element.replace(expression); + } + } } - } } - } - private static boolean replaceBinaryExpression(PyBinaryExpression element) { - PyExpression left = element.getLeftExpression(); - PyExpression right = element.getRightExpression(); - if (left instanceof PyParenthesizedExpression && - right instanceof PyParenthesizedExpression) { - PyExpression leftContained = ((PyParenthesizedExpression)left).getContainedExpression(); - PyExpression rightContained = ((PyParenthesizedExpression)right).getContainedExpression(); - if (leftContained != null && rightContained != null) { - left.replace(leftContained); - right.replace(rightContained); - return true; - } + private static boolean replaceBinaryExpression(PyBinaryExpression element) { + PyExpression left = element.getLeftExpression(); + PyExpression right = element.getRightExpression(); + if (left instanceof PyParenthesizedExpression && + right instanceof PyParenthesizedExpression) { + PyExpression leftContained = ((PyParenthesizedExpression) left).getContainedExpression(); + PyExpression rightContained = ((PyParenthesizedExpression) right).getContainedExpression(); + if (leftContained != null && rightContained != null) { + left.replace(leftContained); + right.replace(rightContained); + return true; + } + } + return false; } - return false; - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReformatFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReformatFix.java index a79435fa..bde173f0 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReformatFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReformatFix.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; import consulo.codeEditor.Editor; @@ -25,6 +24,7 @@ import consulo.language.editor.intention.SyntheticIntentionAction; import consulo.language.psi.PsiFile; import consulo.language.util.IncorrectOperationException; +import consulo.localize.LocalizeValue; import consulo.project.Project; import jakarta.annotation.Nonnull; @@ -32,45 +32,38 @@ * @author yole */ public class ReformatFix implements SyntheticIntentionAction, LocalQuickFix, HighPriorityAction { - @Nonnull - @Override - public String getText() { - return "Reformat file"; - } - - @Nonnull - @Override - public String getName() { - return getText(); - } + @Nonnull + @Override + public LocalizeValue getText() { + return LocalizeValue.localizeTODO("Reformat file"); + } - @Nonnull - @Override - public String getFamilyName() { - return getText(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return getText(); + } - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - CodeStyleManager.getInstance(project).reformat(descriptor.getPsiElement().getContainingFile()); - } + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + CodeStyleManager.getInstance(project).reformat(descriptor.getPsiElement().getContainingFile()); + } - @Override - public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { - return true; - } + @Override + public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { + return true; + } - @Override - public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException - { - if (!FileModificationService.getInstance().prepareFileForWrite(file)) { - return; + @Override + public void invoke(@Nonnull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + if (!FileModificationService.getInstance().prepareFileForWrite(file)) { + return; + } + CodeStyleManager.getInstance(project).reformat(file); } - CodeStyleManager.getInstance(project).reformat(file); - } - @Override - public boolean startInWriteAction() { - return true; - } + @Override + public boolean startInWriteAction() { + return true; + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/RemoveDecoratorQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/RemoveDecoratorQuickFix.java index f3f66cc7..78a60846 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/RemoveDecoratorQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/RemoveDecoratorQuickFix.java @@ -13,35 +13,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; /** - * User: catherine - * * QuickFix to remove redundant decorator + * + * @author catherine */ public class RemoveDecoratorQuickFix implements LocalQuickFix { - @Nonnull - public String getName() { - return PyBundle.message("QFIX.remove.decorator"); - } - - @Nonnull - public String getFamilyName() { - return getName(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixRemoveDecorator(); + } - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement element = descriptor.getPsiElement(); - element.delete(); - } + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement element = descriptor.getPsiElement(); + element.delete(); + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/RemoveTrailingLQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/RemoveTrailingLQuickFix.java index 77c3571b..5b3dc72c 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/RemoveTrailingLQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/RemoveTrailingLQuickFix.java @@ -13,44 +13,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.psi.PyElementGenerator; +import com.jetbrains.python.psi.PyNumericLiteralExpression; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.PyElementGenerator; -import com.jetbrains.python.psi.PyNumericLiteralExpression; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; /** - * Created by IntelliJ IDEA. - * Author: Alexey.Ivanov - * Date: 06.03.2010 - * Time: 16:50:53 + * @author Alexey.Ivanov + * @since 2010-03-06 */ public class RemoveTrailingLQuickFix implements LocalQuickFix { - @Nonnull - @Override - public String getName() { - return PyBundle.message("INTN.remove.trailing.l"); - } - - @Nonnull - public String getFamilyName() { - return getName(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.intnRemoveTrailingL(); + } - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement numericLiteralExpression = descriptor.getPsiElement(); - if (numericLiteralExpression instanceof PyNumericLiteralExpression) { - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - String text = numericLiteralExpression.getText(); - numericLiteralExpression.replace(elementGenerator.createExpressionFromText(text.substring(0, text.length() - 1))); + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement numericLiteralExpression = descriptor.getPsiElement(); + if (numericLiteralExpression instanceof PyNumericLiteralExpression) { + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + String text = numericLiteralExpression.getText(); + numericLiteralExpression.replace(elementGenerator.createExpressionFromText(text.substring(0, text.length() - 1))); + } } - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceBuiltinsQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceBuiltinsQuickFix.java index b74d18e0..8854ee36 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceBuiltinsQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceBuiltinsQuickFix.java @@ -13,52 +13,52 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.psi.*; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.*; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; /** - * Created by IntelliJ IDEA. - * User: Alexey.Ivanov - * Date: 19.02.2010 - * Time: 18:50:24 + * @author Alexey.Ivanov + * @since 2010-02-19 */ public class ReplaceBuiltinsQuickFix implements LocalQuickFix { - @Nonnull - @Override - public String getName() { - return PyBundle.message("INTN.convert.builtin.import"); - } - - @Nonnull - public String getFamilyName() { - return PyBundle.message("INTN.Family.convert.builtin"); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.intnConvertBuiltinImport(); + } - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - PsiElement importStatement = descriptor.getPsiElement(); - if (importStatement instanceof PyImportStatement) { - for (PyImportElement importElement : ((PyImportStatement)importStatement).getImportElements()) { - PyReferenceExpression importReference = importElement.getImportReferenceExpression(); - if (importReference != null) { - if ("__builtin__".equals(importReference.getName())) { - importReference.replace(elementGenerator.createFromText(LanguageLevel.getDefault(), PyReferenceExpression.class, "builtins")); - } - if ("builtins".equals(importReference.getName())) { - importReference.replace(elementGenerator.createFromText(LanguageLevel.getDefault(), PyReferenceExpression.class, "__builtin__")); - } + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + PsiElement importStatement = descriptor.getPsiElement(); + if (importStatement instanceof PyImportStatement) { + for (PyImportElement importElement : ((PyImportStatement) importStatement).getImportElements()) { + PyReferenceExpression importReference = importElement.getImportReferenceExpression(); + if (importReference != null) { + if ("__builtin__".equals(importReference.getName())) { + importReference.replace(elementGenerator.createFromText( + LanguageLevel.getDefault(), + PyReferenceExpression.class, + "builtins" + )); + } + if ("builtins".equals(importReference.getName())) { + importReference.replace(elementGenerator.createFromText( + LanguageLevel.getDefault(), + PyReferenceExpression.class, + "__builtin__" + )); + } + } + } } - } } - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceExceptPartQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceExceptPartQuickFix.java index b266e3bf..cc7ce53d 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceExceptPartQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceExceptPartQuickFix.java @@ -13,55 +13,52 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - -import consulo.language.editor.inspection.LocalQuickFix; -import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.language.ast.ASTNode; -import consulo.project.Project; -import consulo.language.psi.PsiElement; -import consulo.language.psi.PsiWhiteSpace; -import com.jetbrains.python.impl.PyBundle; import com.jetbrains.python.PyTokenTypes; import com.jetbrains.python.psi.LanguageLevel; import com.jetbrains.python.psi.PyElementGenerator; import com.jetbrains.python.psi.PyExceptPart; import com.jetbrains.python.psi.PyTryExceptStatement; +import consulo.language.ast.ASTNode; +import consulo.language.editor.inspection.LocalQuickFix; +import consulo.language.editor.inspection.ProblemDescriptor; +import consulo.language.psi.PsiElement; +import consulo.language.psi.PsiWhiteSpace; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; /** * @author Alexey.Ivanov */ public class ReplaceExceptPartQuickFix implements LocalQuickFix { - @Nonnull - @Override - public String getName() { - return PyBundle.message("INTN.convert.except.to"); - } - - @Nonnull - public String getFamilyName() { - return getName(); - } - - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement exceptPart = descriptor.getPsiElement(); - if (exceptPart instanceof PyExceptPart) { - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - PsiElement element = ((PyExceptPart)exceptPart).getExceptClass().getNextSibling(); - while (element instanceof PsiWhiteSpace) { - element = element.getNextSibling(); - } - assert element != null; - PyTryExceptStatement newElement = - elementGenerator.createFromText(LanguageLevel.forElement(exceptPart), PyTryExceptStatement.class, "try: pass except a as b: pass"); - ASTNode node = newElement.getExceptParts()[0].getNode().findChildByType(PyTokenTypes.AS_KEYWORD); - assert node != null; - element.replace(node.getPsi()); + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.intnConvertExceptTo(); } - } + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement exceptPart = descriptor.getPsiElement(); + if (exceptPart instanceof PyExceptPart) { + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + PsiElement element = ((PyExceptPart) exceptPart).getExceptClass().getNextSibling(); + while (element instanceof PsiWhiteSpace) { + element = element.getNextSibling(); + } + assert element != null; + PyTryExceptStatement newElement = + elementGenerator.createFromText( + LanguageLevel.forElement(exceptPart), + PyTryExceptStatement.class, + "try: pass except a as b: pass" + ); + ASTNode node = newElement.getExceptParts()[0].getNode().findChildByType(PyTokenTypes.AS_KEYWORD); + assert node != null; + element.replace(node.getPsi()); + } + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceListComprehensionsQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceListComprehensionsQuickFix.java index 1d41dad7..874ef298 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceListComprehensionsQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceListComprehensionsQuickFix.java @@ -13,46 +13,41 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import consulo.language.editor.inspection.LocalQuickFix; -import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; -import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; import com.jetbrains.python.psi.LanguageLevel; import com.jetbrains.python.psi.PyElementGenerator; import com.jetbrains.python.psi.PyExpressionStatement; import com.jetbrains.python.psi.PyTupleExpression; +import consulo.language.editor.inspection.LocalQuickFix; +import consulo.language.editor.inspection.ProblemDescriptor; +import consulo.language.psi.PsiElement; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; import jakarta.annotation.Nonnull; /** - * Created by IntelliJ IDEA. - * Author: Alexey.Ivanov - * Date: 06.03.2010 - * Time: 16:50:53 + * @author Alexey.Ivanov + * @since 2010-03-06 */ public class ReplaceListComprehensionsQuickFix implements LocalQuickFix { - @Nonnull - @Override - public String getName() { - return PyBundle.message("INTN.replace.list.comprehensions"); - } - - @Nonnull - public String getFamilyName() { - return getName(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.intnReplaceListComprehensions(); + } - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement expression = descriptor.getPsiElement(); - if (expression instanceof PyTupleExpression) { - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - PyExpressionStatement statement = elementGenerator.createFromText(LanguageLevel.forElement(expression), PyExpressionStatement.class, - "(" + expression.getText() + ")"); - expression.replace(statement.getExpression()); + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement expression = descriptor.getPsiElement(); + if (expression instanceof PyTupleExpression) { + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + PyExpressionStatement statement = + elementGenerator.createFromText(LanguageLevel.forElement(expression), PyExpressionStatement.class, + "(" + expression.getText() + ")" + ); + expression.replace(statement.getExpression()); + } } - } } \ No newline at end of file diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceNotEqOperatorQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceNotEqOperatorQuickFix.java index 97283f19..c4941491 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceNotEqOperatorQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/ReplaceNotEqOperatorQuickFix.java @@ -13,49 +13,41 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.psi.LanguageLevel; +import com.jetbrains.python.psi.PyBinaryExpression; +import com.jetbrains.python.psi.PyElementGenerator; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; import consulo.language.impl.psi.LeafPsiElement; -import consulo.project.Project; import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.LanguageLevel; -import com.jetbrains.python.psi.PyBinaryExpression; -import com.jetbrains.python.psi.PyElementGenerator; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; /** - * Created by IntelliJ IDEA. - * Author: Alexey.Ivanov - * Date: 06.03.2010 - * Time: 16:16:52 + * @author Alexey.Ivanov + * @since 2010-03-06 */ public class ReplaceNotEqOperatorQuickFix implements LocalQuickFix { - @Nonnull - @Override - public String getName() { - return PyBundle.message("INTN.replace.noteq.operator"); - } - - @Nonnull - public String getFamilyName() { - return getName(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.intnReplaceNoteqOperator(); + } - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement binaryExpression = descriptor.getPsiElement(); + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement binaryExpression = descriptor.getPsiElement(); - if (binaryExpression instanceof PyBinaryExpression) { - PsiElement operator = ((PyBinaryExpression)binaryExpression).getPsiOperator(); - if (operator != null) { - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - operator.replace(elementGenerator.createFromText(LanguageLevel.forElement(binaryExpression), LeafPsiElement.class, "!=")); - } + if (binaryExpression instanceof PyBinaryExpression) { + PsiElement operator = ((PyBinaryExpression) binaryExpression).getPsiOperator(); + if (operator != null) { + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + operator.replace(elementGenerator.createFromText(LanguageLevel.forElement(binaryExpression), LeafPsiElement.class, "!=")); + } + } } - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/StatementEffectFunctionCallQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/StatementEffectFunctionCallQuickFix.java index 7aeae741..0da9e62b 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/StatementEffectFunctionCallQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/StatementEffectFunctionCallQuickFix.java @@ -13,77 +13,79 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - -import consulo.language.editor.inspection.LocalQuickFix; -import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; -import consulo.language.psi.PsiElement; -import consulo.language.psi.PsiWhiteSpace; -import com.jetbrains.python.impl.PyBundle; import com.jetbrains.python.psi.LanguageLevel; import com.jetbrains.python.psi.PyElementGenerator; import com.jetbrains.python.psi.PyExpression; import com.jetbrains.python.psi.PyReferenceExpression; +import consulo.language.editor.inspection.LocalQuickFix; +import consulo.language.editor.inspection.ProblemDescriptor; +import consulo.language.psi.PsiElement; +import consulo.language.psi.PsiWhiteSpace; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; /** - * User: catherine - * * QuickFix to replace statement that has no effect with function call + * + * @author catherine */ public class StatementEffectFunctionCallQuickFix implements LocalQuickFix { - @Nonnull - public String getName() { - return PyBundle.message("QFIX.statement.effect"); - } - - @Nonnull - public String getFamilyName() { - return getName(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixStatementEffect(); + } - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement expression = descriptor.getPsiElement(); - if (expression != null && expression.isWritable() && expression instanceof PyReferenceExpression) { - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - if ("print".equals(expression.getText())) - replacePrint(expression, elementGenerator); - else - expression.replace(elementGenerator.createCallExpression(LanguageLevel.forElement(expression), expression.getText())); + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement expression = descriptor.getPsiElement(); + if (expression != null && expression.isWritable() && expression instanceof PyReferenceExpression) { + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + if ("print".equals(expression.getText())) { + replacePrint(expression, elementGenerator); + } + else { + expression.replace(elementGenerator.createCallExpression(LanguageLevel.forElement(expression), expression.getText())); + } + } } - } - private static void replacePrint(PsiElement expression, PyElementGenerator elementGenerator) { - StringBuilder stringBuilder = new StringBuilder("print ("); + private static void replacePrint(PsiElement expression, PyElementGenerator elementGenerator) { + StringBuilder stringBuilder = new StringBuilder("print ("); - final PsiElement whiteSpace = expression.getContainingFile().findElementAt(expression.getTextOffset() + expression.getTextLength()); - PsiElement next = null; - if (whiteSpace instanceof PsiWhiteSpace) { - final String whiteSpaceText = whiteSpace.getText(); - if (!whiteSpaceText.contains("\n")) { - next = whiteSpace.getNextSibling(); - while (next instanceof PsiWhiteSpace && whiteSpaceText.contains("\\")) { - next = next.getNextSibling(); + final PsiElement whiteSpace = expression.getContainingFile().findElementAt(expression.getTextOffset() + expression.getTextLength()); + PsiElement next = null; + if (whiteSpace instanceof PsiWhiteSpace) { + final String whiteSpaceText = whiteSpace.getText(); + if (!whiteSpaceText.contains("\n")) { + next = whiteSpace.getNextSibling(); + while (next instanceof PsiWhiteSpace && whiteSpaceText.contains("\\")) { + next = next.getNextSibling(); + } + } + } + else { + next = whiteSpace; } - } - } - else - next = whiteSpace; - RemoveUnnecessaryBackslashQuickFix.removeBackSlash(next); - if (whiteSpace != null) whiteSpace.delete(); - if (next != null) { - final String text = next.getText(); - stringBuilder.append(text); - if (text.endsWith(",")) - stringBuilder.append(" end=' '"); - next.delete(); + RemoveUnnecessaryBackslashQuickFix.removeBackSlash(next); + if (whiteSpace != null) { + whiteSpace.delete(); + } + if (next != null) { + final String text = next.getText(); + stringBuilder.append(text); + if (text.endsWith(",")) { + stringBuilder.append(" end=' '"); + } + next.delete(); + } + stringBuilder.append(")"); + expression.replace(elementGenerator.createFromText(LanguageLevel.forElement(expression), PyExpression.class, + stringBuilder.toString() + )); } - stringBuilder.append(")"); - expression.replace(elementGenerator.createFromText(LanguageLevel.forElement(expression), PyExpression.class, - stringBuilder.toString())); - } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/UnresolvedRefAddFutureImportQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/UnresolvedRefAddFutureImportQuickFix.java index cbe42841..a60c1068 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/UnresolvedRefAddFutureImportQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/UnresolvedRefAddFutureImportQuickFix.java @@ -13,45 +13,43 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - -import consulo.language.editor.FileModificationService; -import consulo.language.editor.inspection.LocalQuickFix; -import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; -import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; import com.jetbrains.python.psi.LanguageLevel; import com.jetbrains.python.psi.PyElementGenerator; import com.jetbrains.python.psi.PyFile; import com.jetbrains.python.psi.PyFromImportStatement; +import consulo.language.editor.FileModificationService; +import consulo.language.editor.inspection.LocalQuickFix; +import consulo.language.editor.inspection.ProblemDescriptor; +import consulo.language.psi.PsiElement; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; /** - * User: catherine - * * QuickFix to add 'from __future__ import with_statement'' if python version is less than 2.6 + * + * @author catherine */ public class UnresolvedRefAddFutureImportQuickFix implements LocalQuickFix { - @Nonnull - public String getName() { - return PyBundle.message("QFIX.unresolved.reference.add.future"); - } - - @Nonnull - public String getFamilyName() { - return getName(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixUnresolvedReferenceAddFuture(); + } - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PsiElement element = descriptor.getPsiElement(); - PyFile file = (PyFile)element.getContainingFile(); - if (!FileModificationService.getInstance().prepareFileForWrite(file)) return; - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - PyFromImportStatement statement = elementGenerator.createFromText(LanguageLevel.forElement(element), PyFromImportStatement.class, - "from __future__ import with_statement"); - file.addBefore(statement, file.getStatements().get(0)); - } + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PsiElement element = descriptor.getPsiElement(); + PyFile file = (PyFile) element.getContainingFile(); + if (!FileModificationService.getInstance().prepareFileForWrite(file)) { + return; + } + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + PyFromImportStatement statement = elementGenerator.createFromText(LanguageLevel.forElement(element), PyFromImportStatement.class, + "from __future__ import with_statement" + ); + file.addBefore(statement, file.getStatements().get(0)); + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/UnresolvedRefTrueFalseQuickFix.java b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/UnresolvedRefTrueFalseQuickFix.java index ee6751fb..4ebf0ce9 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/UnresolvedRefTrueFalseQuickFix.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/inspections/quickfix/UnresolvedRefTrueFalseQuickFix.java @@ -13,48 +13,44 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.impl.inspections.quickfix; -import jakarta.annotation.Nonnull; - +import com.jetbrains.python.psi.PyElementGenerator; +import com.jetbrains.python.psi.PyExpression; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; -import consulo.project.Project; import consulo.language.psi.PsiElement; -import com.jetbrains.python.impl.PyBundle; -import com.jetbrains.python.psi.PyElementGenerator; -import com.jetbrains.python.psi.PyExpression; +import consulo.localize.LocalizeValue; +import consulo.project.Project; +import consulo.python.impl.localize.PyLocalize; +import jakarta.annotation.Nonnull; /** - * User: catherine - * * QuickFix to replace true with True, false with False + * + * @author catherine */ public class UnresolvedRefTrueFalseQuickFix implements LocalQuickFix { - PsiElement myElement; - String newName; - public UnresolvedRefTrueFalseQuickFix(PsiElement element) { - myElement = element; - char[] charArray = element.getText().toCharArray(); - charArray[0] = Character.toUpperCase(charArray[0]); - newName = new String(charArray); - } - - @Nonnull - public String getName() { - return PyBundle.message("QFIX.unresolved.reference.replace.$0", newName); - } - - @Nonnull - public String getFamilyName() { - return "Replace with True or False"; - } - - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { - PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); - - PyExpression expression = elementGenerator.createExpressionFromText(newName); - myElement.replace(expression); - } + PsiElement myElement; + String newName; + + public UnresolvedRefTrueFalseQuickFix(PsiElement element) { + myElement = element; + char[] charArray = element.getText().toCharArray(); + charArray[0] = Character.toUpperCase(charArray[0]); + newName = new String(charArray); + } + + @Nonnull + @Override + public LocalizeValue getName() { + return PyLocalize.qfixUnresolvedReferenceReplace$0(newName); + } + + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + + PyExpression expression = elementGenerator.createExpressionFromText(newName); + myElement.replace(expression); + } } diff --git a/python-impl/src/main/java/com/jetbrains/python/impl/validation/Pep8ExternalAnnotator.java b/python-impl/src/main/java/com/jetbrains/python/impl/validation/Pep8ExternalAnnotator.java index 3867cbe5..14d01b6a 100644 --- a/python-impl/src/main/java/com/jetbrains/python/impl/validation/Pep8ExternalAnnotator.java +++ b/python-impl/src/main/java/com/jetbrains/python/impl/validation/Pep8ExternalAnnotator.java @@ -60,6 +60,7 @@ import consulo.language.psi.PsiWhiteSpace; import consulo.language.util.IncorrectOperationException; import consulo.language.util.ModuleUtilCore; +import consulo.localize.LocalizeValue; import consulo.logging.Logger; import consulo.process.cmd.GeneralCommandLine; import consulo.process.util.ProcessOutput; @@ -69,6 +70,7 @@ import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; + import java.io.File; import java.util.ArrayList; import java.util.Arrays; @@ -82,387 +84,399 @@ */ @ExtensionImpl public class Pep8ExternalAnnotator extends ExternalAnnotator { - // Taken directly from the sources of pycodestyle.py - private static final String DEFAULT_IGNORED_ERRORS = "E121,E123,E126,E226,E24,E704,W503"; - private static final Logger LOG = Logger.getInstance(Pep8ExternalAnnotator.class); - private static final Pattern E303_LINE_COUNT_PATTERN = Pattern.compile(".*\\((\\d+)\\)$"); - - @Nonnull - @Override - public Language getLanguage() { - return PythonLanguage.INSTANCE; - } - - public static class Problem { - private final int myLine; - private final int myColumn; - private final String myCode; - private final String myDescription; - - public Problem(int line, int column, @Nonnull String code, @Nonnull String description) { - myLine = line; - myColumn = column; - myCode = code; - myDescription = description; - } + // Taken directly from the sources of pycodestyle.py + private static final String DEFAULT_IGNORED_ERRORS = "E121,E123,E126,E226,E24,E704,W503"; + private static final Logger LOG = Logger.getInstance(Pep8ExternalAnnotator.class); + private static final Pattern E303_LINE_COUNT_PATTERN = Pattern.compile(".*\\((\\d+)\\)$"); - public int getLine() { - return myLine; + @Nonnull + @Override + public Language getLanguage() { + return PythonLanguage.INSTANCE; } - public int getColumn() { - return myColumn; - } + public static class Problem { + private final int myLine; + private final int myColumn; + private final String myCode; + private final String myDescription; - @Nonnull - public String getCode() { - return myCode; - } + public Problem(int line, int column, @Nonnull String code, @Nonnull String description) { + myLine = line; + myColumn = column; + myCode = code; + myDescription = description; + } - @Nonnull - public String getDescription() { - return myDescription; - } - } - - public static class State { - private final String interpreterPath; - private final String fileText; - private final HighlightDisplayLevel level; - private final List ignoredErrors; - private final int margin; - - public State(String interpreterPath, String fileText, HighlightDisplayLevel level, List ignoredErrors, int margin) { - this.interpreterPath = interpreterPath; - this.fileText = fileText; - this.level = level; - this.ignoredErrors = ignoredErrors; - this.margin = margin; - } - } + public int getLine() { + return myLine; + } + + public int getColumn() { + return myColumn; + } - public static class Results { - public final List problems = new ArrayList<>(); - private final HighlightDisplayLevel level; + @Nonnull + public String getCode() { + return myCode; + } - public Results(HighlightDisplayLevel level) { - this.level = level; + @Nonnull + public String getDescription() { + return myDescription; + } } - } - private boolean myReportedMissingInterpreter; + public static class State { + private final String interpreterPath; + private final String fileText; + private final HighlightDisplayLevel level; + private final List ignoredErrors; + private final int margin; - @Nullable - @Override - public State collectInformation(@Nonnull PsiFile file) { - VirtualFile vFile = file.getVirtualFile(); - if (vFile == null || vFile.getFileType() != PythonFileType.INSTANCE) { - return null; - } - Sdk sdk = PythonSdkType.findLocalCPython(ModuleUtilCore.findModuleForPsiElement(file)); - if (sdk == null) { - if (!myReportedMissingInterpreter) { - myReportedMissingInterpreter = true; - reportMissingInterpreter(); - } - return null; - } - final String homePath = sdk.getHomePath(); - if (homePath == null) { - if (!myReportedMissingInterpreter) { - myReportedMissingInterpreter = true; - LOG.info("Could not find home path for interpreter " + homePath); - } - return null; - } - final InspectionProfile profile = InspectionProjectProfileManager.getInstance(file.getProject()).getInspectionProfile(); - final HighlightDisplayKey key = HighlightDisplayKey.find(PyPep8Inspection.INSPECTION_SHORT_NAME); - if (!profile.isToolEnabled(key, file)) { - return null; - } - if (file instanceof PyFileImpl && !((PyFileImpl)file).isAcceptedFor(PyPep8Inspection.class)) { - return null; + public State(String interpreterPath, String fileText, HighlightDisplayLevel level, List ignoredErrors, int margin) { + this.interpreterPath = interpreterPath; + this.fileText = fileText; + this.level = level; + this.ignoredErrors = ignoredErrors; + this.margin = margin; + } } - final PyPep8InspectionState toolState = profile.getToolState(PyPep8Inspection.KEY.toString(), file); - final CodeStyleSettings currentSettings = CodeStyleSettingsManager.getInstance(file.getProject()).getCurrentSettings(); + public static class Results { + public final List problems = new ArrayList<>(); + private final HighlightDisplayLevel level; - final List ignoredErrors = new ArrayList<>(toolState.ignoredErrors); - if (!currentSettings.getCustomSettings(PyCodeStyleSettings.class).SPACE_AFTER_NUMBER_SIGN) { - ignoredErrors.add("E262"); // Block comment should start with a space - ignoredErrors.add("E265"); // Inline comment should start with a space + public Results(HighlightDisplayLevel level) { + this.level = level; + } } - if (!currentSettings.getCustomSettings(PyCodeStyleSettings.class).SPACE_BEFORE_NUMBER_SIGN) { - ignoredErrors.add("E261"); // At least two spaces before inline comment - } + private boolean myReportedMissingInterpreter; + + @Nullable + @Override + public State collectInformation(@Nonnull PsiFile file) { + VirtualFile vFile = file.getVirtualFile(); + if (vFile == null || vFile.getFileType() != PythonFileType.INSTANCE) { + return null; + } + Sdk sdk = PythonSdkType.findLocalCPython(ModuleUtilCore.findModuleForPsiElement(file)); + if (sdk == null) { + if (!myReportedMissingInterpreter) { + myReportedMissingInterpreter = true; + reportMissingInterpreter(); + } + return null; + } + final String homePath = sdk.getHomePath(); + if (homePath == null) { + if (!myReportedMissingInterpreter) { + myReportedMissingInterpreter = true; + LOG.info("Could not find home path for interpreter " + homePath); + } + return null; + } + final InspectionProfile profile = InspectionProjectProfileManager.getInstance(file.getProject()).getInspectionProfile(); + final HighlightDisplayKey key = HighlightDisplayKey.find(PyPep8Inspection.INSPECTION_SHORT_NAME); + if (!profile.isToolEnabled(key, file)) { + return null; + } + if (file instanceof PyFileImpl && !((PyFileImpl) file).isAcceptedFor(PyPep8Inspection.class)) { + return null; + } + + final PyPep8InspectionState toolState = profile.getToolState(PyPep8Inspection.KEY.toString(), file); + final CodeStyleSettings currentSettings = CodeStyleSettingsManager.getInstance(file.getProject()).getCurrentSettings(); - final int margin = currentSettings.getRightMargin(file.getLanguage()); - return new State(homePath, file.getText(), profile.getErrorLevel(key, file), ignoredErrors, margin); - } + final List ignoredErrors = new ArrayList<>(toolState.ignoredErrors); + if (!currentSettings.getCustomSettings(PyCodeStyleSettings.class).SPACE_AFTER_NUMBER_SIGN) { + ignoredErrors.add("E262"); // Block comment should start with a space + ignoredErrors.add("E265"); // Inline comment should start with a space + } + + if (!currentSettings.getCustomSettings(PyCodeStyleSettings.class).SPACE_BEFORE_NUMBER_SIGN) { + ignoredErrors.add("E261"); // At least two spaces before inline comment + } - private static void reportMissingInterpreter() { - LOG.info("Found no suitable interpreter to run pycodestyle.py. Available interpreters are: ["); - List allSdks = PythonSdkType.getAllSdks(); - Collections.sort(allSdks, PreferredSdkComparator.INSTANCE); - for (Sdk sdk : allSdks) { - LOG.info(" Path: " + sdk.getHomePath() + "; Flavor: " + PythonSdkFlavor.getFlavor(sdk) + "; Remote: " + PythonSdkType.isRemote(sdk)); + final int margin = currentSettings.getRightMargin(file.getLanguage()); + return new State(homePath, file.getText(), profile.getErrorLevel(key, file), ignoredErrors, margin); } - LOG.info("]"); - } - - @Nullable - @Override - public Results doAnnotate(State collectedInfo) { - if (collectedInfo == null) { - return null; + + private static void reportMissingInterpreter() { + LOG.info("Found no suitable interpreter to run pycodestyle.py. Available interpreters are: ["); + List allSdks = PythonSdkType.getAllSdks(); + Collections.sort(allSdks, PreferredSdkComparator.INSTANCE); + for (Sdk sdk : allSdks) { + LOG.info(" Path: " + sdk.getHomePath() + "; Flavor: " + PythonSdkFlavor.getFlavor(sdk) + "; Remote: " + PythonSdkType.isRemote( + sdk)); + } + LOG.info("]"); } - ArrayList options = new ArrayList<>(); - if (!collectedInfo.ignoredErrors.isEmpty()) { - options.add("--ignore=" + DEFAULT_IGNORED_ERRORS + "," + StringUtil.join(collectedInfo.ignoredErrors, ",")); + @Nullable + @Override + public Results doAnnotate(State collectedInfo) { + if (collectedInfo == null) { + return null; + } + ArrayList options = new ArrayList<>(); + + if (!collectedInfo.ignoredErrors.isEmpty()) { + options.add("--ignore=" + DEFAULT_IGNORED_ERRORS + "," + StringUtil.join(collectedInfo.ignoredErrors, ",")); + } + options.add("--max-line-length=" + collectedInfo.margin); + options.add("-"); + + GeneralCommandLine cmd = PythonHelper.PYCODESTYLE.newCommandLine(collectedInfo.interpreterPath, options); + + ProcessOutput output = PySdkUtil.getProcessOutput( + cmd, + new File(collectedInfo.interpreterPath).getParent(), + ImmutableMap.of("PYTHONBUFFERED", "1"), + 10000, + collectedInfo.fileText.getBytes(), + false + ); + + Results results = new Results(collectedInfo.level); + if (output.isTimeout()) { + LOG.info("Timeout running pycodestyle.py"); + } + else if (output.getStderrLines().isEmpty()) { + for (String line : output.getStdoutLines()) { + final Problem problem = parseProblem(line); + if (problem != null) { + results.problems.add(problem); + } + } + } + else if (ApplicationProperties.isInSandbox()) { + LOG.info("Error running pycodestyle.py: " + output.getStderr()); + } + return results; } - options.add("--max-line-length=" + collectedInfo.margin); - options.add("-"); - GeneralCommandLine cmd = PythonHelper.PYCODESTYLE.newCommandLine(collectedInfo.interpreterPath, options); + @Override + public void apply(@Nonnull PsiFile file, Results annotationResult, @Nonnull AnnotationHolder holder) { + if (annotationResult == null || !file.isValid()) { + return; + } + final String text = file.getText(); + Project project = file.getProject(); + final Document document = PsiDocumentManager.getInstance(project).getDocument(file); + + for (Problem problem : annotationResult.problems) { + final int line = problem.myLine - 1; + final int column = problem.myColumn - 1; + int offset; + if (document != null) { + offset = line >= document.getLineCount() ? document.getTextLength() - 1 : document.getLineStartOffset(line) + column; + } + else { + offset = StringUtil.lineColToOffset(text, line, column); + } + PsiElement problemElement = file.findElementAt(offset); + // E3xx - blank lines warnings + if (!(problemElement instanceof PsiWhiteSpace) && problem.myCode.startsWith("E3")) { + final PsiElement elementBefore = file.findElementAt(Math.max(0, offset - 1)); + if (elementBefore instanceof PsiWhiteSpace) { + problemElement = elementBefore; + } + } + // W292 no newline at end of file + if (problemElement == null && document != null && offset == document.getTextLength() && problem.myCode.equals("W292")) { + problemElement = file.findElementAt(Math.max(0, offset - 1)); + } - ProcessOutput output = PySdkUtil.getProcessOutput(cmd, - new File(collectedInfo.interpreterPath).getParent(), - ImmutableMap.of("PYTHONBUFFERED", "1"), - 10000, - collectedInfo.fileText.getBytes(), - false); + if (ignoreDueToSettings(project, problem, problemElement) || ignoredDueToProblemSuppressors( + project, + problem, + file, + problemElement + )) { + continue; + } - Results results = new Results(collectedInfo.level); - if (output.isTimeout()) { - LOG.info("Timeout running pycodestyle.py"); - } - else if (output.getStderrLines().isEmpty()) { - for (String line : output.getStdoutLines()) { - final Problem problem = parseProblem(line); - if (problem != null) { - results.problems.add(problem); + if (problemElement != null) { + // TODO Remove: a workaround until the bundled pycodestyle.py supports Python 3.6 variable annotations by itself + if (problem.myCode.equals("E701") && + problemElement.getNode().getElementType() == PyTokenTypes.COLON && + problemElement.getParent() instanceof PyAnnotation) { + continue; + } + + TextRange problemRange = problemElement.getTextRange(); + // Multi-line warnings are shown only in the gutter and it's not the desired behavior from the usability point of view. + // So we register it only on that line where pycodestyle.py found the problem originally. + if (crossesLineBoundary(document, text, problemRange)) { + final int lineEndOffset; + if (document != null) { + lineEndOffset = line >= document.getLineCount() ? document.getTextLength() - 1 : document.getLineEndOffset(line); + } + else { + lineEndOffset = StringUtil.lineColToOffset(text, line + 1, 0) - 1; + } + if (offset > lineEndOffset) { + // PSI/document don't match, don't try to highlight random places + continue; + } + problemRange = new TextRange(offset, lineEndOffset); + } + final Annotation annotation; + final boolean inInternalMode = ApplicationProperties.isInSandbox(); + final String message = "PEP 8: " + (inInternalMode ? problem.myCode + " " : "") + problem.myDescription; + if (annotationResult.level == HighlightDisplayLevel.ERROR) { + annotation = holder.createErrorAnnotation(problemRange, message); + } + else if (annotationResult.level == HighlightDisplayLevel.WARNING) { + annotation = holder.createWarningAnnotation(problemRange, message); + } + else { + annotation = holder.createWeakWarningAnnotation(problemRange, message); + } + if (problem.myCode.equals("E401")) { + annotation.registerUniversalFix(new OptimizeImportsQuickFix(), null, null); + } + else if (problem.myCode.equals("W391")) { + annotation.registerUniversalFix(new RemoveTrailingBlankLinesFix(), null, null); + } + else if (problem.myCode.equals("E501")) { + annotation.registerFix(new PyFillParagraphFix()); + } + else { + annotation.registerUniversalFix(new ReformatFix(), null, null); + } + annotation.registerFix(new IgnoreErrorFix(problem.myCode)); + annotation.registerFix(new consulo.ide.impl.idea.codeInspection.ex.CustomEditInspectionToolsSettingsAction( + HighlightDisplayKey.find( + PyPep8Inspection.INSPECTION_SHORT_NAME), + LocalizeValue.localizeTODO("Edit inspection profile setting") + )); + } } - } - } - else if (ApplicationProperties.isInSandbox()) { - LOG.info("Error running pycodestyle.py: " + output.getStderr()); } - return results; - } - @Override - public void apply(@Nonnull PsiFile file, Results annotationResult, @Nonnull AnnotationHolder holder) { - if (annotationResult == null || !file.isValid()) { - return; - } - final String text = file.getText(); - Project project = file.getProject(); - final Document document = PsiDocumentManager.getInstance(project).getDocument(file); - - for (Problem problem : annotationResult.problems) { - final int line = problem.myLine - 1; - final int column = problem.myColumn - 1; - int offset; - if (document != null) { - offset = line >= document.getLineCount() ? document.getTextLength() - 1 : document.getLineStartOffset(line) + column; - } - else { - offset = StringUtil.lineColToOffset(text, line, column); - } - PsiElement problemElement = file.findElementAt(offset); - // E3xx - blank lines warnings - if (!(problemElement instanceof PsiWhiteSpace) && problem.myCode.startsWith("E3")) { - final PsiElement elementBefore = file.findElementAt(Math.max(0, offset - 1)); - if (elementBefore instanceof PsiWhiteSpace) { - problemElement = elementBefore; - } - } - // W292 no newline at end of file - if (problemElement == null && document != null && offset == document.getTextLength() && problem.myCode.equals("W292")) { - problemElement = file.findElementAt(Math.max(0, offset - 1)); - } - - if (ignoreDueToSettings(project, problem, problemElement) || ignoredDueToProblemSuppressors(project, problem, file, problemElement)) { - continue; - } - - if (problemElement != null) { - // TODO Remove: a workaround until the bundled pycodestyle.py supports Python 3.6 variable annotations by itself - if (problem.myCode.equals("E701") && - problemElement.getNode().getElementType() == PyTokenTypes.COLON && - problemElement.getParent() instanceof PyAnnotation) { - continue; - } - - TextRange problemRange = problemElement.getTextRange(); - // Multi-line warnings are shown only in the gutter and it's not the desired behavior from the usability point of view. - // So we register it only on that line where pycodestyle.py found the problem originally. - if (crossesLineBoundary(document, text, problemRange)) { - final int lineEndOffset; - if (document != null) { - lineEndOffset = line >= document.getLineCount() ? document.getTextLength() - 1 : document.getLineEndOffset(line); - } - else { - lineEndOffset = StringUtil.lineColToOffset(text, line + 1, 0) - 1; - } - if (offset > lineEndOffset) { - // PSI/document don't match, don't try to highlight random places - continue; - } - problemRange = new TextRange(offset, lineEndOffset); - } - final Annotation annotation; - final boolean inInternalMode = ApplicationProperties.isInSandbox(); - final String message = "PEP 8: " + (inInternalMode ? problem.myCode + " " : "") + problem.myDescription; - if (annotationResult.level == HighlightDisplayLevel.ERROR) { - annotation = holder.createErrorAnnotation(problemRange, message); - } - else if (annotationResult.level == HighlightDisplayLevel.WARNING) { - annotation = holder.createWarningAnnotation(problemRange, message); - } - else { - annotation = holder.createWeakWarningAnnotation(problemRange, message); - } - if (problem.myCode.equals("E401")) { - annotation.registerUniversalFix(new OptimizeImportsQuickFix(), null, null); - } - else if (problem.myCode.equals("W391")) { - annotation.registerUniversalFix(new RemoveTrailingBlankLinesFix(), null, null); - } - else if (problem.myCode.equals("E501")) { - annotation.registerFix(new PyFillParagraphFix()); - } - else { - annotation.registerUniversalFix(new ReformatFix(), null, null); - } - annotation.registerFix(new IgnoreErrorFix(problem.myCode)); - annotation.registerFix(new consulo.ide.impl.idea.codeInspection.ex.CustomEditInspectionToolsSettingsAction(HighlightDisplayKey.find( - PyPep8Inspection.INSPECTION_SHORT_NAME), () -> "Edit inspection profile setting")); - } + private static boolean ignoredDueToProblemSuppressors( + @Nonnull Project project, + @Nonnull Problem problem, + @Nonnull PsiFile file, + @Nullable PsiElement element + ) { + final Pep8ProblemSuppressor[] suppressors = Pep8ProblemSuppressor.EP_NAME.getExtensions(); + return Arrays.stream(suppressors).anyMatch(p -> p.isProblemSuppressed(problem, file, element)); } - } - - private static boolean ignoredDueToProblemSuppressors(@Nonnull Project project, - @Nonnull Problem problem, - @Nonnull PsiFile file, - @Nullable PsiElement element) { - final Pep8ProblemSuppressor[] suppressors = Pep8ProblemSuppressor.EP_NAME.getExtensions(); - return Arrays.stream(suppressors).anyMatch(p -> p.isProblemSuppressed(problem, file, element)); - } - - private static boolean crossesLineBoundary(@Nullable Document document, String text, TextRange problemRange) { - int start = problemRange.getStartOffset(); - int end = problemRange.getEndOffset(); - if (document != null) { - return document.getLineNumber(start) != document.getLineNumber(end); - } - return StringUtil.offsetToLineNumber(text, start) != StringUtil.offsetToLineNumber(text, end); - } - - private static boolean ignoreDueToSettings(Project project, Problem problem, @Nullable PsiElement element) { - final PersistentEditorSettings editorSettings = PersistentEditorSettings.getInstance(); - if (!editorSettings.getStripTrailingSpaces().equals("None")) { - // ignore trailing spaces errors if they're going to disappear after save - if (problem.myCode.equals("W291") || problem.myCode.equals("W293")) { - return true; - } + + private static boolean crossesLineBoundary(@Nullable Document document, String text, TextRange problemRange) { + int start = problemRange.getStartOffset(); + int end = problemRange.getEndOffset(); + if (document != null) { + return document.getLineNumber(start) != document.getLineNumber(end); + } + return StringUtil.offsetToLineNumber(text, start) != StringUtil.offsetToLineNumber(text, end); } - final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project); - final CommonCodeStyleSettings commonSettings = codeStyleSettings.getCommonSettings(PythonLanguage.getInstance()); - final PyCodeStyleSettings pySettings = codeStyleSettings.getCustomSettings(PyCodeStyleSettings.class); - - if (element instanceof PsiWhiteSpace) { - // E303 too many blank lines (num) - if (problem.myCode.equals("E303")) { - final Matcher matcher = E303_LINE_COUNT_PATTERN.matcher(problem.myDescription); - if (matcher.matches()) { - final int reportedBlanks = Integer.parseInt(matcher.group(1)); - final PsiElement nonWhitespaceAfter = PyPsiUtils.getNextNonWhitespaceSibling(element); - final PsiElement nonWhitespaceBefore = PyPsiUtils.getPrevNonWhitespaceSibling(element); - final boolean classNearby = nonWhitespaceBefore instanceof PyClass || nonWhitespaceAfter instanceof PyClass; - final boolean functionNearby = nonWhitespaceBefore instanceof PyFunction || nonWhitespaceAfter instanceof PyFunction; - if (functionNearby || classNearby) { - if (PyUtil.isTopLevel(element)) { - if (reportedBlanks <= pySettings.BLANK_LINES_AROUND_TOP_LEVEL_CLASSES_FUNCTIONS) { + private static boolean ignoreDueToSettings(Project project, Problem problem, @Nullable PsiElement element) { + final PersistentEditorSettings editorSettings = PersistentEditorSettings.getInstance(); + if (!editorSettings.getStripTrailingSpaces().equals("None")) { + // ignore trailing spaces errors if they're going to disappear after save + if (problem.myCode.equals("W291") || problem.myCode.equals("W293")) { return true; - } } - else { - // Blanks around classes have priority over blanks around functions as defined in Python spacing builder - if (classNearby && reportedBlanks <= commonSettings.BLANK_LINES_AROUND_CLASS || functionNearby && reportedBlanks <= commonSettings.BLANK_LINES_AROUND_METHOD) { + } + + final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project); + final CommonCodeStyleSettings commonSettings = codeStyleSettings.getCommonSettings(PythonLanguage.getInstance()); + final PyCodeStyleSettings pySettings = codeStyleSettings.getCustomSettings(PyCodeStyleSettings.class); + + if (element instanceof PsiWhiteSpace) { + // E303 too many blank lines (num) + if (problem.myCode.equals("E303")) { + final Matcher matcher = E303_LINE_COUNT_PATTERN.matcher(problem.myDescription); + if (matcher.matches()) { + final int reportedBlanks = Integer.parseInt(matcher.group(1)); + final PsiElement nonWhitespaceAfter = PyPsiUtils.getNextNonWhitespaceSibling(element); + final PsiElement nonWhitespaceBefore = PyPsiUtils.getPrevNonWhitespaceSibling(element); + final boolean classNearby = nonWhitespaceBefore instanceof PyClass || nonWhitespaceAfter instanceof PyClass; + final boolean functionNearby = nonWhitespaceBefore instanceof PyFunction || nonWhitespaceAfter instanceof PyFunction; + if (functionNearby || classNearby) { + if (PyUtil.isTopLevel(element)) { + if (reportedBlanks <= pySettings.BLANK_LINES_AROUND_TOP_LEVEL_CLASSES_FUNCTIONS) { + return true; + } + } + else { + // Blanks around classes have priority over blanks around functions as defined in Python spacing builder + if (classNearby && reportedBlanks <= commonSettings.BLANK_LINES_AROUND_CLASS || functionNearby && reportedBlanks <= commonSettings.BLANK_LINES_AROUND_METHOD) { + return true; + } + } + } + } + } + + if (problem.myCode.equals("W191") && codeStyleSettings.useTabCharacter(PythonFileType.INSTANCE)) { + return true; + } + + // E251 unexpected spaces around keyword / parameter equals + // Note that E222 (multiple spaces after operator) is not suppressed, though. + if (problem.myCode.equals("E251") && (element.getParent() instanceof PyParameter && pySettings.SPACE_AROUND_EQ_IN_NAMED_PARAMETER || element + .getParent() instanceof PyKeywordArgument && + pySettings.SPACE_AROUND_EQ_IN_KEYWORD_ARGUMENT)) { return true; - } } - } } - } + return false; + } - if (problem.myCode.equals("W191") && codeStyleSettings.useTabCharacter(PythonFileType.INSTANCE)) { - return true; - } + private static final Pattern PROBLEM_PATTERN = Pattern.compile(".+:(\\d+):(\\d+): ([EW]\\d{3}) (.+)"); - // E251 unexpected spaces around keyword / parameter equals - // Note that E222 (multiple spaces after operator) is not suppressed, though. - if (problem.myCode.equals("E251") && (element.getParent() instanceof PyParameter && pySettings.SPACE_AROUND_EQ_IN_NAMED_PARAMETER || element - .getParent() instanceof PyKeywordArgument && - pySettings.SPACE_AROUND_EQ_IN_KEYWORD_ARGUMENT)) { - return true; - } - } - return false; - } - - private static final Pattern PROBLEM_PATTERN = Pattern.compile(".+:(\\d+):(\\d+): ([EW]\\d{3}) (.+)"); - - @Nullable - private static Problem parseProblem(String s) { - Matcher m = PROBLEM_PATTERN.matcher(s); - if (m.matches()) { - int line = Integer.parseInt(m.group(1)); - int column = Integer.parseInt(m.group(2)); - return new Problem(line, column, m.group(3), m.group(4)); - } - if (ApplicationProperties.isInSandbox()) { - LOG.info("Failed to parse problem line from pycodestyle.py: " + s); + @Nullable + private static Problem parseProblem(String s) { + Matcher m = PROBLEM_PATTERN.matcher(s); + if (m.matches()) { + int line = Integer.parseInt(m.group(1)); + int column = Integer.parseInt(m.group(2)); + return new Problem(line, column, m.group(3), m.group(4)); + } + if (ApplicationProperties.isInSandbox()) { + LOG.info("Failed to parse problem line from pycodestyle.py: " + s); + } + return null; } - return null; - } - private static class IgnoreErrorFix implements SyntheticIntentionAction { - private final String myCode; + private static class IgnoreErrorFix implements SyntheticIntentionAction { + private final String myCode; - public IgnoreErrorFix(String code) { - myCode = code; - } + public IgnoreErrorFix(String code) { + myCode = code; + } - @Nonnull - @Override - public String getText() { - return "Ignore errors like this"; - } + @Nonnull + @Override + public LocalizeValue getText() { + return LocalizeValue.localizeTODO("Ignore errors like this"); + } - @Override - public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { - return true; - } + @Override + public boolean isAvailable(@Nonnull Project project, Editor editor, PsiFile file) { + return true; + } - @Override - public void invoke(@Nonnull Project project, Editor editor, final PsiFile file) throws IncorrectOperationException { - InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile(); - profile.modifyToolSettings(PyPep8Inspection.INSPECTION_SHORT_NAME, file, (i, s) -> - { - if (!s.ignoredErrors.contains(myCode)) { - s.ignoredErrors.add(myCode); - } - }); - } + @Override + public void invoke(@Nonnull Project project, Editor editor, final PsiFile file) throws IncorrectOperationException { + InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile(); + profile.modifyToolSettings(PyPep8Inspection.INSPECTION_SHORT_NAME, file, (i, s) -> { + if (!s.ignoredErrors.contains(myCode)) { + s.ignoredErrors.add(myCode); + } + }); + } - @Override - public boolean startInWriteAction() { - return false; + @Override + public boolean startInWriteAction() { + return false; + } } - } } diff --git a/python-psi-api/src/main/java/com/jetbrains/python/templateLanguages/ConfigureTemplateDirectoriesAction.java b/python-psi-api/src/main/java/com/jetbrains/python/templateLanguages/ConfigureTemplateDirectoriesAction.java index 8b213afd..89b9ba12 100644 --- a/python-psi-api/src/main/java/com/jetbrains/python/templateLanguages/ConfigureTemplateDirectoriesAction.java +++ b/python-psi-api/src/main/java/com/jetbrains/python/templateLanguages/ConfigureTemplateDirectoriesAction.java @@ -21,33 +21,28 @@ import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; import consulo.language.editor.intention.LowPriorityAction; +import consulo.localize.LocalizeValue; import consulo.project.Project; import jakarta.annotation.Nonnull; /** -* @author yole -*/ + * @author yole + */ public class ConfigureTemplateDirectoriesAction implements LocalQuickFix, LowPriorityAction { - @Nonnull - @Override - public String getName() { - return "Configure template directories"; - } - - @Nonnull - @Override - public String getFamilyName() { - return getName(); - } + @Nonnull + @Override + public LocalizeValue getName() { + return LocalizeValue.localizeTODO("Configure template directories"); + } - @Override - public void applyFix(@Nonnull final Project project, @Nonnull ProblemDescriptor descriptor) { - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - ShowSettingsUtil.getInstance().showSettingsDialog(project, "Template Languages"); - } - }, Application.get().getNoneModalityState()); - } + @Override + public void applyFix(@Nonnull final Project project, @Nonnull ProblemDescriptor descriptor) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + ShowSettingsUtil.getInstance().showSettingsDialog(project, "Template Languages"); + } + }, Application.get().getNoneModalityState()); + } } diff --git a/python-rest/src/main/java/com/jetbrains/python/rest/quickfixes/AddIgnoredRoleFix.java b/python-rest/src/main/java/com/jetbrains/python/rest/quickfixes/AddIgnoredRoleFix.java index dcaeb23b..1460ff09 100644 --- a/python-rest/src/main/java/com/jetbrains/python/rest/quickfixes/AddIgnoredRoleFix.java +++ b/python-rest/src/main/java/com/jetbrains/python/rest/quickfixes/AddIgnoredRoleFix.java @@ -13,57 +13,47 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.jetbrains.python.rest.quickfixes; -import com.jetbrains.rest.RestBundle; import com.jetbrains.python.rest.inspections.RestRoleInspection; import com.jetbrains.python.rest.inspections.RestRoleInspectionState; +import com.jetbrains.rest.RestBundle; import consulo.language.editor.inspection.LocalQuickFix; import consulo.language.editor.inspection.ProblemDescriptor; import consulo.language.editor.inspection.scheme.InspectionProfile; import consulo.language.editor.inspection.scheme.InspectionProjectProfileManager; import consulo.language.editor.intention.LowPriorityAction; +import consulo.localize.LocalizeValue; import consulo.project.Project; - import jakarta.annotation.Nonnull; /** - * User : catherine + * @author catherine */ -public class AddIgnoredRoleFix implements LocalQuickFix, LowPriorityAction -{ - private final String myRole; - - public AddIgnoredRoleFix(String role) - { - myRole = role; - } - - @Nonnull - @Override - public String getName() - { - return RestBundle.message("QFIX.ignore.role", myRole); - } - - @Nonnull - @Override - public String getFamilyName() - { - return "Ignore undefined role"; - } - - @Override - public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) - { - final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile(); - profile.modifyToolSettings(RestRoleInspection.class.getSimpleName(), descriptor.getPsiElement(), (t, s) -> - { - if(!s.ignoredRoles.contains(myRole)) - { - s.ignoredRoles.add(myRole); - } - }); - } +public class AddIgnoredRoleFix implements LocalQuickFix, LowPriorityAction { + private final String myRole; + + public AddIgnoredRoleFix(String role) { + myRole = role; + } + + @Nonnull + @Override + public LocalizeValue getName() { + return LocalizeValue.localizeTODO(RestBundle.message("QFIX.ignore.role", myRole)); + } + + @Override + public void applyFix(@Nonnull Project project, @Nonnull ProblemDescriptor descriptor) { + final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile(); + profile.modifyToolSettings( + RestRoleInspection.class.getSimpleName(), + descriptor.getPsiElement(), + (t, s) -> { + if (!s.ignoredRoles.contains(myRole)) { + s.ignoredRoles.add(myRole); + } + } + ); + } }