| 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 import 'package:front_end/src/base/instrumentation.dart'; | 5 import 'package:front_end/src/base/instrumentation.dart'; |
| 6 import 'package:front_end/src/dependency_walker.dart' as dependencyWalker; | 6 import 'package:front_end/src/dependency_walker.dart' as dependencyWalker; |
| 7 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; | 7 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; |
| 8 import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart'
; | 8 import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart'
; |
| 9 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart'; | 9 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart'; |
| 10 import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart'
; | 10 import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart'
; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 | 28 |
| 29 FieldNode(this._typeInferenceEngine, this._field); | 29 FieldNode(this._typeInferenceEngine, this._field); |
| 30 | 30 |
| 31 @override | 31 @override |
| 32 bool get isEvaluated => _typeInferenceEngine.isFieldInferred(_field); | 32 bool get isEvaluated => _typeInferenceEngine.isFieldInferred(_field); |
| 33 | 33 |
| 34 @override | 34 @override |
| 35 List<FieldNode> computeDependencies() { | 35 List<FieldNode> computeDependencies() { |
| 36 return _typeInferenceEngine.computeFieldDependencies(this); | 36 return _typeInferenceEngine.computeFieldDependencies(this); |
| 37 } | 37 } |
| 38 |
| 39 @override |
| 40 String toString() => _field.toString(); |
| 38 } | 41 } |
| 39 | 42 |
| 40 /// Keeps track of the global state for the type inference that occurs outside | 43 /// Keeps track of the global state for the type inference that occurs outside |
| 41 /// of method bodies and initalizers. | 44 /// of method bodies and initalizers. |
| 42 /// | 45 /// |
| 43 /// This class describes the interface for use by clients of type inference | 46 /// This class describes the interface for use by clients of type inference |
| 44 /// (e.g. DietListener). Derived classes should derive from | 47 /// (e.g. DietListener). Derived classes should derive from |
| 45 /// [TypeInferenceEngineImpl]. | 48 /// [TypeInferenceEngineImpl]. |
| 46 abstract class TypeInferenceEngine { | 49 abstract class TypeInferenceEngine { |
| 47 ClassHierarchy get classHierarchy; | 50 ClassHierarchy get classHierarchy; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 75 void recordInitializingFormal(KernelVariableDeclaration formal); | 78 void recordInitializingFormal(KernelVariableDeclaration formal); |
| 76 } | 79 } |
| 77 | 80 |
| 78 /// Derived class containing generic implementations of | 81 /// Derived class containing generic implementations of |
| 79 /// [TypeInferenceEngineImpl]. | 82 /// [TypeInferenceEngineImpl]. |
| 80 /// | 83 /// |
| 81 /// This class contains as much of the implementation of type inference as | 84 /// This class contains as much of the implementation of type inference as |
| 82 /// possible without knowing the identity of the type parameter. It defers to | 85 /// possible without knowing the identity of the type parameter. It defers to |
| 83 /// abstract methods for everything else. | 86 /// abstract methods for everything else. |
| 84 abstract class TypeInferenceEngineImpl extends TypeInferenceEngine { | 87 abstract class TypeInferenceEngineImpl extends TypeInferenceEngine { |
| 88 /// Enables "expanded top level inference", which allows top level inference |
| 89 /// to support all expressions, not just those defined as "immediately |
| 90 /// evident" by https://github.com/dart-lang/sdk/pull/28218. |
| 91 /// |
| 92 /// Note that setting this value to `true` does not yet allow top level |
| 93 /// inference to depend on field and property accesses; that will require |
| 94 /// further work. TODO(paulberry): fix this. |
| 95 static const bool expandedTopLevelInference = true; |
| 96 |
| 85 final Instrumentation instrumentation; | 97 final Instrumentation instrumentation; |
| 86 | 98 |
| 87 final bool strongMode; | 99 final bool strongMode; |
| 88 | 100 |
| 89 final fieldNodes = <FieldNode>[]; | 101 final fieldNodes = <FieldNode>[]; |
| 90 | 102 |
| 91 final initializingFormals = <KernelVariableDeclaration>[]; | 103 final initializingFormals = <KernelVariableDeclaration>[]; |
| 92 | 104 |
| 93 @override | 105 @override |
| 94 CoreTypes coreTypes; | 106 CoreTypes coreTypes; |
| 95 | 107 |
| 96 @override | 108 @override |
| 97 ClassHierarchy classHierarchy; | 109 ClassHierarchy classHierarchy; |
| 98 | 110 |
| 99 TypeSchemaEnvironment typeSchemaEnvironment; | 111 TypeSchemaEnvironment typeSchemaEnvironment; |
| 100 | 112 |
| 101 TypeInferenceEngineImpl(this.instrumentation, this.strongMode); | 113 TypeInferenceEngineImpl(this.instrumentation, this.strongMode); |
| 102 | 114 |
| 103 /// Clears the initializer of [field]. | 115 /// Clears the initializer of [field]. |
| 104 void clearFieldInitializer(KernelField field); | 116 void clearFieldInitializer(KernelField field); |
| 105 | 117 |
| 106 /// Computes type inference dependencies for the given [field]. | 118 /// Computes type inference dependencies for the given [field]. |
| 107 List<FieldNode> computeFieldDependencies(FieldNode fieldNode) { | 119 List<FieldNode> computeFieldDependencies(FieldNode fieldNode) { |
| 108 // TODO(paulberry): add logic to infer field types by inheritance. | 120 // TODO(paulberry): add logic to infer field types by inheritance. |
| 109 if (fieldHasInitializer(fieldNode._field)) { | 121 if (fieldHasInitializer(fieldNode._field)) { |
| 110 var collector = new KernelDependencyCollector(); | 122 if (expandedTopLevelInference) { |
| 111 collector.collectDependencies(fieldNode._field.initializer); | 123 // In expanded top level inference, we determine the dependencies by |
| 112 fieldNode.isImmediatelyEvident = collector.isImmediatelyEvident; | 124 // doing a "dry run" of top level inference and recording which static |
| 113 return collector.dependencies; | 125 // fields were accessed. |
| 126 var typeInferrer = getFieldTypeInferrer(fieldNode._field); |
| 127 typeInferrer.startDryRun(); |
| 128 typeInferrer.listener.dryRunEnter(fieldNode._field.initializer); |
| 129 typeInferrer.inferFieldTopLevel(fieldNode._field, null, true); |
| 130 typeInferrer.listener.dryRunExit(fieldNode._field.initializer); |
| 131 fieldNode.isImmediatelyEvident = true; |
| 132 return typeInferrer.finishDryRun(); |
| 133 } else { |
| 134 // In non-expanded top level inference, we determine the dependencies by |
| 135 // calling `collectDependencies`; as a side effect this flags any |
| 136 // expressions that are not "immediately evident". |
| 137 // TODO(paulberry): get rid of this mode once we are sure we no longer |
| 138 // need it. |
| 139 var collector = new KernelDependencyCollector(); |
| 140 collector.collectDependencies(fieldNode._field.initializer); |
| 141 fieldNode.isImmediatelyEvident = collector.isImmediatelyEvident; |
| 142 return collector.dependencies; |
| 143 } |
| 114 } else { | 144 } else { |
| 115 return const []; | 145 return const []; |
| 116 } | 146 } |
| 117 } | 147 } |
| 118 | 148 |
| 119 /// Creates a [FieldNode] to track dependencies of the given [field]. | 149 /// Creates a [FieldNode] to track dependencies of the given [field]. |
| 120 FieldNode createFieldNode(KernelField field); | 150 FieldNode createFieldNode(KernelField field); |
| 121 | 151 |
| 122 /// Queries whether the given [field] has an initializer. | 152 /// Queries whether the given [field] has an initializer. |
| 123 bool fieldHasInitializer(KernelField field); | 153 bool fieldHasInitializer(KernelField field); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 } | 267 } |
| 238 | 268 |
| 239 @override | 269 @override |
| 240 void evaluateScc(List<FieldNode> scc) { | 270 void evaluateScc(List<FieldNode> scc) { |
| 241 // Mark every field as part of a circularity. | 271 // Mark every field as part of a circularity. |
| 242 for (var f in scc) { | 272 for (var f in scc) { |
| 243 f._typeInferenceEngine.inferFieldCircular(f._field); | 273 f._typeInferenceEngine.inferFieldCircular(f._field); |
| 244 } | 274 } |
| 245 } | 275 } |
| 246 } | 276 } |
| OLD | NEW |