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

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

Issue 10540048: Implement 'as' operator. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update semantics to not throw on null. Merge to head. Created 8 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: lib/compiler/implementation/lib/js_helper.dart
diff --git a/lib/compiler/implementation/lib/js_helper.dart b/lib/compiler/implementation/lib/js_helper.dart
index a7b2f06a280802240ec6c0f0e40707368b3c3077..a7322c040cef705ad3cbc17f44015ad8389e5061 100644
--- a/lib/compiler/implementation/lib/js_helper.dart
+++ b/lib/compiler/implementation/lib/js_helper.dart
@@ -978,8 +978,8 @@ getRuntimeTypeInfo(target) {
/**
* The following methods are called by the runtime to implement
- * checked mode. We specialize each primitive type (eg int, bool), and
- * use the compiler's convention to do is checks on regular objects.
+ * checked mode and casts. We specialize each primitive type (eg int, bool), and
+ * use the compiler's convention to do is-checks on regular objects.
*/
stringTypeCheck(value) {
if (value === null) return value;
@@ -987,42 +987,78 @@ stringTypeCheck(value) {
throw new TypeError('$value does not implement String');
}
+stringTypeCast(value) {
+ if (value is String || value === null) return value;
+ throw new CastException(value, 'String');
+}
+
doubleTypeCheck(value) {
if (value === null) return value;
if (value is double) return value;
throw new TypeError('$value does not implement double');
}
+doubleTypeCast(value) {
+ if (value is double || value === null) return value;
+ throw new CastException(value, 'double');
+}
+
numTypeCheck(value) {
if (value === null) return value;
if (value is num) return value;
throw new TypeError('$value does not implement num');
}
+numTypeCast(value) {
+ if (value is num || value === null) return value;
+ throw new CastException(value, 'num');
+}
+
boolTypeCheck(value) {
if (value === null) return value;
if (value is bool) return value;
throw new TypeError('$value does not implement bool');
}
+boolTypeCast(value) {
+ if (value is bool || value === null) return value;
+ throw new CastException(value, 'bool');
+}
+
functionTypeCheck(value) {
if (value === null) return value;
if (value is Function) return value;
throw new TypeError('$value does not implement Function');
}
+functionTypeCast(value) {
+ if (value is Function || value === null) return value;
+ throw new CastException(value, 'Function');
+}
+
intTypeCheck(value) {
if (value === null) return value;
if (value is int) return value;
throw new TypeError('$value does not implement int');
}
+intTypeCast(value) {
+ if (value is int || value === null) return value;
+ throw new CastException(value, 'int');
+}
+
void propertyTypeError(value, property) {
// Cuts the property name to the class name.
String name = property.substring(3, property.length);
throw new TypeError('$value does not implement $name');
}
+void propertyTypeCastError(value, property) {
+ // Cuts the property name to the class name.
+ String name = property.substring(3, property.length);
+ throw new CastException(value, name);
+}
+
/**
* For types that are not supertypes of native (eg DOM) types,
* we emit a simple property check to check that an object implements
@@ -1034,6 +1070,11 @@ propertyTypeCheck(value, property) {
propertyTypeError(value, property);
}
+propertyTypeCast(Object value, Object property) {
ahe 2012/06/25 10:36:56 Remove types from signature.
Lasse Reichstein Nielsen 2012/06/25 11:20:06 Why?
ahe 2012/06/25 11:57:03 Why are they there?
Lasse Reichstein Nielsen 2012/06/25 12:51:10 For the same reasons we use them everywhere else (
ahe 2012/06/25 12:56:32 Generally, you shouldn't use Object unless you're
Lasse Reichstein Nielsen 2012/06/25 15:16:07 Ack, I agree. There is no good type to use here.
+ if (value === null || JS('bool', '!!#[#]', value, property)) return value;
+ propertyTypeCastError(value, property);
+}
+
/**
* For types that are supertypes of native (eg DOM) types, we emit a
* call because we cannot add a JS property to their prototype at load
@@ -1048,6 +1089,15 @@ callTypeCheck(value, property) {
propertyTypeError(value, property);
}
+callTypeCast(value, property) {
ahe 2012/06/25 10:36:56 A comment would be nice here.
Lasse Reichstein Nielsen 2012/06/25 11:20:06 Will do.
+ if (value === null
+ || ((JS('bool', 'typeof # === "object"', value))
+ && JS('bool', '#[#]()', value, property))) {
+ return value;
+ }
+ propertyTypeCastError(value, property);
+}
+
/**
* Specialization of the type check for String and its supertype
* since [value] can be a JS primitive.
@@ -1059,6 +1109,12 @@ stringSuperTypeCheck(value, property) {
propertyTypeError(value, property);
}
+stringSuperTypeCast(value, property) {
+ if (value is String || value === null) return value;
+ if (JS('bool', '!!#[#]', value, property)) return value;
ahe 2012/06/25 10:36:56 This could be: return propertyTypeCast(value, prop
Lasse Reichstein Nielsen 2012/06/25 11:20:06 Well spotted.
+ propertyTypeCastError(value, property);
+}
+
stringSuperNativeTypeCheck(value, property) {
if (value === null) return value;
if (value is String) return value;
@@ -1066,6 +1122,12 @@ stringSuperNativeTypeCheck(value, property) {
propertyTypeError(value, property);
}
+stringSuperNativeTypeCast(value, property) {
+ if (value is String || value === null) return value;
+ if (JS('bool', '#[#]()', value, property)) return value;
ahe 2012/06/25 10:36:56 Should this call callTypeCast?
ahe 2012/06/25 10:36:56 Don't you need to check for typeof value === 'obje
Lasse Reichstein Nielsen 2012/06/25 11:20:06 I think it should follow the tringSuperNativeTypeC
+ propertyTypeCastError(value, property);
+}
+
/**
* Specialization of the type check for List and its supertypes,
* since [value] can be a JS array.
@@ -1076,6 +1138,11 @@ listTypeCheck(value) {
throw new TypeError('$value does not implement List');
}
+listTypeCast(value) {
+ if (value is List || value === null) return value;
+ throw new CastException(value, 'List');
+}
+
listSuperTypeCheck(value, property) {
if (value === null) return value;
if (value is List) return value;
@@ -1083,6 +1150,12 @@ listSuperTypeCheck(value, property) {
propertyTypeError(value, property);
}
+listSuperTypeCast(value, property) {
+ if (value is List || value === null) return value;
+ if (JS('bool', '!!#[#]', value, property)) return value;
ahe 2012/06/25 10:36:56 Call propertyTypeCast?
Lasse Reichstein Nielsen 2012/06/25 11:20:06 Will do.
+ propertyTypeCastError(value, property);
+}
+
listSuperNativeTypeCheck(value, property) {
if (value === null) return value;
if (value is List) return value;
@@ -1090,6 +1163,12 @@ listSuperNativeTypeCheck(value, property) {
propertyTypeError(value, property);
}
+listSuperNativeTypeCast(value, property) {
+ if (value is List || value === null) return value;
+ if (JS('bool', '#[#]()', value, property)) return value;
ahe 2012/06/25 10:36:56 Call callTypeCast?
Lasse Reichstein Nielsen 2012/06/25 11:20:06 That should work. And ditto for the check.
Lasse Reichstein Nielsen 2012/06/25 15:16:07 Actually, the "callTypeCast" does more tests than
+ propertyTypeCastError(value, property);
+}
+
/**
* Special interface recognized by the compiler and implemented by DOM
* objects that support integer indexing. This interface is not

Powered by Google App Engine
This is Rietveld 408576698