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

Unified Diff: sdk/lib/_internal/compiler/implementation/dart_types.dart

Issue 18721005: Add order to DartType. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased + updated cf. comments. Created 7 years, 3 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 | « no previous file | sdk/lib/_internal/compiler/implementation/elements/elements.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/compiler/implementation/dart_types.dart
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
index f7a43851308fd8953e5de5e20ffc65a781a27a4c..f301f9b04ba697240f45788213cb15ed98e001f5 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -1193,6 +1193,150 @@ class Types {
if (typeVariable == null) return null;
return typeVariable.element.enclosingElement;
}
+
+ /**
+ * A `compareTo` function that globally orders types using
+ * [Elements.compareByPosition] to order types defined by a declaration.
+ *
+ * The order is:
+ * * void
+ * * dynamic
+ * * interface, typedef, type variables ordered by element order
+ * - interface and typedef of the same element are ordered by
+ * the order of their type arguments
+ * * function types, ordered by
+ * - return type
+ * - required parameter types
+ * - optional parameter types
+ * - named parameter names
+ * - named parameter types
+ * * malformed types
+ * * statement types
+ */
+ static int compare(DartType a, DartType b) {
+ if (a == b) return 0;
+ if (a.kind == TypeKind.VOID) {
+ // [b] is not void => a < b.
+ return -1;
+ } else if (b.kind == TypeKind.VOID) {
+ // [a] is not void => a > b.
+ return 1;
+ }
+ if (a.isDynamic) {
+ // [b] is not dynamic => a < b.
+ return -1;
+ } else if (b.isDynamic) {
+ // [a] is not dynamic => a > b.
+ return 1;
+ }
+ bool isDefinedByDeclaration(DartType type) {
+ return type.kind == TypeKind.INTERFACE ||
+ type.kind == TypeKind.TYPEDEF ||
+ type.kind == TypeKind.TYPE_VARIABLE;
+ }
+
+ if (isDefinedByDeclaration(a)) {
+ if (isDefinedByDeclaration(b)) {
+ int result = Elements.compareByPosition(a.element, b.element);
+ if (result != 0) return result;
+ if (a.kind == TypeKind.TYPE_VARIABLE) {
+ return b.kind == TypeKind.TYPE_VARIABLE
+ ? 0
+ : 1; // [b] is not a type variable => a > b.
+ } else {
+ if (b.kind == TypeKind.TYPE_VARIABLE) {
+ // [a] is not a type variable => a < b.
+ return -1;
+ } else {
+ return compareList((a as GenericType).typeArguments,
+ (b as GenericType).typeArguments);
+ }
+ }
+ } else {
+ // [b] is neither an interface, typedef, type variable, dynamic,
+ // nor void => a < b.
+ return -1;
+ }
+ } else if (isDefinedByDeclaration(b)) {
+ // [a] is neither an interface, typedef, type variable, dynamic,
+ // nor void => a > b.
+ return 1;
+ }
+ if (a.kind == TypeKind.FUNCTION) {
+ if (b.kind == TypeKind.FUNCTION) {
+ FunctionType aFunc = a;
+ FunctionType bFunc = b;
+ int result = compare(aFunc.returnType, bFunc.returnType);
+ if (result != 0) return result;
+ result = compareList(aFunc.parameterTypes, bFunc.parameterTypes);
+ if (result != 0) return result;
+ result = compareList(aFunc.optionalParameterTypes,
+ bFunc.optionalParameterTypes);
+ if (result != 0) return result;
+ Link<SourceString> aNames = aFunc.namedParameters;
+ Link<SourceString> bNames = bFunc.namedParameters;
+ while (!aNames.isEmpty && !bNames.isEmpty) {
+ int result = aNames.head.slowToString().compareTo(
+ bNames.head.slowToString());
+ if (result != 0) return result;
+ aNames = aNames.tail;
+ bNames = bNames.tail;
+ }
+ if (!aNames.isEmpty) {
+ // [aNames] is longer that [bNames] => a > b.
+ return 1;
+ } else if (!bNames.isEmpty) {
+ // [bNames] is longer that [aNames] => a < b.
+ return -1;
+ }
+ return compareList(aFunc.namedParameterTypes,
+ bFunc.namedParameterTypes);
+ } else {
+ // [b] is a malformed or statement type => a < b.
+ return -1;
+ }
+ } else if (b.kind == TypeKind.FUNCTION) {
+ // [b] is a malformed or statement type => a > b.
+ return 1;
+ }
+ if (a.kind == TypeKind.STATEMENT) {
+ if (b.kind == TypeKind.STATEMENT) {
+ return (a as StatementType).stringName.compareTo(
+ (b as StatementType).stringName);
+ } else {
+ // [b] is a malformed type => a > b.
+ return 1;
+ }
+ } else if (b.kind == TypeKind.STATEMENT) {
+ // [a] is a malformed type => a < b.
+ return -1;
+ }
+ assert (a.kind == TypeKind.MALFORMED_TYPE);
+ assert (b.kind == TypeKind.MALFORMED_TYPE);
+ // TODO(johnniwinther): Can we do this better?
+ return Elements.compareByPosition(a.element, b.element);
+ }
+
+ static int compareList(Link<DartType> a, Link<DartType> b) {
+ while (!a.isEmpty && !b.isEmpty) {
+ int result = compare(a.head, b.head);
+ if (result != 0) return result;
+ a = a.tail;
+ b = b.tail;
+ }
+ if (!a.isEmpty) {
+ // [a] is longer than [b] => a > b.
+ return 1;
+ } else if (!b.isEmpty) {
+ // [b] is longer than [a] => a < b.
+ return -1;
+ }
+ return 0;
+ }
+
+ static List<DartType> sorted(Iterable<DartType> types) {
+ return types.toList()..sort(compare);
+ }
}
/**
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/elements/elements.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698