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_inferrer.dart'; | 22 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart'; |
22 import 'package:kernel/ast.dart'; | 23 import 'package:kernel/ast.dart'; |
23 | 24 |
24 /// Concrete shadow object representing a statement block in kernel form. | 25 /// Concrete shadow object representing a statement block in kernel form. |
25 class KernelBlock extends Block implements KernelStatement { | 26 class KernelBlock extends Block implements KernelStatement { |
26 KernelBlock(List<Statement> statements) : super(statements); | 27 KernelBlock(List<Statement> statements) : super(statements); |
27 | 28 |
28 @override | 29 @override |
29 void _inferStatement(KernelTypeInferrer inferrer) { | 30 void _inferStatement(KernelTypeInferrer inferrer) { |
30 for (var statement in statements) { | 31 for (var statement in statements) { |
(...skipping 12 matching lines...) Expand all Loading... |
43 } | 44 } |
44 | 45 |
45 /// Concrete shadow object representing a field in kernel form. | 46 /// Concrete shadow object representing a field in kernel form. |
46 class KernelField extends Field { | 47 class KernelField extends Field { |
47 bool _implicitlyTyped = true; | 48 bool _implicitlyTyped = true; |
48 | 49 |
49 FieldNode<KernelField> _fieldNode; | 50 FieldNode<KernelField> _fieldNode; |
50 | 51 |
51 bool _isInferred = false; | 52 bool _isInferred = false; |
52 | 53 |
| 54 KernelTypeInferrer _typeInferrer; |
| 55 |
53 KernelField(Name name, {String fileUri}) : super(name, fileUri: fileUri) {} | 56 KernelField(Name name, {String fileUri}) : super(name, fileUri: fileUri) {} |
54 | 57 |
55 @override | 58 @override |
56 void set type(DartType value) { | 59 void set type(DartType value) { |
57 _implicitlyTyped = false; | 60 _implicitlyTyped = false; |
58 super.type = value; | 61 super.type = value; |
59 } | 62 } |
60 | 63 |
61 String get _fileUri { | 64 String get _fileUri { |
62 // TODO(paulberry): This is a hack. We should use this.fileUri, because we | 65 // TODO(paulberry): This is a hack. We should use this.fileUri, because we |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 class KernelStaticGet extends StaticGet implements KernelExpression { | 146 class KernelStaticGet extends StaticGet implements KernelExpression { |
144 KernelStaticGet(Member target) : super(target); | 147 KernelStaticGet(Member target) : super(target); |
145 | 148 |
146 @override | 149 @override |
147 DartType _inferExpression( | 150 DartType _inferExpression( |
148 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 151 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
149 return inferrer.inferStaticGet(typeContext, typeNeeded, target.getterType); | 152 return inferrer.inferStaticGet(typeContext, typeNeeded, target.getterType); |
150 } | 153 } |
151 } | 154 } |
152 | 155 |
153 /// Concrete implementation of [TypeInferrer] specialized to work with kernel | 156 /// Concrete implementation of [TypeInferenceEngine] specialized to work with |
154 /// objects. | 157 /// kernel objects. |
155 class KernelTypeInferrer extends TypeInferrer<Statement, Expression, | 158 class KernelTypeInferenceEngine extends TypeInferenceEngineImpl<KernelField> { |
156 KernelVariableDeclaration, KernelField> { | 159 KernelTypeInferenceEngine(Instrumentation instrumentation, bool strongMode) |
157 KernelTypeInferrer(Instrumentation instrumentation, bool strongMode) | |
158 : super(instrumentation, strongMode); | 160 : super(instrumentation, strongMode); |
159 | 161 |
160 @override | 162 @override |
161 void clearFieldInitializer(KernelField field) { | 163 void clearFieldInitializer(KernelField field) { |
162 field.initializer = null; | 164 field.initializer = null; |
163 } | 165 } |
164 | 166 |
165 @override | 167 @override |
166 FieldNode<KernelField> createFieldNode(KernelField field) { | 168 FieldNode<KernelField> createFieldNode(KernelField field) { |
167 FieldNode<KernelField> fieldNode = new FieldNode<KernelField>(this, field); | 169 FieldNode<KernelField> fieldNode = new FieldNode<KernelField>(this, field); |
168 field._fieldNode = fieldNode; | 170 field._fieldNode = fieldNode; |
169 return fieldNode; | 171 return fieldNode; |
170 } | 172 } |
171 | 173 |
172 @override | 174 @override |
| 175 KernelTypeInferrer createLocalTypeInferrer(Uri uri) { |
| 176 return new KernelTypeInferrer._(this, uri.toString()); |
| 177 } |
| 178 |
| 179 @override |
| 180 KernelTypeInferrer createTopLevelTypeInferrer(KernelField field) { |
| 181 return field._typeInferrer = |
| 182 new KernelTypeInferrer._(this, getFieldUri(field)); |
| 183 } |
| 184 |
| 185 @override |
| 186 bool fieldHasInitializer(KernelField field) { |
| 187 return field.initializer != null; |
| 188 } |
| 189 |
| 190 @override |
173 DartType getFieldDeclaredType(KernelField field) { | 191 DartType getFieldDeclaredType(KernelField field) { |
174 return field._implicitlyTyped ? null : field.type; | 192 return field._implicitlyTyped ? null : field.type; |
175 } | 193 } |
176 | 194 |
177 @override | 195 @override |
178 List<FieldNode<KernelField>> getFieldDependencies(KernelField field) { | 196 List<FieldNode<KernelField>> getFieldDependencies(KernelField field) { |
179 return field._fieldNode?.dependencies; | 197 return field._fieldNode?.dependencies; |
180 } | 198 } |
181 | 199 |
182 @override | 200 @override |
| 201 int getFieldOffset(KernelField field) { |
| 202 return field.fileOffset; |
| 203 } |
| 204 |
| 205 @override |
| 206 KernelTypeInferrer getFieldTypeInferrer(KernelField field) { |
| 207 return field._typeInferrer; |
| 208 } |
| 209 |
| 210 @override |
| 211 String getFieldUri(KernelField field) { |
| 212 return field._fileUri; |
| 213 } |
| 214 |
| 215 @override |
| 216 bool isFieldInferred(KernelField field) { |
| 217 return field._isInferred; |
| 218 } |
| 219 |
| 220 @override |
| 221 void setFieldInferredType(KernelField field, DartType inferredType) { |
| 222 field._setInferredType(inferredType); |
| 223 } |
| 224 } |
| 225 |
| 226 /// Concrete implementation of [TypeInferrer] specialized to work with kernel |
| 227 /// objects. |
| 228 class KernelTypeInferrer extends TypeInferrerImpl<Statement, Expression, |
| 229 KernelVariableDeclaration, KernelField> { |
| 230 KernelTypeInferrer._(KernelTypeInferenceEngine engine, String uri) |
| 231 : super(engine, uri); |
| 232 |
| 233 @override |
183 Expression getFieldInitializer(KernelField field) { | 234 Expression getFieldInitializer(KernelField field) { |
184 return field.initializer; | 235 return field.initializer; |
185 } | 236 } |
186 | 237 |
187 @override | 238 @override |
188 FieldNode<KernelField> getFieldNodeForReadTarget(Member readTarget) { | 239 FieldNode<KernelField> getFieldNodeForReadTarget(Member readTarget) { |
189 if (readTarget is KernelField) { | 240 if (readTarget is KernelField) { |
190 return readTarget._fieldNode; | 241 return readTarget._fieldNode; |
191 } else { | 242 } else { |
192 return null; | 243 return null; |
193 } | 244 } |
194 } | 245 } |
195 | 246 |
196 @override | 247 @override |
197 int getFieldOffset(KernelField field) { | |
198 return field.fileOffset; | |
199 } | |
200 | |
201 @override | |
202 String getFieldUri(KernelField field) { | |
203 return field._fileUri; | |
204 } | |
205 | |
206 @override | |
207 DartType inferExpression( | 248 DartType inferExpression( |
208 Expression expression, DartType typeContext, bool typeNeeded) { | 249 Expression expression, DartType typeContext, bool typeNeeded) { |
209 if (expression is KernelExpression) { | 250 if (expression is KernelExpression) { |
210 // Use polymorphic dispatch on [KernelExpression] to perform whatever kind | 251 // Use polymorphic dispatch on [KernelExpression] to perform whatever kind |
211 // of type inference is correct for this kind of statement. | 252 // of type inference is correct for this kind of statement. |
212 // TODO(paulberry): experiment to see if dynamic dispatch would be better, | 253 // TODO(paulberry): experiment to see if dynamic dispatch would be better, |
213 // so that the type hierarchy will be simpler (which may speed up "is" | 254 // so that the type hierarchy will be simpler (which may speed up "is" |
214 // checks). | 255 // checks). |
215 return expression._inferExpression(this, typeContext, typeNeeded); | 256 return expression._inferExpression(this, typeContext, typeNeeded); |
216 } else { | 257 } else { |
217 // Encountered an expression type for which type inference is not yet | 258 // Encountered an expression type for which type inference is not yet |
218 // implemented, so just infer dynamic for now. | 259 // implemented, so just infer dynamic for now. |
219 // TODO(paulberry): once the BodyBuilder uses shadow classes for | 260 // TODO(paulberry): once the BodyBuilder uses shadow classes for |
220 // everything, this case should no longer be needed. | 261 // everything, this case should no longer be needed. |
221 return typeNeeded ? const DynamicType() : null; | 262 return typeNeeded ? const DynamicType() : null; |
222 } | 263 } |
223 } | 264 } |
224 | 265 |
225 @override | 266 @override |
| 267 DartType inferFieldInitializer( |
| 268 KernelField field, DartType type, bool typeNeeded) { |
| 269 return inferExpression(field.initializer, type, typeNeeded); |
| 270 } |
| 271 |
| 272 @override |
226 void inferStatement(Statement statement) { | 273 void inferStatement(Statement statement) { |
227 if (statement is KernelStatement) { | 274 if (statement is KernelStatement) { |
228 // Use polymorphic dispatch on [KernelStatement] to perform whatever kind | 275 // Use polymorphic dispatch on [KernelStatement] to perform whatever kind |
229 // of type inference is correct for this kind of statement. | 276 // of type inference is correct for this kind of statement. |
230 // TODO(paulberry): experiment to see if dynamic dispatch would be better, | 277 // TODO(paulberry): experiment to see if dynamic dispatch would be better, |
231 // so that the type hierarchy will be simpler (which may speed up "is" | 278 // so that the type hierarchy will be simpler (which may speed up "is" |
232 // checks). | 279 // checks). |
233 return statement._inferStatement(this); | 280 return statement._inferStatement(this); |
234 } else { | 281 } else { |
235 // Encountered a statement type for which type inference is not yet | 282 // Encountered a statement type for which type inference is not yet |
236 // implemented, so just skip it for now. | 283 // implemented, so just skip it for now. |
237 // TODO(paulberry): once the BodyBuilder uses shadow classes for | 284 // TODO(paulberry): once the BodyBuilder uses shadow classes for |
238 // everything, this case should no longer be needed. | 285 // everything, this case should no longer be needed. |
239 } | 286 } |
240 } | 287 } |
241 | |
242 @override | |
243 bool isFieldInferred(KernelField field) { | |
244 return field._isInferred; | |
245 } | |
246 | |
247 @override | |
248 void setFieldInferredType(KernelField field, DartType inferredType) { | |
249 field._setInferredType(inferredType); | |
250 } | |
251 } | 288 } |
252 | 289 |
253 /// Concrete shadow object representing a variable declaration in kernel form. | 290 /// Concrete shadow object representing a variable declaration in kernel form. |
254 class KernelVariableDeclaration extends VariableDeclaration | 291 class KernelVariableDeclaration extends VariableDeclaration |
255 implements KernelStatement { | 292 implements KernelStatement { |
256 final bool _implicitlyTyped; | 293 final bool _implicitlyTyped; |
257 | 294 |
258 KernelVariableDeclaration(String name, | 295 KernelVariableDeclaration(String name, |
259 {Expression initializer, | 296 {Expression initializer, |
260 DartType type, | 297 DartType type, |
(...skipping 20 matching lines...) Expand all Loading... |
281 KernelVariableGet(VariableDeclaration variable, [DartType promotedType]) | 318 KernelVariableGet(VariableDeclaration variable, [DartType promotedType]) |
282 : super(variable, promotedType); | 319 : super(variable, promotedType); |
283 | 320 |
284 @override | 321 @override |
285 DartType _inferExpression( | 322 DartType _inferExpression( |
286 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 323 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
287 // TODO(paulberry): implement. | 324 // TODO(paulberry): implement. |
288 return typeNeeded ? const DynamicType() : null; | 325 return typeNeeded ? const DynamicType() : null; |
289 } | 326 } |
290 } | 327 } |
OLD | NEW |