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

Side by Side Diff: pkg/compiler/lib/src/scanner/parser.dart

Issue 892583002: Support async getters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 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 part of scanner; 5 part of scanner;
6 6
7 class FormalParameterType { 7 class FormalParameterType {
8 final String type; 8 final String type;
9 const FormalParameterType(this.type); 9 const FormalParameterType(this.type);
10 bool get isRequired => this == REQUIRED; 10 bool get isRequired => this == REQUIRED;
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 } 677 }
678 678
679 Token parseTopLevelMember(Token token) { 679 Token parseTopLevelMember(Token token) {
680 Token start = token; 680 Token start = token;
681 listener.beginTopLevelMember(token); 681 listener.beginTopLevelMember(token);
682 682
683 Link<Token> identifiers = findMemberName(token); 683 Link<Token> identifiers = findMemberName(token);
684 if (identifiers.isEmpty) { 684 if (identifiers.isEmpty) {
685 return listener.expectedDeclaration(start); 685 return listener.expectedDeclaration(start);
686 } 686 }
687 Token afterName = identifiers.head;
688 identifiers = identifiers.tail;
689
690 if (identifiers.isEmpty) {
691 return listener.expectedDeclaration(start);
692 }
687 Token name = identifiers.head; 693 Token name = identifiers.head;
688 identifiers = identifiers.tail; 694 identifiers = identifiers.tail;
689 Token getOrSet; 695 Token getOrSet;
690 if (!identifiers.isEmpty) { 696 if (!identifiers.isEmpty) {
691 String value = identifiers.head.stringValue; 697 String value = identifiers.head.stringValue;
692 if ((identical(value, 'get')) || (identical(value, 'set'))) { 698 if ((identical(value, 'get')) || (identical(value, 'set'))) {
693 getOrSet = identifiers.head; 699 getOrSet = identifiers.head;
694 identifiers = identifiers.tail; 700 identifiers = identifiers.tail;
695 } 701 }
696 } 702 }
697 Token type; 703 Token type;
698 if (!identifiers.isEmpty) { 704 if (!identifiers.isEmpty) {
699 if (isValidTypeReference(identifiers.head)) { 705 if (isValidTypeReference(identifiers.head)) {
700 type = identifiers.head; 706 type = identifiers.head;
701 identifiers = identifiers.tail; 707 identifiers = identifiers.tail;
702 } 708 }
703 } 709 }
704 710
705 token = name.next; 711 token = afterName;
706 bool isField; 712 bool isField;
707 while (true) { 713 while (true) {
708 // Loop to allow the listener to rewrite the token stream for 714 // Loop to allow the listener to rewrite the token stream for
709 // error handling. 715 // error handling.
710 final String value = token.stringValue; 716 final String value = token.stringValue;
711 if ((identical(value, '(')) || (identical(value, '{')) 717 if ((identical(value, '(')) || (identical(value, '{'))
712 || (identical(value, '=>'))) { 718 || (identical(value, '=>'))) {
713 isField = false; 719 isField = false;
714 break; 720 break;
715 } else if ((identical(value, '=')) || (identical(value, ','))) { 721 } else if ((identical(value, '=')) || (identical(value, ','))) {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 listener.endFields(fieldCount, start, semicolon); 865 listener.endFields(fieldCount, start, semicolon);
860 } 866 }
861 return token; 867 return token;
862 } 868 }
863 869
864 Token parseTopLevelMethod(Token start, 870 Token parseTopLevelMethod(Token start,
865 Link<Token> modifiers, 871 Link<Token> modifiers,
866 Token type, 872 Token type,
867 Token getOrSet, 873 Token getOrSet,
868 Token name) { 874 Token name) {
875
869 Token externalModifier; 876 Token externalModifier;
870 for (Token modifier in modifiers) { 877 for (Token modifier in modifiers) {
871 if (externalModifier == null && optional('external', modifier)) { 878 if (externalModifier == null && optional('external', modifier)) {
872 externalModifier = modifier; 879 externalModifier = modifier;
873 } else { 880 } else {
874 listener.reportError( 881 listener.reportError(
875 modifier, MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier}); 882 modifier, MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier});
876 } 883 }
877 } 884 }
878 if (externalModifier != null) { 885 if (externalModifier != null) {
(...skipping 19 matching lines...) Expand all
898 awaitIsKeyword = previousAwaitIsKeyword; 905 awaitIsKeyword = previousAwaitIsKeyword;
899 Token endToken = token; 906 Token endToken = token;
900 token = token.next; 907 token = token.next;
901 if (token.kind == BAD_INPUT_TOKEN) { 908 if (token.kind == BAD_INPUT_TOKEN) {
902 token = listener.unexpected(token); 909 token = listener.unexpected(token);
903 } 910 }
904 listener.endTopLevelMethod(start, getOrSet, endToken); 911 listener.endTopLevelMethod(start, getOrSet, endToken);
905 return token; 912 return token;
906 } 913 }
907 914
915 /// Looks ahead to find the name of a member. Returns a link of the modifiers,
916 /// set/get, (operator) name, and either the start of the method body or the
917 /// end of the declaration.
918 ///
919 /// Examples:
920 ///
921 /// int get foo;
922 /// results in
923 /// [';', 'foo', 'get', 'int']
924 ///
925 ///
926 /// static const List<int> foo = null;
927 /// results in
928 /// ['=', 'foo', 'List', 'const', 'static']
929 ///
930 ///
931 /// get foo async* { return null }
932 /// results in
933 /// ['{', 'foo', 'get']
934 ///
935 ///
936 /// operator *(arg) => null;
937 /// results in
938 /// ['(', '*', 'operator']
939 ///
908 Link<Token> findMemberName(Token token) { 940 Link<Token> findMemberName(Token token) {
909 Token start = token; 941 Token start = token;
910 Link<Token> identifiers = const Link<Token>(); 942 Link<Token> identifiers = const Link<Token>();
943
944 // `true` if 'get' has been seen.
945 bool isGetter = false;
946 // `true` if an identifier has been seen after 'get'.
947 bool hasName = false;
948 // `true` if 'sync' or 'async' has been seen after a name.
949 bool hasAsync = false;
floitsch 2015/01/30 10:48:13 So far this seems unused.
Johnni Winther 2015/01/30 12:16:33 Removed.
950
911 while (!identical(token.kind, EOF_TOKEN)) { 951 while (!identical(token.kind, EOF_TOKEN)) {
912 String value = token.stringValue; 952 String value = token.stringValue;
913 if ((identical(value, '(')) || (identical(value, '{')) 953 if (identical(value, 'get')) {
floitsch 2015/01/30 10:48:13 Why is this "identical"? (it was already there be
Johnni Winther 2015/01/30 12:16:33 The pattern is from when identical on String was f
floitsch 2015/01/30 12:18:14 It might still be, but it feels error-prone to dep
Johnni Winther 2015/01/30 15:40:16 According to http://dartbug.com/15514 the problem
914 || (identical(value, '=>'))) { 954 isGetter = true;
955 } else if (hasName &&
956 (identical(value, 'sync') || identical(value, 'async'))) {
957 // Skip.
958 token = token.next;
floitsch 2015/01/30 10:48:13 shouldn't you set the 'hasAsync' to true?
Johnni Winther 2015/01/30 12:16:33 Wasn't needed after all.
959 value = token.stringValue;
960 if (identical(value, '*')) {
961 // Skip.
962 token = token.next;
963 }
964 continue;
965 } else if (identical(value, '(') ||
966 identical(value, '{') ||
967 identical(value, '=>')) {
915 // A method. 968 // A method.
969 identifiers = identifiers.prepend(token);
916 return identifiers; 970 return identifiers;
917 } else if ((identical(value, '=')) || (identical(value, ';')) 971 } else if (identical(value, '=') ||
918 || (identical(value, ','))) { 972 identical(value, ';') ||
973 identical(value, ',')) {
919 // A field or abstract getter. 974 // A field or abstract getter.
975 identifiers = identifiers.prepend(token);
920 return identifiers; 976 return identifiers;
977 } else if (isGetter) {
978 hasName = true;
921 } 979 }
922 identifiers = identifiers.prepend(token); 980 identifiers = identifiers.prepend(token);
923 if (isValidTypeReference(token)) { 981 if (isValidTypeReference(token)) {
924 // type ... 982 // type ...
925 if (optional('.', token.next)) { 983 if (optional('.', token.next)) {
926 // type '.' ... 984 // type '.' ...
927 if (token.next.next.isIdentifier()) { 985 if (token.next.next.isIdentifier()) {
928 // type '.' identifier 986 // type '.' identifier
929 token = token.next.next; 987 token = token.next.next;
930 } 988 }
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1107 if (isFactoryDeclaration(token)) { 1165 if (isFactoryDeclaration(token)) {
1108 return parseFactoryMethod(token); 1166 return parseFactoryMethod(token);
1109 } 1167 }
1110 Token start = token; 1168 Token start = token;
1111 listener.beginMember(token); 1169 listener.beginMember(token);
1112 1170
1113 Link<Token> identifiers = findMemberName(token); 1171 Link<Token> identifiers = findMemberName(token);
1114 if (identifiers.isEmpty) { 1172 if (identifiers.isEmpty) {
1115 return listener.expectedDeclaration(start); 1173 return listener.expectedDeclaration(start);
1116 } 1174 }
1175 Token afterName = identifiers.head;
1176 identifiers = identifiers.tail;
1177
1178 if (identifiers.isEmpty) {
1179 return listener.expectedDeclaration(start);
1180 }
1117 Token name = identifiers.head; 1181 Token name = identifiers.head;
1118 Token afterName = name.next;
1119 identifiers = identifiers.tail; 1182 identifiers = identifiers.tail;
1120 if (!identifiers.isEmpty) { 1183 if (!identifiers.isEmpty) {
1121 if (optional('operator', identifiers.head)) { 1184 if (optional('operator', identifiers.head)) {
1122 name = identifiers.head; 1185 name = identifiers.head;
1123 identifiers = identifiers.tail; 1186 identifiers = identifiers.tail;
1124 } 1187 }
1125 } 1188 }
1126 Token getOrSet; 1189 Token getOrSet;
1127 if (!identifiers.isEmpty) { 1190 if (!identifiers.isEmpty) {
1128 if (isGetOrSet(identifiers.head)) { 1191 if (isGetOrSet(identifiers.head)) {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 listener.handleOperatorName(operator, token); 1358 listener.handleOperatorName(operator, token);
1296 return token.next; 1359 return token.next;
1297 } else { 1360 } else {
1298 return parseIdentifier(token); 1361 return parseIdentifier(token);
1299 } 1362 }
1300 } 1363 }
1301 1364
1302 Token parseFunction(Token token, Token getOrSet) { 1365 Token parseFunction(Token token, Token getOrSet) {
1303 listener.beginFunction(token); 1366 listener.beginFunction(token);
1304 token = parseModifiers(token); 1367 token = parseModifiers(token);
1305 if (identical(getOrSet, token)) token = token.next; 1368 if (identical(getOrSet, token)) {
1306 if (optional('operator', token)) { 1369 // get <name> => ...
1370 token = token.next;
1371 listener.handleNoType(token);
1372 listener.beginFunctionName(token);
1373 if (optional('operator', token)) {
1374 token = parseOperatorName(token);
1375 } else {
1376 token = parseIdentifier(token);
1377 }
1378 } else if (optional('operator', token)) {
1379 // operator <op> (...
1307 listener.handleNoType(token); 1380 listener.handleNoType(token);
1308 listener.beginFunctionName(token); 1381 listener.beginFunctionName(token);
1309 token = parseOperatorName(token); 1382 token = parseOperatorName(token);
1310 } else { 1383 } else {
1384 // <type>? <get>? <name>
1311 token = parseReturnTypeOpt(token); 1385 token = parseReturnTypeOpt(token);
1312 if (identical(getOrSet, token)) token = token.next; 1386 if (identical(getOrSet, token)) {
1387 token = token.next;
1388 }
1313 listener.beginFunctionName(token); 1389 listener.beginFunctionName(token);
1314 if (optional('operator', token)) { 1390 if (optional('operator', token)) {
1315 token = parseOperatorName(token); 1391 token = parseOperatorName(token);
1316 } else { 1392 } else {
1317 token = parseIdentifier(token); 1393 token = parseIdentifier(token);
1318 } 1394 }
1319 } 1395 }
1320 token = parseQualifiedRestOpt(token); 1396 token = parseQualifiedRestOpt(token);
1321 listener.endFunctionName(token); 1397 listener.endFunctionName(token);
1322 token = parseFormalParametersOpt(token); 1398 token = parseFormalParametersOpt(token);
(...skipping 1275 matching lines...) Expand 10 before | Expand all | Expand 10 after
2598 } 2674 }
2599 listener.handleContinueStatement(hasTarget, continueKeyword, token); 2675 listener.handleContinueStatement(hasTarget, continueKeyword, token);
2600 return expectSemicolon(token); 2676 return expectSemicolon(token);
2601 } 2677 }
2602 2678
2603 Token parseEmptyStatement(Token token) { 2679 Token parseEmptyStatement(Token token) {
2604 listener.handleEmptyStatement(token); 2680 listener.handleEmptyStatement(token);
2605 return expectSemicolon(token); 2681 return expectSemicolon(token);
2606 } 2682 }
2607 } 2683 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/resolution/members.dart ('k') | tests/compiler/dart2js/async_await_syntax.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698