| 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 |