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 the operations that define and manipulate Dart | 5 /// This library defines the operations that define and manipulate Dart |
6 /// classes. Included in this are: | 6 /// classes. Included in this are: |
7 /// - Generics | 7 /// - Generics |
8 /// - Class metadata | 8 /// - Class metadata |
9 /// - Extension methods | 9 /// - Extension methods |
10 /// | 10 /// |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 } | 138 } |
139 makeGenericType[$_genericTypeCtor] = $typeConstructor; | 139 makeGenericType[$_genericTypeCtor] = $typeConstructor; |
140 return makeGenericType; | 140 return makeGenericType; |
141 })()'''); | 141 })()'''); |
142 | 142 |
143 getGenericClass(type) => | 143 getGenericClass(type) => |
144 JS('', '$safeGetOwnProperty($type, $_originalDeclaration)'); | 144 JS('', '$safeGetOwnProperty($type, $_originalDeclaration)'); |
145 | 145 |
146 getGenericArgs(type) => JS('', '$safeGetOwnProperty($type, $_typeArguments)'); | 146 getGenericArgs(type) => JS('', '$safeGetOwnProperty($type, $_typeArguments)'); |
147 | 147 |
| 148 // TODO(vsm): Collapse into one expando. |
148 final _constructorSig = JS('', 'Symbol("sigCtor")'); | 149 final _constructorSig = JS('', 'Symbol("sigCtor")'); |
149 final _methodSig = JS('', 'Symbol("sig")'); | 150 final _methodSig = JS('', 'Symbol("sigMethod")'); |
150 final _staticSig = JS('', 'Symbol("sigStatic")'); | 151 final _fieldSig = JS('', 'Symbol("sigField")'); |
| 152 final _getterSig= JS('', 'Symbol("sigGetter")'); |
| 153 final _setterSig= JS('', 'Symbol("sigSetter")'); |
| 154 final _staticSig = JS('', 'Symbol("sigStaticMethod")'); |
| 155 final _staticFieldSig = JS('', 'Symbol("sigStaticField")'); |
| 156 final _staticGetterSig= JS('', 'Symbol("sigStaticGetter")'); |
| 157 final _staticSetterSig= JS('', 'Symbol("sigStaticSetter")'); |
151 final _genericTypeCtor = JS('', 'Symbol("genericType")'); | 158 final _genericTypeCtor = JS('', 'Symbol("genericType")'); |
152 | 159 |
| 160 // TODO(vsm): Collapse this as well - just provide a dart map to mirrors code. |
| 161 // These are queried by mirrors code. |
| 162 getConstructorSig(value) => JS('', '#[#]', value, _constructorSig); |
153 getMethodSig(value) => JS('', '#[#]', value, _methodSig); | 163 getMethodSig(value) => JS('', '#[#]', value, _methodSig); |
| 164 getFieldSig(value) => JS('', '#[#]', value, _fieldSig); |
| 165 getGetterSig(value) => JS('', '#[#]', value, _getterSig); |
| 166 getSetterSig(value) => JS('', '#[#]', value, _setterSig); |
| 167 getStaticSig(value) => JS('', '#[#]', value, _staticSig); |
| 168 getStaticFieldSig(value) => JS('', '#[#]', value, _staticFieldSig); |
| 169 getStaticGetterSig(value) => JS('', '#[#]', value, _staticGetterSig); |
| 170 getStaticSetterSig(value) => JS('', '#[#]', value, _staticSetterSig); |
| 171 |
154 getGenericTypeCtor(value) => JS('', '#[#]', value, _genericTypeCtor); | 172 getGenericTypeCtor(value) => JS('', '#[#]', value, _genericTypeCtor); |
155 | 173 |
156 /// Get the type of a method from an object using the stored signature | 174 /// Get the type of a method from an object using the stored signature |
157 getMethodType(obj, name) => JS( | 175 getMethodType(obj, name) => JS( |
158 '', | 176 '', |
159 '''(() => { | 177 '''(() => { |
160 let type = $obj == null ? $Object : $obj.__proto__.constructor; | 178 let type = $obj == null ? $Object : $obj.__proto__.constructor; |
161 return $getMethodTypeFromType(type, $name); | 179 return $getMethodTypeFromType(type, $name); |
162 })()'''); | 180 })()'''); |
163 | 181 |
164 /// Get the type of a method from a type using the stored signature | 182 /// Get the type of a method from a type using the stored signature |
165 getMethodTypeFromType(type, name) => JS( | 183 getMethodTypeFromType(type, name) => JS( |
166 '', | 184 '', |
167 '''(() => { | 185 '''(() => { |
168 let sigObj = $type[$_methodSig]; | 186 let sigObj = $type[$_methodSig]; |
169 if (sigObj === void 0) return void 0; | 187 if (sigObj === void 0) return void 0; |
170 return sigObj[$name]; | 188 return sigObj[$name]; |
171 })()'''); | 189 })()'''); |
172 | 190 |
173 /// Get the type of a constructor from a class using the stored signature | 191 /// Get the type of a constructor from a class using the stored signature |
174 /// If name is undefined, returns the type of the default constructor | 192 /// If name is undefined, returns the type of the default constructor |
175 /// Returns undefined if the constructor is not found. | 193 /// Returns undefined if the constructor is not found. |
176 classGetConstructorType(cls, name) => JS( | 194 classGetConstructorType(cls, name) => JS( |
177 '', | 195 '', |
178 '''(() => { | 196 '''(() => { |
179 if(!$name) $name = $cls.name; | 197 if(!$name) $name = 'new'; |
180 if ($cls === void 0) return void 0; | 198 if ($cls === void 0) return void 0; |
181 if ($cls == null) return void 0; | 199 if ($cls == null) return void 0; |
182 let sigCtor = $cls[$_constructorSig]; | 200 let sigCtor = $cls[$_constructorSig]; |
183 if (sigCtor === void 0) return void 0; | 201 if (sigCtor === void 0) return void 0; |
184 return sigCtor[$name]; | 202 return sigCtor[$name]; |
185 })()'''); | 203 })()'''); |
186 | 204 |
187 /// Given an object and a method name, tear off the method. | 205 /// Given an object and a method name, tear off the method. |
188 /// Sets the runtime type of the torn off method appropriately, | 206 /// Sets the runtime type of the torn off method appropriately, |
189 /// and also binds the object. | 207 /// and also binds the object. |
(...skipping 20 matching lines...) Expand all Loading... |
210 /// We need to apply the type arguments both to the function, as well as its | 228 /// We need to apply the type arguments both to the function, as well as its |
211 /// associated function type. | 229 /// associated function type. |
212 gbind(f, @rest typeArgs) { | 230 gbind(f, @rest typeArgs) { |
213 var result = JS('', '#.apply(null, #)', f, typeArgs); | 231 var result = JS('', '#.apply(null, #)', f, typeArgs); |
214 var sig = JS('', '#.apply(null, #)', _getRuntimeType(f), typeArgs); | 232 var sig = JS('', '#.apply(null, #)', _getRuntimeType(f), typeArgs); |
215 tag(result, sig); | 233 tag(result, sig); |
216 return result; | 234 return result; |
217 } | 235 } |
218 | 236 |
219 // Set up the method signature field on the constructor | 237 // Set up the method signature field on the constructor |
220 _setMethodSignature(f, sigF) => JS( | 238 _setInstanceSignature(f, sigF, kind) => JS( |
221 '', | 239 '', |
222 '''(() => { | 240 '''(() => { |
223 $defineMemoizedGetter($f, $_methodSig, () => { | 241 $defineMemoizedGetter($f, $kind, () => { |
224 let sigObj = $sigF(); | 242 let sigObj = $sigF(); |
225 sigObj.__proto__ = $f.__proto__[$_methodSig]; | 243 sigObj.__proto__ = $f.__proto__[$kind]; |
226 return sigObj; | 244 return sigObj; |
227 }); | 245 }); |
228 })()'''); | 246 })()'''); |
229 | 247 |
| 248 _setMethodSignature(f, sigF) => _setInstanceSignature(f, sigF, _methodSig); |
| 249 _setFieldSignature(f, sigF) => _setInstanceSignature(f, sigF, _fieldSig); |
| 250 _setGetterSignature(f, sigF) => _setInstanceSignature(f, sigF, _getterSig); |
| 251 _setSetterSignature(f, sigF) => _setInstanceSignature(f, sigF, _setterSig); |
| 252 |
230 // Set up the constructor signature field on the constructor | 253 // Set up the constructor signature field on the constructor |
231 _setConstructorSignature(f, sigF) => | 254 _setConstructorSignature(f, sigF) => |
232 JS('', '$defineMemoizedGetter($f, $_constructorSig, $sigF)'); | 255 JS('', '$defineMemoizedGetter($f, $_constructorSig, $sigF)'); |
233 | 256 |
234 // Set up the static signature field on the constructor | 257 // Set up the static signature field on the constructor |
235 _setStaticSignature(f, sigF) => | 258 _setStaticSignature(f, sigF) => |
236 JS('', '$defineMemoizedGetter($f, $_staticSig, $sigF)'); | 259 JS('', '$defineMemoizedGetter($f, $_staticSig, $sigF)'); |
237 | 260 |
| 261 _setStaticFieldSignature(f, sigF) => |
| 262 JS('', '$defineMemoizedGetter($f, $_staticFieldSig, $sigF)'); |
| 263 |
| 264 _setStaticGetterSignature(f, sigF) => |
| 265 JS('', '$defineMemoizedGetter($f, $_staticGetterSig, $sigF)'); |
| 266 |
| 267 _setStaticSetterSignature(f, sigF) => |
| 268 JS('', '$defineMemoizedGetter($f, $_staticSetterSig, $sigF)'); |
| 269 |
238 // Set the lazily computed runtime type field on static methods | 270 // Set the lazily computed runtime type field on static methods |
239 _setStaticTypes(f, names) => JS( | 271 _setStaticTypes(f, names) => JS( |
240 '', | 272 '', |
241 '''(() => { | 273 '''(() => { |
242 for (let name of $names) { | 274 for (let name of $names) { |
243 // TODO(vsm): Need to generate static methods. | 275 // TODO(vsm): Need to generate static methods. |
244 if (!$f[name]) continue; | 276 if (!$f[name]) continue; |
245 $tagLazy($f[name], function() { | 277 $tagLazy($f[name], function() { |
246 return $f[$_staticSig][name]; | 278 return $f[$_staticSig][name]; |
247 }) | 279 }) |
248 } | 280 } |
249 })()'''); | 281 })()'''); |
250 | 282 |
251 /// Set up the type signature of a class (constructor object) | 283 /// Set up the type signature of a class (constructor object) |
252 /// f is a constructor object | 284 /// f is a constructor object |
253 /// signature is an object containing optional properties as follows: | 285 /// signature is an object containing optional properties as follows: |
254 /// methods: A function returning an object mapping method names | 286 /// methods: A function returning an object mapping method names |
255 /// to method types. The function is evaluated lazily and cached. | 287 /// to method types. The function is evaluated lazily and cached. |
256 /// statics: A function returning an object mapping static method | 288 /// statics: A function returning an object mapping static method |
257 /// names to types. The function is evalutated lazily and cached. | 289 /// names to types. The function is evalutated lazily and cached. |
258 /// names: An array of the names of the static methods. Used to | 290 /// names: An array of the names of the static methods. Used to |
259 /// permit eagerly setting the runtimeType field on the methods | 291 /// permit eagerly setting the runtimeType field on the methods |
260 /// while still lazily computing the type descriptor object. | 292 /// while still lazily computing the type descriptor object. |
| 293 /// fields: A function returning an object mapping instance field |
| 294 /// names to types. |
261 setSignature(f, signature) => JS( | 295 setSignature(f, signature) => JS( |
262 '', | 296 '', |
263 '''(() => { | 297 '''(() => { |
264 // TODO(ochafik): Deconstruct these when supported by Chrome. | 298 // TODO(ochafik): Deconstruct these when supported by Chrome. |
265 let constructors = | 299 let constructors = |
266 ('constructors' in signature) ? signature.constructors : () => ({}); | 300 ('constructors' in signature) ? signature.constructors : () => ({}); |
267 let methods = | 301 let methods = |
268 ('methods' in signature) ? signature.methods : () => ({}); | 302 ('methods' in signature) ? signature.methods : () => ({}); |
| 303 let fields = |
| 304 ('fields' in signature) ? signature.fields : () => ({}); |
| 305 let getters = |
| 306 ('getters' in signature) ? signature.getters : () => ({}); |
| 307 let setters = |
| 308 ('setters' in signature) ? signature.setters : () => ({}); |
269 let statics = | 309 let statics = |
270 ('statics' in signature) ? signature.statics : () => ({}); | 310 ('statics' in signature) ? signature.statics : () => ({}); |
| 311 let staticFields = |
| 312 ('sfields' in signature) ? signature.sfields : () => ({}); |
| 313 let staticGetters = |
| 314 ('sgetters' in signature) ? signature.sgetters : () => ({}); |
| 315 let staticSetters = |
| 316 ('ssetters' in signature) ? signature.ssetters : () => ({}); |
271 let names = | 317 let names = |
272 ('names' in signature) ? signature.names : []; | 318 ('names' in signature) ? signature.names : []; |
273 $_setConstructorSignature($f, constructors); | 319 $_setConstructorSignature($f, constructors); |
274 $_setMethodSignature($f, methods); | 320 $_setMethodSignature($f, methods); |
| 321 $_setFieldSignature($f, fields); |
| 322 $_setGetterSignature($f, getters); |
| 323 $_setSetterSignature($f, setters); |
275 $_setStaticSignature($f, statics); | 324 $_setStaticSignature($f, statics); |
| 325 $_setStaticFieldSignature($f, staticFields); |
| 326 $_setStaticGetterSignature($f, staticGetters); |
| 327 $_setStaticSetterSignature($f, staticSetters); |
276 $_setStaticTypes($f, names); | 328 $_setStaticTypes($f, names); |
277 })()'''); | 329 })()'''); |
278 | 330 |
279 hasMethod(obj, name) => JS('', '$getMethodType($obj, $name) !== void 0'); | 331 hasMethod(obj, name) => JS('', '$getMethodType($obj, $name) !== void 0'); |
280 | 332 |
281 /// Given a class and an initializer method name, creates a constructor | 333 /// Given a class and an initializer method name, creates a constructor |
282 /// function with the same name. | 334 /// function with the same name. |
283 /// | 335 /// |
284 /// After we define the named constructor, the class can be constructed with | 336 /// After we define the named constructor, the class can be constructed with |
285 /// `new SomeClass.name(args)`. | 337 /// `new SomeClass.name(args)`. |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 /// | 531 /// |
480 /// The constructor | 532 /// The constructor |
481 defineNamedConstructorCallable(clazz, name, ctor) => JS( | 533 defineNamedConstructorCallable(clazz, name, ctor) => JS( |
482 '', | 534 '', |
483 '''(() => { | 535 '''(() => { |
484 ctor.prototype = $clazz.prototype; | 536 ctor.prototype = $clazz.prototype; |
485 // Use defineProperty so we don't hit a property defined on Function, | 537 // Use defineProperty so we don't hit a property defined on Function, |
486 // like `caller` and `arguments`. | 538 // like `caller` and `arguments`. |
487 $defineProperty($clazz, $name, { value: ctor, configurable: true }); | 539 $defineProperty($clazz, $name, { value: ctor, configurable: true }); |
488 })()'''); | 540 })()'''); |
OLD | NEW |