Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Side by Side Diff: pkg/front_end/lib/src/fasta/source/diet_listener.dart

Issue 2876813002: Implement generalized function types. (Closed)
Patch Set: Address comments. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/parser/parser.dart ('k') | pkg/front_end/lib/src/fasta/source/diet_parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698