| Index: pkg/compiler/lib/src/parser/parser.dart
|
| diff --git a/pkg/compiler/lib/src/parser/parser.dart b/pkg/compiler/lib/src/parser/parser.dart
|
| index a584afbc4647d05f69655c6850223bfd63971a3e..1767f8ffac6a751054b58870d208e1441b92a94b 100644
|
| --- a/pkg/compiler/lib/src/parser/parser.dart
|
| +++ b/pkg/compiler/lib/src/parser/parser.dart
|
| @@ -739,12 +739,11 @@ class Parser {
|
| }
|
|
|
| Token parseStringPart(Token token) {
|
| - if (identical(token.kind, STRING_TOKEN)) {
|
| - listener.handleStringPart(token);
|
| - return token.next;
|
| - } else {
|
| - return listener.expected('string', token);
|
| + if (token.kind != STRING_TOKEN) {
|
| + token = listener.expectedString(token);
|
| }
|
| + listener.handleStringPart(token);
|
| + return token.next;
|
| }
|
|
|
| Token parseIdentifier(Token token) {
|
| @@ -1124,6 +1123,17 @@ class Parser {
|
| /// ['(', '*', 'operator']
|
| ///
|
| Link<Token> findMemberName(Token token) {
|
| + Link<Token> discardNative(Link<Token> tokens) {
|
| + if (!tokens.isEmpty && !tokens.tail.isEmpty &&
|
| + tokens.tail.head.kind == STRING_TOKEN &&
|
| + !tokens.tail.tail.isEmpty &&
|
| + optional('native', tokens.tail.tail.head)) {
|
| + return tokens.tail.tail.tail.prepend(tokens.head);
|
| + } else {
|
| + return tokens;
|
| + }
|
| + }
|
| +
|
| Link<Token> identifiers = const Link<Token>();
|
|
|
| // `true` if 'get' has been seen.
|
| @@ -1147,11 +1157,11 @@ class Parser {
|
| } else if (value == '(' || value == '{' || value == '=>') {
|
| // A method.
|
| identifiers = identifiers.prepend(token);
|
| - return identifiers;
|
| + return discardNative(identifiers);
|
| } else if (value == '=' || value == ';' || value == ',') {
|
| // A field or abstract getter.
|
| identifiers = identifiers.prepend(token);
|
| - return identifiers;
|
| + return discardNative(identifiers);
|
| } else if (isGetter) {
|
| hasName = true;
|
| }
|
| @@ -1721,7 +1731,19 @@ class Parser {
|
| return token;
|
| }
|
|
|
| + int statementDepth = 0;
|
| Token parseStatement(Token token) {
|
| + if (statementDepth++ > 500) {
|
| + listener.reportError(
|
| + token, MessageKind.GENERIC, {'text': 'Stack overflow'});
|
| + return listener.skipToEof(token);
|
| + }
|
| + Token result = parseStatementX(token);
|
| + statementDepth--;
|
| + return result;
|
| + }
|
| +
|
| + Token parseStatementX(Token token) {
|
| final value = token.stringValue;
|
| if (identical(token.kind, IDENTIFIER_TOKEN)) {
|
| return parseExpressionStatementOrDeclaration(token);
|
| @@ -1921,10 +1943,18 @@ class Parser {
|
| return expectSemicolon(token);
|
| }
|
|
|
| + int expressionDepth = 0;
|
| Token parseExpression(Token token) {
|
| - return optional('throw', token)
|
| + if (expressionDepth++ > 500) {
|
| + listener.reportError(
|
| + token, MessageKind.GENERIC, {'text': 'Stack overflow'});
|
| + return token.next;
|
| + }
|
| + Token result = optional('throw', token)
|
| ? parseThrowExpression(token, true)
|
| : parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, true);
|
| + expressionDepth--;
|
| + return result;
|
| }
|
|
|
| Token parseExpressionWithoutCascade(Token token) {
|
|
|