Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(703)

Unified Diff: pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart

Issue 2830313002: Split up TypeInferrer class. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index e32850006ba4975f8375ba40c568fa5d0fded9e3..caa08103a55fbb2c0c783274d018a83a1db49b85 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -3,101 +3,67 @@
// BSD-style license that can be found in the LICENSE.md file.
import 'package:front_end/src/base/instrumentation.dart';
-import 'package:front_end/src/dependency_walker.dart' as dependencyWalker;
-import 'package:kernel/ast.dart' show DartType, DynamicType, Member;
-import 'package:kernel/class_hierarchy.dart';
+import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
+import 'package:kernel/ast.dart' show DartType, Member;
import 'package:kernel/core_types.dart';
-/// Data structure for tracking dependencies between fields that require type
-/// inference.
+/// Keeps track of the local state for the type inference that occurs during
+/// compilation of a single method body or top level initializer.
///
-/// TODO(paulberry): see if it's possible to make this class more lightweight
-/// by changing the API so that the walker is passed to computeDependencies().
-/// (This should allow us to drop the _typeInferrer field).
-class FieldNode<F> extends dependencyWalker.Node<FieldNode<F>> {
- final TypeInferrer _typeInferrer;
-
- final F _field;
-
- final dependencies = <FieldNode<F>>[];
-
- FieldNode(this._typeInferrer, this._field);
-
- @override
- bool get isEvaluated => _typeInferrer.isFieldInferred(_field);
-
- @override
- List<FieldNode<F>> computeDependencies() {
- return dependencies;
- }
-}
-
-/// Abstract implementation of type inference which is independent of the
-/// underlying AST representation (but still uses DartType from kernel).
-///
-/// TODO(paulberry): would it make more sense to abstract away the
-/// representation of types as well?
+/// This class abstracts away the representation of the underlying AST using
+/// generic parameters. TODO(paulberry): would it make more sense to abstract
+/// away the representation of types as well?
///
/// Derived classes should set S, E, V, and F to the class they use to represent
/// statements, expressions, variable declarations, and field declarations,
/// respectively.
+///
+/// This class describes the interface for use by clients of type inference
+/// (e.g. BodyBuilder). Derived classes should derive from [TypeInferrerImpl].
abstract class TypeInferrer<S, E, V, F> {
- final Instrumentation instrumentation;
-
- final bool strongMode;
-
- final fieldNodes = <FieldNode<F>>[];
-
- CoreTypes coreTypes;
-
- ClassHierarchy classHierarchy;
-
/// The URI of the code for which type inference is currently being
/// performed--this is used for testing.
- String uri;
+ String get uri;
- /// Indicates whether we are currently performing top level inference.
- bool isTopLevel = false;
+ /// Gets the [FieldNode] corresponding to the given [readTarget], if any.
+ FieldNode<F> getFieldNodeForReadTarget(Member readTarget);
- TypeInferrer(this.instrumentation, this.strongMode);
+ /// Performs type inference on the given [statement].
+ ///
+ /// Derived classes should override this method with logic that dispatches on
+ /// the statement type and calls the appropriate specialized "infer" method.
+ void inferStatement(S statement);
+}
- /// Cleares the initializer of [field].
- void clearFieldInitializer(F field);
+/// Derived class containing generic implementations of [TypeInferrerImpl].
+///
+/// This class contains as much of the implementation of type inference as
+/// possible without knowing the identity of the type parameters. It defers to
+/// abstract methods for everything else.
+abstract class TypeInferrerImpl<S, E, V, F> extends TypeInferrer<S, E, V, F> {
+ @override
+ final String uri;
+
+ /// Indicates whether the construct we are currently performing inference for
+ /// is outside of a method body, and hence top level type inference rules
+ /// should apply.
+ final bool isTopLevel = false;
+
+ final CoreTypes coreTypes;
- /// Creates a [FieldNode] to track dependencies of the given [field].
- FieldNode<F> createFieldNode(F field);
+ final bool strongMode;
- /// Gets the declared type of the given [field], or `null` if the type is
- /// implicit.
- DartType getFieldDeclaredType(F field);
+ final Instrumentation instrumentation;
- /// Gets the list of top level type inference dependencies of the given
- /// [field].
- List<FieldNode<F>> getFieldDependencies(F field);
+ TypeInferrerImpl(TypeInferenceEngineImpl<F> engine, this.uri)
+ : coreTypes = engine.coreTypes,
+ strongMode = engine.strongMode,
+ instrumentation = engine.instrumentation;
/// Gets the initializer for the given [field], or `null` if there is no
/// initializer.
E getFieldInitializer(F field);
- /// Gets the [FieldNode] corresponding to the given [readTarget], if any.
- FieldNode<F> getFieldNodeForReadTarget(Member readTarget);
-
- /// Gets the character offset of the declaration of [field] within its
- /// compilation unit.
- int getFieldOffset(F field);
-
- /// Gets the URI of the compilation unit the [field] is declared in.
- String getFieldUri(F field);
-
- /// Performs type inference on a method with the given method [body].
- ///
- /// [uri] is the URI of the file the method is contained in--this is used for
- /// testing.
- void inferBody(S body, Uri uri) {
- this.uri = uri.toString();
- inferStatement(body);
- }
-
/// Performs type inference on the given [expression].
///
/// [typeContext] is the expected type of the expression, based on surrounding
@@ -109,42 +75,11 @@ abstract class TypeInferrer<S, E, V, F> {
/// the expression type and calls the appropriate specialized "infer" method.
DartType inferExpression(E expression, DartType typeContext, bool typeNeeded);
- /// Performs type inference on the given [field].
- void inferField(F field) {
- var initializer = getFieldInitializer(field);
- if (initializer != null) {
- var type = getFieldDeclaredType(field);
- uri = getFieldUri(field);
- isTopLevel = true;
- var inferredType = inferExpression(initializer, type, type == null);
- if (type == null && strongMode) {
- instrumentation?.record(
- 'topType',
- Uri.parse(uri),
- getFieldOffset(field),
- new InstrumentationValueForType(inferredType));
- setFieldInferredType(field, inferredType);
- }
- // TODO(paulberry): if type != null, then check that the type of the
- // initializer is assignable to it.
- // TODO(paulberry): the following is a hack so that outlines don't contain
- // initializers. But it means that we rebuild the initializers when doing
- // a full compile. There should be a better way.
- clearFieldInitializer(field);
- }
- }
-
- /// Makes a note that the given [field] is part of a circularity, so its type
- /// can't be inferred.
- void inferFieldCircular(F field) {
- // TODO(paulberry): report the appropriate error.
- if (getFieldDeclaredType(field) == null) {
- var uri = getFieldUri(field);
- instrumentation?.record('topType', Uri.parse(uri), getFieldOffset(field),
- const InstrumentationValueLiteral('circular'));
- setFieldInferredType(field, const DynamicType());
- }
- }
+ /// Performs type inference on the given [field]'s initializer expression.
+ ///
+ /// Derived classes should provide an implementation that calls
+ /// [inferExpression] for the given [field]'s initializer expression.
+ DartType inferFieldInitializer(F field, DartType type, bool typeNeeded);
/// Performs the core type inference algorithm for integer literals.
///
@@ -154,12 +89,6 @@ abstract class TypeInferrer<S, E, V, F> {
return typeNeeded ? coreTypes.intClass.rawType : null;
}
- /// Performs type inference on the given [statement].
- ///
- /// Derived classes should override this method with logic that dispatches on
- /// the statement type and calls the appropriate specialized "infer" method.
- void inferStatement(S statement);
-
/// Performs the core type inference algorithm for static variable getters.
///
/// [typeContext], [typeNeeded], and the return value behave as described in
@@ -190,45 +119,4 @@ abstract class TypeInferrer<S, E, V, F> {
setType(inferredType);
}
}
-
- /// Determines if top level type inference has been completed for [field].
- bool isFieldInferred(F field);
-
- /// Performs top level type inference for all fields that have been passed to
- /// [recordField].
- void performInitializerInference() {
- for (var fieldNode in fieldNodes) {
- if (fieldNode.isEvaluated) continue;
- new _FieldWalker<F>().walk(fieldNode);
- }
- }
-
- /// Records that the given [field] will need top level type inference.
- void recordField(F field) {
- fieldNodes.add(createFieldNode(field));
- }
-
- /// Stores [inferredType] as the inferred type of [field].
- void setFieldInferredType(F field, DartType inferredType);
-}
-
-/// Subtype of [dependencyWalker.DependencyWalker] which is specialized to
-/// perform top level type inference.
-class _FieldWalker<F> extends dependencyWalker.DependencyWalker<FieldNode<F>> {
- _FieldWalker();
-
- @override
- void evaluate(FieldNode<F> f) {
- f._typeInferrer.inferField(f._field);
- }
-
- @override
- void evaluateScc(List<FieldNode<F>> scc) {
- for (var f in scc) {
- f._typeInferrer.inferFieldCircular(f._field);
- }
- for (var f in scc) {
- f._typeInferrer.inferField(f._field);
- }
- }
}
« no previous file with comments | « pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698