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

Side by Side Diff: pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart

Issue 2908973002: Add type inference logic for "for-in" loops. (Closed)
Patch Set: Created 3 years, 6 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) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 /// This file declares a "shadow hierarchy" of concrete classes which extend 5 /// This file declares a "shadow hierarchy" of concrete classes which extend
6 /// the kernel class hierarchy, adding methods and fields needed by the 6 /// the kernel class hierarchy, adding methods and fields needed by the
7 /// BodyBuilder. 7 /// BodyBuilder.
8 /// 8 ///
9 /// Instances of these classes may be created using the factory methods in 9 /// Instances of these classes may be created using the factory methods in
10 /// `ast_factory.dart`. 10 /// `ast_factory.dart`.
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 // absolute URI. 433 // absolute URI.
434 return enclosingLibrary.importUri.toString(); 434 return enclosingLibrary.importUri.toString();
435 } 435 }
436 436
437 void _setInferredType(DartType inferredType) { 437 void _setInferredType(DartType inferredType) {
438 _isInferred = true; 438 _isInferred = true;
439 super.type = inferredType; 439 super.type = inferredType;
440 } 440 }
441 } 441 }
442 442
443 /// Concrete shadow object representing a for-in loop in kernel form.
444 class KernelForInStatement extends ForInStatement implements KernelStatement {
445 final bool _declaresVariable;
446
447 KernelForInStatement(VariableDeclaration variable, Expression iterable,
448 Statement body, this._declaresVariable,
449 {bool isAsync: false})
450 : super(variable, iterable, body, isAsync: isAsync);
451
452 @override
453 void _inferStatement(KernelTypeInferrer inferrer) {
454 inferrer.listener.forInStatementEnter(this);
455 var iterableClass = isAsync
456 ? inferrer.coreTypes.streamClass
457 : inferrer.coreTypes.iterableClass;
458 DartType context;
459 bool typeNeeded = false;
460 KernelVariableDeclaration variable;
461 if (_declaresVariable) {
462 variable = this.variable;
463 if (variable._implicitlyTyped) {
464 typeNeeded = true;
465 // TODO(paulberry): In this case, should the context be `Iterable<?>`?
466 } else {
467 context = inferrer.wrapType(variable.type, iterableClass);
468 }
469 } else {
470 // TODO(paulberry): In this case, should the context be based on the
471 // declared type of the loop variable?
ahe 2017/05/29 13:39:22 Notice also that the loop variable corresponds to
Paul Berry 2017/05/29 14:23:32 Good point. I've added a TODO to address this.
472 }
473 var inferredExpressionType =
474 inferrer.inferExpression(iterable, context, typeNeeded);
475 if (typeNeeded) {
476 var inferredType = const DynamicType();
477 if (inferredExpressionType is InterfaceType) {
478 InterfaceType supertype = inferrer.classHierarchy
479 .getTypeAsInstanceOf(inferredExpressionType, iterableClass);
480 if (supertype != null) {
481 inferredType = supertype.typeArguments[0];
482 }
483 }
484 inferrer.instrumentation?.record(
485 Uri.parse(inferrer.uri),
486 variable.fileOffset,
487 'type',
488 new InstrumentationValueForType(inferredType));
489 variable.type = inferredType;
490 }
491 inferrer.inferStatement(body);
492 inferrer.listener.forInStatementExit(this);
493 }
494 }
495
443 /// Concrete shadow object representing a local function declaration in kernel 496 /// Concrete shadow object representing a local function declaration in kernel
444 /// form. 497 /// form.
445 class KernelFunctionDeclaration extends FunctionDeclaration 498 class KernelFunctionDeclaration extends FunctionDeclaration
446 implements KernelStatement { 499 implements KernelStatement {
447 KernelFunctionDeclaration(VariableDeclaration variable, FunctionNode function) 500 KernelFunctionDeclaration(VariableDeclaration variable, FunctionNode function)
448 : super(variable, function); 501 : super(variable, function);
449 502
450 @override 503 @override
451 void _inferStatement(KernelTypeInferrer inferrer) { 504 void _inferStatement(KernelTypeInferrer inferrer) {
452 inferrer.listener.functionDeclarationEnter(this); 505 inferrer.listener.functionDeclarationEnter(this);
(...skipping 1082 matching lines...) Expand 10 before | Expand all | Expand 10 after
1535 closureContext.isAsync 1588 closureContext.isAsync
1536 ? inferrer.coreTypes.streamClass 1589 ? inferrer.coreTypes.streamClass
1537 : inferrer.coreTypes.iterableClass); 1590 : inferrer.coreTypes.iterableClass);
1538 } 1591 }
1539 var inferredType = inferrer.inferExpression( 1592 var inferredType = inferrer.inferExpression(
1540 expression, typeContext, closureContext != null); 1593 expression, typeContext, closureContext != null);
1541 closureContext.handleYield(inferrer, isYieldStar, inferredType); 1594 closureContext.handleYield(inferrer, isYieldStar, inferredType);
1542 inferrer.listener.yieldStatementExit(this); 1595 inferrer.listener.yieldStatementExit(this);
1543 } 1596 }
1544 } 1597 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698