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 |