Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |