Chromium Code Reviews| Index: sdk/lib/_internal/js_runtime/lib/js_helper.dart |
| diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart |
| index 86e80d81b6ddbed5229a0da8d4540ac24cdd27c3..96c200c557d4bedf9c97892d8c7cd14128e689cc 100644 |
| --- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart |
| +++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart |
| @@ -3361,6 +3361,51 @@ voidTypeCheck(value) { |
| throw new TypeErrorImplementation(value, 'void'); |
| } |
| +functionTypeTest(value, functionTypeRti) { |
| + if (value == null) return false; |
| + var functionTypeObject = extractFunctionTypeObjectFrom(value); |
| + return functionTypeObject == null |
| + ? false |
| + : isFunctionSubtype(functionTypeObject, functionTypeRti); |
| +} |
| + |
| +// Declared as 'var' to avoid assignment checks. |
| +var _inTypeAssertion = false; |
| + |
| +functionTypeCheck(value, functionTypeRti) { |
| + if (value == null) return value; |
| + |
| + // The function type test code contains type assertions for function |
| + // types. This leads to unbounded recursion, so disable the type checking of |
| + // function types while checking function types. |
| + |
| + if (true == _inTypeAssertion) return value; |
| + |
| + _inTypeAssertion = true; |
| + try { |
| + if (functionTypeTest(value, functionTypeRti)) return value; |
| + var self = runtimeTypeToString(functionTypeRti); |
| + throw new TypeErrorImplementation(value, self); |
| + } finally { |
| + _inTypeAssertion = false; |
| + } |
| +} |
| + |
| +functionTypeCast(value, functionTypeRti) { |
| + if (value == null) return value; |
| + if (functionTypeTest(value, functionTypeRti)) return value; |
| + |
| + var self = runtimeTypeToString(functionTypeRti); |
| + var functionTypeObject = extractFunctionTypeObjectFrom(value); |
| + var pretty; |
| + if (functionTypeObject != null) { |
| + pretty = runtimeTypeToString(functionTypeObject); |
| + } else { |
| + pretty = Primitives.objectTypeName(value); |
| + } |
| + throw new CastErrorImplementation(pretty, self); |
| +} |
| + |
| checkMalformedType(value, message) { |
| if (value == null) return value; |
| throw new TypeErrorImplementation.fromMessage(message); |
| @@ -3495,18 +3540,19 @@ abstract class RuntimeType { |
| toRti(); |
| } |
| + |
| class RuntimeFunctionType extends RuntimeType { |
| final RuntimeType returnType; |
| final List<RuntimeType> parameterTypes; |
| final List<RuntimeType> optionalParameterTypes; |
| final namedParameters; |
| - static var /* bool */ inAssert = false; |
| - |
| RuntimeFunctionType(this.returnType, |
| this.parameterTypes, |
| this.optionalParameterTypes, |
| - this.namedParameters); |
| + this.namedParameters) { |
| + throw 123; |
| + } |
| bool get isVoid => returnType is VoidRuntimeType; |
| @@ -3514,48 +3560,28 @@ class RuntimeFunctionType extends RuntimeType { |
| /// returns true if [this] is a supertype of [expression]. |
| @NoInline() @NoSideEffects() |
| bool _isTest(expression) { |
| - var functionTypeObject = extractFunctionTypeObjectFrom(expression); |
| - return functionTypeObject == null |
| - ? false |
| - : isFunctionSubtype(functionTypeObject, toRti()); |
| + throw 123; |
|
Emily Fortuna
2017/02/28 16:37:44
maybe just add a comment here to explain that thes
|
| + return functionTypeTest(expression, toRti()); |
| } |
| @NoInline() @NoSideEffects() |
| _asCheck(expression) { |
| + throw 123; |
| // Type inferrer doesn't think this is called with dynamic arguments. |
| return _check(JS('', '#', expression), true); |
| } |
| @NoInline() @NoSideEffects() |
| _assertCheck(expression) { |
| - if (inAssert) return null; |
| - inAssert = true; // Don't try to check this library itself. |
| - try { |
| - // Type inferrer don't think this is called with dynamic arguments. |
| - return _check(JS('', '#', expression), false); |
| - } finally { |
| - inAssert = false; |
| - } |
| + throw 123; |
| + // Type inferrer don't think this is called with dynamic arguments. |
| + return _check(JS('', '#', expression), false); |
| } |
| _check(expression, bool isCast) { |
| - if (expression == null) return null; |
| - if (_isTest(expression)) return expression; |
| - |
| - var self = runtimeTypeToString(toRti()); |
| - if (isCast) { |
| - var functionTypeObject = extractFunctionTypeObjectFrom(expression); |
| - var pretty; |
| - if (functionTypeObject != null) { |
| - pretty = runtimeTypeToString(functionTypeObject); |
| - } else { |
| - pretty = Primitives.objectTypeName(expression); |
| - } |
| - throw new CastErrorImplementation(pretty, self); |
| - } else { |
| - // TODO(ahe): Pass "pretty" function-type to TypeErrorImplementation? |
| - throw new TypeErrorImplementation(expression, self); |
| - } |
| + return isCast |
| + ? functionTypeCast(expression, toRti()) |
| + : functionTypeCheck(expression, toRti()); |
| } |
| toRti() { |