| 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 |