mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Updated star expression annotator to allow * unpacking in tuples and lists
This commit is contained in:
@@ -190,7 +190,7 @@ public class ExpressionParsing extends Parsing {
|
||||
}
|
||||
|
||||
if (atToken(PyTokenTypes.EXP)) {
|
||||
if (!parseStarExpression(false)) {
|
||||
if (!parseDoubleStarExpression(false)) {
|
||||
myBuilder.error("expression expected");
|
||||
expr.done(PyElementTypes.DICT_LITERAL_EXPRESSION);
|
||||
return;
|
||||
@@ -248,7 +248,7 @@ public class ExpressionParsing extends Parsing {
|
||||
while (myBuilder.getTokenType() != PyTokenTypes.RBRACE) {
|
||||
checkMatches(PyTokenTypes.COMMA, message("PARSE.expected.comma"));
|
||||
if (atToken(PyTokenTypes.EXP)) {
|
||||
if (!parseStarExpression(false)) {
|
||||
if (!parseDoubleStarExpression(false)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -789,8 +789,7 @@ public class ExpressionParsing extends Parsing {
|
||||
}
|
||||
|
||||
private boolean parseStarExpression(boolean isTargetExpression) {
|
||||
final IElementType tokenType = myBuilder.getTokenType();
|
||||
if (tokenType == PyTokenTypes.MULT || tokenType == PyTokenTypes.EXP) {
|
||||
if (atToken(PyTokenTypes.MULT)) {
|
||||
PsiBuilder.Marker starExpr = myBuilder.mark();
|
||||
nextToken();
|
||||
if (!parseBitwiseORExpression(isTargetExpression)) {
|
||||
@@ -798,7 +797,22 @@ public class ExpressionParsing extends Parsing {
|
||||
starExpr.drop();
|
||||
return false;
|
||||
}
|
||||
starExpr.done(tokenType == PyTokenTypes.MULT ? PyElementTypes.STAR_EXPRESSION : PyElementTypes.DOUBLE_STAR_EXPRESSION);
|
||||
starExpr.done(PyElementTypes.STAR_EXPRESSION);
|
||||
return true;
|
||||
}
|
||||
return parseBitwiseORExpression(isTargetExpression);
|
||||
}
|
||||
|
||||
private boolean parseDoubleStarExpression(boolean isTargetExpression) {
|
||||
if (atToken(PyTokenTypes.EXP)) {
|
||||
PsiBuilder.Marker starExpr = myBuilder.mark();
|
||||
nextToken();
|
||||
if (!parseBitwiseORExpression(isTargetExpression)) {
|
||||
myBuilder.error(message("PARSE.expected.expression"));
|
||||
starExpr.drop();
|
||||
return false;
|
||||
}
|
||||
starExpr.done(PyElementTypes.DOUBLE_STAR_EXPRESSION);
|
||||
return true;
|
||||
}
|
||||
return parseBitwiseORExpression(isTargetExpression);
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
*/
|
||||
package com.jetbrains.python.validation;
|
||||
|
||||
import com.jetbrains.python.psi.PyStarExpression;
|
||||
import com.jetbrains.python.psi.PyTargetExpression;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -25,8 +26,20 @@ public class StarAnnotator extends PyAnnotator {
|
||||
@Override
|
||||
public void visitPyStarExpression(PyStarExpression node) {
|
||||
super.visitPyStarExpression(node);
|
||||
if (!(node.getExpression() instanceof PyTargetExpression)) {
|
||||
getHolder().createErrorAnnotation(node, "can use starred expression only as assignment target");
|
||||
if (!isAssignmentTarget(node) && !isStarUnpacking(node)) {
|
||||
getHolder().createErrorAnnotation(node, "Can't use starred expression here");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isStarUnpacking(@NotNull PyStarExpression node) {
|
||||
PsiElement parent = node.getParent();
|
||||
while (parent instanceof PyParenthesizedExpression) {
|
||||
parent = parent.getParent();
|
||||
}
|
||||
return parent instanceof PyTupleExpression || parent instanceof PyListLiteralExpression;
|
||||
}
|
||||
|
||||
private static boolean isAssignmentTarget(@NotNull PyStarExpression node) {
|
||||
return node.getExpression() instanceof PyTargetExpression;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
y = (<error descr="can use starred expression only as assignment target">*()</error> for _ in ())
|
||||
y = (<error descr="Can't use starred expression here">*()</error> for _ in ())
|
||||
@@ -0,0 +1,9 @@
|
||||
1, *x
|
||||
(1, *x)
|
||||
[1, *x]
|
||||
|
||||
if <error descr="Can't use starred expression here">*x</error>:
|
||||
pass
|
||||
|
||||
1 + (<error descr="Can't use starred expression here">*x</error>)
|
||||
1 + (*x,)
|
||||
@@ -241,6 +241,10 @@ public class PythonHighlightingTest extends PyTestCase {
|
||||
doTest(LanguageLevel.PYTHON35, false, false);
|
||||
}
|
||||
|
||||
public void testUnpackingStar() {
|
||||
doTest(LanguageLevel.PYTHON35, false, false);
|
||||
}
|
||||
|
||||
// ---
|
||||
private void doTest(final LanguageLevel languageLevel, final boolean checkWarnings, final boolean checkInfos) {
|
||||
PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), languageLevel);
|
||||
|
||||
Reference in New Issue
Block a user