| Index: tool/input_sdk/private/ddc_runtime/operations.dart
|
| diff --git a/tool/input_sdk/private/ddc_runtime/operations.dart b/tool/input_sdk/private/ddc_runtime/operations.dart
|
| index ffb056536c26af75c1c75d34ed448e1b6e75a8fe..3ec38119608e5a59a3b5f3b22a6111fe2b4d51b3 100644
|
| --- a/tool/input_sdk/private/ddc_runtime/operations.dart
|
| +++ b/tool/input_sdk/private/ddc_runtime/operations.dart
|
| @@ -180,13 +180,13 @@ _ignoreTypeFailure(actual, type) => JS('', '''(() => {
|
| // TODO(vsm): Remove this hack ...
|
| // This is primarily due to the lack of generic methods,
|
| // but we need to triage all the types.
|
| - if ($isSubtype($type, $Iterable) && $isSubtype($actual, $Iterable) ||
|
| - $isSubtype($type, $Future) && $isSubtype($actual, $Future) ||
|
| - $isSubtype($type, $Map) && $isSubtype($actual, $Map) ||
|
| - $isSubtype($type, $Function) && $isSubtype($actual, $Function) ||
|
| - $isSubtype($type, $Stream) && $isSubtype($actual, $Stream) ||
|
| - $isSubtype($type, $StreamSubscription) &&
|
| - $isSubtype($actual, $StreamSubscription)) {
|
| + if (!!$isSubtype($type, $Iterable) && !!$isSubtype($actual, $Iterable) ||
|
| + !!$isSubtype($type, $Future) && !!$isSubtype($actual, $Future) ||
|
| + !!$isSubtype($type, $Map) && !!$isSubtype($actual, $Map) ||
|
| + !!$isSubtype($type, $Function) && !!$isSubtype($actual, $Function) ||
|
| + !!$isSubtype($type, $Stream) && !!$isSubtype($actual, $Stream) ||
|
| + !!$isSubtype($type, $StreamSubscription) &&
|
| + !!$isSubtype($actual, $StreamSubscription)) {
|
| console.warn('Ignoring cast fail from ' + $typeName($actual) +
|
| ' to ' + $typeName($type));
|
| return true;
|
| @@ -194,29 +194,34 @@ _ignoreTypeFailure(actual, type) => JS('', '''(() => {
|
| return false;
|
| })()''');
|
|
|
| +/// Returns true if [obj] is an instance of [type]
|
| +/// Returns false if [obj] is not an instance of [type] in both spec
|
| +/// and strong mode
|
| +/// Returns null if [obj] is not an instance of [type] in strong mode
|
| +/// but might be in spec mode
|
| strongInstanceOf(obj, type, ignoreFromWhiteList) => JS('', '''(() => {
|
| let actual = $getReifiedType($obj);
|
| - if ($isSubtype(actual, $type) || actual == $jsobject ||
|
| + let result = $isSubtype(actual, $type);
|
| + if (result || actual == $jsobject ||
|
| actual == $int && type == $double) return true;
|
| - if ($ignoreFromWhiteList == void 0) return false;
|
| - if ($isGroundType($type)) return false;
|
| + if ($ignoreFromWhiteList == void 0) return result;
|
| if ($_ignoreTypeFailure(actual, $type)) return true;
|
| - return false;
|
| + return result;
|
| })()''');
|
|
|
| +/// Returns true if [obj] is null or an instance of [type]
|
| +/// Returns false if [obj] is non-null and not an instance of [type]
|
| +/// in strong mode
|
| instanceOfOrNull(obj, type) => JS('', '''(() => {
|
| + // If strongInstanceOf returns null, convert to false here.
|
| if (($obj == null) || $strongInstanceOf($obj, $type, true)) return true;
|
| return false;
|
| })()''');
|
|
|
| @JSExportName('is')
|
| instanceOf(obj, type) => JS('', '''(() => {
|
| - if ($strongInstanceOf($obj, $type)) return true;
|
| - // TODO(#296): This is perhaps too eager to throw a StrongModeError?
|
| - // It will throw on <int>[] is List<String>.
|
| - // TODO(vsm): We can statically detect many cases where this
|
| - // check is unnecessary.
|
| - if ($isGroundType($type)) return false;
|
| + let result = $strongInstanceOf($obj, $type);
|
| + if (result !== null) return result;
|
| let actual = $getReifiedType($obj);
|
| $throwStrongModeError('Strong mode is check failure: ' +
|
| $typeName(actual) + ' does not soundly subtype ' +
|
| @@ -225,13 +230,14 @@ instanceOf(obj, type) => JS('', '''(() => {
|
|
|
| @JSExportName('as')
|
| cast(obj, type) => JS('', '''(() => {
|
| - // TODO(#296): This is perhaps too eager to throw a StrongModeError?
|
| - // TODO(vsm): handle non-nullable types
|
| - if ($instanceOfOrNull($obj, $type)) return $obj;
|
| + if ($obj == null) return $obj;
|
| +
|
| + let result = $strongInstanceOf($obj, $type, true);
|
| + if (result) return $obj;
|
| +
|
| let actual = $getReifiedType($obj);
|
| - if ($isGroundType($type)) $throwCastError(actual, $type);
|
|
|
| - if ($_ignoreTypeFailure(actual, $type)) return $obj;
|
| + if (result === false) $throwCastError(actual, $type);
|
|
|
| $throwStrongModeError('Strong mode cast failure from ' +
|
| $typeName(actual) + ' to ' + $typeName($type));
|
|
|