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

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

Issue 12018015: Implement substitution for type variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Removed obsolete function. Created 7 years, 11 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/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 1014f047542f1e7c1666ef7752768e05f228991f..9aabb41a9ff2daa2d5db3ad06de0ae7e9c7e3b07 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
@@ -1054,12 +1054,12 @@ setRuntimeTypeInfo(target, typeInfo) {
getRuntimeTypeInfo(target) {
if (target == null) return null;
- var res = JS('var', r'#.$builtinTypeInfo', target);
- // If the object does not have runtime type information, return an
- // empty literal, to avoid null checks.
- // TODO(ngeoffray): Make the object a top-level field to avoid
- // allocating a new object every single time.
- return (res == null) ? JS('var', '{}') : res;
+ return JS('var', r'#.$builtinTypeInfo', target);
+}
+
+getRuntimeTypeArgument(target, index) {
+ var rti = getRuntimeTypeInfo(target);
+ return (rti != null) ? JS('var', r'#[#]', rti, index) : null;
}
/**
@@ -1421,7 +1421,7 @@ String getClassName(var object) {
return JS('String', r'#.constructor.builtin$cls', object);
}
-String getTypeArgumentAsString(List runtimeType) {
+String getRuntimeTypeAsString(List runtimeType) {
String className = getConstructorName(runtimeType[0]);
if (runtimeType.length == 1) return className;
return '$className<${joinArguments(runtimeType, 1)}>';
@@ -1434,7 +1434,7 @@ String runtimeTypeToString(type) {
return 'dynamic';
} else if (isJsArray(type)) {
// A list representing a type with arguments.
- return getTypeArgumentAsString(type);
+ return getRuntimeTypeAsString(type);
} else {
// A reference to the constructor.
return getConstructorName(type);
@@ -1463,6 +1463,50 @@ String getRuntimeTypeString(var object) {
return "$className<${joinArguments(typeInfo, 0)}>";
}
+bool isJsFunction(var o) => JS('bool', r"typeof # == 'function'", o);
+
+Object invoke(function, arguments) {
+ return JS('var', r'#.apply(null, #)', function, arguments);
+}
+
+/**
+ * Check that the types in the list [arguments] are subtypes of the types in
+ * list [checks] (at the respective positions), possibly applying [substitution]
+ * to the arguments before the check.
+ *
+ * See [:RuntimeTypes.getSubtypeSubstitution:] for a description of the possible
+ * values for [substitution].
+ */
+bool checkArguments(var substitution, var arguments, var checks) {
+ if (isJsArray(substitution)) {
+ arguments = substitution;
+ } else if (isJsFunction(substitution)) {
+ arguments = invoke(substitution, arguments);
+ }
+ return areSubtypes(arguments, checks);
+}
+
+bool areSubtypes(var s, var t) {
+ // [:null:] means a raw type.
+ if (s == null || t == null) return true;
+
+ if (!isJsArray(s)) throw 's not an array';
kasperl 2013/01/29 15:02:34 Change to asserts?
karlklose 2013/01/30 12:01:19 Done.
+ if (!isJsArray(t)) throw 't not an array';
+ if (s.length != t.length) throw 'size mismatch';
+
+ int len = s.length;
+ for (int i = 0; i < len; i++) {
+ if (!isSubtype(s[i], t[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+var getArguments(var type) => JS('var', r'#.slice(1)', type);
kasperl 2013/01/29 15:02:34 var isn't a legal return type.
karlklose 2013/01/30 12:01:19 Done.
+
+var getField(var object, String name) => JS('var', r'#[#]', object, name);
kasperl 2013/01/29 15:02:34 var isn't a legal return type.
karlklose 2013/01/30 12:01:19 Done.
+
/**
* Check whether the type represented by [s] is a subtype of the type
* represented by [t].
@@ -1486,20 +1530,20 @@ bool isSubtype(var s, var t) {
// constructed from the type of [t].
var typeOfS = isJsArray(s) ? s[0] : s;
var typeOfT = isJsArray(t) ? t[0] : t;
+ // Check for a subtyping flag.
var test = '${JS_OPERATOR_IS_PREFIX()}${runtimeTypeToString(typeOfT)}';
- if (JS('var', r'#[#]', typeOfS, test) == null) return false;
+ if (getField(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;
- }
+ // Get the necessary substitution of the type arguments, if there is one.
+ var substitution;
+ if (JS('bool', '# !== #', typeOfT, typeOfS)) {
+ var field = '${JS_OPERATOR_AS_PREFIX()}${runtimeTypeToString(typeOfT)}';
+ substitution = getField(typeOfS, field);
}
- return true;
+ // Recursively check the type arguments.
+ return checkArguments(substitution, getArguments(s), getArguments(t));
}
createRuntimeType(String name) => new TypeImpl(name);

Powered by Google App Engine
This is Rietveld 408576698