| 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_inference_listener.dart'
; | 22 import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart'
; |
| 23 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart'; | 23 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart'; |
| 24 import 'package:front_end/src/fasta/type_inference/type_promotion.dart'; | 24 import 'package:front_end/src/fasta/type_inference/type_promotion.dart'; |
| 25 import 'package:front_end/src/fasta/type_inference/type_schema.dart'; | 25 import 'package:front_end/src/fasta/type_inference/type_schema.dart'; |
| 26 import 'package:front_end/src/fasta/type_inference/type_schema_elimination.dart'
; | 26 import 'package:front_end/src/fasta/type_inference/type_schema_elimination.dart'
; |
| 27 import 'package:kernel/ast.dart'; | 27 import 'package:kernel/ast.dart'; |
| 28 import 'package:kernel/frontend/accessors.dart'; |
| 28 import 'package:kernel/type_algebra.dart'; | 29 import 'package:kernel/type_algebra.dart'; |
| 29 | 30 |
| 30 List<DartType> getExplicitTypeArguments(Arguments arguments) { | 31 List<DartType> getExplicitTypeArguments(Arguments arguments) { |
| 31 if (arguments is KernelArguments) { | 32 if (arguments is KernelArguments) { |
| 32 return arguments._hasExplicitTypeArguments ? arguments.types : null; | 33 return arguments._hasExplicitTypeArguments ? arguments.types : null; |
| 33 } else { | 34 } else { |
| 34 // This code path should only be taken in situations where there are no | 35 // This code path should only be taken in situations where there are no |
| 35 // type arguments at all, e.g. calling a user-definable operator. | 36 // type arguments at all, e.g. calling a user-definable operator. |
| 36 assert(arguments.types.isEmpty); | 37 assert(arguments.types.isEmpty); |
| 37 return null; | 38 return null; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 DartType _inferExpression( | 107 DartType _inferExpression( |
| 107 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 108 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
| 108 typeNeeded = | 109 typeNeeded = |
| 109 inferrer.listener.boolLiteralEnter(this, typeContext) || typeNeeded; | 110 inferrer.listener.boolLiteralEnter(this, typeContext) || typeNeeded; |
| 110 var inferredType = typeNeeded ? inferrer.coreTypes.boolClass.rawType : null; | 111 var inferredType = typeNeeded ? inferrer.coreTypes.boolClass.rawType : null; |
| 111 inferrer.listener.boolLiteralExit(this, inferredType); | 112 inferrer.listener.boolLiteralExit(this, inferredType); |
| 112 return inferredType; | 113 return inferredType; |
| 113 } | 114 } |
| 114 } | 115 } |
| 115 | 116 |
| 117 /// Concrete shadow object representing a cascade expression. |
| 118 /// |
| 119 /// A cascade expression of the form `a..b()..c()` is represented as the kernel |
| 120 /// expression: |
| 121 /// |
| 122 /// let v = a in |
| 123 /// let _ = v.b() in |
| 124 /// let _ = v.c() in |
| 125 /// v |
| 126 /// |
| 127 /// In the documentation that follows, `v` is referred to as the "cascade |
| 128 /// variable"--this is the variable that remembers the value of the expression |
| 129 /// preceding the first `..` while the cascades are being evaluated. |
| 130 /// |
| 131 /// After constructing a [KernelCascadeExpression], the caller should |
| 132 /// call [finalize] with an expression representing the expression after the |
| 133 /// `..`. If a further `..` follows that expression, the caller should call |
| 134 /// [extend] followed by [finalize] for each subsequent cascade. |
| 135 class KernelCascadeExpression extends Let implements KernelExpression { |
| 136 /// Pointer to the last "let" expression in the cascade. |
| 137 Let nextCascade; |
| 138 |
| 139 /// Creates a [KernelCascadeExpression] using [variable] as the cascade |
| 140 /// variable. Caller is responsible for ensuring that [variable]'s |
| 141 /// initializer is the expression preceding the first `..` of the cascade |
| 142 /// expression. |
| 143 KernelCascadeExpression(KernelVariableDeclaration variable) |
| 144 : super( |
| 145 variable, |
| 146 makeLet(new VariableDeclaration.forValue(new InvalidExpression()), |
| 147 new VariableGet(variable))) { |
| 148 nextCascade = body; |
| 149 } |
| 150 |
| 151 /// Adds a new unfinalized section to the end of the cascade. Should be |
| 152 /// called after the previous cascade section has been finalized. |
| 153 void extend() { |
| 154 assert(nextCascade.variable.initializer is! InvalidExpression); |
| 155 Let newCascade = makeLet( |
| 156 new VariableDeclaration.forValue(new InvalidExpression()), |
| 157 nextCascade.body); |
| 158 nextCascade.body = newCascade; |
| 159 newCascade.parent = nextCascade; |
| 160 nextCascade = newCascade; |
| 161 } |
| 162 |
| 163 /// Finalizes the last cascade section with the given [expression]. |
| 164 void finalize(Expression expression) { |
| 165 assert(nextCascade.variable.initializer is InvalidExpression); |
| 166 nextCascade.variable.initializer = expression; |
| 167 expression.parent = nextCascade.variable; |
| 168 } |
| 169 |
| 170 @override |
| 171 DartType _inferExpression( |
| 172 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
| 173 typeNeeded = inferrer.listener.cascadeExpressionEnter(this, typeContext) || |
| 174 typeNeeded; |
| 175 var lhsType = inferrer.inferExpression( |
| 176 variable.initializer, typeContext, typeNeeded || inferrer.strongMode); |
| 177 if (inferrer.strongMode) { |
| 178 variable.type = lhsType; |
| 179 } |
| 180 Let section = body; |
| 181 while (true) { |
| 182 inferrer.inferExpression(section.variable.initializer, null, false); |
| 183 if (section.body is! Let) break; |
| 184 section = section.body; |
| 185 } |
| 186 inferrer.listener.cascadeExpressionExit(this, lhsType); |
| 187 return lhsType; |
| 188 } |
| 189 } |
| 190 |
| 116 /// Concrete shadow object representing a conditional expression in kernel form. | 191 /// Concrete shadow object representing a conditional expression in kernel form. |
| 117 /// Shadow object for [ConditionalExpression]. | 192 /// Shadow object for [ConditionalExpression]. |
| 118 class KernelConditionalExpression extends ConditionalExpression | 193 class KernelConditionalExpression extends ConditionalExpression |
| 119 implements KernelExpression { | 194 implements KernelExpression { |
| 120 KernelConditionalExpression( | 195 KernelConditionalExpression( |
| 121 Expression condition, Expression then, Expression otherwise) | 196 Expression condition, Expression then, Expression otherwise) |
| 122 : super(condition, then, otherwise, const DynamicType()); | 197 : super(condition, then, otherwise, const DynamicType()); |
| 123 | 198 |
| 124 @override | 199 @override |
| 125 DartType _inferExpression( | 200 DartType _inferExpression( |
| (...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1223 bool isConst: false, | 1298 bool isConst: false, |
| 1224 bool isLocalFunction: false}) | 1299 bool isLocalFunction: false}) |
| 1225 : _implicitlyTyped = type == null, | 1300 : _implicitlyTyped = type == null, |
| 1226 _isLocalFunction = isLocalFunction, | 1301 _isLocalFunction = isLocalFunction, |
| 1227 super(name, | 1302 super(name, |
| 1228 initializer: initializer, | 1303 initializer: initializer, |
| 1229 type: type ?? const DynamicType(), | 1304 type: type ?? const DynamicType(), |
| 1230 isFinal: isFinal, | 1305 isFinal: isFinal, |
| 1231 isConst: isConst); | 1306 isConst: isConst); |
| 1232 | 1307 |
| 1308 KernelVariableDeclaration.forValue( |
| 1309 Expression initializer, this._functionNestingLevel) |
| 1310 : _implicitlyTyped = true, |
| 1311 _isLocalFunction = false, |
| 1312 super.forValue(initializer); |
| 1313 |
| 1233 @override | 1314 @override |
| 1234 void _inferStatement(KernelTypeInferrer inferrer) { | 1315 void _inferStatement(KernelTypeInferrer inferrer) { |
| 1235 inferrer.listener.variableDeclarationEnter(this); | 1316 inferrer.listener.variableDeclarationEnter(this); |
| 1236 var declaredType = _implicitlyTyped ? null : type; | 1317 var declaredType = _implicitlyTyped ? null : type; |
| 1237 if (initializer != null) { | 1318 if (initializer != null) { |
| 1238 var inferredType = inferrer.inferDeclarationType(inferrer.inferExpression( | 1319 var inferredType = inferrer.inferDeclarationType(inferrer.inferExpression( |
| 1239 initializer, declaredType, _implicitlyTyped)); | 1320 initializer, declaredType, _implicitlyTyped)); |
| 1240 if (inferrer.strongMode && _implicitlyTyped) { | 1321 if (inferrer.strongMode && _implicitlyTyped) { |
| 1241 inferrer.instrumentation?.record(Uri.parse(inferrer.uri), fileOffset, | 1322 inferrer.instrumentation?.record(Uri.parse(inferrer.uri), fileOffset, |
| 1242 'type', new InstrumentationValueForType(inferredType)); | 1323 'type', new InstrumentationValueForType(inferredType)); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1321 closureContext.isAsync | 1402 closureContext.isAsync |
| 1322 ? inferrer.coreTypes.streamClass | 1403 ? inferrer.coreTypes.streamClass |
| 1323 : inferrer.coreTypes.iterableClass); | 1404 : inferrer.coreTypes.iterableClass); |
| 1324 } | 1405 } |
| 1325 var inferredType = inferrer.inferExpression( | 1406 var inferredType = inferrer.inferExpression( |
| 1326 expression, typeContext, closureContext != null); | 1407 expression, typeContext, closureContext != null); |
| 1327 closureContext.handleYield(inferrer, isYieldStar, inferredType); | 1408 closureContext.handleYield(inferrer, isYieldStar, inferredType); |
| 1328 inferrer.listener.yieldStatementExit(this); | 1409 inferrer.listener.yieldStatementExit(this); |
| 1329 } | 1410 } |
| 1330 } | 1411 } |
| OLD | NEW |