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`. |
11 /// | 11 /// |
12 /// Note that these classes represent the Dart language prior to desugaring. | 12 /// Note that these classes represent the Dart language prior to desugaring. |
13 /// When a single Dart construct desugars to a tree containing multiple kernel | 13 /// When a single Dart construct desugars to a tree containing multiple kernel |
14 /// AST nodes, the shadow class extends the kernel object at the top of the | 14 /// AST nodes, the shadow class extends the kernel object at the top of the |
15 /// desugared tree. | 15 /// desugared tree. |
16 /// | 16 /// |
17 /// This means that in some cases multiple shadow classes may extend the same | 17 /// This means that in some cases multiple shadow classes may extend the same |
18 /// kernel class, because multiple constructs in Dart may desugar to a tree | 18 /// kernel class, because multiple constructs in Dart may desugar to a tree |
19 /// with the same kind of root node. | 19 /// with the same kind of root node. |
20 import 'package:front_end/src/base/instrumentation.dart'; | 20 import 'package:front_end/src/base/instrumentation.dart'; |
21 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart'; | 21 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart'; |
22 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart'; | 22 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart'; |
| 23 import 'package:front_end/src/fasta/type_inference/type_promotion.dart'; |
23 import 'package:kernel/ast.dart'; | 24 import 'package:kernel/ast.dart'; |
24 | 25 |
25 /// Concrete shadow object representing a statement block in kernel form. | 26 /// Concrete shadow object representing a statement block in kernel form. |
26 class KernelBlock extends Block implements KernelStatement { | 27 class KernelBlock extends Block implements KernelStatement { |
27 KernelBlock(List<Statement> statements) : super(statements); | 28 KernelBlock(List<Statement> statements) : super(statements); |
28 | 29 |
29 @override | 30 @override |
30 void _inferStatement(KernelTypeInferrer inferrer) { | 31 void _inferStatement(KernelTypeInferrer inferrer) { |
31 for (var statement in statements) { | 32 for (var statement in statements) { |
32 inferrer.inferStatement(statement); | 33 inferrer.inferStatement(statement); |
33 } | 34 } |
34 } | 35 } |
35 } | 36 } |
36 | 37 |
37 /// Common base class for shadow objects representing expressions in kernel | 38 /// Common base class for shadow objects representing expressions in kernel |
38 /// form. | 39 /// form. |
39 abstract class KernelExpression implements Expression { | 40 abstract class KernelExpression implements Expression { |
40 /// Calls back to [inferrer] to perform type inference for whatever concrete | 41 /// Calls back to [inferrer] to perform type inference for whatever concrete |
41 /// type of [KernelExpression] this is. | 42 /// type of [KernelExpression] this is. |
42 DartType _inferExpression( | 43 DartType _inferExpression( |
43 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded); | 44 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded); |
44 } | 45 } |
45 | 46 |
| 47 /// Concrete shadow object representing an expression statement in kernel form. |
| 48 class KernelExpressionStatement extends ExpressionStatement |
| 49 implements KernelStatement { |
| 50 KernelExpressionStatement(Expression expression) : super(expression); |
| 51 |
| 52 @override |
| 53 void _inferStatement(KernelTypeInferrer inferrer) { |
| 54 inferrer.inferExpressionStatement(expression); |
| 55 } |
| 56 } |
| 57 |
46 /// Concrete shadow object representing a field in kernel form. | 58 /// Concrete shadow object representing a field in kernel form. |
47 class KernelField extends Field { | 59 class KernelField extends Field { |
48 bool _implicitlyTyped = true; | 60 bool _implicitlyTyped = true; |
49 | 61 |
50 FieldNode<KernelField> _fieldNode; | 62 FieldNode<KernelField> _fieldNode; |
51 | 63 |
52 bool _isInferred = false; | 64 bool _isInferred = false; |
53 | 65 |
54 KernelTypeInferrer _typeInferrer; | 66 KernelTypeInferrer _typeInferrer; |
55 | 67 |
(...skipping 20 matching lines...) Expand all Loading... |
76 } | 88 } |
77 | 89 |
78 /// Concrete shadow object representing a function expression in kernel form. | 90 /// Concrete shadow object representing a function expression in kernel form. |
79 class KernelFunctionExpression extends FunctionExpression | 91 class KernelFunctionExpression extends FunctionExpression |
80 implements KernelExpression { | 92 implements KernelExpression { |
81 KernelFunctionExpression(FunctionNode function) : super(function); | 93 KernelFunctionExpression(FunctionNode function) : super(function); |
82 | 94 |
83 @override | 95 @override |
84 DartType _inferExpression( | 96 DartType _inferExpression( |
85 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 97 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
86 // TODO(paulberry): implement. | 98 var asyncMarker = function.asyncMarker; |
87 return typeNeeded ? const DynamicType() : null; | 99 bool isAsync = asyncMarker == AsyncMarker.Async || |
| 100 asyncMarker == AsyncMarker.AsyncStar; |
| 101 bool isGenerator = asyncMarker == AsyncMarker.SyncStar || |
| 102 asyncMarker == AsyncMarker.AsyncStar; |
| 103 return inferrer.inferFunctionExpression( |
| 104 typeContext, |
| 105 typeNeeded, |
| 106 function.body, |
| 107 function.body is ReturnStatement, |
| 108 isAsync, |
| 109 isGenerator, |
| 110 fileOffset, (type) { |
| 111 function.returnType = type; |
| 112 }, () => function.functionType); |
88 } | 113 } |
89 } | 114 } |
90 | 115 |
| 116 /// Concrete shadow object representing an if statement in kernel form. |
| 117 class KernelIfStatement extends IfStatement implements KernelStatement { |
| 118 KernelIfStatement(Expression condition, Statement then, Statement otherwise) |
| 119 : super(condition, then, otherwise); |
| 120 |
| 121 @override |
| 122 void _inferStatement(KernelTypeInferrer inferrer) { |
| 123 inferrer.inferIfStatement(condition, then, otherwise); |
| 124 } |
| 125 } |
| 126 |
91 /// Concrete shadow object representing an integer literal in kernel form. | 127 /// Concrete shadow object representing an integer literal in kernel form. |
92 class KernelIntLiteral extends IntLiteral implements KernelExpression { | 128 class KernelIntLiteral extends IntLiteral implements KernelExpression { |
93 KernelIntLiteral(int value) : super(value); | 129 KernelIntLiteral(int value) : super(value); |
94 | 130 |
95 @override | 131 @override |
96 DartType _inferExpression( | 132 DartType _inferExpression( |
97 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 133 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
98 return inferrer.inferIntLiteral(typeContext, typeNeeded); | 134 return inferrer.inferIntLiteral(typeContext, typeNeeded); |
99 } | 135 } |
100 } | 136 } |
101 | 137 |
| 138 /// Concrete shadow object representing a non-inverted "is" test in kernel form. |
| 139 class KernelIsExpression extends IsExpression implements KernelExpression { |
| 140 KernelIsExpression(Expression operand, DartType type) : super(operand, type); |
| 141 |
| 142 @override |
| 143 DartType _inferExpression( |
| 144 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
| 145 return inferrer.inferIsExpression(typeContext, typeNeeded, operand); |
| 146 } |
| 147 } |
| 148 |
| 149 /// Concrete shadow object representing an inverted "is" test in kernel form. |
| 150 class KernelIsNotExpression extends Not implements KernelExpression { |
| 151 KernelIsNotExpression(Expression operand, DartType type, int charOffset) |
| 152 : super(new IsExpression(operand, type)..fileOffset = charOffset); |
| 153 |
| 154 @override |
| 155 DartType _inferExpression( |
| 156 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
| 157 IsExpression isExpression = this.operand; |
| 158 return inferrer.inferIsExpression( |
| 159 typeContext, typeNeeded, isExpression.operand); |
| 160 } |
| 161 } |
| 162 |
102 /// Concrete shadow object representing a list literal in kernel form. | 163 /// Concrete shadow object representing a list literal in kernel form. |
103 class KernelListLiteral extends ListLiteral implements KernelExpression { | 164 class KernelListLiteral extends ListLiteral implements KernelExpression { |
104 KernelListLiteral(List<KernelExpression> expressions, | 165 KernelListLiteral(List<KernelExpression> expressions, |
105 {DartType typeArgument, bool isConst: false}) | 166 {DartType typeArgument, bool isConst: false}) |
106 : super(expressions, typeArgument: typeArgument, isConst: isConst); | 167 : super(expressions, typeArgument: typeArgument, isConst: isConst); |
107 | 168 |
108 @override | 169 @override |
109 DartType _inferExpression( | 170 DartType _inferExpression( |
110 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 171 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
111 // TODO(paulberry): implement. | 172 // TODO(paulberry): implement. |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 | 280 |
220 @override | 281 @override |
221 void setFieldInferredType(KernelField field, DartType inferredType) { | 282 void setFieldInferredType(KernelField field, DartType inferredType) { |
222 field._setInferredType(inferredType); | 283 field._setInferredType(inferredType); |
223 } | 284 } |
224 } | 285 } |
225 | 286 |
226 /// Concrete implementation of [TypeInferrer] specialized to work with kernel | 287 /// Concrete implementation of [TypeInferrer] specialized to work with kernel |
227 /// objects. | 288 /// objects. |
228 class KernelTypeInferrer extends TypeInferrerImpl<Statement, Expression, | 289 class KernelTypeInferrer extends TypeInferrerImpl<Statement, Expression, |
229 KernelVariableDeclaration, KernelField> { | 290 VariableDeclaration, KernelField> { |
| 291 @override |
| 292 final typePromoter = new KernelTypePromoter(); |
| 293 |
230 KernelTypeInferrer._(KernelTypeInferenceEngine engine, String uri) | 294 KernelTypeInferrer._(KernelTypeInferenceEngine engine, String uri) |
231 : super(engine, uri); | 295 : super(engine, uri); |
232 | 296 |
233 @override | 297 @override |
234 Expression getFieldInitializer(KernelField field) { | 298 Expression getFieldInitializer(KernelField field) { |
235 return field.initializer; | 299 return field.initializer; |
236 } | 300 } |
237 | 301 |
238 @override | 302 @override |
239 FieldNode<KernelField> getFieldNodeForReadTarget(Member readTarget) { | 303 FieldNode<KernelField> getFieldNodeForReadTarget(Member readTarget) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 return statement._inferStatement(this); | 344 return statement._inferStatement(this); |
281 } else { | 345 } else { |
282 // Encountered a statement type for which type inference is not yet | 346 // Encountered a statement type for which type inference is not yet |
283 // implemented, so just skip it for now. | 347 // implemented, so just skip it for now. |
284 // TODO(paulberry): once the BodyBuilder uses shadow classes for | 348 // TODO(paulberry): once the BodyBuilder uses shadow classes for |
285 // everything, this case should no longer be needed. | 349 // everything, this case should no longer be needed. |
286 } | 350 } |
287 } | 351 } |
288 } | 352 } |
289 | 353 |
| 354 /// Concrete implementation of [TypePromoter] specialized to work with kernel |
| 355 /// objects. |
| 356 /// |
| 357 /// Note: the second type parameter really ought to be |
| 358 /// KernelVariableDeclaration, but we can't do that yet because BodyBuilder |
| 359 /// still uses raw VariableDeclaration objects sometimes. |
| 360 /// TODO(paulberry): fix this. |
| 361 class KernelTypePromoter |
| 362 extends TypePromoterImpl<Expression, VariableDeclaration> { |
| 363 @override |
| 364 int getVariableFunctionNestingLevel(VariableDeclaration variable) { |
| 365 if (variable is KernelVariableDeclaration) { |
| 366 return variable._functionNestingLevel; |
| 367 } else { |
| 368 // Hack to deal with the fact that BodyBuilder still creates raw |
| 369 // VariableDeclaration objects sometimes. |
| 370 // TODO(paulberry): get rid of this once the type parameter is |
| 371 // KernelVariableDeclaration. |
| 372 return 0; |
| 373 } |
| 374 } |
| 375 |
| 376 @override |
| 377 bool sameExpressions(Expression a, Expression b) { |
| 378 return identical(a, b); |
| 379 } |
| 380 |
| 381 @override |
| 382 void setVariableMutatedAnywhere(VariableDeclaration variable) { |
| 383 if (variable is KernelVariableDeclaration) { |
| 384 variable._mutatedAnywhere = true; |
| 385 } else { |
| 386 // Hack to deal with the fact that BodyBuilder still creates raw |
| 387 // VariableDeclaration objects sometimes. |
| 388 // TODO(paulberry): get rid of this once the type parameter is |
| 389 // KernelVariableDeclaration. |
| 390 } |
| 391 } |
| 392 |
| 393 @override |
| 394 void setVariableMutatedInClosure(VariableDeclaration variable) { |
| 395 if (variable is KernelVariableDeclaration) { |
| 396 variable._mutatedInClosure = true; |
| 397 } else { |
| 398 // Hack to deal with the fact that BodyBuilder still creates raw |
| 399 // VariableDeclaration objects sometimes. |
| 400 // TODO(paulberry): get rid of this once the type parameter is |
| 401 // KernelVariableDeclaration. |
| 402 } |
| 403 } |
| 404 |
| 405 @override |
| 406 bool wasVariableMutatedAnywhere(VariableDeclaration variable) { |
| 407 if (variable is KernelVariableDeclaration) { |
| 408 return variable._mutatedAnywhere; |
| 409 } else { |
| 410 // Hack to deal with the fact that BodyBuilder still creates raw |
| 411 // VariableDeclaration objects sometimes. |
| 412 // TODO(paulberry): get rid of this once the type parameter is |
| 413 // KernelVariableDeclaration. |
| 414 return true; |
| 415 } |
| 416 } |
| 417 } |
| 418 |
290 /// Concrete shadow object representing a variable declaration in kernel form. | 419 /// Concrete shadow object representing a variable declaration in kernel form. |
291 class KernelVariableDeclaration extends VariableDeclaration | 420 class KernelVariableDeclaration extends VariableDeclaration |
292 implements KernelStatement { | 421 implements KernelStatement { |
293 final bool _implicitlyTyped; | 422 final bool _implicitlyTyped; |
294 | 423 |
295 KernelVariableDeclaration(String name, | 424 final int _functionNestingLevel; |
| 425 |
| 426 bool _mutatedInClosure = false; |
| 427 |
| 428 bool _mutatedAnywhere = false; |
| 429 |
| 430 KernelVariableDeclaration(String name, this._functionNestingLevel, |
296 {Expression initializer, | 431 {Expression initializer, |
297 DartType type, | 432 DartType type, |
298 bool isFinal: false, | 433 bool isFinal: false, |
299 bool isConst: false}) | 434 bool isConst: false}) |
300 : _implicitlyTyped = type == null, | 435 : _implicitlyTyped = type == null, |
301 super(name, | 436 super(name, |
302 initializer: initializer, | 437 initializer: initializer, |
303 type: type ?? const DynamicType(), | 438 type: type ?? const DynamicType(), |
304 isFinal: isFinal, | 439 isFinal: isFinal, |
305 isConst: isConst); | 440 isConst: isConst); |
306 | 441 |
| 442 DartType get _declaredType => _implicitlyTyped ? null : type; |
| 443 |
307 @override | 444 @override |
308 void _inferStatement(KernelTypeInferrer inferrer) { | 445 void _inferStatement(KernelTypeInferrer inferrer) { |
309 inferrer.inferVariableDeclaration( | 446 inferrer.inferVariableDeclaration( |
310 _implicitlyTyped ? null : type, initializer, fileOffset, (type) { | 447 _implicitlyTyped ? null : type, initializer, fileOffset, (type) { |
311 this.type = type; | 448 this.type = type; |
312 }); | 449 }); |
313 } | 450 } |
314 } | 451 } |
315 | 452 |
316 /// Concrete shadow object representing a read from a variable in kernel form. | 453 /// Concrete shadow object representing a read from a variable in kernel form. |
317 class KernelVariableGet extends VariableGet implements KernelExpression { | 454 class KernelVariableGet extends VariableGet implements KernelExpression { |
318 KernelVariableGet(VariableDeclaration variable, [DartType promotedType]) | 455 final TypePromotionFact<VariableDeclaration> _fact; |
319 : super(variable, promotedType); | 456 |
| 457 final TypePromotionScope _scope; |
| 458 |
| 459 KernelVariableGet(VariableDeclaration variable, this._fact, this._scope) |
| 460 : super(variable); |
320 | 461 |
321 @override | 462 @override |
322 DartType _inferExpression( | 463 DartType _inferExpression( |
323 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 464 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
324 // TODO(paulberry): implement. | 465 bool mutatedInClosure; |
325 return typeNeeded ? const DynamicType() : null; | 466 DartType declaredType; |
| 467 var variable = this.variable; |
| 468 if (variable is KernelVariableDeclaration) { |
| 469 mutatedInClosure = variable._mutatedInClosure; |
| 470 declaredType = variable._declaredType; |
| 471 } else { |
| 472 // Hack to deal with the fact that BodyBuilder still creates raw |
| 473 // VariableDeclaration objects sometimes. |
| 474 // TODO(paulberry): get rid of this once the type parameter is |
| 475 // KernelVariableDeclaration. |
| 476 mutatedInClosure = true; |
| 477 declaredType = variable.type; |
| 478 } |
| 479 return inferrer.inferVariableGet(typeContext, typeNeeded, mutatedInClosure, |
| 480 _fact, _scope, fileOffset, declaredType, (type) { |
| 481 promotedType = type; |
| 482 }); |
326 } | 483 } |
327 } | 484 } |
OLD | NEW |