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

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: Updated cf. comments. 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>();
911 while (!identical(token.kind, EOF_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
949 while (token.kind != EOF_TOKEN) {
912 String value = token.stringValue; 950 String value = token.stringValue;
913 if ((identical(value, '(')) || (identical(value, '{')) 951 if (value == 'get') {
914 || (identical(value, '=>'))) { 952 isGetter = true;
953 } else if (hasName &&
954 (value == 'sync' || value == 'async')) {
ahe 2016/04/25 12:54:15 FWIW, for sake of performance, it's important that
Johnni Winther 2016/04/25 13:36:02 I was under the imprecision that the VM had optimi
ahe 2016/04/25 13:39:53 It's probably optimized with something like this:
955 // Skip.
956 token = token.next;
957 value = token.stringValue;
958 if (value == '*') {
959 // Skip.
960 token = token.next;
961 }
962 continue;
963 } else if (value == '(' ||
964 value == '{' ||
965 value == '=>') {
915 // A method. 966 // A method.
967 identifiers = identifiers.prepend(token);
916 return identifiers; 968 return identifiers;
917 } else if ((identical(value, '=')) || (identical(value, ';')) 969 } else if (value == '=' ||
918 || (identical(value, ','))) { 970 value == ';' ||
971 value == ',') {
919 // A field or abstract getter. 972 // A field or abstract getter.
973 identifiers = identifiers.prepend(token);
920 return identifiers; 974 return identifiers;
975 } else if (isGetter) {
976 hasName = true;
921 } 977 }
922 identifiers = identifiers.prepend(token); 978 identifiers = identifiers.prepend(token);
923 if (isValidTypeReference(token)) { 979 if (isValidTypeReference(token)) {
924 // type ... 980 // type ...
925 if (optional('.', token.next)) { 981 if (optional('.', token.next)) {
926 // type '.' ... 982 // type '.' ...
927 if (token.next.next.isIdentifier()) { 983 if (token.next.next.isIdentifier()) {
928 // type '.' identifier 984 // type '.' identifier
929 token = token.next.next; 985 token = token.next.next;
930 } 986 }
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1107 if (isFactoryDeclaration(token)) { 1163 if (isFactoryDeclaration(token)) {
1108 return parseFactoryMethod(token); 1164 return parseFactoryMethod(token);
1109 } 1165 }
1110 Token start = token; 1166 Token start = token;
1111 listener.beginMember(token); 1167 listener.beginMember(token);
1112 1168
1113 Link<Token> identifiers = findMemberName(token); 1169 Link<Token> identifiers = findMemberName(token);
1114 if (identifiers.isEmpty) { 1170 if (identifiers.isEmpty) {
1115 return listener.expectedDeclaration(start); 1171 return listener.expectedDeclaration(start);
1116 } 1172 }
1173 Token afterName = identifiers.head;
1174 identifiers = identifiers.tail;
1175
1176 if (identifiers.isEmpty) {
1177 return listener.expectedDeclaration(start);
1178 }
1117 Token name = identifiers.head; 1179 Token name = identifiers.head;
1118 Token afterName = name.next;
1119 identifiers = identifiers.tail; 1180 identifiers = identifiers.tail;
1120 if (!identifiers.isEmpty) { 1181 if (!identifiers.isEmpty) {
1121 if (optional('operator', identifiers.head)) { 1182 if (optional('operator', identifiers.head)) {
1122 name = identifiers.head; 1183 name = identifiers.head;
1123 identifiers = identifiers.tail; 1184 identifiers = identifiers.tail;
1124 } 1185 }
1125 } 1186 }
1126 Token getOrSet; 1187 Token getOrSet;
1127 if (!identifiers.isEmpty) { 1188 if (!identifiers.isEmpty) {
1128 if (isGetOrSet(identifiers.head)) { 1189 if (isGetOrSet(identifiers.head)) {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 listener.handleOperatorName(operator, token); 1356 listener.handleOperatorName(operator, token);
1296 return token.next; 1357 return token.next;
1297 } else { 1358 } else {
1298 return parseIdentifier(token); 1359 return parseIdentifier(token);
1299 } 1360 }
1300 } 1361 }
1301 1362
1302 Token parseFunction(Token token, Token getOrSet) { 1363 Token parseFunction(Token token, Token getOrSet) {
1303 listener.beginFunction(token); 1364 listener.beginFunction(token);
1304 token = parseModifiers(token); 1365 token = parseModifiers(token);
1305 if (identical(getOrSet, token)) token = token.next; 1366 if (identical(getOrSet, token)) {
1306 if (optional('operator', token)) { 1367 // get <name> => ...
1368 token = token.next;
1369 listener.handleNoType(token);
1370 listener.beginFunctionName(token);
1371 if (optional('operator', token)) {
1372 token = parseOperatorName(token);
1373 } else {
1374 token = parseIdentifier(token);
1375 }
1376 } else if (optional('operator', token)) {
1377 // operator <op> (...
1307 listener.handleNoType(token); 1378 listener.handleNoType(token);
1308 listener.beginFunctionName(token); 1379 listener.beginFunctionName(token);
1309 token = parseOperatorName(token); 1380 token = parseOperatorName(token);
1310 } else { 1381 } else {
1382 // <type>? <get>? <name>
1311 token = parseReturnTypeOpt(token); 1383 token = parseReturnTypeOpt(token);
1312 if (identical(getOrSet, token)) token = token.next; 1384 if (identical(getOrSet, token)) {
1385 token = token.next;
1386 }
1313 listener.beginFunctionName(token); 1387 listener.beginFunctionName(token);
1314 if (optional('operator', token)) { 1388 if (optional('operator', token)) {
1315 token = parseOperatorName(token); 1389 token = parseOperatorName(token);
1316 } else { 1390 } else {
1317 token = parseIdentifier(token); 1391 token = parseIdentifier(token);
1318 } 1392 }
1319 } 1393 }
1320 token = parseQualifiedRestOpt(token); 1394 token = parseQualifiedRestOpt(token);
1321 listener.endFunctionName(token); 1395 listener.endFunctionName(token);
1322 token = parseFormalParametersOpt(token); 1396 token = parseFormalParametersOpt(token);
(...skipping 1275 matching lines...) Expand 10 before | Expand all | Expand 10 after
2598 } 2672 }
2599 listener.handleContinueStatement(hasTarget, continueKeyword, token); 2673 listener.handleContinueStatement(hasTarget, continueKeyword, token);
2600 return expectSemicolon(token); 2674 return expectSemicolon(token);
2601 } 2675 }
2602 2676
2603 Token parseEmptyStatement(Token token) { 2677 Token parseEmptyStatement(Token token) {
2604 listener.handleEmptyStatement(token); 2678 listener.handleEmptyStatement(token);
2605 return expectSemicolon(token); 2679 return expectSemicolon(token);
2606 } 2680 }
2607 } 2681 }
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