Chromium Code Reviews| Index: pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart |
| diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart |
| index b2fd6c586fbbfa009403195d6980172b0e652856..a2a1698252dafe25117533c4ab01abfad1bab1fa 100644 |
| --- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart |
| +++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart |
| @@ -29,6 +29,57 @@ class InvocationImpl extends Invocation { |
| } |
| } |
| +/// Given an object and a method name, tear off the method. |
| +/// Sets the runtime type of the torn off method appropriately, |
| +/// and also binds the object. |
| +/// |
| +/// If the optional `f` argument is passed in, it will be used as the method. |
| +/// This supports cases like `super.foo` where we need to tear off the method |
| +/// from the superclass, not from the `obj` directly. |
| +/// TODO(leafp): Consider caching the tearoff on the object? |
| +bind(obj, name, f) { |
| + if (f == null) f = JS('', '#[#]', obj, name); |
| + |
| + // TODO(jmesserly): it would be nice to do this lazily, but JS interop seems |
| + // to require us to be eager (the test below). |
| + var sig = getMethodType(getType(obj), name); |
| + |
| + // JS interop case: do not bind this for compatibility with the dart2js |
| + // implementation where we cannot bind this reliably here until we trust |
| + // types more. |
| + if (sig == null) return f; |
| + |
| + f = JS('', '#.bind(#)', f, obj); |
| + JS( |
| + '', |
| + r'''#[dartx["=="]] = function boundMethodEquals(other) { |
| + return other[#] === this[#] && other[#] === this[#]; |
|
vsm
2017/05/09 22:50:15
check other is non-null too?
Jennifer Messerly
2017/05/09 23:10:33
equality operator is spec'd to check for this:
Ev
Jennifer Messerly
2017/05/09 23:11:17
(in other words, it checks before the operator met
|
| + }''', |
| + f, |
| + _boundMethodTarget, |
| + _boundMethodTarget, |
| + _boundMethodName, |
| + _boundMethodName); |
| + JS('', '#[#] = #', f, _boundMethodTarget, obj); |
| + JS('', '#[#] = #', f, _boundMethodName, name); |
| + tag(f, sig); |
| + return f; |
| +} |
| + |
| +final _boundMethodTarget = JS('', 'Symbol("_boundMethodTarget")'); |
| +final _boundMethodName = JS('', 'Symbol("_boundMethodName")'); |
| + |
| +/// Instantiate a generic method. |
| +/// |
| +/// We need to apply the type arguments both to the function, as well as its |
| +/// associated function type. |
| +gbind(f, @rest typeArgs) { |
| + var result = JS('', '#.apply(null, #)', f, typeArgs); |
| + var sig = JS('', '#.instantiate(#)', _getRuntimeType(f), typeArgs); |
| + tag(result, sig); |
| + return result; |
| +} |
| + |
| // Warning: dload, dput, and dsend assume they are never called on methods |
| // implemented by the Object base class as those methods can always be |
| // statically resolved. |