mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Moved replace expression to PyReplaceExpressionUtil
This commit is contained in:
@@ -4,9 +4,6 @@ import com.google.common.collect.Lists;
|
||||
import com.intellij.extapi.psi.ASTDelegatePsiElement;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
@@ -15,7 +12,6 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonStringUtil;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -29,8 +25,6 @@ import java.util.List;
|
||||
* @author max
|
||||
*/
|
||||
public class PyPsiUtils {
|
||||
public static final Key<Pair<PsiElement, TextRange>> SELECTION_BREAKS_AST_NODE =
|
||||
new Key<Pair<PsiElement, TextRange>>("python.selection.breaks.ast.node");
|
||||
private static final Logger LOG = Logger.getInstance(PyPsiUtils.class.getName());
|
||||
|
||||
private PyPsiUtils() {
|
||||
@@ -68,52 +62,6 @@ public class PyPsiUtils {
|
||||
return node;
|
||||
}
|
||||
|
||||
public static PsiElement replaceExpression(@NotNull final PsiElement oldExpression,
|
||||
@NotNull final PsiElement newExpression) {
|
||||
final Pair<PsiElement, TextRange> data = oldExpression.getUserData(SELECTION_BREAKS_AST_NODE);
|
||||
if (data != null) {
|
||||
final PsiElement element = data.first;
|
||||
final TextRange textRange = data.second;
|
||||
final String parentText = element.getText();
|
||||
final String prefix = parentText.substring(0, textRange.getStartOffset());
|
||||
final String suffix = parentText.substring(textRange.getEndOffset(), element.getTextLength());
|
||||
final PyElementGenerator generator = PyElementGenerator.getInstance(oldExpression.getProject());
|
||||
final LanguageLevel languageLevel = LanguageLevel.forElement(oldExpression);
|
||||
if (element instanceof PyStringLiteralExpression) {
|
||||
final Pair<String, String> quotes = PythonStringUtil.getQuotes(parentText);
|
||||
final PsiElement parent = element.getParent();
|
||||
final boolean parensNeeded = parent instanceof PyExpression && !(parent instanceof PyParenthesizedExpression);
|
||||
if (quotes != null) {
|
||||
final String leftQuote = quotes.getFirst();
|
||||
final String rightQuote = quotes.getSecond();
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
if (parensNeeded) {
|
||||
builder.append("(");
|
||||
}
|
||||
if (!leftQuote.endsWith(prefix)) {
|
||||
builder.append(prefix + rightQuote + " + ");
|
||||
}
|
||||
final int pos = builder.toString().length();
|
||||
builder.append(newExpression.getText());
|
||||
if (!rightQuote.startsWith(suffix)) {
|
||||
builder.append(" + " + leftQuote + suffix);
|
||||
}
|
||||
if (parensNeeded) {
|
||||
builder.append(")");
|
||||
}
|
||||
final PsiElement expression = generator.createExpressionFromText(languageLevel, builder.toString());
|
||||
final PsiElement newElement = element.replace(expression);
|
||||
return newElement.findElementAt(pos);
|
||||
}
|
||||
}
|
||||
final PsiElement expression = generator.createFromText(languageLevel, element.getClass(), prefix + newExpression.getText() + suffix);
|
||||
return element.replace(expression);
|
||||
}
|
||||
else {
|
||||
return oldExpression.replace(newExpression);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addBeforeInParent(@NotNull final PsiElement anchor, @NotNull final PsiElement... newElements) {
|
||||
final ASTNode anchorNode = anchor.getNode();
|
||||
LOG.assertTrue(anchorNode != null);
|
||||
|
||||
@@ -14,7 +14,6 @@ import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.jetbrains.python.findUsages.PyFindUsagesHandlerFactory;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -43,7 +42,7 @@ public class PyRefactoringUtil {
|
||||
return;
|
||||
}
|
||||
if (element instanceof PyStringLiteralExpression) {
|
||||
final Pair<PsiElement, TextRange> selection = pattern.getUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE);
|
||||
final Pair<PsiElement, TextRange> selection = pattern.getUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE);
|
||||
if (selection != null) {
|
||||
final String substring = selection.getSecond().substring(pattern.getText());
|
||||
final PyStringLiteralExpression expr = (PyStringLiteralExpression)element;
|
||||
@@ -51,7 +50,7 @@ public class PyRefactoringUtil {
|
||||
if (text != null && expr.getStringNodes().size() == 1) {
|
||||
final int start = text.indexOf(substring);
|
||||
if (start >= 0) {
|
||||
element.putUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE, Pair.create(element, TextRange.from(start, substring.length())));
|
||||
element.putUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE, Pair.create(element, TextRange.from(start, substring.length())));
|
||||
occurrences.add(element);
|
||||
return;
|
||||
}
|
||||
@@ -113,7 +112,7 @@ public class PyRefactoringUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
expression.putUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE, Pair.create(parent, textRange));
|
||||
expression.putUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE, Pair.create(parent, textRange));
|
||||
return expression;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
package com.jetbrains.python.refactoring;
|
||||
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.jetbrains.python.PyElementTypes;
|
||||
import com.jetbrains.python.PythonStringUtil;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.jetbrains.python.PyTokenTypes.*;
|
||||
|
||||
@@ -11,6 +17,8 @@ import static com.jetbrains.python.PyTokenTypes.*;
|
||||
* @author Dennis.Ushakov
|
||||
*/
|
||||
public class PyReplaceExpressionUtil implements PyElementTypes {
|
||||
public static final Key<Pair<PsiElement, TextRange>> SELECTION_BREAKS_AST_NODE =
|
||||
new Key<Pair<PsiElement, TextRange>>("python.selection.breaks.ast.node");
|
||||
|
||||
private PyReplaceExpressionUtil() {}
|
||||
|
||||
@@ -37,6 +45,63 @@ public class PyReplaceExpressionUtil implements PyElementTypes {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static PsiElement replaceExpression(@NotNull final PsiElement oldExpression,
|
||||
@NotNull final PsiElement newExpression) {
|
||||
final Pair<PsiElement, TextRange> data = oldExpression.getUserData(SELECTION_BREAKS_AST_NODE);
|
||||
if (data != null) {
|
||||
final PsiElement element = data.first;
|
||||
final TextRange textRange = data.second;
|
||||
final String parentText = element.getText();
|
||||
final String prefix = parentText.substring(0, textRange.getStartOffset());
|
||||
final String suffix = parentText.substring(textRange.getEndOffset(), element.getTextLength());
|
||||
final PyElementGenerator generator = PyElementGenerator.getInstance(oldExpression.getProject());
|
||||
final LanguageLevel languageLevel = LanguageLevel.forElement(oldExpression);
|
||||
if (element instanceof PyStringLiteralExpression) {
|
||||
return replaceSubstringInStringLiteral((PyStringLiteralExpression)element, newExpression, textRange);
|
||||
}
|
||||
final PsiElement expression = generator.createFromText(languageLevel, element.getClass(), prefix + newExpression.getText() + suffix);
|
||||
return element.replace(expression);
|
||||
}
|
||||
else {
|
||||
return oldExpression.replace(newExpression);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement replaceSubstringInStringLiteral(@NotNull PyStringLiteralExpression oldExpression,
|
||||
@NotNull PsiElement newExpression,
|
||||
@NotNull TextRange textRange) {
|
||||
final String fullText = oldExpression.getText();
|
||||
final PyElementGenerator generator = PyElementGenerator.getInstance(oldExpression.getProject());
|
||||
final LanguageLevel languageLevel = LanguageLevel.forElement(oldExpression);
|
||||
final String prefix = fullText.substring(0, textRange.getStartOffset());
|
||||
final String suffix = fullText.substring(textRange.getEndOffset(), oldExpression.getTextLength());
|
||||
final Pair<String, String> detectedQuotes = PythonStringUtil.getQuotes(fullText);
|
||||
final Pair<String, String> quotes = detectedQuotes != null ? detectedQuotes : Pair.create("'", "'");
|
||||
final PsiElement parent = oldExpression.getParent();
|
||||
final boolean parensNeeded = parent instanceof PyExpression && !(parent instanceof PyParenthesizedExpression);
|
||||
final String leftQuote = quotes.getFirst();
|
||||
final String rightQuote = quotes.getSecond();
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
if (parensNeeded) {
|
||||
builder.append("(");
|
||||
}
|
||||
if (!leftQuote.endsWith(prefix)) {
|
||||
builder.append(prefix + rightQuote + " + ");
|
||||
}
|
||||
final int pos = builder.toString().length();
|
||||
builder.append(newExpression.getText());
|
||||
if (!rightQuote.startsWith(suffix)) {
|
||||
builder.append(" + " + leftQuote + suffix);
|
||||
}
|
||||
if (parensNeeded) {
|
||||
builder.append(")");
|
||||
}
|
||||
final PsiElement expression = generator.createExpressionFromText(languageLevel, builder.toString());
|
||||
final PsiElement newElement = oldExpression.replace(expression);
|
||||
return newElement.findElementAt(pos);
|
||||
}
|
||||
|
||||
private static boolean isNotAssociative(@NotNull final PyBinaryExpression binaryExpression) {
|
||||
final IElementType opType = getOperationType(binaryExpression);
|
||||
return COMPARISON_OPERATIONS.contains(opType) || binaryExpression instanceof PySliceExpression ||
|
||||
|
||||
@@ -41,6 +41,7 @@ import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyFunctionBuilder;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import com.jetbrains.python.refactoring.PyReplaceExpressionUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -308,7 +309,7 @@ public class PyExtractMethodUtil {
|
||||
|
||||
// replace statements with call
|
||||
if (callElement != null) {
|
||||
callElement = PyPsiUtils.replaceExpression(expression, callElement);
|
||||
callElement = PyReplaceExpressionUtil.replaceExpression(expression, callElement);
|
||||
}
|
||||
|
||||
// Set editor
|
||||
@@ -397,7 +398,7 @@ public class PyExtractMethodUtil {
|
||||
}
|
||||
|
||||
private static PyFunction insertGeneratedMethod(PsiElement anchor, final PyFunction generatedMethod) {
|
||||
final Pair<PsiElement, TextRange> data = anchor.getUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE);
|
||||
final Pair<PsiElement, TextRange> data = anchor.getUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE);
|
||||
if (data != null) {
|
||||
anchor = data.first;
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ import com.jetbrains.python.PythonStringUtil;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.inspections.PyStringFormatParser;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
import com.jetbrains.python.psi.types.PyNoneType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import com.jetbrains.python.refactoring.NameSuggesterUtil;
|
||||
import com.jetbrains.python.refactoring.PyRefactoringUtil;
|
||||
import com.jetbrains.python.refactoring.PyReplaceExpressionUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -116,12 +116,12 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
|
||||
protected PsiElement replaceExpression(PsiElement expression, PyExpression newExpression, IntroduceOperation operation) {
|
||||
PyExpressionStatement statement = PsiTreeUtil.getParentOfType(expression, PyExpressionStatement.class);
|
||||
if (statement != null) {
|
||||
if (statement.getExpression() == expression && expression.getUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE) == null) {
|
||||
if (statement.getExpression() == expression && expression.getUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE) == null) {
|
||||
statement.delete();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return PyPsiUtils.replaceExpression(expression, newExpression);
|
||||
return PyReplaceExpressionUtil.replaceExpression(expression, newExpression);
|
||||
}
|
||||
|
||||
private final IntroduceValidator myValidator;
|
||||
@@ -173,7 +173,7 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
|
||||
}
|
||||
};
|
||||
String text = expression.getText();
|
||||
final Pair<PsiElement, TextRange> selection = expression.getUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE);
|
||||
final Pair<PsiElement, TextRange> selection = expression.getUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE);
|
||||
if (selection != null) {
|
||||
text = selection.getSecond().substring(text);
|
||||
}
|
||||
@@ -293,7 +293,7 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
|
||||
showCannotPerformError(project, editor);
|
||||
return;
|
||||
}
|
||||
element1.putUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE, Pair.create(element1, finalRange));
|
||||
element1.putUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE, Pair.create(element1, finalRange));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,7 +505,7 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
|
||||
|
||||
@Override
|
||||
public void visitPyStringLiteralExpression(PyStringLiteralExpression node) {
|
||||
final Pair<PsiElement, TextRange> data = node.getUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE);
|
||||
final Pair<PsiElement, TextRange> data = node.getUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE);
|
||||
if (data != null) {
|
||||
final PsiElement parent = data.getFirst();
|
||||
final String text = parent.getText();
|
||||
@@ -598,7 +598,7 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
|
||||
@Nullable
|
||||
public PsiElement addDeclaration(IntroduceOperation operation, PsiElement declaration) {
|
||||
final PsiElement expression = operation.getInitializer();
|
||||
final Pair<PsiElement, TextRange> data = expression.getUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE);
|
||||
final Pair<PsiElement, TextRange> data = expression.getUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE);
|
||||
if (data == null) {
|
||||
return addDeclaration(expression, declaration, operation);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import com.jetbrains.python.refactoring.PyRefactoringUtil;
|
||||
import com.jetbrains.python.refactoring.PyReplaceExpressionUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -40,8 +40,8 @@ public abstract class IntroduceValidator {
|
||||
public abstract String check(String name, PsiElement psiElement);
|
||||
|
||||
public static boolean isDefinedInScope(String name, PsiElement psiElement) {
|
||||
if (psiElement.getUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE) != null) {
|
||||
final Pair<PsiElement,TextRange> data = psiElement.getUserData(PyPsiUtils.SELECTION_BREAKS_AST_NODE);
|
||||
if (psiElement.getUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE) != null) {
|
||||
final Pair<PsiElement,TextRange> data = psiElement.getUserData(PyReplaceExpressionUtil.SELECTION_BREAKS_AST_NODE);
|
||||
psiElement = data.first;
|
||||
}
|
||||
PsiElement context = PsiTreeUtil.getParentOfType(psiElement, PyFunction.class);
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.codeInsight.imports.AddImportHelper;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyFile;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import com.jetbrains.python.refactoring.PyReplaceExpressionUtil;
|
||||
import com.jetbrains.python.refactoring.introduce.IntroduceHandler;
|
||||
import com.jetbrains.python.refactoring.introduce.IntroduceOperation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -29,7 +29,7 @@ public class PyIntroduceConstantHandler extends IntroduceHandler {
|
||||
if (PsiTreeUtil.getParentOfType(expression, ScopeOwner.class) instanceof PyFile) {
|
||||
return super.replaceExpression(expression, newExpression, operation);
|
||||
}
|
||||
return PyPsiUtils.replaceExpression(expression, newExpression);
|
||||
return PyReplaceExpressionUtil.replaceExpression(expression, newExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@ import com.jetbrains.python.inspections.quickfix.AddFieldQuickFix;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyFunctionBuilder;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import com.jetbrains.python.refactoring.PyReplaceExpressionUtil;
|
||||
import com.jetbrains.python.refactoring.introduce.IntroduceHandler;
|
||||
import com.jetbrains.python.refactoring.introduce.IntroduceOperation;
|
||||
import com.jetbrains.python.refactoring.introduce.variable.PyIntroduceVariableHandler;
|
||||
@@ -78,7 +78,7 @@ public class PyIntroduceFieldHandler extends IntroduceHandler {
|
||||
@Override
|
||||
protected PsiElement replaceExpression(PsiElement expression, PyExpression newExpression, IntroduceOperation operation) {
|
||||
if (operation.getInitPlace() != InitPlace.SAME_METHOD) {
|
||||
return PyPsiUtils.replaceExpression(expression, newExpression);
|
||||
return PyReplaceExpressionUtil.replaceExpression(expression, newExpression);
|
||||
}
|
||||
return super.replaceExpression(expression, newExpression, operation);
|
||||
}
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@ import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import com.jetbrains.python.refactoring.PyReplaceExpressionUtil;
|
||||
import com.jetbrains.python.refactoring.introduce.IntroduceHandler;
|
||||
import com.jetbrains.python.refactoring.introduce.IntroduceOperation;
|
||||
import com.jetbrains.python.refactoring.introduce.variable.VariableValidator;
|
||||
@@ -56,7 +56,7 @@ public class PyIntroduceParameterHandler extends IntroduceHandler {
|
||||
@Nullable
|
||||
@Override
|
||||
protected PsiElement replaceExpression(PsiElement expression, PyExpression newExpression, IntroduceOperation operation) {
|
||||
return PyPsiUtils.replaceExpression(expression, newExpression);
|
||||
return PyReplaceExpressionUtil.replaceExpression(expression, newExpression);
|
||||
}
|
||||
|
||||
protected boolean isValidIntroduceContext(PsiElement element) {
|
||||
|
||||
Reference in New Issue
Block a user