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

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

Issue 11557010: Implement subtype checks on type arguments. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address Kasper's comments. Created 8 years 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/lib/js_helper.dart
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
index 3fa0f5df29a5183c84c48a74249baae5d98946e5..77a0c9c44c2f23841a5dd2f7b99ebeef96a253b9 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
@@ -1632,23 +1632,22 @@ String getClassName(var object) {
}
String getTypeArgumentAsString(List runtimeType) {
- String className = runtimeTypeToString(runtimeType[0]);
+ String className = getConstructorName(runtimeType[0]);
if (runtimeType.length == 1) return className;
return '$className<${joinArguments(runtimeType, 1)}>';
}
+String getConstructorName(type) => JS('String', r'#.builtin$cls', type);
+
String runtimeTypeToString(type) {
if (type == null) {
return 'dynamic';
- } else if (type is String) {
- // A native class. The string is the unique name.
- return type;
} else if (isJsArray(type)) {
// A list representing a type with arguments.
return getTypeArgumentAsString(type);
} else {
// A reference to the constructor.
- return JS('String', r'#.builtin$cls', type);
+ return getConstructorName(type);
}
}
@@ -1674,13 +1673,37 @@ String getRuntimeTypeString(var object) {
return "$className<${joinArguments(typeInfo, 0)}>";
}
+/**
+ * Check whether the type represented by [s] is a subtype of the type
+ * represented by [t].
+ *
+ * Type representations can be:
+ * 1) a JavaScript constructor for a class C: the represented type is the raw
+ * type C.
+ * 2) a JavaScript object: this represents a class for which there is no
+ * JavaScript constructor, because it is only used in type arguments or it
+ * is native. The represented type is the raw type of this class.
+ * 3) a JavaScript array: the first entry is of type 1 or 2 and identifies the
+ * class of the type and the rest of the array are the type arguments.
+ * 4) [:null:]: the dynamic type.
+ */
bool isSubtype(var s, var t) {
+ // If either type is dynamic, [s] is a subtype of [t].
if (s == null || t == null) return true;
- if (!isJsArray(s)) return s == t;
- // TODO(karlklose): support subtyping: if s[0] != t[0], check if there is
- // a function is$s[0] on t[0] and call it with substitutes type arguments.
- if (s[0] != t[0]) return false;
+ // Subtyping is reflexive.
+ if (s == t) return true;
+ // Get the object describing the class and check for the subtyping flag
+ // constructed from the type of [t].
+ var typeOfS = isJsArray(s) ? s[0] : s;
+ var typeOfT = isJsArray(t) ? t[0] : t;
+ var test = 'is\$${runtimeTypeToString(typeOfT)}';
+ if (JS('var', r'#[#]', typeOfS, test) == null) return false;
+ // The class of [s] is a subclass of the class of [t]. If either of the types
+ // is raw, [s] is a subtype of [t].
+ if (!isJsArray(s) || !isJsArray(t)) return true;
+ // Recursively check the type arguments.
int len = s.length;
+ if (len != t.length) return false;
for (int i = 1; i < len; i++) {
if (!isSubtype(s[i], t[i])) {
return false;

Powered by Google App Engine
This is Rietveld 408576698