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 |