Chromium Code Reviews| 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 |