Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(616)

Side by Side Diff: dart/lib/compiler/implementation/scanner/parser.dart

Issue 10913153: Parse methods named 'get' or 'set' (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 /** 5 /**
6 * An event generating parser of Dart programs. This parser expects 6 * An event generating parser of Dart programs. This parser expects
7 * all tokens in a linked list (aka a token stream). 7 * all tokens in a linked list (aka a token stream).
8 * 8 *
9 * The class [Scanner] is used to generate a token stream. See the 9 * The class [Scanner] is used to generate a token stream. See the
10 * file scanner.dart. 10 * file scanner.dart.
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 listener.endOptionalFormalParameters(parameterCount, begin, token); 197 listener.endOptionalFormalParameters(parameterCount, begin, token);
198 if (isNamed) { 198 if (isNamed) {
199 return expect('}', token); 199 return expect('}', token);
200 } else { 200 } else {
201 return expect(']', token); 201 return expect(']', token);
202 } 202 }
203 } 203 }
204 204
205 Token parseTypeOpt(Token token) { 205 Token parseTypeOpt(Token token) {
206 String value = token.stringValue; 206 String value = token.stringValue;
207 if (value === 'var') return parseType(token);
208 if (value !== 'this') { 207 if (value !== 'this') {
209 Token peek = peekAfterExpectedType(token); 208 Token peek = peekAfterExpectedType(token);
210 if (peek.isIdentifier() || optional('this', peek)) { 209 if (peek.isIdentifier() || optional('this', peek)) {
211 return parseType(token); 210 return parseType(token);
212 } 211 }
213 } 212 }
214 listener.handleNoType(token); 213 listener.handleNoType(token);
215 return token; 214 return token;
216 } 215 }
217 216
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 endStuff(count, begin, token); 400 endStuff(count, begin, token);
402 return expect('>', token); 401 return expect('>', token);
403 } 402 }
404 handleNoStuff(token); 403 handleNoStuff(token);
405 return token; 404 return token;
406 } 405 }
407 406
408 Token parseTopLevelMember(Token token) { 407 Token parseTopLevelMember(Token token) {
409 Token start = token; 408 Token start = token;
410 listener.beginTopLevelMember(token); 409 listener.beginTopLevelMember(token);
411 token = parseModifiers(token); 410
412 Token getOrSet = findGetOrSet(token); 411 Link<Token> identifiers = findMemberName(token);
413 if (token === getOrSet) token = token.next; 412 if (identifiers.isEmpty()) {
414 Token peek = peekAfterExpectedType(token); 413 return listener.unexpected(start);
415 if (peek.isIdentifier()) {
416 // Skip type.
417 token = peek;
418 } 414 }
419 if (token === getOrSet) token = token.next; 415 Token name = identifiers.head;
420 token = parseIdentifier(token); 416 identifiers = identifiers.tail;
417 Token getOrSet;
418 if (!identifiers.isEmpty()) {
419 String value = identifiers.head.stringValue;
420 if ((value === 'get') || (value === 'set')) {
421 getOrSet = identifiers.head;
422 identifiers = identifiers.tail;
423 }
424 }
425 Token type;
426 if (!identifiers.isEmpty()) {
427 if (isValidTypeReference(identifiers.head)) {
428 type = identifiers.head;
429 identifiers = identifiers.tail;
430 }
431 }
432 parseModifierList(identifiers.reverse());
433 if (type === null) {
434 listener.handleNoType(token);
435 } else {
436 parseReturnTypeOpt(type);
437 }
438 token = parseIdentifier(name);
439
421 bool isField; 440 bool isField;
422 while (true) { 441 while (true) {
423 // Loop to allow the listener to rewrite the token stream for 442 // Loop to allow the listener to rewrite the token stream for
424 // error handling. 443 // error handling.
425 final String value = token.stringValue; 444 final String value = token.stringValue;
426 if ((value === '(') || (value === '{') || (value === '=>')) { 445 if ((value === '(') || (value === '{') || (value === '=>')) {
427 isField = false; 446 isField = false;
428 break; 447 break;
429 } else if ((value === '=') || (value === ';') || (value === ',')) { 448 } else if ((value === '=') || (value === ';') || (value === ',')) {
430 isField = true; 449 isField = true;
(...skipping 19 matching lines...) Expand all
450 expectSemicolon(token); 469 expectSemicolon(token);
451 listener.endTopLevelFields(fieldCount, start, token); 470 listener.endTopLevelFields(fieldCount, start, token);
452 } else { 471 } else {
453 token = parseFormalParametersOpt(token); 472 token = parseFormalParametersOpt(token);
454 token = parseFunctionBody(token, false); 473 token = parseFunctionBody(token, false);
455 listener.endTopLevelMethod(start, getOrSet, token); 474 listener.endTopLevelMethod(start, getOrSet, token);
456 } 475 }
457 return token.next; 476 return token.next;
458 } 477 }
459 478
479 Link<Token> findMemberName(Token token) {
480 Link<Token> identifiers = const EmptyLink<Token>();
481 while (token.kind !== EOF_TOKEN) {
482 String value = token.stringValue;
483 if ((value === '(') || (value === '{') || (value === '=>')) {
484 // A method.
485 return identifiers;
486 } else if ((value === '=') || (value === ';') || (value === ',')) {
487 // A field or abstract getter.
488 return identifiers;
489 }
490 identifiers = identifiers.prepend(token);
491 if (isValidTypeReference(token)) {
492 // type ...
493 if (optional('.', token.next)) {
494 // type '.' ...
495 if (token.next.next.isIdentifier()) {
496 // type '.' identifier
497 token = token.next.next;
498 }
499 }
500 if (optional('<', token.next)) {
501 if (token.next is BeginGroupToken) {
502 BeginGroupToken beginGroup = token.next;
503 token = beginGroup.endGroup;
504 }
505 }
506 }
507 token = token.next;
508 }
509 return listener.unexpected(token);
510 }
511
460 Token parseVariableInitializerOpt(Token token) { 512 Token parseVariableInitializerOpt(Token token) {
461 if (optional('=', token)) { 513 if (optional('=', token)) {
462 Token assignment = token; 514 Token assignment = token;
463 listener.beginInitializer(token); 515 listener.beginInitializer(token);
464 token = parseExpression(token.next); 516 token = parseExpression(token.next);
465 listener.endInitializer(assignment); 517 listener.endInitializer(assignment);
466 } 518 }
467 return token; 519 return token;
468 } 520 }
469 521
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 ('static' === value) || 584 ('static' === value) ||
533 ('external' === value); 585 ('external' === value);
534 } 586 }
535 587
536 Token parseModifier(Token token) { 588 Token parseModifier(Token token) {
537 assert(isModifier(token)); 589 assert(isModifier(token));
538 listener.handleModifier(token); 590 listener.handleModifier(token);
539 return token.next; 591 return token.next;
540 } 592 }
541 593
594 void parseModifierList(Link<Token> tokens) {
595 int count = 0;
596 for (; !tokens.isEmpty(); tokens = tokens.tail) {
597 Token token = tokens.head;
598 if (isModifier(token)) {
599 parseModifier(token);
600 } else {
601 listener.unexpected(token);
602 }
603 count++;
604 }
605 listener.handleModifiers(count);
606 }
607
542 Token parseModifiers(Token token) { 608 Token parseModifiers(Token token) {
543 int count = 0; 609 int count = 0;
544 while (token.kind === KEYWORD_TOKEN) { 610 while (token.kind === KEYWORD_TOKEN) {
545 if (!isModifier(token)) 611 if (!isModifier(token))
546 break; 612 break;
547 token = parseModifier(token); 613 token = parseModifier(token);
548 count++; 614 count++;
549 } 615 }
550 listener.handleModifiers(count); 616 listener.handleModifiers(count);
551 return token; 617 return token;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 } 666 }
601 listener.endClassBody(count, begin, token); 667 listener.endClassBody(count, begin, token);
602 return token; 668 return token;
603 } 669 }
604 670
605 bool isGetOrSet(Token token) { 671 bool isGetOrSet(Token token) {
606 final String value = token.stringValue; 672 final String value = token.stringValue;
607 return (value === 'get') || (value === 'set'); 673 return (value === 'get') || (value === 'set');
608 } 674 }
609 675
610 Token findGetOrSet(Token token) {
611 if (isGetOrSet(token)) {
612 if (optional('<', token.next)) {
613 // For example: get<T> ...
614 final Token peek = peekAfterExpectedType(token);
615 if (isGetOrSet(peek) && peek.next.isIdentifier()) {
616 // For example: get<T> get identifier
617 return peek;
618 }
619 } else {
620 // For example: get ...
621 if (isGetOrSet(token.next) && token.next.next.isIdentifier()) {
622 // For example: get get identifier
623 return token.next;
624 } else {
625 // For example: get identifier
626 return token;
627 }
628 }
629 } else if (token.stringValue !== 'operator') {
630 final Token peek = peekAfterExpectedType(token);
631 if (isGetOrSet(peek) && peek.next.isIdentifier()) {
632 // type? get identifier
633 return peek;
634 }
635 }
636 return null;
637 }
638
639 Token parseMember(Token token) { 676 Token parseMember(Token token) {
640 token = parseMetadataStar(token); 677 token = parseMetadataStar(token);
641 String value = token.stringValue; 678 String value = token.stringValue;
642 if (value === 'factory' || 679 if (value === 'factory' ||
643 (value === 'external' && optional('factory', token.next))) { 680 (value === 'external' && optional('factory', token.next))) {
644 return parseFactoryMethod(token); 681 return parseFactoryMethod(token);
645 } 682 }
646 Token start = token; 683 Token start = token;
647 listener.beginMember(token); 684 listener.beginMember(token);
648 token = parseModifiers(token); 685
649 Token getOrSet = findGetOrSet(token); 686 Link<Token> identifiers = findMemberName(token);
650 if (token === getOrSet) token = token.next; 687 if (identifiers.isEmpty()) {
651 Token peek = peekAfterExpectedType(token); 688 return listener.unexpected(start);
652 if (peek.isIdentifier() && token.stringValue !== 'operator') {
653 // Skip type.
654 token = peek;
655 } 689 }
656 if (token === getOrSet) token = token.next; 690 Token name = identifiers.head;
657 if (optional('operator', token)) { 691 identifiers = identifiers.tail;
658 token = parseOperatorName(token); 692 if (!identifiers.isEmpty()) {
693 if (optional('operator', identifiers.head)) {
694 name = identifiers.head;
695 identifiers = identifiers.tail;
696 }
697 }
698 Token getOrSet;
699 if (!identifiers.isEmpty()) {
700 if (isGetOrSet(identifiers.head)) {
701 getOrSet = identifiers.head;
702 identifiers = identifiers.tail;
703 }
704 }
705 Token type;
706 if (!identifiers.isEmpty()) {
707 if (isValidTypeReference(identifiers.head)) {
708 type = identifiers.head;
709 identifiers = identifiers.tail;
710 }
711 }
712 parseModifierList(identifiers.reverse());
713 if (type === null) {
714 listener.handleNoType(token);
659 } else { 715 } else {
660 token = parseIdentifier(token); 716 parseReturnTypeOpt(type);
717 }
718
719 if (optional('operator', name)) {
720 token = parseOperatorName(name);
721 } else {
722 token = parseIdentifier(name);
661 } 723 }
662 bool isField; 724 bool isField;
663 while (true) { 725 while (true) {
664 // Loop to allow the listener to rewrite the token stream for 726 // Loop to allow the listener to rewrite the token stream for
665 // error handling. 727 // error handling.
666 final String value = token.stringValue; 728 final String value = token.stringValue;
667 if ((value === '(') || (value === '.') || (value === '{') || 729 if ((value === '(') || (value === '.') || (value === '{') ||
668 (value === '=>')) { 730 (value === '=>')) {
669 isField = false; 731 isField = false;
670 break; 732 break;
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1864 } 1926 }
1865 listener.handleContinueStatement(hasTarget, continueKeyword, token); 1927 listener.handleContinueStatement(hasTarget, continueKeyword, token);
1866 return expectSemicolon(token); 1928 return expectSemicolon(token);
1867 } 1929 }
1868 1930
1869 Token parseEmptyStatement(Token token) { 1931 Token parseEmptyStatement(Token token) {
1870 listener.handleEmptyStatement(token); 1932 listener.handleEmptyStatement(token);
1871 return expectSemicolon(token); 1933 return expectSemicolon(token);
1872 } 1934 }
1873 } 1935 }
OLDNEW
« no previous file with comments | « dart/lib/compiler/implementation/scanner/listener.dart ('k') | dart/tests/co19/co19-dart2js.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698