mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Add method isEmpty() in PySequenceExpression, simplify several usages of getElements()
This commit is contained in:
@@ -23,4 +23,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
public interface PySequenceExpression extends PyExpression{
|
||||
@NotNull
|
||||
PyExpression[] getElements();
|
||||
|
||||
/**
|
||||
* Calling {@link #getElements()} may take too much time in case of large literals with thousands of elements. If you only need to
|
||||
* know whether collection is empty, use this method instead.
|
||||
*
|
||||
* @return true if sequence expression contains no elements
|
||||
*/
|
||||
boolean isEmpty();
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.intellij.psi.impl.source.tree.TreeUtil;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.jetbrains.python.PyElementTypes;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonDialectsTokenSetProvider;
|
||||
@@ -82,7 +83,7 @@ public class PyBlock implements ASTBlock {
|
||||
private final PyBlockContext myContext;
|
||||
private List<PyBlock> mySubBlocks = null;
|
||||
private Alignment myChildAlignment;
|
||||
private final boolean myEmptyList;
|
||||
private final boolean myEmptySequence;
|
||||
|
||||
public PyBlock(final PyBlock parent,
|
||||
final ASTNode node,
|
||||
@@ -96,7 +97,7 @@ public class PyBlock implements ASTBlock {
|
||||
myNode = node;
|
||||
myWrap = wrap;
|
||||
myContext = context;
|
||||
myEmptyList = node.getPsi() instanceof PySequenceExpression && ((PySequenceExpression)node.getPsi()).getElements().length == 0;
|
||||
myEmptySequence = isEmptySequence(node);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -133,7 +134,7 @@ public class PyBlock implements ASTBlock {
|
||||
|
||||
final IElementType childType = child.getElementType();
|
||||
|
||||
if (child.getTextRange().getLength() == 0) continue;
|
||||
if (child.getTextRange().isEmpty()) continue;
|
||||
|
||||
if (childType == TokenType.WHITE_SPACE) {
|
||||
continue;
|
||||
@@ -160,7 +161,7 @@ public class PyBlock implements ASTBlock {
|
||||
while (p != null) {
|
||||
final ASTNode pNode = p.getNode();
|
||||
if (ourListElementTypes.contains(pNode.getElementType())) {
|
||||
if (needListAlignment(child) && !myEmptyList) {
|
||||
if (needListAlignment(child) && !myEmptySequence) {
|
||||
|
||||
childAlignment = p.getChildAlignment();
|
||||
break;
|
||||
@@ -198,7 +199,7 @@ public class PyBlock implements ASTBlock {
|
||||
!isSliceOperand(child) /*&& !isSubscriptionOperand(child)*/) {
|
||||
wrap = Wrap.createWrap(WrapType.NORMAL, true);
|
||||
}
|
||||
if (needListAlignment(child) && !myEmptyList) {
|
||||
if (needListAlignment(child) && !myEmptySequence) {
|
||||
childAlignment = getAlignmentForChildren();
|
||||
}
|
||||
if (childType == PyTokenTypes.END_OF_LINE_COMMENT) {
|
||||
@@ -349,6 +350,10 @@ public class PyBlock implements ASTBlock {
|
||||
return new PyBlock(this, child, childAlignment, childIndent, wrap, myContext);
|
||||
}
|
||||
|
||||
private static boolean isEmptySequence(@NotNull ASTNode node) {
|
||||
return node.getPsi() instanceof PySequenceExpression && ((PySequenceExpression)node.getPsi()).isEmpty();
|
||||
}
|
||||
|
||||
private boolean argumentMayHaveSameIndentAsFollowingStatementList() {
|
||||
// This check is supposed to prevent PEP8's error: Continuation line with the same indent as next logical line
|
||||
final PsiElement header = getControlStatementHeader(myNode);
|
||||
@@ -499,11 +504,8 @@ public class PyBlock implements ASTBlock {
|
||||
if (PyTokenTypes.OPEN_BRACES.contains(childType)) {
|
||||
return false;
|
||||
}
|
||||
if (PyTokenTypes.OPEN_BRACES.contains(firstGrandchildType)) {
|
||||
final PsiElement psi = child.getPsi();
|
||||
if (psi instanceof PySequenceExpression && ((PySequenceExpression)psi).getElements().length == 0) {
|
||||
return false;
|
||||
}
|
||||
if (PyTokenTypes.OPEN_BRACES.contains(firstGrandchildType) && isEmptySequence(child)) {
|
||||
return false;
|
||||
}
|
||||
if (PyTokenTypes.CLOSE_BRACES.contains(childType)) {
|
||||
final ASTNode prevNonSpace = findPrevNonSpaceNode(child);
|
||||
@@ -757,12 +759,8 @@ public class PyBlock implements ASTBlock {
|
||||
return null;
|
||||
}
|
||||
if (myNode.getPsi() instanceof PyDictLiteralExpression) {
|
||||
final PyKeyValueExpression[] elements = ((PyDictLiteralExpression)myNode.getPsi()).getElements();
|
||||
if (elements.length == 0) {
|
||||
return null;
|
||||
}
|
||||
final PyKeyValueExpression last = elements[elements.length - 1];
|
||||
if (last.getValue() == null) { // incomplete
|
||||
final PyKeyValueExpression lastElement = ArrayUtil.getLastElement(((PyDictLiteralExpression)myNode.getPsi()).getElements());
|
||||
if (lastElement == null || lastElement.getValue() == null /* incomplete */) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,9 +58,10 @@ public class PyDictDuplicateKeysInspection extends PyInspection {
|
||||
|
||||
@Override
|
||||
public void visitPyDictLiteralExpression(PyDictLiteralExpression node) {
|
||||
if (node.getElements().length != 0){
|
||||
final PyKeyValueExpression[] elements = node.getElements();
|
||||
if (elements.length != 0){
|
||||
final Map<String, PyElement> map = new HashMap<String, PyElement>();
|
||||
for (PyExpression exp : node.getElements()) {
|
||||
for (PyExpression exp : elements) {
|
||||
final PyExpression key = ((PyKeyValueExpression)exp).getKey();
|
||||
if (key instanceof PyNumericLiteralExpression
|
||||
|| key instanceof PyStringLiteralExpression || key instanceof PyReferenceExpression) {
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ public class PyReplaceTupleWithListQuickFix implements LocalQuickFix {
|
||||
}
|
||||
|
||||
private static void replaceWithListLiteral(PsiElement element, PyTupleExpression expression) {
|
||||
final String expressionText = expression.getElements().length == 0 ? "" :expression.getText();
|
||||
final String expressionText = expression.isEmpty() ? "" :expression.getText();
|
||||
final PyExpression literal = PyElementGenerator.getInstance(element.getProject()).
|
||||
createExpressionFromText(LanguageLevel.forElement(element),
|
||||
"[" + expressionText + "]");
|
||||
|
||||
@@ -110,6 +110,13 @@ public class PyBaseElementImpl<T extends StubElement> extends StubBasedPsiElemen
|
||||
return (T)node.getPsi();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected <T extends PyElement> T childToPsi(@NotNull TokenSet elTypes) {
|
||||
final ASTNode node = getNode().findChildByType(elTypes);
|
||||
//noinspection unchecked
|
||||
return node != null ? (T)node.getPsi() : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected <T extends PyElement> T childToPsiNotNull(TokenSet filterSet, int index) {
|
||||
final PyElement child = childToPsi(filterSet, index);
|
||||
|
||||
@@ -4,12 +4,13 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.jetbrains.python.PythonDialectsTokenSetProvider;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PySequenceExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Mikhail Golubev
|
||||
*/
|
||||
public class PySequenceExpressionImpl extends PyElementImpl {
|
||||
public abstract class PySequenceExpressionImpl extends PyElementImpl implements PySequenceExpression {
|
||||
public PySequenceExpressionImpl(ASTNode astNode) {
|
||||
super(astNode);
|
||||
}
|
||||
@@ -26,4 +27,9 @@ public class PySequenceExpressionImpl extends PyElementImpl {
|
||||
public PyExpression[] getElements() {
|
||||
return childrenToPsi(PythonDialectsTokenSetProvider.INSTANCE.getExpressionTokens(), PyExpression.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return childToPsi(PythonDialectsTokenSetProvider.INSTANCE.getExpressionTokens()) == null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ public class AssignTargetAnnotator extends PyAnnotator {
|
||||
|
||||
@Override
|
||||
public void visitPyTupleExpression(final PyTupleExpression node) {
|
||||
if (node.getElements().length == 0) {
|
||||
if (node.isEmpty()) {
|
||||
getHolder().createErrorAnnotation(node, message("ANN.cant.assign.to.parens"));
|
||||
}
|
||||
else if (myOp == Operation.AugAssign) {
|
||||
@@ -153,7 +153,7 @@ public class AssignTargetAnnotator extends PyAnnotator {
|
||||
|
||||
@Override
|
||||
public void visitPyListLiteralExpression(final PyListLiteralExpression node) {
|
||||
if (node.getElements().length == 0) {
|
||||
if (node.isEmpty()) {
|
||||
getHolder().createErrorAnnotation(node, message("ANN.cant.assign.to.brackets"));
|
||||
}
|
||||
else if (myOp == Operation.AugAssign) {
|
||||
|
||||
Reference in New Issue
Block a user