| 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_inferrer.dart'; | 21 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart'; |
| 22 import 'package:kernel/ast.dart'; | 22 import 'package:kernel/ast.dart'; |
| 23 import 'package:kernel/class_hierarchy.dart'; | |
| 24 import 'package:kernel/core_types.dart'; | |
| 25 | 23 |
| 26 /// Concrete shadow object representing a statement block in kernel form. | 24 /// Concrete shadow object representing a statement block in kernel form. |
| 27 class KernelBlock extends Block implements KernelStatement { | 25 class KernelBlock extends Block implements KernelStatement { |
| 28 KernelBlock(List<Statement> statements) : super(statements); | 26 KernelBlock(List<Statement> statements) : super(statements); |
| 29 | 27 |
| 30 @override | 28 @override |
| 31 void _inferStatement(KernelTypeInferrer inferrer) { | 29 void _inferStatement(KernelTypeInferrer inferrer) { |
| 32 for (var statement in statements) { | 30 for (var statement in statements) { |
| 33 inferrer.inferStatement(statement); | 31 inferrer.inferStatement(statement); |
| 34 } | 32 } |
| 35 } | 33 } |
| 36 } | 34 } |
| 37 | 35 |
| 38 /// Common base class for shadow objects representing expressions in kernel | 36 /// Common base class for shadow objects representing expressions in kernel |
| 39 /// form. | 37 /// form. |
| 40 abstract class KernelExpression implements Expression { | 38 abstract class KernelExpression implements Expression { |
| 41 /// Calls back to [inferrer] to perform type inference for whatever concrete | 39 /// Calls back to [inferrer] to perform type inference for whatever concrete |
| 42 /// type of [KernelExpression] this is. | 40 /// type of [KernelExpression] this is. |
| 43 DartType _inferExpression( | 41 DartType _inferExpression( |
| 44 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded); | 42 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded); |
| 45 } | 43 } |
| 46 | 44 |
| 45 /// Concrete shadow object representing a field in kernel form. |
| 46 class KernelField extends Field { |
| 47 bool _implicitlyTyped = true; |
| 48 |
| 49 FieldNode<KernelField> _fieldNode; |
| 50 |
| 51 bool _isInferred = false; |
| 52 |
| 53 KernelField(Name name, {String fileUri}) : super(name, fileUri: fileUri) {} |
| 54 |
| 55 @override |
| 56 void set type(DartType value) { |
| 57 _implicitlyTyped = false; |
| 58 super.type = value; |
| 59 } |
| 60 |
| 61 String get _fileUri { |
| 62 // TODO(paulberry): This is a hack. We should use this.fileUri, because we |
| 63 // want the URI of the compilation unit. But that gives a relative URI, |
| 64 // and I don't know what it's relative to or how to convert it to an |
| 65 // absolute URI. |
| 66 return enclosingLibrary.importUri.toString(); |
| 67 } |
| 68 |
| 69 void _setInferredType(DartType inferredType) { |
| 70 _isInferred = true; |
| 71 super.type = inferredType; |
| 72 } |
| 73 } |
| 74 |
| 47 /// Concrete shadow object representing a function expression in kernel form. | 75 /// Concrete shadow object representing a function expression in kernel form. |
| 48 class KernelFunctionExpression extends FunctionExpression | 76 class KernelFunctionExpression extends FunctionExpression |
| 49 implements KernelExpression { | 77 implements KernelExpression { |
| 50 KernelFunctionExpression(FunctionNode function) : super(function); | 78 KernelFunctionExpression(FunctionNode function) : super(function); |
| 51 | 79 |
| 52 @override | 80 @override |
| 53 DartType _inferExpression( | 81 DartType _inferExpression( |
| 54 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 82 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
| 55 // TODO(paulberry): implement. | 83 // TODO(paulberry): implement. |
| 56 return typeNeeded ? const DynamicType() : null; | 84 return typeNeeded ? const DynamicType() : null; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 } | 131 } |
| 104 | 132 |
| 105 /// Common base class for shadow objects representing statements in kernel | 133 /// Common base class for shadow objects representing statements in kernel |
| 106 /// form. | 134 /// form. |
| 107 abstract class KernelStatement extends Statement { | 135 abstract class KernelStatement extends Statement { |
| 108 /// Calls back to [inferrer] to perform type inference for whatever concrete | 136 /// Calls back to [inferrer] to perform type inference for whatever concrete |
| 109 /// type of [KernelStatement] this is. | 137 /// type of [KernelStatement] this is. |
| 110 void _inferStatement(KernelTypeInferrer inferrer); | 138 void _inferStatement(KernelTypeInferrer inferrer); |
| 111 } | 139 } |
| 112 | 140 |
| 141 /// Concrete shadow object representing a read of a static variable in kernel |
| 142 /// form. |
| 143 class KernelStaticGet extends StaticGet implements KernelExpression { |
| 144 KernelStaticGet(Member target) : super(target); |
| 145 |
| 146 @override |
| 147 DartType _inferExpression( |
| 148 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
| 149 return inferrer.inferStaticGet(typeContext, typeNeeded, target.getterType); |
| 150 } |
| 151 } |
| 152 |
| 113 /// Concrete implementation of [TypeInferrer] specialized to work with kernel | 153 /// Concrete implementation of [TypeInferrer] specialized to work with kernel |
| 114 /// objects. | 154 /// objects. |
| 115 class KernelTypeInferrer extends TypeInferrer<Statement, Expression, | 155 class KernelTypeInferrer extends TypeInferrer<Statement, Expression, |
| 116 KernelVariableDeclaration, Field> { | 156 KernelVariableDeclaration, KernelField> { |
| 117 KernelTypeInferrer(CoreTypes coreTypes, ClassHierarchy classHierarchy, | 157 KernelTypeInferrer(Instrumentation instrumentation, bool strongMode) |
| 118 Instrumentation instrumentation, bool strongMode) | 158 : super(instrumentation, strongMode); |
| 119 : super(coreTypes, classHierarchy, instrumentation, strongMode); | 159 |
| 160 @override |
| 161 void clearFieldInitializer(KernelField field) { |
| 162 field.initializer = null; |
| 163 } |
| 164 |
| 165 @override |
| 166 FieldNode<KernelField> createFieldNode(KernelField field) { |
| 167 FieldNode<KernelField> fieldNode = new FieldNode<KernelField>(this, field); |
| 168 field._fieldNode = fieldNode; |
| 169 return fieldNode; |
| 170 } |
| 171 |
| 172 @override |
| 173 DartType getFieldDeclaredType(KernelField field) { |
| 174 return field._implicitlyTyped ? null : field.type; |
| 175 } |
| 176 |
| 177 @override |
| 178 List<FieldNode<KernelField>> getFieldDependencies(KernelField field) { |
| 179 return field._fieldNode?.dependencies; |
| 180 } |
| 181 |
| 182 @override |
| 183 Expression getFieldInitializer(KernelField field) { |
| 184 return field.initializer; |
| 185 } |
| 186 |
| 187 @override |
| 188 FieldNode<KernelField> getFieldNodeForReadTarget(Member readTarget) { |
| 189 if (readTarget is KernelField) { |
| 190 return readTarget._fieldNode; |
| 191 } else { |
| 192 return null; |
| 193 } |
| 194 } |
| 195 |
| 196 @override |
| 197 int getFieldOffset(KernelField field) { |
| 198 return field.fileOffset; |
| 199 } |
| 200 |
| 201 @override |
| 202 String getFieldUri(KernelField field) { |
| 203 return field._fileUri; |
| 204 } |
| 120 | 205 |
| 121 @override | 206 @override |
| 122 DartType inferExpression( | 207 DartType inferExpression( |
| 123 Expression expression, DartType typeContext, bool typeNeeded) { | 208 Expression expression, DartType typeContext, bool typeNeeded) { |
| 124 if (expression is KernelExpression) { | 209 if (expression is KernelExpression) { |
| 125 // Use polymorphic dispatch on [KernelExpression] to perform whatever kind | 210 // Use polymorphic dispatch on [KernelExpression] to perform whatever kind |
| 126 // of type inference is correct for this kind of statement. | 211 // of type inference is correct for this kind of statement. |
| 127 // TODO(paulberry): experiment to see if dynamic dispatch would be better, | 212 // TODO(paulberry): experiment to see if dynamic dispatch would be better, |
| 128 // so that the type hierarchy will be simpler (which may speed up "is" | 213 // so that the type hierarchy will be simpler (which may speed up "is" |
| 129 // checks). | 214 // checks). |
| (...skipping 16 matching lines...) Expand all Loading... |
| 146 // so that the type hierarchy will be simpler (which may speed up "is" | 231 // so that the type hierarchy will be simpler (which may speed up "is" |
| 147 // checks). | 232 // checks). |
| 148 return statement._inferStatement(this); | 233 return statement._inferStatement(this); |
| 149 } else { | 234 } else { |
| 150 // Encountered a statement type for which type inference is not yet | 235 // Encountered a statement type for which type inference is not yet |
| 151 // implemented, so just skip it for now. | 236 // implemented, so just skip it for now. |
| 152 // TODO(paulberry): once the BodyBuilder uses shadow classes for | 237 // TODO(paulberry): once the BodyBuilder uses shadow classes for |
| 153 // everything, this case should no longer be needed. | 238 // everything, this case should no longer be needed. |
| 154 } | 239 } |
| 155 } | 240 } |
| 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 } |
| 156 } | 251 } |
| 157 | 252 |
| 158 /// Concrete shadow object representing a variable declaration in kernel form. | 253 /// Concrete shadow object representing a variable declaration in kernel form. |
| 159 class KernelVariableDeclaration extends VariableDeclaration | 254 class KernelVariableDeclaration extends VariableDeclaration |
| 160 implements KernelStatement { | 255 implements KernelStatement { |
| 161 final bool _implicitlyTyped; | 256 final bool _implicitlyTyped; |
| 162 | 257 |
| 163 KernelVariableDeclaration(String name, | 258 KernelVariableDeclaration(String name, |
| 164 {Expression initializer, | 259 {Expression initializer, |
| 165 DartType type, | 260 DartType type, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 186 KernelVariableGet(VariableDeclaration variable, [DartType promotedType]) | 281 KernelVariableGet(VariableDeclaration variable, [DartType promotedType]) |
| 187 : super(variable, promotedType); | 282 : super(variable, promotedType); |
| 188 | 283 |
| 189 @override | 284 @override |
| 190 DartType _inferExpression( | 285 DartType _inferExpression( |
| 191 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 286 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
| 192 // TODO(paulberry): implement. | 287 // TODO(paulberry): implement. |
| 193 return typeNeeded ? const DynamicType() : null; | 288 return typeNeeded ? const DynamicType() : null; |
| 194 } | 289 } |
| 195 } | 290 } |
| OLD | NEW |