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 |