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 '../fasta_codes.dart' show Code, Message, Template; | 7 import '../fasta_codes.dart' show Code, Message, Template; |
8 | 8 |
9 import '../fasta_codes.dart' as fasta; | 9 import '../fasta_codes.dart' as fasta; |
10 | 10 |
(...skipping 1158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1169 } | 1169 } |
1170 continue optional; | 1170 continue optional; |
1171 | 1171 |
1172 case TypeContinuation.ExpressionStatementOrDeclaration: | 1172 case TypeContinuation.ExpressionStatementOrDeclaration: |
1173 assert(begin.isIdentifier || identical(begin.stringValue, 'void')); | 1173 assert(begin.isIdentifier || identical(begin.stringValue, 'void')); |
1174 if (!inPlainSync && optional("await", begin)) { | 1174 if (!inPlainSync && optional("await", begin)) { |
1175 return parseExpressionStatement(begin); | 1175 return parseExpressionStatement(begin); |
1176 } | 1176 } |
1177 | 1177 |
1178 if (looksLikeType && token.isIdentifier) { | 1178 if (looksLikeType && token.isIdentifier) { |
1179 // If the identifier token has a type substitution comment /*=T*/, | |
1180 // then the set of tokens type tokens should be replaced with the | |
1181 // tokens parsed from the comment. | |
1182 Token afterId = token.next; | 1179 Token afterId = token.next; |
1183 | 1180 |
1184 begin = | |
1185 listener.replaceTokenWithGenericCommentTypeAssign(begin, token); | |
ahe
2017/07/21 16:02:19
This has already been called when we analyze the t
| |
1186 | |
1187 int afterIdKind = afterId.kind; | 1181 int afterIdKind = afterId.kind; |
1188 if (looksLikeVariableDeclarationEnd(afterIdKind)) { | 1182 if (looksLikeVariableDeclarationEnd(afterIdKind)) { |
1189 // We are looking at `type identifier` followed by | 1183 // We are looking at `type identifier` followed by |
1190 // `(',' | '=' | ';')`. | 1184 // `(',' | '=' | ';')`. |
1191 | 1185 |
1192 // TODO(ahe): Generate type events and call | 1186 // TODO(ahe): Generate type events and call |
1193 // parseVariablesDeclarationRest instead. | 1187 // parseVariablesDeclarationRest instead. |
1194 return parseVariablesDeclaration(begin); | 1188 return parseVariablesDeclaration(begin); |
1195 } else if (OPEN_PAREN_TOKEN == afterIdKind) { | 1189 } else if (OPEN_PAREN_TOKEN == afterIdKind) { |
1196 // We are looking at `type identifier '('`. | 1190 // We are looking at `type identifier '('`. |
1197 if (looksLikeFunctionBody(closeBraceTokenFor(afterId).next)) { | 1191 if (looksLikeFunctionBody(closeBraceTokenFor(afterId).next)) { |
1198 // We are looking at `type identifier '(' ... ')'` followed | 1192 // We are looking at `type identifier '(' ... ')'` followed |
1199 // `( '{' | '=>' | 'async' | 'sync' )`. | 1193 // `( '{' | '=>' | 'async' | 'sync' )`. |
1200 return parseLocalFunctionDeclaration(begin); | 1194 |
1195 // Although it looks like there are no type variables here, they | |
1196 // may get injected from a comment. | |
1197 Token formals = parseTypeVariablesOpt(afterId); | |
1198 | |
1199 listener.beginLocalFunctionDeclaration(begin); | |
1200 listener.handleModifiers(0); | |
1201 if (voidToken != null) { | |
1202 listener.handleVoidKeyword(voidToken); | |
1203 } else { | |
1204 commitType(); | |
1205 } | |
1206 listener.beginFunctionName(token); | |
1207 token = parseIdentifier( | |
1208 token, IdentifierContext.localFunctionDeclaration); | |
1209 listener.endFunctionName(begin, token); | |
1210 return parseLocalFunctionDeclarationFromFormals(formals); | |
1201 } | 1211 } |
1202 } else if (identical(afterIdKind, LT_TOKEN)) { | 1212 } else if (identical(afterIdKind, LT_TOKEN)) { |
1203 // We are looking at `type identifier '<'`. | 1213 // We are looking at `type identifier '<'`. |
1204 Token afterTypeVariables = closeBraceTokenFor(afterId)?.next; | 1214 Token formals = closeBraceTokenFor(afterId)?.next; |
1205 if (afterTypeVariables != null && | 1215 if (formals != null && optional("(", formals)) { |
1206 optional("(", afterTypeVariables)) { | 1216 if (looksLikeFunctionBody(closeBraceTokenFor(formals).next)) { |
1207 if (looksLikeFunctionBody( | |
1208 closeBraceTokenFor(afterTypeVariables).next)) { | |
1209 // We are looking at "type identifier '<' ... '>' '(' ... ')'" | 1217 // We are looking at "type identifier '<' ... '>' '(' ... ')'" |
1210 // followed by '{', '=>', 'async', or 'sync'. | 1218 // followed by '{', '=>', 'async', or 'sync'. |
1211 return parseLocalFunctionDeclaration(begin); | 1219 parseTypeVariablesOpt(afterId); |
1220 listener.beginLocalFunctionDeclaration(begin); | |
1221 listener.handleModifiers(0); | |
1222 if (voidToken != null) { | |
1223 listener.handleVoidKeyword(voidToken); | |
1224 } else { | |
1225 commitType(); | |
1226 } | |
1227 listener.beginFunctionName(token); | |
1228 token = parseIdentifier( | |
1229 token, IdentifierContext.localFunctionDeclaration); | |
1230 listener.endFunctionName(begin, token); | |
1231 return parseLocalFunctionDeclarationFromFormals(formals); | |
1212 } | 1232 } |
1213 } | 1233 } |
1214 } | 1234 } |
1215 // Fall-through to expression statement. | 1235 // Fall-through to expression statement. |
1216 } else { | 1236 } else { |
1217 token = begin; | 1237 token = begin; |
1218 if (optional(':', token.next)) { | 1238 if (optional(':', token.next)) { |
1219 return parseLabeledStatement(token); | 1239 return parseLabeledStatement(token); |
1220 } else if (optional('(', token.next)) { | 1240 } else if (optional('(', token.next)) { |
1221 if (looksLikeFunctionBody(closeBraceTokenFor(token.next).next)) { | 1241 if (looksLikeFunctionBody(closeBraceTokenFor(token.next).next)) { |
1222 return parseLocalFunctionDeclaration(token); | 1242 // We are looking at `identifier '(' ... ')'` followed by `'{'`, |
1243 // `'=>'`, `'async'`, or `'sync'`. | |
1244 | |
1245 // Although it looks like there are no type variables here, they | |
1246 // may get injected from a comment. | |
1247 Token formals = parseTypeVariablesOpt(token.next); | |
1248 | |
1249 listener.beginLocalFunctionDeclaration(token); | |
1250 listener.handleModifiers(0); | |
1251 listener.handleNoType(token); | |
1252 listener.beginFunctionName(token); | |
1253 token = parseIdentifier( | |
1254 token, IdentifierContext.localFunctionDeclaration); | |
1255 listener.endFunctionName(begin, token); | |
1256 return parseLocalFunctionDeclarationFromFormals(formals); | |
1223 } | 1257 } |
1224 } else if (optional('<', token.next)) { | 1258 } else if (optional('<', token.next)) { |
1225 Token afterTypeVariables = closeBraceTokenFor(token.next)?.next; | 1259 Token afterTypeVariables = closeBraceTokenFor(token.next)?.next; |
1226 if (afterTypeVariables != null && | 1260 if (afterTypeVariables != null && |
1227 optional("(", afterTypeVariables)) { | 1261 optional("(", afterTypeVariables)) { |
1228 if (looksLikeFunctionBody( | 1262 if (looksLikeFunctionBody( |
1229 closeBraceTokenFor(afterTypeVariables).next)) { | 1263 closeBraceTokenFor(afterTypeVariables).next)) { |
1230 return parseLocalFunctionDeclaration(token); | 1264 // We are looking at `identifier '<' ... '>' '(' ... ')'` |
1265 // followed by `'{'`, `'=>'`, `'async'`, or `'sync'`. | |
1266 parseTypeVariablesOpt(token.next); | |
1267 listener.beginLocalFunctionDeclaration(token); | |
1268 listener.handleModifiers(0); | |
1269 listener.handleNoType(token); | |
1270 listener.beginFunctionName(token); | |
danrubel
2017/07/21 17:11:20
From this line down to the return statement looks
ahe
2017/08/07 11:45:27
You inspired me to go a bit further, and I decided
| |
1271 token = parseIdentifier( | |
1272 token, IdentifierContext.localFunctionDeclaration); | |
1273 listener.endFunctionName(begin, token); | |
1274 return parseLocalFunctionDeclarationFromFormals( | |
1275 afterTypeVariables); | |
1231 } | 1276 } |
1232 } | 1277 } |
1233 // Fall through to expression statement. | 1278 // Fall through to expression statement. |
1234 } | 1279 } |
1235 } | 1280 } |
1236 return parseExpressionStatement(begin); | 1281 return parseExpressionStatement(begin); |
1237 | 1282 |
1238 case TypeContinuation.ExpressionStatementOrConstDeclaration: | 1283 case TypeContinuation.ExpressionStatementOrConstDeclaration: |
1239 Token identifier; | 1284 Token identifier; |
1240 if (looksLikeType && token.isIdentifier) { | 1285 if (looksLikeType && token.isIdentifier) { |
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2328 token = parseFormalParameters(token, MemberKind.Local); | 2373 token = parseFormalParameters(token, MemberKind.Local); |
2329 AsyncModifier savedAsyncModifier = asyncState; | 2374 AsyncModifier savedAsyncModifier = asyncState; |
2330 token = parseAsyncModifier(token); | 2375 token = parseAsyncModifier(token); |
2331 bool isBlock = optional('{', token); | 2376 bool isBlock = optional('{', token); |
2332 token = parseFunctionBody(token, true, false); | 2377 token = parseFunctionBody(token, true, false); |
2333 asyncState = savedAsyncModifier; | 2378 asyncState = savedAsyncModifier; |
2334 listener.endFunctionExpression(beginToken, token); | 2379 listener.endFunctionExpression(beginToken, token); |
2335 return isBlock ? token.next : token; | 2380 return isBlock ? token.next : token; |
2336 } | 2381 } |
2337 | 2382 |
2338 Token parseLocalFunctionDeclaration(Token token) { | 2383 /// Parses the rest of a local function declaration starting from formal |
2339 listener.beginLocalFunctionDeclaration(token); | 2384 /// parameters. |
2340 Token beginToken = token; | 2385 /// |
2341 token = parseModifiers(token, MemberKind.Local); | 2386 /// Precondition: the parser has previously generated these events: |
2342 listener.beginFunctionName(token); | 2387 /// |
2343 token = parseIdentifier(token, IdentifierContext.localFunctionDeclaration); | 2388 /// - Type variables. |
2344 token = parseQualifiedRestOpt( | 2389 /// - beginLocalFunctionDeclaration. |
2345 token, IdentifierContext.localFunctionDeclarationContinuation); | 2390 /// - Modifiers. |
2346 listener.endFunctionName(beginToken, token); | 2391 /// - Return type. |
2347 token = parseTypeVariablesOpt(token); | 2392 /// - Function name. |
2393 Token parseLocalFunctionDeclarationFromFormals(Token token) { | |
2348 token = parseFormalParametersOpt(token, MemberKind.Local); | 2394 token = parseFormalParametersOpt(token, MemberKind.Local); |
2349 token = parseInitializersOpt(token); | 2395 token = parseInitializersOpt(token); |
2350 AsyncModifier savedAsyncModifier = asyncState; | 2396 AsyncModifier savedAsyncModifier = asyncState; |
2351 token = parseAsyncModifier(token); | 2397 token = parseAsyncModifier(token); |
2352 token = parseFunctionBody(token, false, true); | 2398 token = parseFunctionBody(token, false, true); |
2353 asyncState = savedAsyncModifier; | 2399 asyncState = savedAsyncModifier; |
2354 token = token.next; | 2400 token = token.next; |
2355 listener.endLocalFunctionDeclaration(token); | 2401 listener.endLocalFunctionDeclaration(token); |
2356 return token; | 2402 return token; |
2357 } | 2403 } |
(...skipping 1645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4003 } | 4049 } |
4004 | 4050 |
4005 Token reportUnexpectedToken(Token token) { | 4051 Token reportUnexpectedToken(Token token) { |
4006 return reportUnrecoverableErrorWithToken( | 4052 return reportUnrecoverableErrorWithToken( |
4007 token, fasta.templateUnexpectedToken); | 4053 token, fasta.templateUnexpectedToken); |
4008 } | 4054 } |
4009 } | 4055 } |
4010 | 4056 |
4011 // TODO(ahe): Remove when analyzer supports generalized function syntax. | 4057 // TODO(ahe): Remove when analyzer supports generalized function syntax. |
4012 typedef _MessageWithArgument<T> = Message Function(T); | 4058 typedef _MessageWithArgument<T> = Message Function(T); |
OLD | NEW |