| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library engine.parser; | 5 library engine.parser; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import "dart:math" as math; | 8 import "dart:math" as math; |
| 9 | 9 |
| 10 import 'ast.dart'; | 10 import 'ast.dart'; |
| (...skipping 4020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4031 if (_matchesKeyword(Keyword.CONST)) { | 4031 if (_matchesKeyword(Keyword.CONST)) { |
| 4032 // Look to see whether we might be at the start of a list or map literal, | 4032 // Look to see whether we might be at the start of a list or map literal, |
| 4033 // otherwise this should be the start of a variable declaration. | 4033 // otherwise this should be the start of a variable declaration. |
| 4034 return !_peek().matchesAny([ | 4034 return !_peek().matchesAny([ |
| 4035 TokenType.LT, | 4035 TokenType.LT, |
| 4036 TokenType.OPEN_CURLY_BRACKET, | 4036 TokenType.OPEN_CURLY_BRACKET, |
| 4037 TokenType.OPEN_SQUARE_BRACKET, | 4037 TokenType.OPEN_SQUARE_BRACKET, |
| 4038 TokenType.INDEX | 4038 TokenType.INDEX |
| 4039 ]); | 4039 ]); |
| 4040 } | 4040 } |
| 4041 bool allowAdditionalTokens = true; |
| 4041 // We know that we have an identifier, and need to see whether it might be | 4042 // We know that we have an identifier, and need to see whether it might be |
| 4042 // a type name. | 4043 // a type name. |
| 4044 if (_currentToken.type != TokenType.IDENTIFIER) { |
| 4045 allowAdditionalTokens = false; |
| 4046 } |
| 4043 Token token = _skipTypeName(_currentToken); | 4047 Token token = _skipTypeName(_currentToken); |
| 4044 if (token == null) { | 4048 if (token == null) { |
| 4045 // There was no type name, so this can't be a declaration. | 4049 // There was no type name, so this can't be a declaration. |
| 4046 return false; | 4050 return false; |
| 4047 } | 4051 } |
| 4052 if (token.type != TokenType.IDENTIFIER) { |
| 4053 allowAdditionalTokens = false; |
| 4054 } |
| 4048 token = _skipSimpleIdentifier(token); | 4055 token = _skipSimpleIdentifier(token); |
| 4049 if (token == null) { | 4056 if (token == null) { |
| 4050 return false; | 4057 return false; |
| 4051 } | 4058 } |
| 4052 TokenType type = token.type; | 4059 TokenType type = token.type; |
| 4053 return type == TokenType.EQ || | 4060 // Usual cases in valid code: |
| 4061 // String v = ''; |
| 4062 // String v, v2; |
| 4063 // String v; |
| 4064 // for (String item in items) {} |
| 4065 if (type == TokenType.EQ || |
| 4054 type == TokenType.COMMA || | 4066 type == TokenType.COMMA || |
| 4055 type == TokenType.SEMICOLON || | 4067 type == TokenType.SEMICOLON || |
| 4056 _tokenMatchesKeyword(token, Keyword.IN); | 4068 _tokenMatchesKeyword(token, Keyword.IN)) { |
| 4069 return true; |
| 4070 } |
| 4071 // It is OK to parse as a variable declaration in these cases: |
| 4072 // String v } |
| 4073 // String v if (true) print('OK'); |
| 4074 // String v { print(42); } |
| 4075 // ...but not in these cases: |
| 4076 // get getterName { |
| 4077 // String get getterName |
| 4078 if (allowAdditionalTokens) { |
| 4079 if (type == TokenType.CLOSE_CURLY_BRACKET || |
| 4080 type == TokenType.KEYWORD || |
| 4081 type == TokenType.IDENTIFIER || |
| 4082 type == TokenType.OPEN_CURLY_BRACKET) { |
| 4083 return true; |
| 4084 } |
| 4085 } |
| 4086 return false; |
| 4057 } | 4087 } |
| 4058 | 4088 |
| 4059 bool _isLikelyParameterList() { | 4089 bool _isLikelyParameterList() { |
| 4060 if (_matches(TokenType.OPEN_PAREN)) { | 4090 if (_matches(TokenType.OPEN_PAREN)) { |
| 4061 return true; | 4091 return true; |
| 4062 } | 4092 } |
| 4063 if (!parseGenericMethods) { | 4093 if (!parseGenericMethods) { |
| 4064 return false; | 4094 return false; |
| 4065 } | 4095 } |
| 4066 Token token = _skipTypeArgumentList(_currentToken); | 4096 Token token = _skipTypeArgumentList(_currentToken); |
| (...skipping 4207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8274 * token following the simple identifier that was parsed, or `null` if the | 8304 * token following the simple identifier that was parsed, or `null` if the |
| 8275 * given token is not the first token in a valid simple identifier. | 8305 * given token is not the first token in a valid simple identifier. |
| 8276 * | 8306 * |
| 8277 * This method must be kept in sync with [parseSimpleIdentifier]. | 8307 * This method must be kept in sync with [parseSimpleIdentifier]. |
| 8278 * | 8308 * |
| 8279 * identifier ::= | 8309 * identifier ::= |
| 8280 * IDENTIFIER | 8310 * IDENTIFIER |
| 8281 */ | 8311 */ |
| 8282 Token _skipSimpleIdentifier(Token startToken) { | 8312 Token _skipSimpleIdentifier(Token startToken) { |
| 8283 if (_tokenMatches(startToken, TokenType.IDENTIFIER) || | 8313 if (_tokenMatches(startToken, TokenType.IDENTIFIER) || |
| 8284 (_tokenMatches(startToken, TokenType.KEYWORD) && | 8314 _tokenMatchesPseudoKeyword(startToken)) { |
| 8285 (startToken as KeywordToken).keyword.isPseudoKeyword)) { | |
| 8286 return startToken.next; | 8315 return startToken.next; |
| 8287 } | 8316 } |
| 8288 return null; | 8317 return null; |
| 8289 } | 8318 } |
| 8290 | 8319 |
| 8291 /** | 8320 /** |
| 8292 * Parse a string literal that contains interpolations, starting at the | 8321 * Parse a string literal that contains interpolations, starting at the |
| 8293 * [startToken], without actually creating a string literal or changing the | 8322 * [startToken], without actually creating a string literal or changing the |
| 8294 * current token. Return the token following the string literal that was | 8323 * current token. Return the token following the string literal that was |
| 8295 * parsed, or `null` if the given token is not the first token in a valid | 8324 * parsed, or `null` if the given token is not the first token in a valid |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8499 * Return `true` if the given [token] has the given [type]. | 8528 * Return `true` if the given [token] has the given [type]. |
| 8500 */ | 8529 */ |
| 8501 bool _tokenMatches(Token token, TokenType type) => token.type == type; | 8530 bool _tokenMatches(Token token, TokenType type) => token.type == type; |
| 8502 | 8531 |
| 8503 /** | 8532 /** |
| 8504 * Return `true` if the given [token] is a valid identifier. Valid identifiers | 8533 * Return `true` if the given [token] is a valid identifier. Valid identifiers |
| 8505 * include built-in identifiers (pseudo-keywords). | 8534 * include built-in identifiers (pseudo-keywords). |
| 8506 */ | 8535 */ |
| 8507 bool _tokenMatchesIdentifier(Token token) => | 8536 bool _tokenMatchesIdentifier(Token token) => |
| 8508 _tokenMatches(token, TokenType.IDENTIFIER) || | 8537 _tokenMatches(token, TokenType.IDENTIFIER) || |
| 8509 (_tokenMatches(token, TokenType.KEYWORD) && | 8538 _tokenMatchesPseudoKeyword(token); |
| 8510 (token as KeywordToken).keyword.isPseudoKeyword); | |
| 8511 | 8539 |
| 8512 /** | 8540 /** |
| 8513 * Return `true` if the given [token] matches the given [keyword]. | 8541 * Return `true` if the given [token] matches the given [keyword]. |
| 8514 */ | 8542 */ |
| 8515 bool _tokenMatchesKeyword(Token token, Keyword keyword) => | 8543 bool _tokenMatchesKeyword(Token token, Keyword keyword) => |
| 8516 token.type == TokenType.KEYWORD && | 8544 token.type == TokenType.KEYWORD && |
| 8517 (token as KeywordToken).keyword == keyword; | 8545 (token as KeywordToken).keyword == keyword; |
| 8518 | 8546 |
| 8519 /** | 8547 /** |
| 8548 * Return `true` if the given [token] matches a pseudo keyword. |
| 8549 */ |
| 8550 bool _tokenMatchesPseudoKeyword(Token token) => |
| 8551 _tokenMatches(token, TokenType.KEYWORD) && |
| 8552 (token as KeywordToken).keyword.isPseudoKeyword; |
| 8553 |
| 8554 /** |
| 8520 * Return `true` if the given [token] matches the given [identifier]. | 8555 * Return `true` if the given [token] matches the given [identifier]. |
| 8521 */ | 8556 */ |
| 8522 bool _tokenMatchesString(Token token, String identifier) => | 8557 bool _tokenMatchesString(Token token, String identifier) => |
| 8523 token.type == TokenType.IDENTIFIER && token.lexeme == identifier; | 8558 token.type == TokenType.IDENTIFIER && token.lexeme == identifier; |
| 8524 | 8559 |
| 8525 /** | 8560 /** |
| 8526 * Translate the characters at the given [index] in the given [lexeme], | 8561 * Translate the characters at the given [index] in the given [lexeme], |
| 8527 * appending the translated character to the given [buffer]. The index is | 8562 * appending the translated character to the given [buffer]. The index is |
| 8528 * assumed to be valid. | 8563 * assumed to be valid. |
| 8529 */ | 8564 */ |
| (...skipping 2488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11018 } | 11053 } |
| 11019 | 11054 |
| 11020 /** | 11055 /** |
| 11021 * Copy resolution data from the [fromNode] to the [toNode]. | 11056 * Copy resolution data from the [fromNode] to the [toNode]. |
| 11022 */ | 11057 */ |
| 11023 static void copyResolutionData(AstNode fromNode, AstNode toNode) { | 11058 static void copyResolutionData(AstNode fromNode, AstNode toNode) { |
| 11024 ResolutionCopier copier = new ResolutionCopier(); | 11059 ResolutionCopier copier = new ResolutionCopier(); |
| 11025 copier._isEqualNodes(fromNode, toNode); | 11060 copier._isEqualNodes(fromNode, toNode); |
| 11026 } | 11061 } |
| 11027 } | 11062 } |
| OLD | NEW |