Chromium Code Reviews| 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 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |