mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Move several related methods for navigating PSI and AST trees from PyUtil to PyPsiUtil
This commit is contained in:
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -58,7 +59,6 @@ public class PyPsiUtils {
|
||||
|
||||
/**
|
||||
* Finds the closest comma after the element skipping any whitespaces in-between.
|
||||
* @param element
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getPrevComma(@NotNull PsiElement element) {
|
||||
@@ -66,13 +66,36 @@ public class PyPsiUtils {
|
||||
return prevNode != null && prevNode.getNode().getElementType() == PyTokenTypes.COMMA ? prevNode : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds first non-whitespace sibling before given PSI element.
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getPrevNonWhitespaceSibling(@NotNull PsiElement element) {
|
||||
public static PsiElement getPrevNonWhitespaceSibling(@Nullable PsiElement element) {
|
||||
return PsiTreeUtil.skipSiblingsBackward(element, PsiWhiteSpace.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the closest comma before the element skipping any whitespaces in-between.
|
||||
* Find first non-whitespace sibling before given AST node.
|
||||
*/
|
||||
@Nullable
|
||||
public static ASTNode getPrevNonWhitespaceSibling(@NotNull ASTNode node) {
|
||||
return skipSiblingsBackward(node, TokenSet.create(TokenType.WHITE_SPACE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Find first sibling that is neither comment, nor whitespace before given element or this element itself.
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getFirstNonCommentBefore(@Nullable PsiElement start) {
|
||||
PsiElement seeker = start;
|
||||
while (seeker instanceof PsiWhiteSpace || seeker instanceof PsiComment) {
|
||||
seeker = seeker.getPrevSibling();
|
||||
}
|
||||
return seeker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the closest comma after the element skipping any whitespaces in-between.
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getNextComma(@NotNull PsiElement element) {
|
||||
@@ -80,11 +103,32 @@ public class PyPsiUtils {
|
||||
return nextNode != null && nextNode.getNode().getElementType() == PyTokenTypes.COMMA ? nextNode : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds first non-whitespace sibling after given PSI element.
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getNextNonWhitespaceSibling(@NotNull PsiElement element) {
|
||||
public static PsiElement getNextNonWhitespaceSibling(@Nullable PsiElement element) {
|
||||
return PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find first non-whitespace sibling after given AST node.
|
||||
*/
|
||||
@Nullable
|
||||
public static ASTNode getNextNonWhitespaceSibling(@NotNull ASTNode after) {
|
||||
return skipSiblingsForward(after, TokenSet.create(TokenType.WHITE_SPACE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Find first sibling that is neither comment, nor whitespace after given element or this element itself.
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getFirstNonCommentAfter(@Nullable PsiElement start) {
|
||||
PsiElement seeker = start;
|
||||
while (seeker instanceof PsiWhiteSpace || seeker instanceof PsiComment) seeker = seeker.getNextSibling();
|
||||
return seeker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the closest comma looking for the next comma first and then for the preceding one.
|
||||
*/
|
||||
@@ -94,6 +138,70 @@ public class PyPsiUtils {
|
||||
return nextComma != null ? nextComma : getPrevComma(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Works similarly to {@link PsiTreeUtil#skipSiblingsForward(PsiElement, Class[])}, but for AST nodes.
|
||||
*/
|
||||
@Nullable
|
||||
public static ASTNode skipSiblingsForward(@Nullable ASTNode node, @NotNull TokenSet types) {
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
for (ASTNode next = node.getTreeNext(); next != null; next = next.getTreeNext()) {
|
||||
if (!types.contains(next.getElementType())) {
|
||||
return next;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Works similarly to {@link PsiTreeUtil#skipSiblingsBackward(PsiElement, Class[])}, but for AST nodes.
|
||||
*/
|
||||
@Nullable
|
||||
public static ASTNode skipSiblingsBackward(@Nullable ASTNode node, @NotNull TokenSet types) {
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
for (ASTNode prev = node.getTreePrev(); prev != null; prev = prev.getTreePrev()) {
|
||||
if (!types.contains(prev.getElementType())) {
|
||||
return prev;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first child psi element with specified element type or {@code null} if no such element exists.
|
||||
* Semantically it's the same as {@code getChildByFilter(element, TokenSet.create(type), 0)}.
|
||||
*
|
||||
* @param element tree parent node
|
||||
* @param type element type expected
|
||||
* @return child element described
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getFirstChildOfType(@NotNull final PsiElement element, @NotNull PyElementType type) {
|
||||
final ASTNode child = element.getNode().findChildByType(type);
|
||||
return child != null ? child.getPsi() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns child element in the psi tree
|
||||
*
|
||||
* @param filter Types of expected child
|
||||
* @param number number
|
||||
* @param element tree parent node
|
||||
* @return PsiElement - child psiElement
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getChildByFilter(@NotNull PsiElement element, @NotNull TokenSet filter, int number) {
|
||||
final ASTNode node = element.getNode();
|
||||
if (node != null) {
|
||||
final ASTNode[] children = node.getChildren(filter);
|
||||
return (0 <= number && number < children.length) ? children[number].getPsi() : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void addBeforeInParent(@NotNull final PsiElement anchor, @NotNull final PsiElement... newElements) {
|
||||
final ASTNode anchorNode = anchor.getNode();
|
||||
LOG.assertTrue(anchorNode != null);
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonFileType;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
|
||||
/**
|
||||
* Adds appropriate first parameter to a freshly-typed method declaration.
|
||||
@@ -55,7 +56,7 @@ public class PyMethodNameTypedHandler extends TypedHandlerDelegate {
|
||||
|
||||
final ASTNode token_node = token.getNode();
|
||||
if (token_node != null && token_node.getElementType() == PyTokenTypes.IDENTIFIER) {
|
||||
PsiElement maybe_def = PyUtil.getFirstNonCommentBefore(token.getPrevSibling());
|
||||
PsiElement maybe_def = PyPsiUtils.getFirstNonCommentBefore(token.getPrevSibling());
|
||||
if (maybe_def != null) {
|
||||
ASTNode def_node = maybe_def.getNode();
|
||||
if (def_node != null && def_node.getElementType() == PyTokenTypes.DEF_KEYWORD) {
|
||||
|
||||
+3
-3
@@ -24,7 +24,7 @@ import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterPro
|
||||
import com.jetbrains.python.psi.PyArgumentList;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyDecorator;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -37,9 +37,9 @@ public class PyArgumentListFixer extends PyFixer<PyArgumentList> {
|
||||
|
||||
@Override
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyArgumentList arguments) throws IncorrectOperationException {
|
||||
final PsiElement rBrace = PyUtil.getChildByFilter(arguments, PyTokenTypes.CLOSE_BRACES, 0);
|
||||
final PsiElement rBrace = PyPsiUtils.getChildByFilter(arguments, PyTokenTypes.CLOSE_BRACES, 0);
|
||||
if (arguments.getParent() instanceof PyClass || arguments.getParent() instanceof PyDecorator) {
|
||||
final PsiElement lBrace = PyUtil.getChildByFilter(arguments, PyTokenTypes.OPEN_BRACES, 0);
|
||||
final PsiElement lBrace = PyPsiUtils.getChildByFilter(arguments, PyTokenTypes.OPEN_BRACES, 0);
|
||||
if (lBrace != null && rBrace == null) {
|
||||
final Document document = editor.getDocument();
|
||||
document.insertString(arguments.getTextRange().getEndOffset(), ")");
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.PyArgumentList;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.jetbrains.python.psi.PyUtil.sure;
|
||||
@@ -40,7 +40,7 @@ public class PyClassFixer extends PyFixer<PyClass> {
|
||||
}
|
||||
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyClass pyClass) throws IncorrectOperationException {
|
||||
final PsiElement colon = PyUtil.getFirstChildOfType(pyClass, PyTokenTypes.COLON);
|
||||
final PsiElement colon = PyPsiUtils.getFirstChildOfType(pyClass, PyTokenTypes.COLON);
|
||||
if (colon == null) {
|
||||
final PyArgumentList argList = PsiTreeUtil.getChildOfType(pyClass, PyArgumentList.class);
|
||||
final int colonOffset = sure(argList).getTextRange().getEndOffset();
|
||||
|
||||
+5
-5
@@ -24,7 +24,7 @@ import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.PyConditionalStatementPart;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.jetbrains.python.psi.PyUtil.sure;
|
||||
@@ -45,18 +45,18 @@ public class PyConditionalStatementPartFixer extends PyFixer<PyConditionalStatem
|
||||
throws IncorrectOperationException {
|
||||
final PyExpression condition = statementPart.getCondition();
|
||||
final Document document = editor.getDocument();
|
||||
final PsiElement colon = PyUtil.getFirstChildOfType(statementPart, PyTokenTypes.COLON);
|
||||
final PsiElement colon = PyPsiUtils.getFirstChildOfType(statementPart, PyTokenTypes.COLON);
|
||||
if (colon == null) {
|
||||
if (condition != null) {
|
||||
final PsiElement firstNonComment = PyUtil.getFirstNonCommentAfter(condition.getNextSibling());
|
||||
final PsiElement firstNonComment = PyPsiUtils.getFirstNonCommentAfter(condition.getNextSibling());
|
||||
if (firstNonComment != null && !":".equals(firstNonComment.getNode().getText())) {
|
||||
document.insertString(firstNonComment.getTextRange().getEndOffset(), ":");
|
||||
}
|
||||
}
|
||||
else {
|
||||
final TokenSet keywords = TokenSet.create(PyTokenTypes.IF_KEYWORD, PyTokenTypes.ELIF_KEYWORD, PyTokenTypes.WHILE_KEYWORD);
|
||||
final PsiElement keywordToken = PyUtil.getChildByFilter(statementPart,
|
||||
keywords, 0);
|
||||
final PsiElement keywordToken = PyPsiUtils.getChildByFilter(statementPart,
|
||||
keywords, 0);
|
||||
final int offset = sure(keywordToken).getTextRange().getEndOffset();
|
||||
document.insertString(offset, " :");
|
||||
processor.registerUnresolvedError(offset + 1);
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.PyExceptPart;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.jetbrains.python.psi.PyUtil.sure;
|
||||
@@ -40,9 +40,9 @@ public class PyExceptFixer extends PyFixer<PyExceptPart> {
|
||||
|
||||
@Override
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyExceptPart exceptPart) throws IncorrectOperationException {
|
||||
final PsiElement colon = PyUtil.getFirstChildOfType(exceptPart, PyTokenTypes.COLON);
|
||||
final PsiElement colon = PyPsiUtils.getFirstChildOfType(exceptPart, PyTokenTypes.COLON);
|
||||
if (colon == null) {
|
||||
final PsiElement exceptToken = PyUtil.getFirstChildOfType(exceptPart, PyTokenTypes.EXCEPT_KEYWORD);
|
||||
final PsiElement exceptToken = PyPsiUtils.getFirstChildOfType(exceptPart, PyTokenTypes.EXCEPT_KEYWORD);
|
||||
int offset = sure(exceptToken).getTextRange().getEndOffset();
|
||||
final PyExpression exceptClass = exceptPart.getExceptClass();
|
||||
if (exceptClass != null) {
|
||||
|
||||
+4
-4
@@ -21,7 +21,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.PyForPart;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.jetbrains.python.psi.PyUtil.sure;
|
||||
@@ -39,16 +39,16 @@ public class PyForPartFixer extends PyFixer<PyForPart> {
|
||||
|
||||
@Override
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyForPart forPart) {
|
||||
final PsiElement colon = PyUtil.getFirstChildOfType(forPart, PyTokenTypes.COLON);
|
||||
final PsiElement colon = PyPsiUtils.getFirstChildOfType(forPart, PyTokenTypes.COLON);
|
||||
final Document document = editor.getDocument();
|
||||
final PsiElement forToken = PyUtil.getFirstChildOfType(forPart, PyTokenTypes.FOR_KEYWORD);
|
||||
final PsiElement forToken = PyPsiUtils.getFirstChildOfType(forPart, PyTokenTypes.FOR_KEYWORD);
|
||||
if (colon == null) {
|
||||
String textToInsert = ":";
|
||||
PsiElement sourceOrTarget = forPart.getSource();
|
||||
PsiElement positionToInsert = sourceOrTarget;
|
||||
if (sourceOrTarget == null) {
|
||||
sourceOrTarget = forPart.getTarget();
|
||||
final PsiElement inToken = PyUtil.getFirstChildOfType(forPart, PyTokenTypes.IN_KEYWORD);
|
||||
final PsiElement inToken = PyPsiUtils.getFirstChildOfType(forPart, PyTokenTypes.IN_KEYWORD);
|
||||
if (inToken == null) {
|
||||
if (sourceOrTarget == null) {
|
||||
positionToInsert = sure(forToken);
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyParameterList;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ public class PyFunctionFixer extends PyFixer<PyFunction> {
|
||||
@Override
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyFunction function)
|
||||
throws IncorrectOperationException {
|
||||
final PsiElement colon = PyUtil.getFirstChildOfType(function, PyTokenTypes.COLON);
|
||||
final PsiElement colon = PyPsiUtils.getFirstChildOfType(function, PyTokenTypes.COLON);
|
||||
if (!isFakeFunction(function) && colon == null) {
|
||||
final PyParameterList parameterList = function.getParameterList();
|
||||
if (function.getNameNode() == null) {
|
||||
|
||||
+3
-2
@@ -20,6 +20,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -37,7 +38,7 @@ public class PyMissingBracesFixer extends PyFixer<PyElement> {
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyElement psiElement)
|
||||
throws IncorrectOperationException {
|
||||
if (psiElement instanceof PySetLiteralExpression || psiElement instanceof PyDictLiteralExpression) {
|
||||
final PsiElement lastChild = PyUtil.getFirstNonCommentBefore(psiElement.getLastChild());
|
||||
final PsiElement lastChild = PyPsiUtils.getFirstNonCommentBefore(psiElement.getLastChild());
|
||||
if (lastChild != null && !"}".equals(lastChild.getText())) {
|
||||
editor.getDocument().insertString(lastChild.getTextRange().getEndOffset(), "}");
|
||||
}
|
||||
@@ -45,7 +46,7 @@ public class PyMissingBracesFixer extends PyFixer<PyElement> {
|
||||
else if (psiElement instanceof PyListLiteralExpression ||
|
||||
psiElement instanceof PySliceExpression ||
|
||||
psiElement instanceof PySubscriptionExpression) {
|
||||
final PsiElement lastChild = PyUtil.getFirstNonCommentBefore(psiElement.getLastChild());
|
||||
final PsiElement lastChild = PyPsiUtils.getFirstNonCommentBefore(psiElement.getLastChild());
|
||||
if (lastChild != null && !"]".equals(lastChild.getText())) {
|
||||
editor.getDocument().insertString(lastChild.getTextRange().getEndOffset(), "]");
|
||||
}
|
||||
|
||||
+3
-3
@@ -23,7 +23,7 @@ import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyParameterList;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.jetbrains.python.psi.PyUtil.as;
|
||||
@@ -42,8 +42,8 @@ public class PyParameterListFixer extends PyFixer<PyParameterList> {
|
||||
@Override
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyParameterList parameters)
|
||||
throws IncorrectOperationException {
|
||||
final PsiElement lBrace = PyUtil.getChildByFilter(parameters, PyTokenTypes.OPEN_BRACES, 0);
|
||||
final PsiElement rBrace = PyUtil.getChildByFilter(parameters, PyTokenTypes.CLOSE_BRACES, 0);
|
||||
final PsiElement lBrace = PyPsiUtils.getChildByFilter(parameters, PyTokenTypes.OPEN_BRACES, 0);
|
||||
final PsiElement rBrace = PyPsiUtils.getChildByFilter(parameters, PyTokenTypes.CLOSE_BRACES, 0);
|
||||
final PyFunction pyFunction = as(parameters.getParent(), PyFunction.class);
|
||||
if (pyFunction != null && !PyFunctionFixer.isFakeFunction(pyFunction) && (lBrace == null || rBrace == null)) {
|
||||
final Document document = editor.getDocument();
|
||||
|
||||
+3
-2
@@ -22,6 +22,7 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.jetbrains.python.psi.PyUtil.sure;
|
||||
@@ -41,10 +42,10 @@ public class PyUnconditionalStatementPartFixer extends PyFixer<PyElement> {
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyElement psiElement)
|
||||
throws IncorrectOperationException {
|
||||
if (PyUtil.instanceOf(psiElement, PyElsePart.class, PyTryPart.class, PyFinallyPart.class)) {
|
||||
final PsiElement colon = PyUtil.getFirstChildOfType(psiElement, PyTokenTypes.COLON);
|
||||
final PsiElement colon = PyPsiUtils.getFirstChildOfType(psiElement, PyTokenTypes.COLON);
|
||||
if (colon == null) {
|
||||
final TokenSet keywords = TokenSet.create(PyTokenTypes.ELSE_KEYWORD, PyTokenTypes.TRY_KEYWORD, PyTokenTypes.FINALLY_KEYWORD);
|
||||
final PsiElement keywordToken = PyUtil.getChildByFilter(psiElement, keywords, 0);
|
||||
final PsiElement keywordToken = PyPsiUtils.getChildByFilter(psiElement, keywords, 0);
|
||||
editor.getDocument().insertString(sure(keywordToken).getTextRange().getEndOffset(), ":");
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -23,9 +23,9 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.PyWithItem;
|
||||
import com.jetbrains.python.psi.PyWithStatement;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -38,8 +38,8 @@ public class PyWithFixer extends PyFixer<PyWithStatement> {
|
||||
|
||||
@Override
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyWithStatement withStatement) throws IncorrectOperationException {
|
||||
final PsiElement colonToken = PyUtil.getFirstChildOfType(withStatement, PyTokenTypes.COLON);
|
||||
final PsiElement withToken = PyUtil.getFirstChildOfType(withStatement, PyTokenTypes.WITH_KEYWORD);
|
||||
final PsiElement colonToken = PyPsiUtils.getFirstChildOfType(withStatement, PyTokenTypes.COLON);
|
||||
final PsiElement withToken = PyPsiUtils.getFirstChildOfType(withStatement, PyTokenTypes.WITH_KEYWORD);
|
||||
final Document document = editor.getDocument();
|
||||
if (colonToken == null && withToken != null) {
|
||||
int insertAt = withToken.getTextRange().getEndOffset();
|
||||
@@ -52,7 +52,7 @@ public class PyWithFixer extends PyFixer<PyWithStatement> {
|
||||
else {
|
||||
final PyExpression expression = lastItem.getExpression();
|
||||
insertAt = expression.getTextRange().getEndOffset();
|
||||
final PsiElement asToken = PyUtil.getFirstChildOfType(lastItem, PyTokenTypes.AS_KEYWORD);
|
||||
final PsiElement asToken = PyPsiUtils.getFirstChildOfType(lastItem, PyTokenTypes.AS_KEYWORD);
|
||||
if (asToken != null) {
|
||||
insertAt = asToken.getTextRange().getEndOffset();
|
||||
final PyExpression target = lastItem.getTarget();
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -54,11 +55,11 @@ public class PySplitIfIntention extends BaseIntentionAction {
|
||||
final IElementType elementType = elementAtOffset.getNode().getElementType();
|
||||
if (elementType == PyTokenTypes.COLON) {
|
||||
elementAtOffset = elementAtOffset.getPrevSibling();
|
||||
elementAtOffset = PyUtil.getFirstNonCommentBefore(elementAtOffset);
|
||||
elementAtOffset = PyPsiUtils.getFirstNonCommentBefore(elementAtOffset);
|
||||
}
|
||||
else if (elementType == PyTokenTypes.IF_KEYWORD) {
|
||||
elementAtOffset = elementAtOffset.getNextSibling();
|
||||
elementAtOffset = PyUtil.getFirstNonCommentAfter(elementAtOffset);
|
||||
elementAtOffset = PyPsiUtils.getFirstNonCommentAfter(elementAtOffset);
|
||||
}
|
||||
|
||||
PsiElement element = PsiTreeUtil.getParentOfType(elementAtOffset, PyBinaryExpression.class, false);
|
||||
@@ -87,11 +88,11 @@ public class PySplitIfIntention extends BaseIntentionAction {
|
||||
final IElementType elementType = elementAtOffset.getNode().getElementType();
|
||||
if (elementType == PyTokenTypes.COLON) {
|
||||
elementAtOffset = elementAtOffset.getPrevSibling();
|
||||
elementAtOffset = PyUtil.getFirstNonCommentBefore(elementAtOffset);
|
||||
elementAtOffset = PyPsiUtils.getFirstNonCommentBefore(elementAtOffset);
|
||||
}
|
||||
else if (elementType == PyTokenTypes.IF_KEYWORD) {
|
||||
elementAtOffset = elementAtOffset.getNextSibling();
|
||||
elementAtOffset = PyUtil.getFirstNonCommentAfter(elementAtOffset);
|
||||
elementAtOffset = PyPsiUtils.getFirstNonCommentAfter(elementAtOffset);
|
||||
}
|
||||
|
||||
PyBinaryExpression element = PsiTreeUtil.getParentOfType(elementAtOffset, PyBinaryExpression.class, false);
|
||||
|
||||
@@ -64,8 +64,8 @@ public class DocStringUtil {
|
||||
@Nullable
|
||||
public static PyStringLiteralExpression findDocStringExpression(@Nullable PyElement parent) {
|
||||
if (parent != null) {
|
||||
PsiElement seeker = PyUtil.getFirstNonCommentAfter(parent.getFirstChild());
|
||||
if (seeker instanceof PyExpressionStatement) seeker = PyUtil.getFirstNonCommentAfter(seeker.getFirstChild());
|
||||
PsiElement seeker = PyPsiUtils.getFirstNonCommentAfter(parent.getFirstChild());
|
||||
if (seeker instanceof PyExpressionStatement) seeker = PyPsiUtils.getFirstNonCommentAfter(seeker.getFirstChild());
|
||||
if (seeker instanceof PyStringLiteralExpression) return (PyStringLiteralExpression)seeker;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -51,7 +51,6 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings.IndentOptions;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
@@ -100,44 +99,6 @@ public class PyUtil {
|
||||
private PyUtil() {
|
||||
}
|
||||
|
||||
public static ASTNode getNextNonWhitespace(ASTNode after) {
|
||||
ASTNode node = after;
|
||||
do {
|
||||
node = node.getTreeNext();
|
||||
}
|
||||
while (isWhitespace(node));
|
||||
return node;
|
||||
}
|
||||
|
||||
public static ASTNode getPreviousNonWhitespace(ASTNode after) {
|
||||
ASTNode node = after;
|
||||
do {
|
||||
node = node.getTreePrev();
|
||||
}
|
||||
while (isWhitespace(node));
|
||||
return node;
|
||||
}
|
||||
|
||||
private static boolean isWhitespace(ASTNode node) {
|
||||
return node != null && node.getElementType().equals(TokenType.WHITE_SPACE);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement getFirstNonCommentAfter(PsiElement start) {
|
||||
PsiElement seeker = start;
|
||||
while (seeker instanceof PsiWhiteSpace || seeker instanceof PsiComment) seeker = seeker.getNextSibling();
|
||||
return seeker;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement getFirstNonCommentBefore(PsiElement start) {
|
||||
PsiElement seeker = start;
|
||||
while (seeker instanceof PsiWhiteSpace || seeker instanceof PsiComment) {
|
||||
seeker = seeker.getPrevSibling();
|
||||
}
|
||||
return seeker;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <T extends PyElement> T[] getAllChildrenOfType(@NotNull PsiElement element, @NotNull Class<T> aClass) {
|
||||
List<T> result = new SmartList<T>();
|
||||
@@ -917,38 +878,6 @@ public class PyUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns child element in the psi tree
|
||||
*
|
||||
* @param filter Types of expected child
|
||||
* @param number number
|
||||
* @param element tree parent node
|
||||
* @return PsiElement - child psiElement
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getChildByFilter(@NotNull final PsiElement element, final @NotNull TokenSet filter, final int number) {
|
||||
final ASTNode node = element.getNode();
|
||||
if (node != null) {
|
||||
final ASTNode[] children = node.getChildren(filter);
|
||||
return (0 <= number && number < children.length) ? children[number].getPsi() : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first child psi element with specified element type or {@code null} if no such element exists.
|
||||
* Semantically it's the same as {@code getChildByFilter(element, TokenSet.create(type), 0)}.
|
||||
*
|
||||
* @param element tree parent node
|
||||
* @param type element type expected
|
||||
* @return child element described
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getFirstChildOfType(@NotNull final PsiElement element, @NotNull PyElementType type) {
|
||||
final ASTNode child = element.getNode().findChildByType(type);
|
||||
return child != null ? child.getPsi() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If argument is a PsiDirectory, turn it into a PsiFile that points to __init__.py in that directory.
|
||||
* If there's no __init__.py there, null is returned, there's no point to resolve to a dir which is not a package.
|
||||
|
||||
@@ -157,7 +157,7 @@ public class PyArgumentListImpl extends PyElementImpl implements PyArgumentList
|
||||
}
|
||||
}
|
||||
else {
|
||||
ASTNode before = PyUtil.getNextNonWhitespace(pars[0]);
|
||||
ASTNode before = PyPsiUtils.getNextNonWhitespaceSibling(pars[0]);
|
||||
ASTNode anchorBefore;
|
||||
if (before != null && elementPrecedesElementsOfType(before, PythonDialectsTokenSetProvider.INSTANCE.getExpressionTokens())) {
|
||||
ASTNode comma = createComma();
|
||||
@@ -265,7 +265,7 @@ public class PyArgumentListImpl extends PyElementImpl implements PyArgumentList
|
||||
break;
|
||||
}
|
||||
else if (type == PyTokenTypes.COMMA) {
|
||||
ASTNode next = PyUtil.getNextNonWhitespace(node);
|
||||
ASTNode next = PyPsiUtils.getNextNonWhitespaceSibling(node);
|
||||
if (next == null) {
|
||||
addArgumentLastWithoutComma(argument);
|
||||
}
|
||||
|
||||
@@ -19,11 +19,10 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonDialectsTokenSetProvider;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import com.jetbrains.python.psi.PyAugAssignmentStatement;
|
||||
import com.jetbrains.python.psi.PyElementVisitor;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -55,6 +54,6 @@ public class PyAugAssignmentStatementImpl extends PyElementImpl implements PyAug
|
||||
|
||||
@Nullable
|
||||
public PsiElement getOperation() {
|
||||
return PyUtil.getChildByFilter(this, PyTokenTypes.AUG_ASSIGN_OPERATIONS, 0);
|
||||
return PyPsiUtils.getChildByFilter(this, PyTokenTypes.AUG_ASSIGN_OPERATIONS, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ public class PyElementGeneratorImpl extends PyElementGenerator {
|
||||
exprNode.addChild(add);
|
||||
}
|
||||
else {
|
||||
ASTNode next = PyUtil.getNextNonWhitespace(closingTokens[closingTokens.length - 1]);
|
||||
ASTNode next = PyPsiUtils.getNextNonWhitespaceSibling(closingTokens[closingTokens.length - 1]);
|
||||
if (next != null) {
|
||||
ASTNode comma = createComma();
|
||||
exprNode.addChild(comma, next);
|
||||
|
||||
@@ -75,7 +75,7 @@ public class PyParameterListImpl extends PyBaseElementImpl<PyParameterListStub>
|
||||
}
|
||||
}
|
||||
}
|
||||
final ASTNode previous = PyUtil.getPreviousNonWhitespace(beforeWhat);
|
||||
final ASTNode previous = PyPsiUtils.getPrevNonWhitespaceSibling(beforeWhat);
|
||||
PyUtil.addListNode(this, param, beforeWhat, !isLast || params.length == 0 ||
|
||||
previous.getElementType() == PyTokenTypes.COMMA, isLast,
|
||||
beforeWhat.getElementType() != PyTokenTypes.RPAR);
|
||||
|
||||
Reference in New Issue
Block a user