| Index: pkg/analyzer/lib/src/generated/parser.dart
|
| diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
|
| index 2a90fbb491f0f93aebee7fbff00dc84a40fb0053..6c782fa809cee5281d8f736e5f307b183ba0efc0 100644
|
| --- a/pkg/analyzer/lib/src/generated/parser.dart
|
| +++ b/pkg/analyzer/lib/src/generated/parser.dart
|
| @@ -3591,12 +3591,16 @@ class Parser {
|
| *
|
| * assignableExpression ::=
|
| * primary (arguments* assignableSelector)+
|
| - * | 'super' assignableSelector
|
| + * | 'super' unconditionalAssignableSelector
|
| * | identifier
|
| *
|
| - * assignableSelector ::=
|
| + * unconditionalAssignableSelector ::=
|
| * '[' expression ']'
|
| * | '.' identifier
|
| + *
|
| + * assignableSelector ::=
|
| + * unconditionalAssignableSelector
|
| + * | '?.' identifier
|
| */
|
| void _ensureAssignable(Expression expression) {
|
| if (expression != null && !expression.isAssignable) {
|
| @@ -4155,13 +4159,13 @@ class Parser {
|
| *
|
| * assignableExpression ::=
|
| * primary (arguments* assignableSelector)+
|
| - * | 'super' assignableSelector
|
| + * | 'super' unconditionalAssignableSelector
|
| * | identifier
|
| */
|
| Expression _parseAssignableExpression(bool primaryAllowed) {
|
| if (_matchesKeyword(Keyword.SUPER)) {
|
| return _parseAssignableSelector(
|
| - new SuperExpression(getAndAdvance()), false);
|
| + new SuperExpression(getAndAdvance()), false, allowConditional: false);
|
| }
|
| //
|
| // A primary expression can start with an identifier. We resolve the
|
| @@ -4211,13 +4215,19 @@ class Parser {
|
| * Parse an assignable selector. The [prefix] is the expression preceding the
|
| * selector. The [optional] is `true` if the selector is optional. Return the
|
| * assignable selector that was parsed, or the original prefix if there was no
|
| - * assignable selector.
|
| + * assignable selector. If [allowConditional] is false, then the '?.'
|
| + * operator will still be parsed, but a parse error will be generated.
|
| *
|
| - * assignableSelector ::=
|
| + * unconditionalAssignableSelector ::=
|
| * '[' expression ']'
|
| * | '.' identifier
|
| + *
|
| + * assignableSelector ::=
|
| + * unconditionalAssignableSelector
|
| + * | '?.' identifier
|
| */
|
| - Expression _parseAssignableSelector(Expression prefix, bool optional) {
|
| + Expression _parseAssignableSelector(Expression prefix, bool optional,
|
| + {bool allowConditional: true}) {
|
| if (_matches(TokenType.OPEN_SQUARE_BRACKET)) {
|
| Token leftBracket = getAndAdvance();
|
| bool wasInInitializer = _inInitializer;
|
| @@ -4232,6 +4242,9 @@ class Parser {
|
| }
|
| } else if (_matches(TokenType.PERIOD) ||
|
| _matches(TokenType.QUESTION_PERIOD)) {
|
| + if (_matches(TokenType.QUESTION_PERIOD) && !allowConditional) {
|
| + _reportErrorForCurrentToken(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER);
|
| + }
|
| Token operator = getAndAdvance();
|
| return new PropertyAccess(prefix, operator, parseSimpleIdentifier());
|
| } else {
|
| @@ -6705,7 +6718,7 @@ class Parser {
|
| *
|
| * primary ::=
|
| * thisExpression
|
| - * | 'super' assignableSelector
|
| + * | 'super' unconditionalAssignableSelector
|
| * | functionExpression
|
| * | literal
|
| * | identifier
|
| @@ -6727,8 +6740,10 @@ class Parser {
|
| if (_matchesKeyword(Keyword.THIS)) {
|
| return new ThisExpression(getAndAdvance());
|
| } else if (_matchesKeyword(Keyword.SUPER)) {
|
| + // TODO(paulberry): verify with Gilad that "super" must be followed by
|
| + // unconditionalAssignableSelector in this case.
|
| return _parseAssignableSelector(
|
| - new SuperExpression(getAndAdvance()), false);
|
| + new SuperExpression(getAndAdvance()), false, allowConditional: false);
|
| } else if (_matchesKeyword(Keyword.NULL)) {
|
| return new NullLiteral(getAndAdvance());
|
| } else if (_matchesKeyword(Keyword.FALSE)) {
|
|
|