OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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.diet_listener; | 5 library fasta.diet_listener; |
6 | 6 |
7 import 'package:front_end/src/fasta/kernel/kernel_ast_factory.dart' | 7 import 'package:front_end/src/fasta/kernel/kernel_ast_factory.dart' |
8 show KernelAstFactory; | 8 show KernelAstFactory; |
9 | 9 |
10 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart' | 10 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart' |
11 show TypeInferenceEngine; | 11 show TypeInferenceEngine; |
12 | 12 |
13 import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart' | 13 import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart' |
14 show TypeInferenceListener; | 14 show TypeInferenceListener; |
15 | 15 |
16 import 'package:kernel/ast.dart' show AsyncMarker; | 16 import 'package:kernel/ast.dart' show AsyncMarker; |
17 | 17 |
18 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; | 18 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; |
19 | 19 |
20 import 'package:kernel/core_types.dart' show CoreTypes; | 20 import 'package:kernel/core_types.dart' show CoreTypes; |
21 | 21 |
22 import '../fasta_codes.dart' show FastaMessage, codeExpectedBlockToSkip; | 22 import '../fasta_codes.dart' show FastaMessage, codeExpectedBlockToSkip; |
23 | 23 |
24 import '../parser/parser.dart' show Parser, optional; | 24 import '../parser/parser.dart' show MemberKind, Parser, optional; |
25 | 25 |
26 import '../scanner/token.dart' show BeginGroupToken; | 26 import '../scanner/token.dart' show BeginGroupToken; |
27 | 27 |
28 import '../../scanner/token.dart' show Token; | 28 import '../../scanner/token.dart' show Token; |
29 | 29 |
30 import '../parser/dart_vm_native.dart' show removeNativeClause; | 30 import '../parser/dart_vm_native.dart' show removeNativeClause; |
31 | 31 |
32 import '../util/link.dart' show Link; | 32 import '../util/link.dart' show Link; |
33 | 33 |
34 import '../errors.dart' show Crash, InputError, inputError, internalError; | 34 import '../errors.dart' show Crash, InputError, inputError, internalError; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 void handleNoFieldInitializer(Token token) { | 147 void handleNoFieldInitializer(Token token) { |
148 debugEvent("NoFieldInitializer"); | 148 debugEvent("NoFieldInitializer"); |
149 } | 149 } |
150 | 150 |
151 @override | 151 @override |
152 void handleNoTypeVariables(Token token) { | 152 void handleNoTypeVariables(Token token) { |
153 debugEvent("NoTypeVariables"); | 153 debugEvent("NoTypeVariables"); |
154 } | 154 } |
155 | 155 |
156 @override | 156 @override |
157 void endFormalParameters(int count, Token beginToken, Token endToken) { | 157 void endFormalParameters( |
| 158 int count, Token beginToken, Token endToken, MemberKind kind) { |
158 debugEvent("FormalParameters"); | 159 debugEvent("FormalParameters"); |
159 assert(count == 0); // Count is always 0 as the diet parser skips formals. | 160 assert(count == 0); // Count is always 0 as the diet parser skips formals. |
160 if (identical(peek(), "-") && identical(beginToken.next, endToken)) { | 161 if (kind != MemberKind.GeneralizedFunctionType && |
| 162 identical(peek(), "-") && |
| 163 identical(beginToken.next, endToken)) { |
161 pop(); | 164 pop(); |
162 push("unary-"); | 165 push("unary-"); |
163 } | 166 } |
164 push(beginToken); | 167 push(beginToken); |
165 } | 168 } |
166 | 169 |
167 @override | 170 @override |
168 void handleNoFormalParameters(Token token) { | 171 void handleNoFormalParameters(Token token, MemberKind kind) { |
169 debugEvent("NoFormalParameters"); | 172 debugEvent("NoFormalParameters"); |
170 if (identical(peek(), "-")) { | 173 if (identical(peek(), "-")) { |
171 pop(); | 174 pop(); |
172 push("unary-"); | 175 push("unary-"); |
173 } | 176 } |
174 push(token); | 177 push(token); |
175 } | 178 } |
176 | 179 |
177 @override | 180 @override |
178 void handleFunctionType(Token functionToken, Token endToken) { | 181 void handleFunctionType(Token functionToken, Token endToken) { |
179 debugEvent("FunctionType"); | 182 debugEvent("FunctionType"); |
| 183 discard(1); |
180 } | 184 } |
181 | 185 |
182 @override | 186 @override |
183 void endFunctionTypeAlias( | 187 void endFunctionTypeAlias( |
184 Token typedefKeyword, Token equals, Token endToken) { | 188 Token typedefKeyword, Token equals, Token endToken) { |
185 debugEvent("FunctionTypeAlias"); | 189 debugEvent("FunctionTypeAlias"); |
186 if (stack.length == 1) { | 190 if (equals != null) { |
187 // TODO(ahe): This happens when recovering from `typedef I = A;`. Find a | 191 // This is a `typedef NAME = TYPE`. |
188 // different way to track tokens of formal parameters. | |
189 discard(1); // Name. | 192 discard(1); // Name. |
190 } else { | 193 } else { |
191 discard(2); // Name + endToken. | 194 discard(2); // Name + endToken. |
192 } | 195 } |
193 checkEmpty(typedefKeyword.charOffset); | 196 checkEmpty(typedefKeyword.charOffset); |
194 } | 197 } |
195 | 198 |
196 @override | 199 @override |
197 void endFields( | 200 void endFields(int count, Token beginToken, Token endToken) { |
198 int count, Token covariantToken, Token beginToken, Token endToken) { | |
199 debugEvent("Fields"); | 201 debugEvent("Fields"); |
200 List<String> names = popList(count); | 202 List<String> names = popList(count); |
201 Builder builder = lookupBuilder(beginToken, null, names.first); | 203 Builder builder = lookupBuilder(beginToken, null, names.first); |
202 buildFields(beginToken, false, builder); | 204 buildFields(beginToken, false, builder); |
203 } | 205 } |
204 | 206 |
205 @override | 207 @override |
206 void handleAsyncModifier(Token asyncToken, Token startToken) { | 208 void handleAsyncModifier(Token asyncToken, Token startToken) { |
207 debugEvent("AsyncModifier"); | 209 debugEvent("AsyncModifier"); |
208 } | 210 } |
209 | 211 |
210 @override | 212 @override |
211 void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) { | 213 void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) { |
212 debugEvent("TopLevelMethod"); | 214 debugEvent("TopLevelMethod"); |
213 Token bodyToken = pop(); | 215 Token bodyToken = pop(); |
214 String name = pop(); | 216 String name = pop(); |
215 checkEmpty(beginToken.charOffset); | 217 checkEmpty(beginToken.charOffset); |
216 buildFunctionBody(bodyToken, lookupBuilder(beginToken, getOrSet, name)); | 218 buildFunctionBody(bodyToken, lookupBuilder(beginToken, getOrSet, name), |
| 219 MemberKind.TopLevelMethod); |
217 } | 220 } |
218 | 221 |
219 @override | 222 @override |
220 void handleNoFunctionBody(Token token) { | 223 void handleNoFunctionBody(Token token) { |
221 debugEvent("NoFunctionBody"); | 224 debugEvent("NoFunctionBody"); |
222 } | 225 } |
223 | 226 |
224 @override | 227 @override |
225 void endTopLevelFields(int count, Token beginToken, Token endToken) { | 228 void endTopLevelFields(int count, Token beginToken, Token endToken) { |
226 debugEvent("TopLevelFields"); | 229 debugEvent("TopLevelFields"); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 @override | 369 @override |
367 void endFactoryMethod( | 370 void endFactoryMethod( |
368 Token beginToken, Token factoryKeyword, Token endToken) { | 371 Token beginToken, Token factoryKeyword, Token endToken) { |
369 debugEvent("FactoryMethod"); | 372 debugEvent("FactoryMethod"); |
370 BeginGroupToken bodyToken = pop(); | 373 BeginGroupToken bodyToken = pop(); |
371 String name = pop(); | 374 String name = pop(); |
372 checkEmpty(beginToken.charOffset); | 375 checkEmpty(beginToken.charOffset); |
373 if (bodyToken == null || optional("=", bodyToken.endGroup.next)) { | 376 if (bodyToken == null || optional("=", bodyToken.endGroup.next)) { |
374 return; | 377 return; |
375 } | 378 } |
376 buildFunctionBody(bodyToken, lookupBuilder(beginToken, null, name)); | 379 buildFunctionBody( |
| 380 bodyToken, lookupBuilder(beginToken, null, name), MemberKind.Factory); |
377 } | 381 } |
378 | 382 |
379 @override | 383 @override |
380 void endRedirectingFactoryBody(Token beginToken, Token endToken) { | 384 void endRedirectingFactoryBody(Token beginToken, Token endToken) { |
381 debugEvent("RedirectingFactoryBody"); | 385 debugEvent("RedirectingFactoryBody"); |
382 discard(1); // ConstructorReference. | 386 discard(1); // ConstructorReference. |
383 } | 387 } |
384 | 388 |
385 @override | 389 @override |
386 void endMethod(Token getOrSet, Token beginToken, Token endToken) { | 390 void endMethod(Token getOrSet, Token beginToken, Token endToken) { |
387 debugEvent("Method"); | 391 debugEvent("Method"); |
388 Token bodyToken = pop(); | 392 Token bodyToken = pop(); |
389 String name = pop(); | 393 String name = pop(); |
390 checkEmpty(beginToken.charOffset); | 394 checkEmpty(beginToken.charOffset); |
391 if (bodyToken == null) { | 395 if (bodyToken == null) { |
392 return; | 396 return; |
393 } | 397 } |
394 buildFunctionBody(bodyToken, lookupBuilder(beginToken, getOrSet, name)); | 398 ProcedureBuilder builder = lookupBuilder(beginToken, getOrSet, name); |
| 399 buildFunctionBody( |
| 400 bodyToken, |
| 401 builder, |
| 402 builder.isStatic |
| 403 ? MemberKind.StaticMethod |
| 404 : MemberKind.NonStaticMethod); |
395 } | 405 } |
396 | 406 |
397 StackListener createListener( | 407 StackListener createListener( |
398 MemberBuilder builder, Scope memberScope, bool isInstanceMember, | 408 MemberBuilder builder, Scope memberScope, bool isInstanceMember, |
399 [Scope formalParameterScope]) { | 409 [Scope formalParameterScope]) { |
400 var listener = new TypeInferenceListener(); | 410 var listener = new TypeInferenceListener(); |
401 var typeInferrer = | 411 var typeInferrer = |
402 typeInferenceEngine.createLocalTypeInferrer(uri, listener); | 412 typeInferenceEngine.createLocalTypeInferrer(uri, listener); |
403 return new BodyBuilder( | 413 return new BodyBuilder( |
404 library, | 414 library, |
405 builder, | 415 builder, |
406 memberScope, | 416 memberScope, |
407 formalParameterScope, | 417 formalParameterScope, |
408 hierarchy, | 418 hierarchy, |
409 coreTypes, | 419 coreTypes, |
410 currentClass, | 420 currentClass, |
411 isInstanceMember, | 421 isInstanceMember, |
412 uri, | 422 uri, |
413 typeInferrer, | 423 typeInferrer, |
414 new KernelAstFactory()) | 424 new KernelAstFactory()) |
415 ..constantExpressionRequired = builder.isConstructor && builder.isConst; | 425 ..constantExpressionRequired = builder.isConstructor && builder.isConst; |
416 } | 426 } |
417 | 427 |
418 void buildFunctionBody(Token token, ProcedureBuilder builder) { | 428 void buildFunctionBody( |
| 429 Token token, ProcedureBuilder builder, MemberKind kind) { |
419 Scope typeParameterScope = builder.computeTypeParameterScope(memberScope); | 430 Scope typeParameterScope = builder.computeTypeParameterScope(memberScope); |
420 Scope formalParameterScope = | 431 Scope formalParameterScope = |
421 builder.computeFormalParameterScope(typeParameterScope); | 432 builder.computeFormalParameterScope(typeParameterScope); |
422 assert(typeParameterScope != null); | 433 assert(typeParameterScope != null); |
423 assert(formalParameterScope != null); | 434 assert(formalParameterScope != null); |
424 parseFunctionBody( | 435 parseFunctionBody( |
425 createListener(builder, typeParameterScope, builder.isInstanceMember, | 436 createListener(builder, typeParameterScope, builder.isInstanceMember, |
426 formalParameterScope), | 437 formalParameterScope), |
427 token); | 438 token, |
| 439 kind); |
428 } | 440 } |
429 | 441 |
430 void buildFields(Token token, bool isTopLevel, MemberBuilder builder) { | 442 void buildFields(Token token, bool isTopLevel, MemberBuilder builder) { |
431 // TODO(paulberry): don't re-parse the field if we've already parsed it | 443 // TODO(paulberry): don't re-parse the field if we've already parsed it |
432 // for type inference. | 444 // for type inference. |
433 parseFields(createListener(builder, memberScope, builder.isInstanceMember), | 445 parseFields(createListener(builder, memberScope, builder.isInstanceMember), |
434 token, isTopLevel); | 446 token, isTopLevel); |
435 } | 447 } |
436 | 448 |
437 @override | 449 @override |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 } | 508 } |
497 | 509 |
498 @override | 510 @override |
499 Link<Token> handleMemberName(Link<Token> identifiers) { | 511 Link<Token> handleMemberName(Link<Token> identifiers) { |
500 if (!isDartLibrary || identifiers.isEmpty) return identifiers; | 512 if (!isDartLibrary || identifiers.isEmpty) return identifiers; |
501 return removeNativeClause(identifiers); | 513 return removeNativeClause(identifiers); |
502 } | 514 } |
503 | 515 |
504 AsyncMarker getAsyncMarker(StackListener listener) => listener.pop(); | 516 AsyncMarker getAsyncMarker(StackListener listener) => listener.pop(); |
505 | 517 |
506 void parseFunctionBody(StackListener listener, Token token) { | 518 void parseFunctionBody(StackListener listener, Token token, MemberKind kind) { |
507 try { | 519 try { |
508 Parser parser = new Parser(listener); | 520 Parser parser = new Parser(listener); |
509 token = parser.parseFormalParametersOpt(token); | 521 token = parser.parseFormalParametersOpt(token, kind); |
510 var formals = listener.pop(); | 522 var formals = listener.pop(); |
511 listener.checkEmpty(token.charOffset); | 523 listener.checkEmpty(token.charOffset); |
512 listener.prepareInitializers(); | 524 listener.prepareInitializers(); |
513 token = parser.parseInitializersOpt(token); | 525 token = parser.parseInitializersOpt(token); |
514 token = parser.parseAsyncModifier(token); | 526 token = parser.parseAsyncModifier(token); |
515 AsyncMarker asyncModifier = getAsyncMarker(listener) ?? AsyncMarker.Sync; | 527 AsyncMarker asyncModifier = getAsyncMarker(listener) ?? AsyncMarker.Sync; |
516 bool isExpression = false; | 528 bool isExpression = false; |
517 bool allowAbstract = asyncModifier == AsyncMarker.Sync; | 529 bool allowAbstract = asyncModifier == AsyncMarker.Sync; |
518 parser.parseFunctionBody(token, isExpression, allowAbstract); | 530 parser.parseFunctionBody(token, isExpression, allowAbstract); |
519 var body = listener.pop(); | 531 var body = listener.pop(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 return inputError(uri, token.charOffset, "Duplicated name: $name"); | 582 return inputError(uri, token.charOffset, "Duplicated name: $name"); |
571 } | 583 } |
572 return builder; | 584 return builder; |
573 } | 585 } |
574 | 586 |
575 @override | 587 @override |
576 void debugEvent(String name) { | 588 void debugEvent(String name) { |
577 // printEvent(name); | 589 // printEvent(name); |
578 } | 590 } |
579 } | 591 } |
OLD | NEW |