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 /** | 7 /** |
8 * An event generating parser of Dart programs. This parser expects | 8 * An event generating parser of Dart programs. This parser expects |
9 * all tokens in a linked list (aka a token stream). | 9 * all tokens in a linked list (aka a token stream). |
10 * | 10 * |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 } | 45 } |
46 | 46 |
47 Token parseTopLevelDeclaration(Token token) { | 47 Token parseTopLevelDeclaration(Token token) { |
48 token = parseMetadataStar(token); | 48 token = parseMetadataStar(token); |
49 final String value = token.stringValue; | 49 final String value = token.stringValue; |
50 if (identical(value, 'interface')) { | 50 if (identical(value, 'interface')) { |
51 return parseInterface(token); | 51 return parseInterface(token); |
52 } else if ((identical(value, 'abstract')) || (identical(value, 'class'))) { | 52 } else if ((identical(value, 'abstract')) || (identical(value, 'class'))) { |
53 return parseClass(token); | 53 return parseClass(token); |
54 } else if (identical(value, 'typedef')) { | 54 } else if (identical(value, 'typedef')) { |
55 return parseNamedFunctionAlias(token); | 55 return parseTypedef(token); |
56 } else if (identical(value, '#')) { | 56 } else if (identical(value, '#')) { |
57 return parseScriptTags(token); | 57 return parseScriptTags(token); |
58 } else if (identical(value, 'library')) { | 58 } else if (identical(value, 'library')) { |
59 return parseLibraryName(token); | 59 return parseLibraryName(token); |
60 } else if (identical(value, 'import')) { | 60 } else if (identical(value, 'import')) { |
61 return parseImport(token); | 61 return parseImport(token); |
62 } else if (identical(value, 'export')) { | 62 } else if (identical(value, 'export')) { |
63 return parseExport(token); | 63 return parseExport(token); |
64 } else if (identical(value, 'part')) { | 64 } else if (identical(value, 'part')) { |
65 return parsePartOrPartOf(token); | 65 return parsePartOrPartOf(token); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
154 token = parseIdentifier(token); | 154 token = parseIdentifier(token); |
155 int count = 1; | 155 int count = 1; |
156 while (optional(',', token)) { | 156 while (optional(',', token)) { |
157 token = parseIdentifier(token.next); | 157 token = parseIdentifier(token.next); |
158 count++; | 158 count++; |
159 } | 159 } |
160 listener.endIdentifierList(count); | 160 listener.endIdentifierList(count); |
161 return token; | 161 return token; |
162 } | 162 } |
163 | 163 |
164 /// type (, type)* | |
165 Token parseTypeList(Token token) { | |
166 listener.beginTypeList(token); | |
167 token = parseType(token); | |
168 int count = 1; | |
169 while (optional(',', token)) { | |
170 token = parseType(token.next); | |
171 count++; | |
172 } | |
173 listener.endTypeList(count); | |
174 return token; | |
175 } | |
176 | |
164 Token parsePartOrPartOf(Token token) { | 177 Token parsePartOrPartOf(Token token) { |
165 assert(optional('part', token)); | 178 assert(optional('part', token)); |
166 if (optional('of', token.next)) { | 179 if (optional('of', token.next)) { |
167 return parsePartOf(token); | 180 return parsePartOf(token); |
168 } else { | 181 } else { |
169 return parsePart(token); | 182 return parsePart(token); |
170 } | 183 } |
171 } | 184 } |
172 | 185 |
173 Token parsePart(Token token) { | 186 Token parsePart(Token token) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 token = parseInterfaceBody(token); | 252 token = parseInterfaceBody(token); |
240 listener.endInterface(supertypeCount, interfaceKeyword, | 253 listener.endInterface(supertypeCount, interfaceKeyword, |
241 extendsKeyword, token); | 254 extendsKeyword, token); |
242 return token.next; | 255 return token.next; |
243 } | 256 } |
244 | 257 |
245 Token parseInterfaceBody(Token token) { | 258 Token parseInterfaceBody(Token token) { |
246 return parseClassBody(token); | 259 return parseClassBody(token); |
247 } | 260 } |
248 | 261 |
249 Token parseNamedFunctionAlias(Token token) { | 262 Token parseTypedef(Token token) { |
250 Token typedefKeyword = token; | 263 Token typedefKeyword = token; |
251 listener.beginFunctionTypeAlias(token); | 264 // Figure out if we're dealing with a function type alias by |
252 token = parseReturnTypeOpt(token.next); | 265 // peeking ahead at the token following the name and optional type |
253 token = parseIdentifier(token); | 266 // parameters. If that is an = token, we found something that |
254 token = parseTypeVariablesOpt(token); | 267 // isn't a function type alias. |
255 token = parseFormalParameters(token); | 268 bool isFunctionTypeAlias = true; |
ahe
2013/01/16 09:37:57
Try using peekAfterType.
| |
256 listener.endFunctionTypeAlias(typedefKeyword, token); | 269 if (identical(token.next.kind, IDENTIFIER_TOKEN)) { |
ahe
2013/01/16 09:37:57
token.next.isIdentifier() (it's complicated)
| |
270 Token peek = token.next.next; | |
271 if (identical(peek.kind, LT_TOKEN)) { | |
ahe
2013/01/16 09:37:57
optional('<', peek)
| |
272 BeginGroupToken beginGroupToken = peek; | |
273 Token endGroupToken = beginGroupToken.endGroup; | |
274 if (endGroupToken != null) peek = endGroupToken.next; | |
275 } | |
276 // Function type aliases do not use = so the name and type | |
277 // parameters we've peeked past are part of the return type | |
278 // specification instead. | |
279 isFunctionTypeAlias = !optional('=', peek); | |
280 } | |
281 | |
282 if (isFunctionTypeAlias) { | |
283 listener.beginFunctionTypeAlias(token); | |
284 token = parseReturnTypeOpt(token.next); | |
285 token = parseIdentifier(token); | |
286 token = parseTypeVariablesOpt(token); | |
287 token = parseFormalParameters(token); | |
288 listener.endFunctionTypeAlias(typedefKeyword, token); | |
289 } else { | |
290 listener.beginNamedMixinApplication(token); | |
291 token = parseIdentifier(token.next); | |
292 token = parseTypeVariablesOpt(token); | |
293 token = expect('=', token); | |
294 token = parseMixinApplication(token); | |
295 listener.endNamedMixinApplication(typedefKeyword, token); | |
296 } | |
257 return expect(';', token); | 297 return expect(';', token); |
258 } | 298 } |
259 | 299 |
300 Token parseMixinApplication(Token token) { | |
301 listener.beginMixinApplication(token); | |
302 token = parseModifiers(token); | |
303 token = parseType(token); | |
304 token = expect('with', token); | |
305 token = parseTypeList(token); | |
306 listener.endMixinApplication(); | |
307 return token; | |
308 } | |
309 | |
260 Token parseReturnTypeOpt(Token token) { | 310 Token parseReturnTypeOpt(Token token) { |
261 if (identical(token.stringValue, 'void')) { | 311 if (identical(token.stringValue, 'void')) { |
262 listener.handleVoidKeyword(token); | 312 listener.handleVoidKeyword(token); |
263 return token.next; | 313 return token.next; |
264 } else { | 314 } else { |
265 return parseTypeOpt(token); | 315 return parseTypeOpt(token); |
266 } | 316 } |
267 } | 317 } |
268 | 318 |
269 Token parseFormalParametersOpt(Token token) { | 319 Token parseFormalParametersOpt(Token token) { |
(...skipping 1885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2155 } | 2205 } |
2156 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 2206 listener.handleContinueStatement(hasTarget, continueKeyword, token); |
2157 return expectSemicolon(token); | 2207 return expectSemicolon(token); |
2158 } | 2208 } |
2159 | 2209 |
2160 Token parseEmptyStatement(Token token) { | 2210 Token parseEmptyStatement(Token token) { |
2161 listener.handleEmptyStatement(token); | 2211 listener.handleEmptyStatement(token); |
2162 return expectSemicolon(token); | 2212 return expectSemicolon(token); |
2163 } | 2213 } |
2164 } | 2214 } |
OLD | NEW |