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 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 |