PY-253: make both foo and bar refs in assignments like 'foo.bar[1] = 1'

This commit is contained in:
Dmitry Cheryasov
2009-12-19 16:43:08 +02:00
parent 8f80611a9c
commit c801fc5bfe
3 changed files with 38 additions and 17 deletions

View File

@@ -210,6 +210,7 @@ public class ExpressionParsing extends Parsing {
public boolean parseMemberExpression(PsiBuilder builder, boolean isTargetExpression) {
// in sequence a.b.... .c all members but last are always references, and the last may be target.
boolean recast_first_identifier = false;
boolean recast_qualifier = false;
do {
boolean first_identifier_is_target = isTargetExpression && ! recast_first_identifier;
PsiBuilder.Marker expr = builder.mark();
@@ -229,7 +230,7 @@ public class ExpressionParsing extends Parsing {
else recast_first_identifier = false;
builder.advanceLexer();
checkMatches(PyTokenTypes.IDENTIFIER, message("PARSE.expected.name"));
if (isTargetExpression && builder.getTokenType() != PyTokenTypes.DOT) {
if (isTargetExpression && ! recast_qualifier && builder.getTokenType() != PyTokenTypes.DOT) {
expr.done(PyElementTypes.TARGET_EXPRESSION);
}
else {
@@ -257,8 +258,9 @@ public class ExpressionParsing extends Parsing {
else {
checkMatches(PyTokenTypes.RBRACKET, message("PARSE.expected.rbracket"));
expr.done(PyElementTypes.SUBSCRIPTION_EXPRESSION);
if (first_identifier_is_target) {
if (isTargetExpression && ! recast_qualifier) {
recast_first_identifier = true; // subscription is always a reference
recast_qualifier = true; // recast non-first qualifiers too
expr.rollbackTo();
break;
}
@@ -271,6 +273,7 @@ public class ExpressionParsing extends Parsing {
break;
}
recast_first_identifier = false; // it is true only after a break; normal flow always unsets it.
// recast_qualifier is untouched, it remembers whether qualifiers were already recast
}
}
while (recast_first_identifier);

View File

@@ -1 +1,2 @@
a[1] = 2
a[1] = 1
a.b[1] = 2

View File

@@ -1,14 +1,31 @@
PyFile:SubscribedAssignmentLHS.py(0,8)
PyAssignmentStatement(0,8)
PySubscriptionExpression(0,4)
PyReferenceExpression: a(0,1)
PsiElement(Py:IDENTIFIER)('a')(0,1)
PsiElement(Py:LBRACKET)('[')(1,2)
PyNumericLiteralExpression(2,3)
PsiElement(Py:INTEGER_LITERAL)('1')(2,3)
PsiElement(Py:RBRACKET)(']')(3,4)
PsiWhiteSpace(' ')(4,5)
PsiElement(Py:EQ)('=')(5,6)
PsiWhiteSpace(' ')(6,7)
PyNumericLiteralExpression(7,8)
PsiElement(Py:INTEGER_LITERAL)('2')(7,8)
PyFile:SubscribedAssignmentLHS.py
PyAssignmentStatement
PySubscriptionExpression
PyReferenceExpression: a
PsiElement(Py:IDENTIFIER)('a')
PsiElement(Py:LBRACKET)('[')
PyNumericLiteralExpression
PsiElement(Py:INTEGER_LITERAL)('1')
PsiElement(Py:RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(Py:EQ)('=')
PsiWhiteSpace(' ')
PyNumericLiteralExpression
PsiElement(Py:INTEGER_LITERAL)('1')
PsiWhiteSpace('\n')
PyAssignmentStatement
PySubscriptionExpression
PyReferenceExpression: b
PyReferenceExpression: a
PsiElement(Py:IDENTIFIER)('a')
PsiElement(Py:DOT)('.')
PsiElement(Py:IDENTIFIER)('b')
PsiElement(Py:LBRACKET)('[')
PyNumericLiteralExpression
PsiElement(Py:INTEGER_LITERAL)('1')
PsiElement(Py:RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(Py:EQ)('=')
PsiWhiteSpace(' ')
PyNumericLiteralExpression
PsiElement(Py:INTEGER_LITERAL)('2')