 Chromium Code Reviews
 Chromium Code Reviews Issue 2711463005:
  Add contextual information about identifiers to the parser listener API.  (Closed)
    
  
    Issue 2711463005:
  Add contextual information about identifiers to the parser listener API.  (Closed) 
  | OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 fasta.parser.parser; | 5 library fasta.parser.parser; | 
| 6 | 6 | 
| 7 import '../scanner.dart' show | 7 import '../scanner.dart' show | 
| 8 ErrorToken; | 8 ErrorToken; | 
| 9 | 9 | 
| 10 import '../scanner/recover.dart' show | 10 import '../scanner/recover.dart' show | 
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 67 | 67 | 
| 68 import 'package:front_end/src/fasta/util/link.dart' show | 68 import 'package:front_end/src/fasta/util/link.dart' show | 
| 69 Link; | 69 Link; | 
| 70 | 70 | 
| 71 import 'listener.dart' show | 71 import 'listener.dart' show | 
| 72 Listener; | 72 Listener; | 
| 73 | 73 | 
| 74 import 'error_kind.dart' show | 74 import 'error_kind.dart' show | 
| 75 ErrorKind; | 75 ErrorKind; | 
| 76 | 76 | 
| 77 import 'identifier_context.dart' show IdentifierContext; | |
| 78 | |
| 77 /// Returns true if [token] is the symbol or keyword [value]. | 79 /// Returns true if [token] is the symbol or keyword [value]. | 
| 78 bool optional(String value, Token token) { | 80 bool optional(String value, Token token) { | 
| 79 return identical(value, token.stringValue); | 81 return identical(value, token.stringValue); | 
| 80 } | 82 } | 
| 81 | 83 | 
| 82 class FormalParameterType { | 84 class FormalParameterType { | 
| 83 final String type; | 85 final String type; | 
| 84 const FormalParameterType(this.type); | 86 const FormalParameterType(this.type); | 
| 85 bool get isRequired => this == REQUIRED; | 87 bool get isRequired => this == REQUIRED; | 
| 86 bool get isPositional => this == POSITIONAL; | 88 bool get isPositional => this == POSITIONAL; | 
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 160 } else { | 162 } else { | 
| 161 return parseTopLevelMember(token); | 163 return parseTopLevelMember(token); | 
| 162 } | 164 } | 
| 163 } | 165 } | 
| 164 | 166 | 
| 165 /// library qualified ';' | 167 /// library qualified ';' | 
| 166 Token parseLibraryName(Token token) { | 168 Token parseLibraryName(Token token) { | 
| 167 Token libraryKeyword = token; | 169 Token libraryKeyword = token; | 
| 168 listener.beginLibraryName(libraryKeyword); | 170 listener.beginLibraryName(libraryKeyword); | 
| 169 assert(optional('library', token)); | 171 assert(optional('library', token)); | 
| 170 token = parseQualified(token.next); | 172 token = parseQualified(token.next, IdentifierContext.libraryName, | 
| 173 IdentifierContext.libraryNameContinuation); | |
| 171 Token semicolon = token; | 174 Token semicolon = token; | 
| 172 token = expect(';', token); | 175 token = expect(';', token); | 
| 173 listener.endLibraryName(libraryKeyword, semicolon); | 176 listener.endLibraryName(libraryKeyword, semicolon); | 
| 174 return token; | 177 return token; | 
| 175 } | 178 } | 
| 176 | 179 | 
| 177 /// import uri (if (test) uri)* (as identifier)? combinator* ';' | 180 /// import uri (if (test) uri)* (as identifier)? combinator* ';' | 
| 178 Token parseImport(Token token) { | 181 Token parseImport(Token token) { | 
| 179 Token importKeyword = token; | 182 Token importKeyword = token; | 
| 180 listener.beginImport(importKeyword); | 183 listener.beginImport(importKeyword); | 
| 181 assert(optional('import', token)); | 184 assert(optional('import', token)); | 
| 182 token = parseLiteralStringOrRecoverExpression(token.next); | 185 token = parseLiteralStringOrRecoverExpression(token.next); | 
| 183 token = parseConditionalUris(token); | 186 token = parseConditionalUris(token); | 
| 184 Token deferredKeyword; | 187 Token deferredKeyword; | 
| 185 if (optional('deferred', token)) { | 188 if (optional('deferred', token)) { | 
| 186 deferredKeyword = token; | 189 deferredKeyword = token; | 
| 187 token = token.next; | 190 token = token.next; | 
| 188 } | 191 } | 
| 189 Token asKeyword; | 192 Token asKeyword; | 
| 190 if (optional('as', token)) { | 193 if (optional('as', token)) { | 
| 191 asKeyword = token; | 194 asKeyword = token; | 
| 192 token = parseIdentifier(token.next); | 195 token = parseIdentifier( | 
| 196 token.next, IdentifierContext.importPrefixDeclaration); | |
| 193 } | 197 } | 
| 194 token = parseCombinators(token); | 198 token = parseCombinators(token); | 
| 195 Token semicolon = token; | 199 Token semicolon = token; | 
| 196 token = expect(';', token); | 200 token = expect(';', token); | 
| 197 listener.endImport(importKeyword, deferredKeyword, asKeyword, semicolon); | 201 listener.endImport(importKeyword, deferredKeyword, asKeyword, semicolon); | 
| 198 return token; | 202 return token; | 
| 199 } | 203 } | 
| 200 | 204 | 
| 201 /// if (test) uri | 205 /// if (test) uri | 
| 202 Token parseConditionalUris(Token token) { | 206 Token parseConditionalUris(Token token) { | 
| (...skipping 20 matching lines...) Expand all Loading... | |
| 223 } | 227 } | 
| 224 token = expect(')', token); | 228 token = expect(')', token); | 
| 225 token = parseLiteralStringOrRecoverExpression(token); | 229 token = parseLiteralStringOrRecoverExpression(token); | 
| 226 listener.endConditionalUri(ifKeyword, equalitySign); | 230 listener.endConditionalUri(ifKeyword, equalitySign); | 
| 227 return token; | 231 return token; | 
| 228 } | 232 } | 
| 229 | 233 | 
| 230 Token parseDottedName(Token token) { | 234 Token parseDottedName(Token token) { | 
| 231 listener.beginDottedName(token); | 235 listener.beginDottedName(token); | 
| 232 Token firstIdentifier = token; | 236 Token firstIdentifier = token; | 
| 233 token = parseIdentifier(token); | 237 token = parseIdentifier(token, IdentifierContext.dottedName); | 
| 234 int count = 1; | 238 int count = 1; | 
| 235 while (optional('.', token)) { | 239 while (optional('.', token)) { | 
| 236 token = parseIdentifier(token.next); | 240 token = | 
| 241 parseIdentifier(token.next, IdentifierContext.dottedNameContinuation); | |
| 237 count++; | 242 count++; | 
| 238 } | 243 } | 
| 239 listener.endDottedName(count, firstIdentifier); | 244 listener.endDottedName(count, firstIdentifier); | 
| 240 return token; | 245 return token; | 
| 241 } | 246 } | 
| 242 | 247 | 
| 243 /// export uri conditional-uris* combinator* ';' | 248 /// export uri conditional-uris* combinator* ';' | 
| 244 Token parseExport(Token token) { | 249 Token parseExport(Token token) { | 
| 245 Token exportKeyword = token; | 250 Token exportKeyword = token; | 
| 246 listener.beginExport(exportKeyword); | 251 listener.beginExport(exportKeyword); | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 listener.beginShow(showKeyword); | 293 listener.beginShow(showKeyword); | 
| 289 assert(optional('show', token)); | 294 assert(optional('show', token)); | 
| 290 token = parseIdentifierList(token.next); | 295 token = parseIdentifierList(token.next); | 
| 291 listener.endShow(showKeyword); | 296 listener.endShow(showKeyword); | 
| 292 return token; | 297 return token; | 
| 293 } | 298 } | 
| 294 | 299 | 
| 295 /// identifier (, identifier)* | 300 /// identifier (, identifier)* | 
| 296 Token parseIdentifierList(Token token) { | 301 Token parseIdentifierList(Token token) { | 
| 297 listener.beginIdentifierList(token); | 302 listener.beginIdentifierList(token); | 
| 298 token = parseIdentifier(token); | 303 token = parseIdentifier(token, IdentifierContext.combinator); | 
| 299 int count = 1; | 304 int count = 1; | 
| 300 while (optional(',', token)) { | 305 while (optional(',', token)) { | 
| 301 token = parseIdentifier(token.next); | 306 token = parseIdentifier(token.next, IdentifierContext.combinator); | 
| 302 count++; | 307 count++; | 
| 303 } | 308 } | 
| 304 listener.endIdentifierList(count); | 309 listener.endIdentifierList(count); | 
| 305 return token; | 310 return token; | 
| 306 } | 311 } | 
| 307 | 312 | 
| 308 /// type (, type)* | 313 /// type (, type)* | 
| 309 Token parseTypeList(Token token) { | 314 Token parseTypeList(Token token) { | 
| 310 listener.beginTypeList(token); | 315 listener.beginTypeList(token); | 
| 311 token = parseType(token); | 316 token = parseType(token); | 
| (...skipping 24 matching lines...) Expand all Loading... | |
| 336 token = expect(';', token); | 341 token = expect(';', token); | 
| 337 listener.endPart(partKeyword, semicolon); | 342 listener.endPart(partKeyword, semicolon); | 
| 338 return token; | 343 return token; | 
| 339 } | 344 } | 
| 340 | 345 | 
| 341 Token parsePartOf(Token token) { | 346 Token parsePartOf(Token token) { | 
| 342 listener.beginPartOf(token); | 347 listener.beginPartOf(token); | 
| 343 assert(optional('part', token)); | 348 assert(optional('part', token)); | 
| 344 assert(optional('of', token.next)); | 349 assert(optional('of', token.next)); | 
| 345 Token partKeyword = token; | 350 Token partKeyword = token; | 
| 346 token = parseQualified(token.next.next); | 351 token = parseQualified(token.next.next, IdentifierContext.partName, | 
| 352 IdentifierContext.partNameContinuation); | |
| 347 Token semicolon = token; | 353 Token semicolon = token; | 
| 348 token = expect(';', token); | 354 token = expect(';', token); | 
| 349 listener.endPartOf(partKeyword, semicolon); | 355 listener.endPartOf(partKeyword, semicolon); | 
| 350 return token; | 356 return token; | 
| 351 } | 357 } | 
| 352 | 358 | 
| 353 Token parseMetadataStar(Token token, {bool forParameter: false}) { | 359 Token parseMetadataStar(Token token, {bool forParameter: false}) { | 
| 354 listener.beginMetadataStar(token); | 360 listener.beginMetadataStar(token); | 
| 355 int count = 0; | 361 int count = 0; | 
| 356 while (optional('@', token)) { | 362 while (optional('@', token)) { | 
| 357 token = parseMetadata(token); | 363 token = parseMetadata(token); | 
| 358 count++; | 364 count++; | 
| 359 } | 365 } | 
| 360 listener.endMetadataStar(count, forParameter); | 366 listener.endMetadataStar(count, forParameter); | 
| 361 return token; | 367 return token; | 
| 362 } | 368 } | 
| 363 | 369 | 
| 364 /** | 370 /** | 
| 365 * Parse | 371 * Parse | 
| 366 * [: '@' qualified (‘.’ identifier)? (arguments)? :] | 372 * [: '@' qualified (‘.’ identifier)? (arguments)? :] | 
| 367 */ | 373 */ | 
| 368 Token parseMetadata(Token token) { | 374 Token parseMetadata(Token token) { | 
| 369 listener.beginMetadata(token); | 375 listener.beginMetadata(token); | 
| 370 Token atToken = token; | 376 Token atToken = token; | 
| 371 assert(optional('@', token)); | 377 assert(optional('@', token)); | 
| 372 token = parseIdentifier(token.next); | 378 token = parseIdentifier(token.next, IdentifierContext.metadataReference); | 
| 373 token = parseQualifiedRestOpt(token); | 379 token = | 
| 380 parseQualifiedRestOpt(token, IdentifierContext.metadataContinuation); | |
| 374 token = parseTypeArgumentsOpt(token); | 381 token = parseTypeArgumentsOpt(token); | 
| 375 Token period = null; | 382 Token period = null; | 
| 376 if (optional('.', token)) { | 383 if (optional('.', token)) { | 
| 377 period = token; | 384 period = token; | 
| 378 token = parseIdentifier(token.next); | 385 token = parseIdentifier( | 
| 386 token.next, IdentifierContext.metadataContinuationAfterTypeArguments); | |
| 379 } | 387 } | 
| 380 token = parseArgumentsOpt(token); | 388 token = parseArgumentsOpt(token); | 
| 381 listener.endMetadata(atToken, period, token); | 389 listener.endMetadata(atToken, period, token); | 
| 382 return token; | 390 return token; | 
| 383 } | 391 } | 
| 384 | 392 | 
| 385 Token parseTypedef(Token token) { | 393 Token parseTypedef(Token token) { | 
| 386 Token typedefKeyword = token; | 394 Token typedefKeyword = token; | 
| 387 listener.beginFunctionTypeAlias(token); | 395 listener.beginFunctionTypeAlias(token); | 
| 388 token = parseReturnTypeOpt(token.next); | 396 token = parseReturnTypeOpt(token.next); | 
| 389 token = parseIdentifier(token); | 397 token = parseIdentifier(token, IdentifierContext.typedefDeclaration); | 
| 390 token = parseTypeVariablesOpt(token); | 398 token = parseTypeVariablesOpt(token); | 
| 391 token = parseFormalParameters(token); | 399 token = parseFormalParameters(token); | 
| 392 listener.endFunctionTypeAlias(typedefKeyword, token); | 400 listener.endFunctionTypeAlias(typedefKeyword, token); | 
| 393 return expect(';', token); | 401 return expect(';', token); | 
| 394 } | 402 } | 
| 395 | 403 | 
| 396 Token parseMixinApplication(Token token) { | 404 Token parseMixinApplication(Token token) { | 
| 397 listener.beginMixinApplication(token); | 405 listener.beginMixinApplication(token); | 
| 398 token = parseType(token); | 406 token = parseType(token); | 
| 399 token = expect('with', token); | 407 token = expect('with', token); | 
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 476 } | 484 } | 
| 477 token = parseModifiers(token); | 485 token = parseModifiers(token); | 
| 478 // TODO(ahe): Validate that there are formal parameters if void. | 486 // TODO(ahe): Validate that there are formal parameters if void. | 
| 479 token = parseReturnTypeOpt(token); | 487 token = parseReturnTypeOpt(token); | 
| 480 Token thisKeyword = null; | 488 Token thisKeyword = null; | 
| 481 if (optional('this', token)) { | 489 if (optional('this', token)) { | 
| 482 thisKeyword = token; | 490 thisKeyword = token; | 
| 483 // TODO(ahe): Validate field initializers are only used in | 491 // TODO(ahe): Validate field initializers are only used in | 
| 484 // constructors, and not for function-typed arguments. | 492 // constructors, and not for function-typed arguments. | 
| 485 token = expect('.', token.next); | 493 token = expect('.', token.next); | 
| 494 token = parseIdentifier(token, IdentifierContext.fieldInitializer); | |
| 495 } else { | |
| 496 token = | |
| 497 parseIdentifier(token, IdentifierContext.formalParameterDeclaration); | |
| 486 } | 498 } | 
| 487 token = parseIdentifier(token); | |
| 488 if (optional('(', token)) { | 499 if (optional('(', token)) { | 
| 489 listener.beginFunctionTypedFormalParameter(token); | 500 listener.beginFunctionTypedFormalParameter(token); | 
| 490 listener.handleNoTypeVariables(token); | 501 listener.handleNoTypeVariables(token); | 
| 491 token = parseFormalParameters(token); | 502 token = parseFormalParameters(token); | 
| 492 listener.endFunctionTypedFormalParameter(token); | 503 listener.endFunctionTypedFormalParameter(token); | 
| 493 } else if (optional('<', token)) { | 504 } else if (optional('<', token)) { | 
| 494 listener.beginFunctionTypedFormalParameter(token); | 505 listener.beginFunctionTypedFormalParameter(token); | 
| 495 token = parseTypeVariablesOpt(token); | 506 token = parseTypeVariablesOpt(token); | 
| 496 token = parseFormalParameters(token); | 507 token = parseFormalParameters(token); | 
| 497 listener.endFunctionTypedFormalParameter(token); | 508 listener.endFunctionTypedFormalParameter(token); | 
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 636 if (identical(token.kind, GT_TOKEN)) return token.next; | 647 if (identical(token.kind, GT_TOKEN)) return token.next; | 
| 637 if (!identical(token.kind, GT_GT_TOKEN)) return null; | 648 if (!identical(token.kind, GT_GT_TOKEN)) return null; | 
| 638 // [token] is '>>' of which the final '>' that we are parsing is the first | 649 // [token] is '>>' of which the final '>' that we are parsing is the first | 
| 639 // character. In order to keep the parsing process on track we must return | 650 // character. In order to keep the parsing process on track we must return | 
| 640 // a synthetic '>' corresponding to the second character of that '>>'. | 651 // a synthetic '>' corresponding to the second character of that '>>'. | 
| 641 Token syntheticToken = new SymbolToken(GT_INFO, token.charOffset + 1); | 652 Token syntheticToken = new SymbolToken(GT_INFO, token.charOffset + 1); | 
| 642 syntheticToken.next = token.next; | 653 syntheticToken.next = token.next; | 
| 643 return syntheticToken; | 654 return syntheticToken; | 
| 644 } | 655 } | 
| 645 | 656 | 
| 646 Token parseQualified(Token token) { | 657 Token parseQualified(Token token, IdentifierContext context, | 
| 647 token = parseIdentifier(token); | 658 IdentifierContext continuationContext) { | 
| 659 token = parseIdentifier(token, context); | |
| 648 while (optional('.', token)) { | 660 while (optional('.', token)) { | 
| 649 token = parseQualifiedRest(token); | 661 token = parseQualifiedRest(token, continuationContext); | 
| 650 } | 662 } | 
| 651 return token; | 663 return token; | 
| 652 } | 664 } | 
| 653 | 665 | 
| 654 Token parseQualifiedRestOpt(Token token) { | 666 Token parseQualifiedRestOpt( | 
| 667 Token token, IdentifierContext continuationContext) { | |
| 655 if (optional('.', token)) { | 668 if (optional('.', token)) { | 
| 656 return parseQualifiedRest(token); | 669 return parseQualifiedRest(token, continuationContext); | 
| 657 } else { | 670 } else { | 
| 658 return token; | 671 return token; | 
| 659 } | 672 } | 
| 660 } | 673 } | 
| 661 | 674 | 
| 662 Token parseQualifiedRest(Token token) { | 675 Token parseQualifiedRest(Token token, IdentifierContext context) { | 
| 663 assert(optional('.', token)); | 676 assert(optional('.', token)); | 
| 664 Token period = token; | 677 Token period = token; | 
| 665 token = parseIdentifier(token.next); | 678 token = parseIdentifier(token.next, context); | 
| 666 listener.handleQualified(period); | 679 listener.handleQualified(period); | 
| 667 return token; | 680 return token; | 
| 668 } | 681 } | 
| 669 | 682 | 
| 670 Token skipBlock(Token token) { | 683 Token skipBlock(Token token) { | 
| 671 if (!optional('{', token)) { | 684 if (!optional('{', token)) { | 
| 672 return reportUnrecoverableError(token, ErrorKind.ExpectedBlockToSkip); | 685 return reportUnrecoverableError(token, ErrorKind.ExpectedBlockToSkip); | 
| 673 } | 686 } | 
| 674 BeginGroupToken beginGroupToken = token; | 687 BeginGroupToken beginGroupToken = token; | 
| 675 Token endGroup = beginGroupToken.endGroup; | 688 Token endGroup = beginGroupToken.endGroup; | 
| 676 if (endGroup == null) { | 689 if (endGroup == null) { | 
| 677 return reportUnrecoverableError( | 690 return reportUnrecoverableError( | 
| 678 beginGroupToken, ErrorKind.UnmatchedToken); | 691 beginGroupToken, ErrorKind.UnmatchedToken); | 
| 679 } else if (!identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) { | 692 } else if (!identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) { | 
| 680 return reportUnrecoverableError( | 693 return reportUnrecoverableError( | 
| 681 beginGroupToken, ErrorKind.UnmatchedToken); | 694 beginGroupToken, ErrorKind.UnmatchedToken); | 
| 682 } | 695 } | 
| 683 return beginGroupToken.endGroup; | 696 return beginGroupToken.endGroup; | 
| 684 } | 697 } | 
| 685 | 698 | 
| 686 Token parseEnum(Token token) { | 699 Token parseEnum(Token token) { | 
| 687 listener.beginEnum(token); | 700 listener.beginEnum(token); | 
| 688 Token enumKeyword = token; | 701 Token enumKeyword = token; | 
| 689 token = parseIdentifier(token.next); | 702 token = parseIdentifier(token.next, IdentifierContext.enumDeclaration); | 
| 690 token = expect('{', token); | 703 token = expect('{', token); | 
| 691 int count = 0; | 704 int count = 0; | 
| 692 if (!optional('}', token)) { | 705 if (!optional('}', token)) { | 
| 693 token = parseIdentifier(token); | 706 token = parseIdentifier(token, IdentifierContext.enumValueDeclaration); | 
| 694 count++; | 707 count++; | 
| 695 while (optional(',', token)) { | 708 while (optional(',', token)) { | 
| 696 token = token.next; | 709 token = token.next; | 
| 697 if (optional('}', token)) break; | 710 if (optional('}', token)) break; | 
| 698 token = parseIdentifier(token); | 711 token = parseIdentifier(token, IdentifierContext.enumValueDeclaration); | 
| 699 count++; | 712 count++; | 
| 700 } | 713 } | 
| 701 } | 714 } | 
| 702 Token endBrace = token; | 715 Token endBrace = token; | 
| 703 token = expect('}', token); | 716 token = expect('}', token); | 
| 704 listener.endEnum(enumKeyword, endBrace, count); | 717 listener.endEnum(enumKeyword, endBrace, count); | 
| 705 return token; | 718 return token; | 
| 706 } | 719 } | 
| 707 | 720 | 
| 708 Token parseClassOrNamedMixinApplication(Token token) { | 721 Token parseClassOrNamedMixinApplication(Token token) { | 
| 709 Token begin = token; | 722 Token begin = token; | 
| 710 Token abstractKeyword; | 723 Token abstractKeyword; | 
| 711 if (optional('abstract', token)) { | 724 if (optional('abstract', token)) { | 
| 712 abstractKeyword = token; | 725 abstractKeyword = token; | 
| 713 token = token.next; | 726 token = token.next; | 
| 714 } | 727 } | 
| 715 int modifierCount = 0; | 728 int modifierCount = 0; | 
| 716 if (abstractKeyword != null) { | 729 if (abstractKeyword != null) { | 
| 717 parseModifier(abstractKeyword); | 730 parseModifier(abstractKeyword); | 
| 718 modifierCount++; | 731 modifierCount++; | 
| 719 } | 732 } | 
| 720 listener.handleModifiers(modifierCount); | 733 listener.handleModifiers(modifierCount); | 
| 721 bool isMixinApplication = optional('=', peekAfterType(token)); | 734 bool isMixinApplication = optional('=', peekAfterType(token)); | 
| 722 Token name = token.next; | 735 Token name = token.next; | 
| 723 token = parseIdentifier(name); | |
| 724 | 736 | 
| 725 if (isMixinApplication) { | 737 if (isMixinApplication) { | 
| 738 token = parseIdentifier(name, IdentifierContext.namedMixinDeclaration); | |
| 726 listener.beginNamedMixinApplication(begin, name); | 739 listener.beginNamedMixinApplication(begin, name); | 
| 727 } else { | 740 } else { | 
| 741 token = parseIdentifier(name, IdentifierContext.classDeclaration); | |
| 728 listener.beginClassDeclaration(begin, name); | 742 listener.beginClassDeclaration(begin, name); | 
| 729 } | 743 } | 
| 730 | 744 | 
| 731 token = parseTypeVariablesOpt(token); | 745 token = parseTypeVariablesOpt(token); | 
| 732 | 746 | 
| 733 if (optional('=', token)) { | 747 if (optional('=', token)) { | 
| 734 Token equals = token; | 748 Token equals = token; | 
| 735 token = token.next; | 749 token = token.next; | 
| 736 return parseNamedMixinApplication(token, begin, name, equals); | 750 return parseNamedMixinApplication(token, begin, name, equals); | 
| 737 } else { | 751 } else { | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 780 } | 794 } | 
| 781 | 795 | 
| 782 Token parseStringPart(Token token) { | 796 Token parseStringPart(Token token) { | 
| 783 if (token.kind != STRING_TOKEN) { | 797 if (token.kind != STRING_TOKEN) { | 
| 784 token = reportUnrecoverableError(token, ErrorKind.ExpectedString); | 798 token = reportUnrecoverableError(token, ErrorKind.ExpectedString); | 
| 785 } | 799 } | 
| 786 listener.handleStringPart(token); | 800 listener.handleStringPart(token); | 
| 787 return token.next; | 801 return token.next; | 
| 788 } | 802 } | 
| 789 | 803 | 
| 790 Token parseIdentifier(Token token) { | 804 Token parseIdentifier(Token token, IdentifierContext context) { | 
| 791 if (!token.isIdentifier()) { | 805 if (!token.isIdentifier()) { | 
| 792 token = reportUnrecoverableError(token, ErrorKind.ExpectedIdentifier); | 806 token = reportUnrecoverableError(token, ErrorKind.ExpectedIdentifier); | 
| 793 } | 807 } | 
| 794 listener.handleIdentifier(token); | 808 listener.handleIdentifier(token, context); | 
| 795 return token.next; | 809 return token.next; | 
| 796 } | 810 } | 
| 797 | 811 | 
| 798 Token expect(String string, Token token) { | 812 Token expect(String string, Token token) { | 
| 799 if (!identical(string, token.stringValue)) { | 813 if (!identical(string, token.stringValue)) { | 
| 800 return reportUnrecoverableError( | 814 return reportUnrecoverableError( | 
| 801 token, ErrorKind.ExpectedButGot, {"expected": string}); | 815 token, ErrorKind.ExpectedButGot, {"expected": string}); | 
| 802 } | 816 } | 
| 803 return token.next; | 817 return token.next; | 
| 804 } | 818 } | 
| 805 | 819 | 
| 806 Token parseTypeVariable(Token token) { | 820 Token parseTypeVariable(Token token) { | 
| 807 listener.beginTypeVariable(token); | 821 listener.beginTypeVariable(token); | 
| 808 token = parseIdentifier(token); | 822 token = parseIdentifier(token, IdentifierContext.typeVariableDeclaration); | 
| 809 Token extendsOrSuper = null; | 823 Token extendsOrSuper = null; | 
| 810 if (optional('extends', token) || optional('super', token)) { | 824 if (optional('extends', token) || optional('super', token)) { | 
| 811 extendsOrSuper = token; | 825 extendsOrSuper = token; | 
| 812 token = parseType(token.next); | 826 token = parseType(token.next); | 
| 813 } else { | 827 } else { | 
| 814 listener.handleNoType(token); | 828 listener.handleNoType(token); | 
| 815 } | 829 } | 
| 816 listener.endTypeVariable(token, extendsOrSuper); | 830 listener.endTypeVariable(token, extendsOrSuper); | 
| 817 return token; | 831 return token; | 
| 818 } | 832 } | 
| (...skipping 23 matching lines...) Expand all Loading... | |
| 842 } | 856 } | 
| 843 | 857 | 
| 844 bool notEofOrValue(String value, Token token) { | 858 bool notEofOrValue(String value, Token token) { | 
| 845 return !identical(token.kind, EOF_TOKEN) && | 859 return !identical(token.kind, EOF_TOKEN) && | 
| 846 !identical(value, token.stringValue); | 860 !identical(value, token.stringValue); | 
| 847 } | 861 } | 
| 848 | 862 | 
| 849 Token parseType(Token token) { | 863 Token parseType(Token token) { | 
| 850 Token begin = token; | 864 Token begin = token; | 
| 851 if (isValidTypeReference(token)) { | 865 if (isValidTypeReference(token)) { | 
| 852 token = parseIdentifier(token); | 866 token = parseIdentifier(token, IdentifierContext.typeReference); | 
| 853 token = parseQualifiedRestOpt(token); | 867 token = parseQualifiedRestOpt( | 
| 868 token, IdentifierContext.typeReferenceContinuation); | |
| 854 } else { | 869 } else { | 
| 855 token = reportUnrecoverableError(token, ErrorKind.ExpectedType); | 870 token = reportUnrecoverableError(token, ErrorKind.ExpectedType); | 
| 856 listener.handleInvalidTypeReference(token); | 871 listener.handleInvalidTypeReference(token); | 
| 857 } | 872 } | 
| 858 token = parseTypeArgumentsOpt(token); | 873 token = parseTypeArgumentsOpt(token); | 
| 859 listener.endType(begin, token); | 874 listener.endType(begin, token); | 
| 860 return token; | 875 return token; | 
| 861 } | 876 } | 
| 862 | 877 | 
| 863 Token parseTypeArgumentsOpt(Token token) { | 878 Token parseTypeArgumentsOpt(Token token) { | 
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1083 // [PartialFieldListElement.parseNode]. | 1098 // [PartialFieldListElement.parseNode]. | 
| 1084 reportRecoverableError(type, ErrorKind.InvalidVoid); | 1099 reportRecoverableError(type, ErrorKind.InvalidVoid); | 
| 1085 } else { | 1100 } else { | 
| 1086 parseType(type); | 1101 parseType(type); | 
| 1087 if (isVar) { | 1102 if (isVar) { | 
| 1088 reportRecoverableError(modifiers.head, ErrorKind.ExtraneousModifier, | 1103 reportRecoverableError(modifiers.head, ErrorKind.ExtraneousModifier, | 
| 1089 {'modifier': modifiers.head}); | 1104 {'modifier': modifiers.head}); | 
| 1090 } | 1105 } | 
| 1091 } | 1106 } | 
| 1092 | 1107 | 
| 1093 Token token = parseIdentifier(name); | 1108 IdentifierContext context = isTopLevel | 
| 1109 ? IdentifierContext.topLevelVariableDeclaration | |
| 1110 : IdentifierContext.fieldDeclaration; | |
| 1111 Token token = parseIdentifier(name, context); | |
| 1094 | 1112 | 
| 1095 int fieldCount = 1; | 1113 int fieldCount = 1; | 
| 1096 token = parseFieldInitializerOpt(token); | 1114 token = parseFieldInitializerOpt(token); | 
| 1097 while (optional(',', token)) { | 1115 while (optional(',', token)) { | 
| 1098 token = parseIdentifier(token.next); | 1116 token = parseIdentifier(token.next, context); | 
| 1099 token = parseFieldInitializerOpt(token); | 1117 token = parseFieldInitializerOpt(token); | 
| 1100 ++fieldCount; | 1118 ++fieldCount; | 
| 1101 } | 1119 } | 
| 1102 Token semicolon = token; | 1120 Token semicolon = token; | 
| 1103 token = expectSemicolon(token); | 1121 token = expectSemicolon(token); | 
| 1104 if (isTopLevel) { | 1122 if (isTopLevel) { | 
| 1105 listener.endTopLevelFields(fieldCount, start, semicolon); | 1123 listener.endTopLevelFields(fieldCount, start, semicolon); | 
| 1106 } else { | 1124 } else { | 
| 1107 listener.endFields(fieldCount, start, semicolon); | 1125 listener.endFields(fieldCount, start, semicolon); | 
| 1108 } | 1126 } | 
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1128 listener.handleModifiers(1); | 1146 listener.handleModifiers(1); | 
| 1129 } else { | 1147 } else { | 
| 1130 listener.handleModifiers(0); | 1148 listener.handleModifiers(0); | 
| 1131 } | 1149 } | 
| 1132 | 1150 | 
| 1133 if (type == null) { | 1151 if (type == null) { | 
| 1134 listener.handleNoType(name); | 1152 listener.handleNoType(name); | 
| 1135 } else { | 1153 } else { | 
| 1136 parseReturnTypeOpt(type); | 1154 parseReturnTypeOpt(type); | 
| 1137 } | 1155 } | 
| 1138 Token token = parseIdentifier(name); | 1156 Token token = | 
| 1157 parseIdentifier(name, IdentifierContext.topLevelFunctionDeclaration); | |
| 1139 | 1158 | 
| 1140 if (getOrSet == null) { | 1159 if (getOrSet == null) { | 
| 1141 token = parseTypeVariablesOpt(token); | 1160 token = parseTypeVariablesOpt(token); | 
| 1142 } else { | 1161 } else { | 
| 1143 listener.handleNoTypeVariables(token); | 1162 listener.handleNoTypeVariables(token); | 
| 1144 } | 1163 } | 
| 1145 token = parseFormalParametersOpt(token); | 1164 token = parseFormalParametersOpt(token); | 
| 1146 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; | 1165 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; | 
| 1147 token = parseAsyncModifier(token); | 1166 token = parseAsyncModifier(token); | 
| 1148 token = parseFunctionBody(token, false, externalModifier != null); | 1167 token = parseFunctionBody(token, false, externalModifier != null); | 
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1567 parseReturnTypeOpt(type); | 1586 parseReturnTypeOpt(type); | 
| 1568 } | 1587 } | 
| 1569 Token token; | 1588 Token token; | 
| 1570 if (optional('operator', name)) { | 1589 if (optional('operator', name)) { | 
| 1571 token = parseOperatorName(name); | 1590 token = parseOperatorName(name); | 
| 1572 if (staticModifier != null) { | 1591 if (staticModifier != null) { | 
| 1573 reportRecoverableError(staticModifier, ErrorKind.ExtraneousModifier, | 1592 reportRecoverableError(staticModifier, ErrorKind.ExtraneousModifier, | 
| 1574 {'modifier': staticModifier}); | 1593 {'modifier': staticModifier}); | 
| 1575 } | 1594 } | 
| 1576 } else { | 1595 } else { | 
| 1577 token = parseIdentifier(name); | 1596 token = parseIdentifier(name, IdentifierContext.methodDeclaration); | 
| 1578 } | 1597 } | 
| 1579 | 1598 | 
| 1580 token = parseQualifiedRestOpt(token); | 1599 token = parseQualifiedRestOpt( | 
| 1600 token, IdentifierContext.methodDeclarationContinuation); | |
| 1581 if (getOrSet == null) { | 1601 if (getOrSet == null) { | 
| 1582 token = parseTypeVariablesOpt(token); | 1602 token = parseTypeVariablesOpt(token); | 
| 1583 } else { | 1603 } else { | 
| 1584 listener.handleNoTypeVariables(token); | 1604 listener.handleNoTypeVariables(token); | 
| 1585 } | 1605 } | 
| 1586 token = parseFormalParametersOpt(token); | 1606 token = parseFormalParametersOpt(token); | 
| 1587 token = parseInitializersOpt(token); | 1607 token = parseInitializersOpt(token); | 
| 1588 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; | 1608 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; | 
| 1589 token = parseAsyncModifier(token); | 1609 token = parseAsyncModifier(token); | 
| 1590 if (optional('=', token)) { | 1610 if (optional('=', token)) { | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1625 } | 1645 } | 
| 1626 | 1646 | 
| 1627 Token parseOperatorName(Token token) { | 1647 Token parseOperatorName(Token token) { | 
| 1628 assert(optional('operator', token)); | 1648 assert(optional('operator', token)); | 
| 1629 if (isUserDefinableOperator(token.next.stringValue)) { | 1649 if (isUserDefinableOperator(token.next.stringValue)) { | 
| 1630 Token operator = token; | 1650 Token operator = token; | 
| 1631 token = token.next; | 1651 token = token.next; | 
| 1632 listener.handleOperatorName(operator, token); | 1652 listener.handleOperatorName(operator, token); | 
| 1633 return token.next; | 1653 return token.next; | 
| 1634 } else { | 1654 } else { | 
| 1635 return parseIdentifier(token); | 1655 return parseIdentifier(token, IdentifierContext.operatorName); | 
| 1636 } | 1656 } | 
| 1637 } | 1657 } | 
| 1638 | 1658 | 
| 1639 Token parseFunction(Token token, Token getOrSet) { | 1659 Token parseFunction(Token token, Token getOrSet) { | 
| 1640 listener.beginFunction(token); | 1660 listener.beginFunction(token); | 
| 1641 token = parseModifiers(token); | 1661 token = parseModifiers(token); | 
| 1642 if (identical(getOrSet, token)) { | 1662 if (identical(getOrSet, token)) { | 
| 1643 // get <name> => ... | 1663 // get <name> => ... | 
| 1644 token = token.next; | 1664 token = token.next; | 
| 1645 listener.handleNoType(token); | 1665 listener.handleNoType(token); | 
| 1646 listener.beginFunctionName(token); | 1666 listener.beginFunctionName(token); | 
| 1647 if (optional('operator', token)) { | 1667 if (optional('operator', token)) { | 
| 1648 token = parseOperatorName(token); | 1668 token = parseOperatorName(token); | 
| 1649 } else { | 1669 } else { | 
| 1650 token = parseIdentifier(token); | 1670 token = | 
| 1671 parseIdentifier(token, IdentifierContext.localAccessorDeclaration); | |
| 
ahe
2017/02/22 09:46:20
Not 100% sure, but I think dart2js sometimes uses
 | |
| 1651 } | 1672 } | 
| 1652 } else if (optional('operator', token)) { | 1673 } else if (optional('operator', token)) { | 
| 1653 // operator <op> (... | 1674 // operator <op> (... | 
| 1654 listener.handleNoType(token); | 1675 listener.handleNoType(token); | 
| 1655 listener.beginFunctionName(token); | 1676 listener.beginFunctionName(token); | 
| 1656 token = parseOperatorName(token); | 1677 token = parseOperatorName(token); | 
| 1657 } else { | 1678 } else { | 
| 1658 // <type>? <get>? <name> | 1679 // <type>? <get>? <name> | 
| 1659 token = parseReturnTypeOpt(token); | 1680 token = parseReturnTypeOpt(token); | 
| 1660 if (identical(getOrSet, token)) { | 1681 if (identical(getOrSet, token)) { | 
| 1661 token = token.next; | 1682 token = token.next; | 
| 1662 } | 1683 } | 
| 1663 listener.beginFunctionName(token); | 1684 listener.beginFunctionName(token); | 
| 1664 if (optional('operator', token)) { | 1685 if (optional('operator', token)) { | 
| 1665 token = parseOperatorName(token); | 1686 token = parseOperatorName(token); | 
| 1666 } else { | 1687 } else { | 
| 1667 token = parseIdentifier(token); | 1688 token = | 
| 1689 parseIdentifier(token, IdentifierContext.localFunctionDeclaration); | |
| 1668 } | 1690 } | 
| 1669 } | 1691 } | 
| 1670 token = parseQualifiedRestOpt(token); | 1692 token = parseQualifiedRestOpt( | 
| 1693 token, IdentifierContext.localFunctionDeclarationContinuation); | |
| 1671 listener.endFunctionName(token); | 1694 listener.endFunctionName(token); | 
| 1672 if (getOrSet == null) { | 1695 if (getOrSet == null) { | 
| 1673 token = parseTypeVariablesOpt(token); | 1696 token = parseTypeVariablesOpt(token); | 
| 1674 } else { | 1697 } else { | 
| 1675 listener.handleNoTypeVariables(token); | 1698 listener.handleNoTypeVariables(token); | 
| 1676 } | 1699 } | 
| 1677 token = parseFormalParametersOpt(token); | 1700 token = parseFormalParametersOpt(token); | 
| 1678 token = parseInitializersOpt(token); | 1701 token = parseInitializersOpt(token); | 
| 1679 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; | 1702 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; | 
| 1680 token = parseAsyncModifier(token); | 1703 token = parseAsyncModifier(token); | 
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1701 token = parseFunction(token, null); | 1724 token = parseFunction(token, null); | 
| 1702 listener.endFunctionDeclaration(token); | 1725 listener.endFunctionDeclaration(token); | 
| 1703 return token; | 1726 return token; | 
| 1704 } | 1727 } | 
| 1705 | 1728 | 
| 1706 Token parseFunctionExpression(Token token) { | 1729 Token parseFunctionExpression(Token token) { | 
| 1707 listener.beginFunction(token); | 1730 listener.beginFunction(token); | 
| 1708 listener.handleModifiers(0); | 1731 listener.handleModifiers(0); | 
| 1709 token = parseReturnTypeOpt(token); | 1732 token = parseReturnTypeOpt(token); | 
| 1710 listener.beginFunctionName(token); | 1733 listener.beginFunctionName(token); | 
| 1711 token = parseIdentifier(token); | 1734 token = parseIdentifier(token, IdentifierContext.functionExpressionName); | 
| 1712 listener.endFunctionName(token); | 1735 listener.endFunctionName(token); | 
| 1713 token = parseTypeVariablesOpt(token); | 1736 token = parseTypeVariablesOpt(token); | 
| 1714 token = parseFormalParameters(token); | 1737 token = parseFormalParameters(token); | 
| 1715 listener.handleNoInitializers(); | 1738 listener.handleNoInitializers(); | 
| 1716 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; | 1739 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; | 
| 1717 token = parseAsyncModifier(token); | 1740 token = parseAsyncModifier(token); | 
| 1718 bool isBlock = optional('{', token); | 1741 bool isBlock = optional('{', token); | 
| 1719 token = parseFunctionBody(token, true, false); | 1742 token = parseFunctionBody(token, true, false); | 
| 1720 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled; | 1743 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled; | 
| 1721 listener.endFunction(null, token); | 1744 listener.endFunction(null, token); | 
| 1722 return isBlock ? token.next : token; | 1745 return isBlock ? token.next : token; | 
| 1723 } | 1746 } | 
| 1724 | 1747 | 
| 1725 Token parseConstructorReference(Token token) { | 1748 Token parseConstructorReference(Token token) { | 
| 1726 Token start = token; | 1749 Token start = token; | 
| 1727 listener.beginConstructorReference(start); | 1750 listener.beginConstructorReference(start); | 
| 1728 token = parseIdentifier(token); | 1751 token = parseIdentifier(token, IdentifierContext.constructorReference); | 
| 1729 token = parseQualifiedRestOpt(token); | 1752 token = parseQualifiedRestOpt( | 
| 1753 token, IdentifierContext.constructorReferenceContinuation); | |
| 1730 token = parseTypeArgumentsOpt(token); | 1754 token = parseTypeArgumentsOpt(token); | 
| 1731 Token period = null; | 1755 Token period = null; | 
| 1732 if (optional('.', token)) { | 1756 if (optional('.', token)) { | 
| 1733 period = token; | 1757 period = token; | 
| 1734 token = parseIdentifier(token.next); | 1758 token = parseIdentifier(token.next, | 
| 1759 IdentifierContext.constructorReferenceContinuationAfterTypeArguments); | |
| 1735 } | 1760 } | 
| 1736 listener.endConstructorReference(start, period, token); | 1761 listener.endConstructorReference(start, period, token); | 
| 1737 return token; | 1762 return token; | 
| 1738 } | 1763 } | 
| 1739 | 1764 | 
| 1740 Token parseRedirectingFactoryBody(Token token) { | 1765 Token parseRedirectingFactoryBody(Token token) { | 
| 1741 listener.beginRedirectingFactoryBody(token); | 1766 listener.beginRedirectingFactoryBody(token); | 
| 1742 assert(optional('=', token)); | 1767 assert(optional('=', token)); | 
| 1743 Token equals = token; | 1768 Token equals = token; | 
| 1744 token = parseConstructorReference(token.next); | 1769 token = parseConstructorReference(token.next); | 
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2089 // ','. | 2114 // ','. | 
| 2090 return parseVariablesDeclaration(token); | 2115 return parseVariablesDeclaration(token); | 
| 2091 } | 2116 } | 
| 2092 // Fall-through to expression statement. | 2117 // Fall-through to expression statement. | 
| 2093 } | 2118 } | 
| 2094 | 2119 | 
| 2095 return parseExpressionStatement(token); | 2120 return parseExpressionStatement(token); | 
| 2096 } | 2121 } | 
| 2097 | 2122 | 
| 2098 Token parseLabel(Token token) { | 2123 Token parseLabel(Token token) { | 
| 2099 token = parseIdentifier(token); | 2124 token = parseIdentifier(token, IdentifierContext.labelDeclaration); | 
| 2100 Token colon = token; | 2125 Token colon = token; | 
| 2101 token = expect(':', token); | 2126 token = expect(':', token); | 
| 2102 listener.handleLabel(colon); | 2127 listener.handleLabel(colon); | 
| 2103 return token; | 2128 return token; | 
| 2104 } | 2129 } | 
| 2105 | 2130 | 
| 2106 Token parseLabeledStatement(Token token) { | 2131 Token parseLabeledStatement(Token token) { | 
| 2107 int labelCount = 0; | 2132 int labelCount = 0; | 
| 2108 do { | 2133 do { | 
| 2109 token = parseLabel(token); | 2134 token = parseLabel(token); | 
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2290 } | 2315 } | 
| 2291 | 2316 | 
| 2292 Token parseCascadeExpression(Token token) { | 2317 Token parseCascadeExpression(Token token) { | 
| 2293 listener.beginCascade(token); | 2318 listener.beginCascade(token); | 
| 2294 assert(optional('..', token)); | 2319 assert(optional('..', token)); | 
| 2295 Token cascadeOperator = token; | 2320 Token cascadeOperator = token; | 
| 2296 token = token.next; | 2321 token = token.next; | 
| 2297 if (optional('[', token)) { | 2322 if (optional('[', token)) { | 
| 2298 token = parseArgumentOrIndexStar(token); | 2323 token = parseArgumentOrIndexStar(token); | 
| 2299 } else if (token.isIdentifier()) { | 2324 } else if (token.isIdentifier()) { | 
| 2300 token = parseSend(token); | 2325 token = parseSend(token, IdentifierContext.expressionContinuation); | 
| 2301 listener.handleBinaryExpression(cascadeOperator); | 2326 listener.handleBinaryExpression(cascadeOperator); | 
| 2302 } else { | 2327 } else { | 
| 2303 return reportUnrecoverableError(token, ErrorKind.UnexpectedToken); | 2328 return reportUnrecoverableError(token, ErrorKind.UnexpectedToken); | 
| 2304 } | 2329 } | 
| 2305 Token mark; | 2330 Token mark; | 
| 2306 do { | 2331 do { | 
| 2307 mark = token; | 2332 mark = token; | 
| 2308 if (optional('.', token)) { | 2333 if (optional('.', token)) { | 
| 2309 Token period = token; | 2334 Token period = token; | 
| 2310 token = parseSend(token.next); | 2335 token = parseSend(token.next, IdentifierContext.expressionContinuation); | 
| 2311 listener.handleBinaryExpression(period); | 2336 listener.handleBinaryExpression(period); | 
| 2312 } | 2337 } | 
| 2313 token = parseArgumentOrIndexStar(token); | 2338 token = parseArgumentOrIndexStar(token); | 
| 2314 } while (!identical(mark, token)); | 2339 } while (!identical(mark, token)); | 
| 2315 | 2340 | 
| 2316 if (identical(token.info.precedence, ASSIGNMENT_PRECEDENCE)) { | 2341 if (identical(token.info.precedence, ASSIGNMENT_PRECEDENCE)) { | 
| 2317 Token assignment = token; | 2342 Token assignment = token; | 
| 2318 token = parseExpressionWithoutCascade(token.next); | 2343 token = parseExpressionWithoutCascade(token.next); | 
| 2319 listener.handleAssignmentExpression(assignment); | 2344 listener.handleAssignmentExpression(assignment); | 
| 2320 } | 2345 } | 
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2601 // Assume the listener rejects non-string keys. | 2626 // Assume the listener rejects non-string keys. | 
| 2602 token = parseExpression(token); | 2627 token = parseExpression(token); | 
| 2603 Token colon = token; | 2628 Token colon = token; | 
| 2604 token = expect(':', token); | 2629 token = expect(':', token); | 
| 2605 token = parseExpression(token); | 2630 token = parseExpression(token); | 
| 2606 listener.endLiteralMapEntry(colon, token); | 2631 listener.endLiteralMapEntry(colon, token); | 
| 2607 return token; | 2632 return token; | 
| 2608 } | 2633 } | 
| 2609 | 2634 | 
| 2610 Token parseSendOrFunctionLiteral(Token token) { | 2635 Token parseSendOrFunctionLiteral(Token token) { | 
| 2611 if (!mayParseFunctionExpressions) return parseSend(token); | 2636 if (!mayParseFunctionExpressions) { | 
| 2637 return parseSend(token, IdentifierContext.expression); | |
| 2638 } | |
| 2612 Token peek = peekAfterIfType(token); | 2639 Token peek = peekAfterIfType(token); | 
| 2613 if (peek != null && | 2640 if (peek != null && | 
| 2614 identical(peek.kind, IDENTIFIER_TOKEN) && | 2641 identical(peek.kind, IDENTIFIER_TOKEN) && | 
| 2615 isFunctionDeclaration(peek.next)) { | 2642 isFunctionDeclaration(peek.next)) { | 
| 2616 return parseFunctionExpression(token); | 2643 return parseFunctionExpression(token); | 
| 2617 } else if (isFunctionDeclaration(token.next)) { | 2644 } else if (isFunctionDeclaration(token.next)) { | 
| 2618 return parseFunctionExpression(token); | 2645 return parseFunctionExpression(token); | 
| 2619 } else { | 2646 } else { | 
| 2620 return parseSend(token); | 2647 return parseSend(token, IdentifierContext.expression); | 
| 2621 } | 2648 } | 
| 2622 } | 2649 } | 
| 2623 | 2650 | 
| 2624 bool isFunctionDeclaration(Token token) { | 2651 bool isFunctionDeclaration(Token token) { | 
| 2625 if (optional('<', token)) { | 2652 if (optional('<', token)) { | 
| 2626 BeginGroupToken begin = token; | 2653 BeginGroupToken begin = token; | 
| 2627 if (begin.endGroup == null) return false; | 2654 if (begin.endGroup == null) return false; | 
| 2628 token = begin.endGroup.next; | 2655 token = begin.endGroup.next; | 
| 2629 } | 2656 } | 
| 2630 if (optional('(', token)) { | 2657 if (optional('(', token)) { | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2710 Token parseLiteralSymbol(Token token) { | 2737 Token parseLiteralSymbol(Token token) { | 
| 2711 Token hashToken = token; | 2738 Token hashToken = token; | 
| 2712 listener.beginLiteralSymbol(hashToken); | 2739 listener.beginLiteralSymbol(hashToken); | 
| 2713 token = token.next; | 2740 token = token.next; | 
| 2714 if (isUserDefinableOperator(token.stringValue)) { | 2741 if (isUserDefinableOperator(token.stringValue)) { | 
| 2715 listener.handleOperator(token); | 2742 listener.handleOperator(token); | 
| 2716 listener.endLiteralSymbol(hashToken, 1); | 2743 listener.endLiteralSymbol(hashToken, 1); | 
| 2717 return token.next; | 2744 return token.next; | 
| 2718 } else { | 2745 } else { | 
| 2719 int count = 1; | 2746 int count = 1; | 
| 2720 token = parseIdentifier(token); | 2747 token = parseIdentifier(token, IdentifierContext.literalSymbol); | 
| 2721 while (identical(token.stringValue, '.')) { | 2748 while (identical(token.stringValue, '.')) { | 
| 2722 count++; | 2749 count++; | 
| 2723 token = parseIdentifier(token.next); | 2750 token = parseIdentifier( | 
| 2751 token.next, IdentifierContext.literalSymbolContinuation); | |
| 2724 } | 2752 } | 
| 2725 listener.endLiteralSymbol(hashToken, count); | 2753 listener.endLiteralSymbol(hashToken, count); | 
| 2726 return token; | 2754 return token; | 
| 2727 } | 2755 } | 
| 2728 } | 2756 } | 
| 2729 | 2757 | 
| 2730 /** | 2758 /** | 
| 2731 * Only called when [:token.kind === STRING_TOKEN:]. | 2759 * Only called when [:token.kind === STRING_TOKEN:]. | 
| 2732 */ | 2760 */ | 
| 2733 Token parseSingleLiteralString(Token token) { | 2761 Token parseSingleLiteralString(Token token) { | 
| (...skipping 27 matching lines...) Expand all Loading... | |
| 2761 Token parseLiteralBool(Token token) { | 2789 Token parseLiteralBool(Token token) { | 
| 2762 listener.handleLiteralBool(token); | 2790 listener.handleLiteralBool(token); | 
| 2763 return token.next; | 2791 return token.next; | 
| 2764 } | 2792 } | 
| 2765 | 2793 | 
| 2766 Token parseLiteralNull(Token token) { | 2794 Token parseLiteralNull(Token token) { | 
| 2767 listener.handleLiteralNull(token); | 2795 listener.handleLiteralNull(token); | 
| 2768 return token.next; | 2796 return token.next; | 
| 2769 } | 2797 } | 
| 2770 | 2798 | 
| 2771 Token parseSend(Token token) { | 2799 Token parseSend(Token token, IdentifierContext context) { | 
| 2772 listener.beginSend(token); | 2800 listener.beginSend(token); | 
| 2773 token = parseIdentifier(token); | 2801 token = parseIdentifier(token, context); | 
| 2774 if (isValidMethodTypeArguments(token)) { | 2802 if (isValidMethodTypeArguments(token)) { | 
| 2775 token = parseTypeArgumentsOpt(token); | 2803 token = parseTypeArgumentsOpt(token); | 
| 2776 } else { | 2804 } else { | 
| 2777 listener.handleNoTypeArguments(token); | 2805 listener.handleNoTypeArguments(token); | 
| 2778 } | 2806 } | 
| 2779 token = parseArgumentsOpt(token); | 2807 token = parseArgumentsOpt(token); | 
| 2780 listener.endSend(token); | 2808 listener.endSend(token); | 
| 2781 return token; | 2809 return token; | 
| 2782 } | 2810 } | 
| 2783 | 2811 | 
| (...skipping 27 matching lines...) Expand all Loading... | |
| 2811 } | 2839 } | 
| 2812 bool old = mayParseFunctionExpressions; | 2840 bool old = mayParseFunctionExpressions; | 
| 2813 mayParseFunctionExpressions = true; | 2841 mayParseFunctionExpressions = true; | 
| 2814 do { | 2842 do { | 
| 2815 if (optional(')', token.next)) { | 2843 if (optional(')', token.next)) { | 
| 2816 token = token.next; | 2844 token = token.next; | 
| 2817 break; | 2845 break; | 
| 2818 } | 2846 } | 
| 2819 Token colon = null; | 2847 Token colon = null; | 
| 2820 if (optional(':', token.next.next)) { | 2848 if (optional(':', token.next.next)) { | 
| 2821 token = parseIdentifier(token.next); | 2849 token = parseIdentifier( | 
| 2850 token.next, IdentifierContext.namedArgumentReference); | |
| 2822 colon = token; | 2851 colon = token; | 
| 2823 } | 2852 } | 
| 2824 token = parseExpression(token.next); | 2853 token = parseExpression(token.next); | 
| 2825 if (colon != null) listener.handleNamedArgument(colon); | 2854 if (colon != null) listener.handleNamedArgument(colon); | 
| 2826 ++argumentCount; | 2855 ++argumentCount; | 
| 2827 } while (optional(',', token)); | 2856 } while (optional(',', token)); | 
| 2828 mayParseFunctionExpressions = old; | 2857 mayParseFunctionExpressions = old; | 
| 2829 listener.endArguments(argumentCount, begin, token); | 2858 listener.endArguments(argumentCount, begin, token); | 
| 2830 return expect(')', token); | 2859 return expect(')', token); | 
| 2831 } | 2860 } | 
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2888 listener.endVariablesDeclaration(count, semicolon); | 2917 listener.endVariablesDeclaration(count, semicolon); | 
| 2889 return token; | 2918 return token; | 
| 2890 } else { | 2919 } else { | 
| 2891 listener.endVariablesDeclaration(count, null); | 2920 listener.endVariablesDeclaration(count, null); | 
| 2892 return token; | 2921 return token; | 
| 2893 } | 2922 } | 
| 2894 } | 2923 } | 
| 2895 | 2924 | 
| 2896 Token parseOptionallyInitializedIdentifier(Token token) { | 2925 Token parseOptionallyInitializedIdentifier(Token token) { | 
| 2897 listener.beginInitializedIdentifier(token); | 2926 listener.beginInitializedIdentifier(token); | 
| 2898 token = parseIdentifier(token); | 2927 token = parseIdentifier(token, IdentifierContext.localVariableDeclaration); | 
| 2899 token = parseVariableInitializerOpt(token); | 2928 token = parseVariableInitializerOpt(token); | 
| 2900 listener.endInitializedIdentifier(); | 2929 listener.endInitializedIdentifier(); | 
| 2901 return token; | 2930 return token; | 
| 2902 } | 2931 } | 
| 2903 | 2932 | 
| 2904 Token parseIfStatement(Token token) { | 2933 Token parseIfStatement(Token token) { | 
| 2905 Token ifToken = token; | 2934 Token ifToken = token; | 
| 2906 listener.beginIfStatement(ifToken); | 2935 listener.beginIfStatement(ifToken); | 
| 2907 token = expect('if', token); | 2936 token = expect('if', token); | 
| 2908 token = parseParenthesizedExpression(token); | 2937 token = parseParenthesizedExpression(token); | 
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3209 statementCount, begin, token); | 3238 statementCount, begin, token); | 
| 3210 return token; | 3239 return token; | 
| 3211 } | 3240 } | 
| 3212 | 3241 | 
| 3213 Token parseBreakStatement(Token token) { | 3242 Token parseBreakStatement(Token token) { | 
| 3214 assert(optional('break', token)); | 3243 assert(optional('break', token)); | 
| 3215 Token breakKeyword = token; | 3244 Token breakKeyword = token; | 
| 3216 token = token.next; | 3245 token = token.next; | 
| 3217 bool hasTarget = false; | 3246 bool hasTarget = false; | 
| 3218 if (token.isIdentifier()) { | 3247 if (token.isIdentifier()) { | 
| 3219 token = parseIdentifier(token); | 3248 token = parseIdentifier(token, IdentifierContext.labelReference); | 
| 3220 hasTarget = true; | 3249 hasTarget = true; | 
| 3221 } | 3250 } | 
| 3222 listener.handleBreakStatement(hasTarget, breakKeyword, token); | 3251 listener.handleBreakStatement(hasTarget, breakKeyword, token); | 
| 3223 return expectSemicolon(token); | 3252 return expectSemicolon(token); | 
| 3224 } | 3253 } | 
| 3225 | 3254 | 
| 3226 Token parseAssertStatement(Token token) { | 3255 Token parseAssertStatement(Token token) { | 
| 3227 Token assertKeyword = token; | 3256 Token assertKeyword = token; | 
| 3228 Token commaToken = null; | 3257 Token commaToken = null; | 
| 3229 token = expect('assert', token); | 3258 token = expect('assert', token); | 
| (...skipping 11 matching lines...) Expand all Loading... | |
| 3241 listener.handleAssertStatement(assertKeyword, commaToken, token); | 3270 listener.handleAssertStatement(assertKeyword, commaToken, token); | 
| 3242 return expectSemicolon(token); | 3271 return expectSemicolon(token); | 
| 3243 } | 3272 } | 
| 3244 | 3273 | 
| 3245 Token parseContinueStatement(Token token) { | 3274 Token parseContinueStatement(Token token) { | 
| 3246 assert(optional('continue', token)); | 3275 assert(optional('continue', token)); | 
| 3247 Token continueKeyword = token; | 3276 Token continueKeyword = token; | 
| 3248 token = token.next; | 3277 token = token.next; | 
| 3249 bool hasTarget = false; | 3278 bool hasTarget = false; | 
| 3250 if (token.isIdentifier()) { | 3279 if (token.isIdentifier()) { | 
| 3251 token = parseIdentifier(token); | 3280 token = parseIdentifier(token, IdentifierContext.labelReference); | 
| 3252 hasTarget = true; | 3281 hasTarget = true; | 
| 3253 } | 3282 } | 
| 3254 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 3283 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 
| 3255 return expectSemicolon(token); | 3284 return expectSemicolon(token); | 
| 3256 } | 3285 } | 
| 3257 | 3286 | 
| 3258 Token parseEmptyStatement(Token token) { | 3287 Token parseEmptyStatement(Token token) { | 
| 3259 listener.handleEmptyStatement(token); | 3288 listener.handleEmptyStatement(token); | 
| 3260 return expectSemicolon(token); | 3289 return expectSemicolon(token); | 
| 3261 } | 3290 } | 
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3317 break; | 3346 break; | 
| 3318 } | 3347 } | 
| 3319 if (isRecoverable) { | 3348 if (isRecoverable) { | 
| 3320 listener.handleRecoverableError(token, kind, arguments); | 3349 listener.handleRecoverableError(token, kind, arguments); | 
| 3321 return null; | 3350 return null; | 
| 3322 } else { | 3351 } else { | 
| 3323 return listener.handleUnrecoverableError(token, kind, arguments); | 3352 return listener.handleUnrecoverableError(token, kind, arguments); | 
| 3324 } | 3353 } | 
| 3325 } | 3354 } | 
| 3326 } | 3355 } | 
| OLD | NEW |