| 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 class InvocationImpl extends Invocation { | 9 class InvocationImpl extends Invocation { |
| 10 final Symbol memberName; | 10 final Symbol memberName; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 } | 73 } |
| 74 | 74 |
| 75 // Version of dput that matches legacy Dart 1 type check rules and mirrors | 75 // Version of dput that matches legacy Dart 1 type check rules and mirrors |
| 76 // behavior for JS types. | 76 // behavior for JS types. |
| 77 // TODO(jacobr): remove the type checking rules workaround when mirrors based | 77 // TODO(jacobr): remove the type checking rules workaround when mirrors based |
| 78 // PageLoader code can generate the correct reified generic types. | 78 // PageLoader code can generate the correct reified generic types. |
| 79 dputMirror(obj, field, value) { | 79 dputMirror(obj, field, value) { |
| 80 var f = _canonicalMember(obj, field); | 80 var f = _canonicalMember(obj, field); |
| 81 _trackCall(obj); | 81 _trackCall(obj); |
| 82 if (f != null) { | 82 if (f != null) { |
| 83 var objType = getType(obj); | 83 var setterType = getSetterType(getType(obj), f); |
| 84 var setterType = getSetterType(objType, f); | 84 if (setterType != null) { |
| 85 if (JS('bool', '# != void 0', setterType)) { | 85 setterType = _stripGenericArguments(setterType); |
| 86 return JS( | 86 return JS('', '#[#] = #', obj, f, check(value, setterType)); |
| 87 '', | |
| 88 '#[#] = #', | |
| 89 obj, | |
| 90 f, | |
| 91 check( | |
| 92 value, _stripGenericArguments(JS('', '#.args[0]', setterType)))); | |
| 93 } else { | |
| 94 var fieldType = getFieldType(objType, f); | |
| 95 // TODO(jacobr): add metadata tracking which fields are final and throw | |
| 96 // if a setter is called on a final field. | |
| 97 if (JS('bool', '# != void 0', fieldType)) { | |
| 98 return JS('', '#[#] = #', obj, f, | |
| 99 check(value, _stripGenericArguments(fieldType))); | |
| 100 } | |
| 101 | |
| 102 // Do not support calls on JS interop objects to match Dart2JS behavior. | |
| 103 } | 87 } |
| 104 } | 88 } |
| 105 return noSuchMethod( | 89 return noSuchMethod( |
| 106 obj, new InvocationImpl(field, JS('', '[#]', value), isSetter: true)); | 90 obj, new InvocationImpl(field, JS('', '[#]', value), isSetter: true)); |
| 107 } | 91 } |
| 108 | 92 |
| 109 dput(obj, field, value) { | 93 dput(obj, field, value) { |
| 110 var f = _canonicalMember(obj, field); | 94 var f = _canonicalMember(obj, field); |
| 111 _trackCall(obj); | 95 _trackCall(obj); |
| 112 if (f != null) { | 96 if (f != null) { |
| 113 var objType = getType(obj); | 97 var setterType = getSetterType(getType(obj), f); |
| 114 var setterType = getSetterType(objType, f); | 98 if (setterType != null) { |
| 115 if (JS('bool', '# != void 0', setterType)) { | 99 return JS('', '#[#] = #', obj, f, check(value, setterType)); |
| 116 return JS('', '#[#] = #', obj, f, | 100 } |
| 117 check(value, JS('', '#.args[0]', setterType))); | 101 // Always allow for JS interop objects. |
| 118 } else { | 102 if (isJsInterop(obj)) { |
| 119 var fieldType = getFieldType(objType, f); | 103 return JS('', '#[#] = #', obj, f, value); |
| 120 // TODO(jacobr): add metadata tracking which fields are final and throw | |
| 121 // if a setter is called on a final field. | |
| 122 if (JS('bool', '# != void 0', fieldType)) { | |
| 123 return JS('', '#[#] = #', obj, f, check(value, fieldType)); | |
| 124 } | |
| 125 // Always allow for JS interop objects. | |
| 126 if (isJsInterop(obj)) { | |
| 127 return JS('', '#[#] = #', obj, f, value); | |
| 128 } | |
| 129 } | 104 } |
| 130 } | 105 } |
| 131 return noSuchMethod( | 106 return noSuchMethod( |
| 132 obj, new InvocationImpl(field, JS('', '[#]', value), isSetter: true)); | 107 obj, new InvocationImpl(field, JS('', '[#]', value), isSetter: true)); |
| 133 } | 108 } |
| 134 | 109 |
| 135 /// Check that a function of a given type can be applied to | 110 /// Check that a function of a given type can be applied to |
| 136 /// actuals. | 111 /// actuals. |
| 137 _checkApply(type, actuals) => JS( | 112 _checkApply(type, actuals) => JS( |
| 138 '', | 113 '', |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 $ftype = $getMethodType($getType($f), 'call'); | 220 $ftype = $getMethodType($getType($f), 'call'); |
| 246 $f = f.call ? $bind($f, 'call') : void 0; | 221 $f = f.call ? $bind($f, 'call') : void 0; |
| 247 } | 222 } |
| 248 if (!($f instanceof Function)) { | 223 if (!($f instanceof Function)) { |
| 249 return callNSM(); | 224 return callNSM(); |
| 250 } | 225 } |
| 251 } | 226 } |
| 252 // If f is a function, but not a method (no method type) | 227 // If f is a function, but not a method (no method type) |
| 253 // then it should have been a function valued field, so | 228 // then it should have been a function valued field, so |
| 254 // get the type from the function. | 229 // get the type from the function. |
| 255 if ($ftype === void 0) { | 230 if ($ftype == null) { |
| 256 $ftype = $_getRuntimeType($f); | 231 $ftype = $_getRuntimeType($f); |
| 257 } | 232 } |
| 258 | 233 |
| 259 if (!$ftype) { | 234 if ($ftype == null) { |
| 260 // TODO(leafp): Allow JS objects to go through? | 235 // TODO(leafp): Allow JS objects to go through? |
| 261 if ($typeArgs != null) { | 236 if ($typeArgs != null) { |
| 262 // TODO(jmesserly): is there a sensible way to handle these? | 237 // TODO(jmesserly): is there a sensible way to handle these? |
| 263 $throwStrongModeError('call to JS object `' + $obj + | 238 $throwStrongModeError('call to JS object `' + $obj + |
| 264 '` with type arguments <' + $typeArgs + '> is not supported.'); | 239 '` with type arguments <' + $typeArgs + '> is not supported.'); |
| 265 } | 240 } |
| 266 return $f.apply($obj, $args); | 241 return $f.apply($obj, $args); |
| 267 } | 242 } |
| 268 | 243 |
| 269 // Apply type arguments | 244 // Apply type arguments |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 936 name = '+' + name; | 911 name = '+' + name; |
| 937 } | 912 } |
| 938 return name; | 913 return name; |
| 939 } | 914 } |
| 940 | 915 |
| 941 /// Emulates the implicit "loadLibrary" function provided by a deferred library. | 916 /// Emulates the implicit "loadLibrary" function provided by a deferred library. |
| 942 /// | 917 /// |
| 943 /// Libraries are not actually deferred in DDC, so this just returns a future | 918 /// Libraries are not actually deferred in DDC, so this just returns a future |
| 944 /// that completes immediately. | 919 /// that completes immediately. |
| 945 Future loadLibrary() => new Future.value(); | 920 Future loadLibrary() => new Future.value(); |
| OLD | NEW |