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

Unified Diff: sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart

Issue 22398008: Refactor and reorganize type inference classes before porting ConcreteTypesInferrer to InferrerVisi… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Sync to head and fix imports in tests Created 7 years, 4 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
Index: sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
diff --git a/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart b/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
index 86602247a6ca606ebf50b26d8233b2e5673a9cba..00c9295b7b2e5edca100e04e89480302a43f79fc 100644
--- a/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
@@ -2,7 +2,14 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of simple_types_inferrer;
+library inferrer_visitor;
+
+import '../dart2jslib.dart' hide Selector, TypedSelector;
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../tree/tree.dart';
+import '../universe/universe.dart';
+import '../util/util.dart';
/**
* The interface [InferrerVisitor] will use when working on types.
@@ -75,106 +82,6 @@ abstract class TypeSystem<T> {
}
/**
- * An implementation of [TypeSystem] for [TypeMask].
- */
-class TypeMaskSystem implements TypeSystem<TypeMask> {
- final Compiler compiler;
- TypeMaskSystem(this.compiler);
-
- TypeMask narrowType(TypeMask type,
- DartType annotation,
- {bool isNullable: true}) {
- if (annotation.treatAsDynamic) return type;
- if (annotation.isVoid) return nullType;
- if (annotation.element == compiler.objectClass) return type;
- TypeMask otherType;
- if (annotation.kind == TypeKind.TYPEDEF
- || annotation.kind == TypeKind.FUNCTION) {
- otherType = functionType;
- } else if (annotation.kind == TypeKind.TYPE_VARIABLE) {
- // TODO(ngeoffray): Narrow to bound.
- return type;
- } else {
- assert(annotation.kind == TypeKind.INTERFACE);
- otherType = new TypeMask.nonNullSubtype(annotation);
- }
- if (isNullable) otherType = otherType.nullable();
- if (type == null) return otherType;
- return type.intersection(otherType, compiler);
- }
-
- TypeMask computeLUB(TypeMask firstType, TypeMask secondType) {
- if (firstType == null) {
- return secondType;
- } else if (secondType == dynamicType || firstType == dynamicType) {
- return dynamicType;
- } else if (firstType == secondType) {
- return firstType;
- } else {
- TypeMask union = firstType.union(secondType, compiler);
- // TODO(kasperl): If the union isn't nullable it seems wasteful
- // to use dynamic. Fix that.
- return union.containsAll(compiler) ? dynamicType : union;
- }
- }
-
- TypeMask allocateDiamondPhi(TypeMask firstType, TypeMask secondType) {
- return computeLUB(firstType, secondType);
- }
-
- TypeMask get dynamicType => compiler.typesTask.dynamicType;
- TypeMask get nullType => compiler.typesTask.nullType;
- TypeMask get intType => compiler.typesTask.intType;
- TypeMask get doubleType => compiler.typesTask.doubleType;
- TypeMask get numType => compiler.typesTask.numType;
- TypeMask get boolType => compiler.typesTask.boolType;
- TypeMask get functionType => compiler.typesTask.functionType;
- TypeMask get listType => compiler.typesTask.listType;
- TypeMask get constListType => compiler.typesTask.constListType;
- TypeMask get fixedListType => compiler.typesTask.fixedListType;
- TypeMask get growableListType => compiler.typesTask.growableListType;
- TypeMask get mapType => compiler.typesTask.mapType;
- TypeMask get constMapType => compiler.typesTask.constMapType;
- TypeMask get stringType => compiler.typesTask.stringType;
- TypeMask get typeType => compiler.typesTask.typeType;
-
- TypeMask nonNullSubtype(DartType type) => new TypeMask.nonNullSubtype(type);
- TypeMask nonNullSubclass(DartType type) => new TypeMask.nonNullSubclass(type);
- TypeMask nonNullExact(DartType type) => new TypeMask.nonNullExact(type);
- TypeMask nonNullEmpty() => new TypeMask.nonNullEmpty();
-
- TypeMask nullable(TypeMask type) {
- return type.nullable();
- }
-
- TypeMask allocateContainer(TypeMask type,
- Node node,
- Element enclosing,
- [TypeMask elementType, int length]) {
- ContainerTypeMask mask = new ContainerTypeMask(type, node, enclosing);
- mask.elementType = elementType;
- mask.length = length;
- return mask;
- }
-
- Selector newTypedSelector(TypeMask receiver, Selector selector) {
- return new TypedSelector(receiver, selector);
- }
-
- TypeMask addPhiInput(Element element, TypeMask phiType, TypeMask newType) {
- return computeLUB(phiType, newType);
- }
-
- TypeMask allocatePhi(Node node, Element element, TypeMask inputType) {
- return inputType;
- }
-
- TypeMask simplifyPhi(Node node, Element element, TypeMask phiType) {
- return phiType;
- }
-}
-
-/**
* A variable scope holds types for variables. It has a link to a
* parent scope, but never changes the types in that parent. Instead,
* updates to locals of a parent scope are put in the current scope.
@@ -304,12 +211,73 @@ class FieldInitializationScope<T> {
}
/**
+ * Placeholder for inferred arguments types on sends.
+ */
+class ArgumentsTypes<T> {
+ final List<T> positional;
+ final Map<SourceString, T> named;
+ ArgumentsTypes(this.positional, named)
+ : this.named = (named == null) ? new Map<SourceString, T>() : named;
+
+ int get length => positional.length + named.length;
+
+ String toString() => "{ positional = $positional, named = $named }";
+
+ bool operator==(other) {
+ if (positional.length != other.positional.length) return false;
+ if (named.length != other.named.length) return false;
+ for (int i = 0; i < positional.length; i++) {
+ if (positional[i] != other.positional[i]) return false;
+ }
+ named.forEach((name, type) {
+ if (other.named[name] != type) return false;
+ });
+ return true;
+ }
+
+ int get hashCode => throw new UnsupportedError('ArgumentsTypes.hashCode');
+
+ bool hasNoArguments() => positional.isEmpty && named.isEmpty;
+
+ bool hasOnePositionalArgumentWithType(T type) {
+ return named.isEmpty && positional.length == 1 && positional[0] == type;
+ }
+}
+
+class CallSite {
+ final Selector selector;
+ final ArgumentsTypes arguments;
+ CallSite(this.selector, this.arguments) {
+ assert(selector != null);
+ }
+}
+
+abstract class MinimalInferrerEngine<T> {
+ /**
+ * Returns the type of [element].
+ */
+ T typeOfElement(Element element);
+
+ /**
+ * Records that [node] sets non-final field [element] to be of type
+ * [type].
+ *
+ * [constraint] is a field assignment constraint, as described in
+ * [InternalSimpleTypesInferrer].
+ */
+ void recordTypeOfNonFinalField(Node node,
+ Element field,
+ T type,
+ CallSite constraint);
+}
+
+/**
* Placeholder for inferred types of local variables.
*/
class LocalsHandler<T> {
final Compiler compiler;
final TypeSystem<T> types;
- final InferrerEngine<T> inferrer;
+ final MinimalInferrerEngine<T> inferrer;
final VariableScope<T> locals;
final Map<Element, Element> capturedAndBoxed;
final FieldInitializationScope<T> fieldScope;
@@ -535,10 +503,11 @@ class LocalsHandler<T> {
}
}
-abstract class InferrerVisitor<T> extends ResolvedVisitor<T> {
+abstract class InferrerVisitor
+ <T, E extends MinimalInferrerEngine<T>> extends ResolvedVisitor<T> {
final Element analyzedElement;
final TypeSystem<T> types;
- final InferrerEngine<T> inferrer;
+ final E inferrer;
final Compiler compiler;
final Map<TargetElement, List<LocalsHandler<T>>> breaksFor =
new Map<TargetElement, List<LocalsHandler<T>>>();

Powered by Google App Engine
This is Rietveld 408576698