Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /// This library defines runtime operations on objects used by the code | 5 /// This library defines runtime operations on objects used by the code |
| 6 /// generator. | 6 /// generator. |
| 7 part of dart._runtime; | 7 part of dart._runtime; |
| 8 | 8 |
| 9 _canonicalFieldName(obj, name, args, displayName) => JS('', '''(() => { | 9 _canonicalFieldName(obj, name, args, displayName) => JS('', '''(() => { |
| 10 $name = $canonicalMember($obj, $name); | 10 $name = $canonicalMember($obj, $name); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 dput(obj, field, value) => JS('', '''(() => { | 32 dput(obj, field, value) => JS('', '''(() => { |
| 33 $field = $_canonicalFieldName($obj, $field, [$value], $field); | 33 $field = $_canonicalFieldName($obj, $field, [$value], $field); |
| 34 // TODO(vsm): Implement NSM and type checks. | 34 // TODO(vsm): Implement NSM and type checks. |
| 35 // See: https://github.com/dart-lang/dev_compiler/issues/170 | 35 // See: https://github.com/dart-lang/dev_compiler/issues/170 |
| 36 $obj[$field] = $value; | 36 $obj[$field] = $value; |
| 37 return $value; | 37 return $value; |
| 38 })()'''); | 38 })()'''); |
| 39 | 39 |
| 40 /// Check that a function of a given type can be applied to | 40 /// Check that a function of a given type can be applied to |
| 41 /// actuals. | 41 /// actuals. |
| 42 checkApply(type, actuals) => JS('', '''(() => { | 42 _checkApply(type, actuals) => JS('', '''(() => { |
| 43 if ($actuals.length < $type.args.length) return false; | 43 if ($actuals.length < $type.args.length) return false; |
| 44 let index = 0; | 44 let index = 0; |
| 45 for(let i = 0; i < $type.args.length; ++i) { | 45 for(let i = 0; i < $type.args.length; ++i) { |
| 46 if (!$instanceOfOrNull($actuals[i], $type.args[i])) return false; | 46 if (!$instanceOfOrNull($actuals[i], $type.args[i])) return false; |
| 47 ++index; | 47 ++index; |
| 48 } | 48 } |
| 49 if ($actuals.length == $type.args.length) return true; | 49 if ($actuals.length == $type.args.length) return true; |
| 50 let extras = $actuals.length - $type.args.length; | 50 let extras = $actuals.length - $type.args.length; |
| 51 if ($type.optionals.length > 0) { | 51 if ($type.optionals.length > 0) { |
| 52 if (extras > $type.optionals.length) return false; | 52 if (extras > $type.optionals.length) return false; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 80 | 80 |
| 81 throwNoSuchMethod(obj, name, pArgs, nArgs, extras) => JS('', '''(() => { | 81 throwNoSuchMethod(obj, name, pArgs, nArgs, extras) => JS('', '''(() => { |
| 82 $throw_(new $NoSuchMethodError($obj, $_dartSymbol($name), $pArgs, $nArgs, $ext ras)); | 82 $throw_(new $NoSuchMethodError($obj, $_dartSymbol($name), $pArgs, $nArgs, $ext ras)); |
| 83 })()'''); | 83 })()'''); |
| 84 | 84 |
| 85 throwNoSuchMethodFunc(obj, name, pArgs, opt_func) => JS('', '''(() => { | 85 throwNoSuchMethodFunc(obj, name, pArgs, opt_func) => JS('', '''(() => { |
| 86 if ($obj === void 0) $obj = $opt_func; | 86 if ($obj === void 0) $obj = $opt_func; |
| 87 $throwNoSuchMethod($obj, $name, $pArgs); | 87 $throwNoSuchMethod($obj, $name, $pArgs); |
| 88 })()'''); | 88 })()'''); |
| 89 | 89 |
| 90 checkAndCall(f, ftype, obj, args, name) => JS('', '''(() => { | 90 _checkAndCall(f, ftype, obj, typeArgs, args, name) => JS('', '''(() => { |
| 91 let originalFunction = $f; | 91 let originalFunction = $f; |
| 92 if (!($f instanceof Function)) { | 92 if (!($f instanceof Function)) { |
| 93 // We're not a function (and hence not a method either) | 93 // We're not a function (and hence not a method either) |
| 94 // Grab the `call` method if it's not a function. | 94 // Grab the `call` method if it's not a function. |
| 95 if ($f != null) { | 95 if ($f != null) { |
| 96 $ftype = $getMethodType($f, 'call'); | 96 $ftype = $getMethodType($f, 'call'); |
| 97 $f = $f.call; | 97 $f = $f.call; |
| 98 } | 98 } |
| 99 if (!($f instanceof Function)) { | 99 if (!($f instanceof Function)) { |
| 100 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction); | 100 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction); |
| 101 } | 101 } |
| 102 } | 102 } |
| 103 // If f is a function, but not a method (no method type) | 103 // If f is a function, but not a method (no method type) |
| 104 // then it should have been a function valued field, so | 104 // then it should have been a function valued field, so |
| 105 // get the type from the function. | 105 // get the type from the function. |
| 106 if ($ftype === void 0) { | 106 if ($ftype === void 0) { |
| 107 $ftype = $read($f); | 107 $ftype = $read($f); |
| 108 } | 108 } |
| 109 | 109 |
| 110 if (!$ftype) { | 110 if (!$ftype) { |
| 111 // TODO(leafp): Allow JS objects to go through? | 111 // TODO(leafp): Allow JS objects to go through? |
| 112 // This includes the DOM. | 112 if ($typeArgs != null) { |
| 113 // TODO(jmesserly): is there a sensible way to handle these? | |
| 114 $throwStrongModeError('call to JS object `' + $obj + | |
| 115 '` with type arguments <' + $typeArgs + '> is not supported.'); | |
| 116 } | |
| 113 return $f.apply($obj, $args); | 117 return $f.apply($obj, $args); |
| 114 } | 118 } |
| 115 | 119 |
| 116 if ($checkApply($ftype, $args)) { | 120 // Apply type arguments |
| 121 let formalCount = $ftype[$_typeFormalCount]; | |
| 122 if (formalCount != null) { | |
| 123 if ($typeArgs == null) { | |
| 124 $typeArgs = Array(formalCount).fill($dynamicR); | |
|
Jennifer Messerly
2016/04/28 23:28:54
This should be instantiating to bounds.
Related to
| |
| 125 } else if ($typeArgs.length != formalCount) { | |
| 126 // TODO(jmesserly): is this the right error? | |
| 127 $throwStrongModeError( | |
| 128 'incorrect number of arguments to generic function ' + | |
| 129 $typeName($ftype) + ', got <' + $typeArgs + '> expected ' + | |
| 130 formalCount + '.'); | |
| 131 } | |
| 132 // Instantiate the function. | |
| 133 $ftype = $ftype(...$typeArgs); | |
| 134 } else if ($typeArgs != null) { | |
| 135 $throwStrongModeError( | |
| 136 'got type arguments to non-generic function ' + $typeName($ftype) + | |
| 137 ', got <' + $typeArgs + '> expected none.'); | |
| 138 } | |
| 139 | |
| 140 if ($_checkApply($ftype, $args)) { | |
| 141 if ($typeArgs != null) { | |
| 142 return $f.apply($obj, $typeArgs).apply($obj, $args); | |
| 143 } | |
| 117 return $f.apply($obj, $args); | 144 return $f.apply($obj, $args); |
| 118 } | 145 } |
| 119 | 146 |
| 120 // TODO(leafp): throw a type error (rather than NSM) | 147 // TODO(leafp): throw a type error (rather than NSM) |
| 121 // if the arity matches but the types are wrong. | 148 // if the arity matches but the types are wrong. |
| 149 // TODO(jmesserly): nSM should include type args? | |
| 122 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction); | 150 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction); |
| 123 })()'''); | 151 })()'''); |
| 124 | 152 |
| 125 dcall(f, @rest args) => JS('', '''(() => { | 153 dcall(f, @rest args) => |
| 126 let ftype = $read($f); | 154 _checkAndCall(f, read(f), JS('', 'void 0'), null, args, 'call'); |
| 127 return $checkAndCall($f, ftype, void 0, $args, 'call'); | |
| 128 })()'''); | |
| 129 | 155 |
| 130 /// Shared code for dsend, dindex, and dsetindex. */ | |
| 131 callMethod(obj, name, args, displayName) => JS('', '''(() => { | |
| 132 let symbol = $_canonicalFieldName($obj, $name, $args, $displayName); | |
| 133 let f = $obj != null ? $obj[symbol] : null; | |
| 134 let ftype = $getMethodType($obj, $name); | |
| 135 return $checkAndCall(f, ftype, $obj, $args, $displayName); | |
| 136 })()'''); | |
| 137 | 156 |
| 138 dsend(obj, method, @rest args) => JS('', '''(() => { | 157 dgcall(f, typeArgs, @rest args) => |
| 139 return $callMethod($obj, $method, $args, $method); | 158 _checkAndCall(f, read(f), JS('', 'void 0'), typeArgs, args, 'call'); |
| 140 })()'''); | |
| 141 | 159 |
| 142 dindex(obj, index) => JS('', '''(() => { | |
| 143 return $callMethod($obj, 'get', [$index], '[]'); | |
| 144 })()'''); | |
| 145 | 160 |
| 146 dsetindex(obj, index, value) => JS('', '''(() => { | 161 /// Shared code for dsend, dindex, and dsetindex. |
| 147 $callMethod($obj, 'set', [$index, $value], '[]='); | 162 _callMethod(obj, name, typeArgs, args, displayName) { |
| 148 return $value; | 163 var symbol = _canonicalFieldName(obj, name, args, displayName); |
| 149 })()'''); | 164 var f = obj != null ? JS('', '#[#]', obj, symbol) : null; |
| 165 var ftype = getMethodType(obj, symbol); | |
| 166 return _checkAndCall(f, ftype, obj, typeArgs, args, displayName); | |
| 167 } | |
| 168 | |
| 169 dsend(obj, method, @rest args) => _callMethod(obj, method, null, args, method); | |
| 170 | |
| 171 dgsend(obj, typeArgs, method, @rest args) => | |
| 172 _callMethod(obj, method, typeArgs, args, method); | |
| 173 | |
| 174 dindex(obj, index) => _callMethod(obj, 'get', null, JS('', '[#]', index), '[]'); | |
| 175 | |
| 176 dsetindex(obj, index, value) => | |
| 177 _callMethod(obj, 'set', null, JS('', '[#, #]', index, value), '[]='); | |
| 150 | 178 |
| 151 _ignoreTypeFailure(actual, type) => JS('', '''(() => { | 179 _ignoreTypeFailure(actual, type) => JS('', '''(() => { |
| 152 // TODO(vsm): Remove this hack ... | 180 // TODO(vsm): Remove this hack ... |
| 153 // This is primarily due to the lack of generic methods, | 181 // This is primarily due to the lack of generic methods, |
| 154 // but we need to triage all the types. | 182 // but we need to triage all the types. |
| 155 if ($isSubtype($type, $Iterable) && $isSubtype($actual, $Iterable) || | 183 if ($isSubtype($type, $Iterable) && $isSubtype($actual, $Iterable) || |
| 156 $isSubtype($type, $Future) && $isSubtype($actual, $Future) || | 184 $isSubtype($type, $Future) && $isSubtype($actual, $Future) || |
| 157 $isSubtype($type, $Map) && $isSubtype($actual, $Map) || | 185 $isSubtype($type, $Map) && $isSubtype($actual, $Map) || |
| 158 $isSubtype($type, $Function) && $isSubtype($actual, $Function) || | 186 $isSubtype($type, $Function) && $isSubtype($actual, $Function) || |
| 159 $isSubtype($type, $Stream) && $isSubtype($actual, $Stream) || | 187 $isSubtype($type, $Stream) && $isSubtype($actual, $Stream) || |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 constructor(dartIterator) { | 455 constructor(dartIterator) { |
| 428 this.dartIterator = dartIterator; | 456 this.dartIterator = dartIterator; |
| 429 } | 457 } |
| 430 next() { | 458 next() { |
| 431 let i = this.dartIterator; | 459 let i = this.dartIterator; |
| 432 let done = !i.moveNext(); | 460 let done = !i.moveNext(); |
| 433 return { done: done, value: done ? void 0 : i.current }; | 461 return { done: done, value: done ? void 0 : i.current }; |
| 434 } | 462 } |
| 435 } | 463 } |
| 436 '''); | 464 '''); |
| OLD | NEW |