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

Unified Diff: pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart

Issue 2962263002: fix #30030, fix #27327 - fix tearoffs and various Object member bugs (Closed)
Patch Set: fix Created 3 years, 5 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: pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
index 6308359f9e1654c5f92a86cc00c1a68227182be6..1102b1d7a9364fac8edefa142f540e9be756f71f 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
@@ -56,110 +56,104 @@ final _typeObject = JS('', 'Symbol("typeObject")');
// TODO(jmesserly): we shouldn't implement Type here. It should be moved down
// to AbstractFunctionType.
class TypeRep implements Type {
- TypeRep() {
- _initialize;
- }
String get name => this.toString();
+
+ @JSExportName('is')
+ bool is_T(object) => instanceOf(object, this);
+
+ @JSExportName('as')
+ as_T(object) => cast(object, this);
+
+ @JSExportName('_check')
+ check_T(object) => check(object, this);
}
class Dynamic extends TypeRep {
toString() => 'dynamic';
+
+ @JSExportName('is')
+ bool is_T(object) => true;
+
+ @JSExportName('as')
+ as_T(object) => object;
+
+ @JSExportName('_check')
+ check_T(object) => object;
}
class LazyJSType extends TypeRep {
- final _jsTypeCallback;
- final _dartName;
+ final Function() _rawJSType;
+ final String _dartName;
+
+ LazyJSType(this._rawJSType, this._dartName);
+
+ toString() => typeName(_rawJSType());
- LazyJSType(this._jsTypeCallback, this._dartName);
+ rawJSTypeForCheck() {
+ var raw = _rawJSType();
+ if (raw != null) return raw;
+ _warn('Cannot find native JavaScript type ($_dartName) for type check');
+ return _dynamic;
+ }
+
+ @JSExportName('is')
+ bool is_T(obj) => instanceOf(obj, rawJSTypeForCheck());
- get _rawJSType => JS('', '#()', _jsTypeCallback);
+ @JSExportName('as')
+ as_T(obj) => cast(obj, rawJSTypeForCheck());
- toString() => _jsTypeCallback != null ? typeName(_rawJSType) : _dartName;
+ @JSExportName('_check')
+ check_T(obj) => check(obj, rawJSTypeForCheck());
+}
+
+/// An anonymous JS type
+///
+/// For the purposes of subtype checks, these match any JS type.
+class AnonymousJSType extends TypeRep {
+ final String _dartName;
+ AnonymousJSType(this._dartName);
+ toString() => _dartName;
+
+ @JSExportName('is')
+ bool is_T(obj) => _isJSType(getReifiedType(obj));
+
+ @JSExportName('as')
+ as_T(obj) => is_T(obj) ? obj : cast(obj, this);
+
+ @JSExportName('_check')
+ check_T(obj) => is_T(obj) ? obj : check(obj, this);
}
void _warn(arg) {
JS('void', 'console.warn(#)', arg);
}
-_isInstanceOfLazyJSType(o, LazyJSType t) {
- if (t._jsTypeCallback != null) {
- if (t._rawJSType == null) {
- var expected = t._dartName;
- var actual = typeName(getReifiedType(o));
- _warn('Cannot find native JavaScript type ($expected) '
- 'to type check $actual');
- return true;
- }
- return JS('bool', 'dart.is(#, #)', o, t._rawJSType);
+bool _isJSType(t) => JS('bool', '!#[dart._runtimeType]', t);
+
+var _lazyJSTypes = JS('', 'new Map()');
+var _anonymousJSTypes = JS('', 'new Map()');
+
+lazyJSType(Function() getJSTypeCallback, String name) {
+ var ret = JS('', '#.get(#)', _lazyJSTypes, name);
+ if (ret == null) {
+ ret = new LazyJSType(getJSTypeCallback, name);
+ JS('', '#.set(#, #)', _lazyJSTypes, name, ret);
}
- if (o == null) return false;
- // Anonymous case: match any JS type.
- return _isJSObject(o);
+ return ret;
}
-_asInstanceOfLazyJSType(o, LazyJSType t) {
- if (t._jsTypeCallback != null) {
- if (t._rawJSType == null) {
- var expected = t._dartName;
- var actual = typeName(getReifiedType(o));
- _warn('Cannot find native JavaScript type ($expected) '
- 'to type check $actual');
- return o;
- }
- return JS('bool', 'dart.as(#, #)', o, t._rawJSType);
+anonymousJSType(String name) {
+ var ret = JS('', '#.get(#)', _anonymousJSTypes, name);
+ if (ret == null) {
+ ret = new AnonymousJSType(name);
+ JS('', '#.set(#, #)', _anonymousJSTypes, name, ret);
}
- // Anonymous case: allow any JS type.
- if (o == null) return null;
- if (!_isJSObject(o)) _throwCastError(o, t, true);
- return o;
+ return ret;
}
-bool _isJSObject(o) =>
- JS('bool', '!dart.getReifiedType(#)[dart._runtimeType]', o);
-
-bool _isJSType(t) => JS('bool', '!#[dart._runtimeType]', t);
-
@JSExportName('dynamic')
final _dynamic = new Dynamic();
-final _initialize = _initialize2();
-
-_initialize2() => JS(
- '',
- '''(() => {
- // JavaScript API forwards to runtime library.
- $TypeRep.prototype.is = function is_T(object) {
- return dart.is(object, this);
- };
- $TypeRep.prototype.as = function as_T(object) {
- return dart.as(object, this);
- };
- $TypeRep.prototype._check = function check_T(object) {
- return dart.check(object, this);
- };
-
- // Fast path for type `dynamic`.
- $Dynamic.prototype.is = function is_Dynamic(object) {
- return true;
- };
- $Dynamic.prototype.as = function as_Dynamic(object) {
- return object;
- };
- $Dynamic.prototype._check = function check_Dynamic(object) {
- return object;
- };
-
- $LazyJSType.prototype.is = function is_T(object) {
- return $_isInstanceOfLazyJSType(object, this);
- };
- $LazyJSType.prototype.as = function as_T(object) {
- return $_asInstanceOfLazyJSType(object, this);
- };
- $LazyJSType.prototype._check = function check_T(object) {
- return $_asInstanceOfLazyJSType(object, this);
- };
-})()''');
-
class Void extends TypeRep {
toString() => 'void';
}
@@ -709,14 +703,6 @@ String typeName(type) => JS(
bool _isFunctionType(type) => JS('bool', '# instanceof # || # === #', type,
AbstractFunctionType, type, Function);
-isLazyJSSubtype(t1, LazyJSType t2, isCovariant) {
- // All JS types are subtypes of anonymous JS types.
- if (t2._jsTypeCallback == null) {
- return _isJSType(t1);
- }
- return _isSubtype(t1, t2._rawJSType, isCovariant);
-}
-
/// Returns true if [ft1] <: [ft2].
/// Returns false if [ft1] </: [ft2] in both spec and strong mode
/// Returns null if [ft1] </: [ft2] in strong mode, but spec mode
@@ -891,8 +877,12 @@ bool _isSubtype(t1, t2, isCovariant) => JS(
if (result === true || result === null) return result;
}
+ if ($t2 instanceof $AnonymousJSType) {
+ // All JS types are subtypes of anonymous JS types.
+ return $_isJSType($t1);
+ }
if ($t2 instanceof $LazyJSType) {
- return $isLazyJSSubtype($t1, $t2, $isCovariant);
+ return $_isSubtype($t1, $t2.rawJSTypeForCheck(), isCovariant);
}
// Function subtyping.

Powered by Google App Engine
This is Rietveld 408576698