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

Unified Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 1179343004: Refactor least upper bound computation; support bottom correctly. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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: pkg/analyzer/lib/src/generated/resolver.dart
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index d4eee826ddcff6ff8e2851183745f19500163583..dcdc71d0fc2881d65602576a598d1f6123901659 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -14925,6 +14925,114 @@ class TypeResolverVisitor extends ScopedVisitor {
}
/**
+ * The interface `TypeSystem` defines the behavior of an object representing
+ * the type system. This provides a common location to put methods that act on
+ * types but may need access to more global data structures, and it paves the
+ * way for a possible future where we may wish to make the type system
+ * pluggable.
+ */
+abstract class TypeSystem {
+ /**
+ * Return the [TypeProvider] associated with this [TypeSystem].
+ */
+ TypeProvider get typeProvider;
+
+ /**
+ * Compute the least upper bound of two types.
+ */
+ DartType getLeastUpperBound(DartType type1, DartType type2);
+}
+
+/**
+ * Implementation of [TypeSystem] using the rules in the Dart specification.
+ */
+class TypeSystemImpl implements TypeSystem {
+ @override
+ final TypeProvider typeProvider;
+
+ TypeSystemImpl(this.typeProvider);
+
+ @override
+ DartType getLeastUpperBound(DartType type1, DartType type2) {
+ // The least upper bound relation is reflexive.
+ if (identical(type1, type2)) {
+ return type1;
+ }
+ // The least upper bound of dynamic and any type T is dynamic.
+ if (type1.isDynamic) {
+ return type1;
+ }
+ if (type2.isDynamic) {
+ return type2;
+ }
+ // The least upper bound of void and any type T != dynamic is void.
+ if (type1.isVoid) {
+ return type1;
+ }
+ if (type2.isVoid) {
+ return type2;
+ }
+ // The least upper bound of bottom and any type T is T.
+ if (type1.isBottom) {
+ return type2;
+ }
+ if (type2.isBottom) {
+ return type1;
+ }
+ // Let U be a type variable with upper bound B. The least upper bound of U
+ // and a type T is the least upper bound of B and T.
+ while (type1 is TypeParameterType) {
+ // TODO(paulberry): is this correct in the complex of F-bounded
+ // polymorphism?
+ DartType bound = (type1 as TypeParameterType).element.bound;
+ if (bound == null) {
+ bound = typeProvider.objectType;
+ }
+ type1 = bound;
+ }
+ while (type2 is TypeParameterType) {
+ // TODO(paulberry): is this correct in the context of F-bounded
+ // polymorphism?
+ DartType bound = (type2 as TypeParameterType).element.bound;
+ if (bound == null) {
+ bound = typeProvider.objectType;
+ }
+ type2 = bound;
+ }
+ // The least upper bound of a function type and an interface type T is the
+ // least upper bound of Function and T.
+ if (type1 is FunctionType && type2 is InterfaceType) {
+ type1 = typeProvider.functionType;
+ }
+ if (type2 is FunctionType && type1 is InterfaceType) {
+ type2 = typeProvider.functionType;
+ }
+
+ // At this point type1 and type2 should both either be interface types or
+ // function types.
+ if (type1 is InterfaceType && type2 is InterfaceType) {
+ InterfaceType result =
+ InterfaceTypeImpl.computeLeastUpperBound(type1, type2);
+ if (result == null) {
+ return typeProvider.dynamicType;
+ }
+ return result;
+ } else if (type1 is FunctionType && type2 is FunctionType) {
+ FunctionType result =
+ FunctionTypeImpl.computeLeastUpperBound(type1, type2);
+ if (result == null) {
+ return typeProvider.functionType;
+ }
+ return result;
+ } else {
+ // Should never happen. As a defensive measure, return the dynamic type.
+ assert(false);
Brian Wilkerson 2015/06/16 21:35:19 We should log information about which types we hav
+ return typeProvider.dynamicType;
+ }
+ }
+}
+
+/**
* Instances of the class [UnusedLocalElementsVerifier] traverse an element
* structure looking for cases of [HintCode.UNUSED_ELEMENT],
* [HintCode.UNUSED_FIELD], [HintCode.UNUSED_LOCAL_VARIABLE], etc.

Powered by Google App Engine
This is Rietveld 408576698