Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: tool/input_sdk/private/ddc_runtime/classes.dart

Issue 2164763005: Library custom formatters (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 ///
11 11
12 // TODO(leafp): Consider splitting some of this out. 12 // TODO(leafp): Consider splitting some of this out.
13 part of dart._runtime; 13 part of dart._runtime;
14 14
15 /// 15 ///
16 /// Returns a new type that mixes members from base and all mixins. 16 /// Returns a new type that mixes members from base and all mixins.
17 /// 17 ///
18 /// Each mixin applies in sequence, with further to the right ones overriding 18 /// Each mixin applies in sequence, with further to the right ones overriding
19 /// previous entries. 19 /// previous entries.
20 /// 20 ///
21 /// For each mixin, we only take its own properties, not anything from its 21 /// For each mixin, we only take its own properties, not anything from its
22 /// superclass (prototype). 22 /// superclass (prototype).
23 /// 23 ///
24 mixin(base, @rest mixins) => JS('', '''(() => { 24 mixin(base, @rest mixins) => JS(
25 '',
26 '''(() => {
25 // Create an initializer for the mixin, so when derived constructor calls 27 // Create an initializer for the mixin, so when derived constructor calls
26 // super, we can correctly initialize base and mixins. 28 // super, we can correctly initialize base and mixins.
27 29
28 // Create a class that will hold all of the mixin methods. 30 // Create a class that will hold all of the mixin methods.
29 class Mixin extends $base {} 31 class Mixin extends $base {}
30 // Copy each mixin's methods, with later ones overwriting earlier entries. 32 // Copy each mixin's methods, with later ones overwriting earlier entries.
31 for (let m of $mixins) { 33 for (let m of $mixins) {
32 $copyProperties(Mixin.prototype, m.prototype); 34 $copyProperties(Mixin.prototype, m.prototype);
33 } 35 }
34 // Initializer method: run mixin initializers, then the base. 36 // Initializer method: run mixin initializers, then the base.
(...skipping 17 matching lines...) Expand all
52 } 54 }
53 return s; 55 return s;
54 } 56 }
55 }); 57 });
56 58
57 // Save mixins for reflection 59 // Save mixins for reflection
58 Mixin[$_mixins] = $mixins; 60 Mixin[$_mixins] = $mixins;
59 return Mixin; 61 return Mixin;
60 })()'''); 62 })()''');
61 63
62
63 /// The Symbol for storing type arguments on a specialized generic type. 64 /// The Symbol for storing type arguments on a specialized generic type.
64 final _mixins = JS('', 'Symbol("mixins")'); 65 final _mixins = JS('', 'Symbol("mixins")');
65 66
66 getMixins(clazz) => JS('', '$clazz[$_mixins]'); 67 getMixins(clazz) => JS('', '$clazz[$_mixins]');
67 68
68 @JSExportName('implements') 69 @JSExportName('implements')
69 final _implements = JS('', 'Symbol("implements")'); 70 final _implements = JS('', 'Symbol("implements")');
70 71
71 getImplements(clazz) => JS('', '#[#]', clazz, _implements); 72 getImplements(clazz) => JS('', '#[#]', clazz, _implements);
72 73
73 /// The Symbol for storing type arguments on a specialized generic type. 74 /// The Symbol for storing type arguments on a specialized generic type.
74 final _typeArguments = JS('', 'Symbol("typeArguments")'); 75 final _typeArguments = JS('', 'Symbol("typeArguments")');
75 76
76 final _originalDeclaration = JS('', 'Symbol("originalDeclaration")'); 77 final _originalDeclaration = JS('', 'Symbol("originalDeclaration")');
77 78
78 /// Wrap a generic class builder function with future flattening. 79 /// Wrap a generic class builder function with future flattening.
79 flattenFutures(builder) => JS('', '''(() => { 80 flattenFutures(builder) => JS(
81 '',
82 '''(() => {
80 function flatten(T) { 83 function flatten(T) {
81 if (!T) return $builder($dynamic); 84 if (!T) return $builder($dynamic);
82 let futureClass = $getGenericClass($Future); 85 let futureClass = $getGenericClass($Future);
83 //TODO(leafp): This only handles the direct flattening case. 86 //TODO(leafp): This only handles the direct flattening case.
84 // It would probably be good to at least search up the class 87 // It would probably be good to at least search up the class
85 // hierarchy. If we keep doing flattening long term, we may 88 // hierarchy. If we keep doing flattening long term, we may
86 // want to implement the full future flattening per spec. 89 // want to implement the full future flattening per spec.
87 if ($getGenericClass(T) == futureClass) { 90 if ($getGenericClass(T) == futureClass) {
88 let args = $getGenericArgs(T); 91 let args = $getGenericArgs(T);
89 if (args) return $builder(args[0]); 92 if (args) return $builder(args[0]);
90 } 93 }
91 return $builder(T); 94 return $builder(T);
92 } 95 }
93 return flatten; 96 return flatten;
94 })()'''); 97 })()''');
95 98
96 /// Memoize a generic type constructor function. 99 /// Memoize a generic type constructor function.
97 generic(typeConstructor) => JS('', '''(() => { 100 generic(typeConstructor) => JS(
101 '',
102 '''(() => {
98 let length = $typeConstructor.length; 103 let length = $typeConstructor.length;
99 if (length < 1) { 104 if (length < 1) {
100 $throwInternalError('must have at least one generic type argument'); 105 $throwInternalError('must have at least one generic type argument');
101 } 106 }
102 let resultMap = new Map(); 107 let resultMap = new Map();
103 function makeGenericType(...args) { 108 function makeGenericType(...args) {
104 if (args.length != length && args.length != 0) { 109 if (args.length != length && args.length != 0) {
105 $throwInternalError('requires ' + length + ' or 0 type arguments'); 110 $throwInternalError('requires ' + length + ' or 0 type arguments');
106 } 111 }
107 while (args.length < length) args.push($dynamic); 112 while (args.length < length) args.push($dynamic);
(...skipping 22 matching lines...) Expand all
130 } 135 }
131 } 136 }
132 return value; 137 return value;
133 } 138 }
134 return makeGenericType; 139 return makeGenericType;
135 })()'''); 140 })()''');
136 141
137 getGenericClass(type) => 142 getGenericClass(type) =>
138 JS('', '$safeGetOwnProperty($type, $_originalDeclaration)'); 143 JS('', '$safeGetOwnProperty($type, $_originalDeclaration)');
139 144
140 getGenericArgs(type) => 145 getGenericArgs(type) => JS('', '$safeGetOwnProperty($type, $_typeArguments)');
141 JS('', '$safeGetOwnProperty($type, $_typeArguments)');
142 146
143 final _constructorSig = JS('', 'Symbol("sigCtor")'); 147 final _constructorSig = JS('', 'Symbol("sigCtor")');
144 final _methodSig = JS('', 'Symbol("sig")'); 148 final _methodSig = JS('', 'Symbol("sig")');
145 final _staticSig = JS('', 'Symbol("sigStatic")'); 149 final _staticSig = JS('', 'Symbol("sigStatic")');
146 150
147 /// Get the type of a method from an object using the stored signature 151 /// Get the type of a method from an object using the stored signature
148 getMethodType(obj, name) => JS('', '''(() => { 152 getMethodType(obj, name) => JS(
153 '',
154 '''(() => {
149 let type = $obj == null ? $Object : $obj.__proto__.constructor; 155 let type = $obj == null ? $Object : $obj.__proto__.constructor;
150 return $getMethodTypeFromType(type, $name); 156 return $getMethodTypeFromType(type, $name);
151 })()'''); 157 })()''');
152 158
153 /// Get the type of a method from a type using the stored signature 159 /// Get the type of a method from a type using the stored signature
154 getMethodTypeFromType(type, name) => JS('', '''(() => { 160 getMethodTypeFromType(type, name) => JS(
161 '',
162 '''(() => {
155 let sigObj = $type[$_methodSig]; 163 let sigObj = $type[$_methodSig];
156 if (sigObj === void 0) return void 0; 164 if (sigObj === void 0) return void 0;
157 return sigObj[$name]; 165 return sigObj[$name];
158 })()'''); 166 })()''');
159 167
160 /// Get the type of a constructor from a class using the stored signature 168 /// Get the type of a constructor from a class using the stored signature
161 /// If name is undefined, returns the type of the default constructor 169 /// If name is undefined, returns the type of the default constructor
162 /// Returns undefined if the constructor is not found. 170 /// Returns undefined if the constructor is not found.
163 classGetConstructorType(cls, name) => JS('', '''(() => { 171 classGetConstructorType(cls, name) => JS(
172 '',
173 '''(() => {
164 if(!$name) $name = $cls.name; 174 if(!$name) $name = $cls.name;
165 if ($cls === void 0) return void 0; 175 if ($cls === void 0) return void 0;
166 if ($cls == null) return void 0; 176 if ($cls == null) return void 0;
167 let sigCtor = $cls[$_constructorSig]; 177 let sigCtor = $cls[$_constructorSig];
168 if (sigCtor === void 0) return void 0; 178 if (sigCtor === void 0) return void 0;
169 return sigCtor[$name]; 179 return sigCtor[$name];
170 })()'''); 180 })()''');
171 181
172 /// Given an object and a method name, tear off the method. 182 /// Given an object and a method name, tear off the method.
173 /// Sets the runtime type of the torn off method appropriately, 183 /// Sets the runtime type of the torn off method appropriately,
174 /// and also binds the object. 184 /// and also binds the object.
175 /// 185 ///
176 /// If the optional `f` argument is passed in, it will be used as the method. 186 /// If the optional `f` argument is passed in, it will be used as the method.
177 /// This supports cases like `super.foo` where we need to tear off the method 187 /// This supports cases like `super.foo` where we need to tear off the method
178 /// from the superclass, not from the `obj` directly. 188 /// from the superclass, not from the `obj` directly.
179 /// TODO(leafp): Consider caching the tearoff on the object? 189 /// TODO(leafp): Consider caching the tearoff on the object?
180 bind(obj, name, f) => JS('', '''(() => { 190 bind(obj, name, f) => JS(
191 '',
192 '''(() => {
181 if ($f === void 0) $f = $obj[$name]; 193 if ($f === void 0) $f = $obj[$name];
182 $f = $f.bind($obj); 194 $f = $f.bind($obj);
183 // TODO(jmesserly): track the function's signature on the function, instead 195 // TODO(jmesserly): track the function's signature on the function, instead
184 // of having to go back to the class? 196 // of having to go back to the class?
185 let sig = $getMethodType($obj, $name); 197 let sig = $getMethodType($obj, $name);
186 $assert_(sig); 198 $assert_(sig);
187 $tag($f, sig); 199 $tag($f, sig);
188 return $f; 200 return $f;
189 })()'''); 201 })()''');
190 202
191 /// Instantiate a generic method. 203 /// Instantiate a generic method.
192 /// 204 ///
193 /// We need to apply the type arguments both to the function, as well as its 205 /// We need to apply the type arguments both to the function, as well as its
194 /// associated function type. 206 /// associated function type.
195 gbind(f, @rest typeArgs) { 207 gbind(f, @rest typeArgs) {
196 var result = JS('', '#.apply(null, #)', f, typeArgs); 208 var result = JS('', '#.apply(null, #)', f, typeArgs);
197 var sig = JS('', '#.apply(null, #)', _getRuntimeType(f), typeArgs); 209 var sig = JS('', '#.apply(null, #)', _getRuntimeType(f), typeArgs);
198 tag(result, sig); 210 tag(result, sig);
199 return result; 211 return result;
200 } 212 }
201 213
202 // Set up the method signature field on the constructor 214 // Set up the method signature field on the constructor
203 _setMethodSignature(f, sigF) => JS('', '''(() => { 215 _setMethodSignature(f, sigF) => JS(
216 '',
217 '''(() => {
204 $defineMemoizedGetter($f, $_methodSig, () => { 218 $defineMemoizedGetter($f, $_methodSig, () => {
205 let sigObj = $sigF(); 219 let sigObj = $sigF();
206 sigObj.__proto__ = $f.__proto__[$_methodSig]; 220 sigObj.__proto__ = $f.__proto__[$_methodSig];
207 return sigObj; 221 return sigObj;
208 }); 222 });
209 })()'''); 223 })()''');
210 224
211 // Set up the constructor signature field on the constructor 225 // Set up the constructor signature field on the constructor
212 _setConstructorSignature(f, sigF) => 226 _setConstructorSignature(f, sigF) =>
213 JS('', '$defineMemoizedGetter($f, $_constructorSig, $sigF)'); 227 JS('', '$defineMemoizedGetter($f, $_constructorSig, $sigF)');
214 228
215 // Set up the static signature field on the constructor 229 // Set up the static signature field on the constructor
216 _setStaticSignature(f, sigF) => 230 _setStaticSignature(f, sigF) =>
217 JS('', '$defineMemoizedGetter($f, $_staticSig, $sigF)'); 231 JS('', '$defineMemoizedGetter($f, $_staticSig, $sigF)');
218 232
219 // Set the lazily computed runtime type field on static methods 233 // Set the lazily computed runtime type field on static methods
220 _setStaticTypes(f, names) => JS('', '''(() => { 234 _setStaticTypes(f, names) => JS(
235 '',
236 '''(() => {
221 for (let name of $names) { 237 for (let name of $names) {
222 // TODO(vsm): Need to generate static methods. 238 // TODO(vsm): Need to generate static methods.
223 if (!$f[name]) continue; 239 if (!$f[name]) continue;
224 $tagLazy($f[name], function() { 240 $tagLazy($f[name], function() {
225 return $f[$_staticSig][name]; 241 return $f[$_staticSig][name];
226 }) 242 })
227 } 243 }
228 })()'''); 244 })()''');
229 245
230 /// Set up the type signature of a class (constructor object) 246 /// Set up the type signature of a class (constructor object)
231 /// f is a constructor object 247 /// f is a constructor object
232 /// signature is an object containing optional properties as follows: 248 /// signature is an object containing optional properties as follows:
233 /// methods: A function returning an object mapping method names 249 /// methods: A function returning an object mapping method names
234 /// to method types. The function is evaluated lazily and cached. 250 /// to method types. The function is evaluated lazily and cached.
235 /// statics: A function returning an object mapping static method 251 /// statics: A function returning an object mapping static method
236 /// names to types. The function is evalutated lazily and cached. 252 /// names to types. The function is evalutated lazily and cached.
237 /// names: An array of the names of the static methods. Used to 253 /// names: An array of the names of the static methods. Used to
238 /// permit eagerly setting the runtimeType field on the methods 254 /// permit eagerly setting the runtimeType field on the methods
239 /// while still lazily computing the type descriptor object. 255 /// while still lazily computing the type descriptor object.
240 setSignature(f, signature) => JS('', '''(() => { 256 setSignature(f, signature) => JS(
257 '',
258 '''(() => {
241 // TODO(ochafik): Deconstruct these when supported by Chrome. 259 // TODO(ochafik): Deconstruct these when supported by Chrome.
242 let constructors = 260 let constructors =
243 ('constructors' in signature) ? signature.constructors : () => ({}); 261 ('constructors' in signature) ? signature.constructors : () => ({});
244 let methods = 262 let methods =
245 ('methods' in signature) ? signature.methods : () => ({}); 263 ('methods' in signature) ? signature.methods : () => ({});
246 let statics = 264 let statics =
247 ('statics' in signature) ? signature.statics : () => ({}); 265 ('statics' in signature) ? signature.statics : () => ({});
248 let names = 266 let names =
249 ('names' in signature) ? signature.names : []; 267 ('names' in signature) ? signature.names : [];
250 $_setConstructorSignature($f, constructors); 268 $_setConstructorSignature($f, constructors);
251 $_setMethodSignature($f, methods); 269 $_setMethodSignature($f, methods);
252 $_setStaticSignature($f, statics); 270 $_setStaticSignature($f, statics);
253 $_setStaticTypes($f, names); 271 $_setStaticTypes($f, names);
254 })()'''); 272 })()''');
255 273
256 hasMethod(obj, name) => JS('', '$getMethodType($obj, $name) !== void 0'); 274 hasMethod(obj, name) => JS('', '$getMethodType($obj, $name) !== void 0');
257 275
258 /// Given a class and an initializer method name, creates a constructor 276 /// Given a class and an initializer method name, creates a constructor
259 /// function with the same name. 277 /// function with the same name.
260 /// 278 ///
261 /// After we define the named constructor, the class can be constructed with 279 /// After we define the named constructor, the class can be constructed with
262 /// `new SomeClass.name(args)`. 280 /// `new SomeClass.name(args)`.
263 defineNamedConstructor(clazz, name) => JS('', '''(() => { 281 defineNamedConstructor(clazz, name) => JS(
282 '',
283 '''(() => {
264 let proto = $clazz.prototype; 284 let proto = $clazz.prototype;
265 let initMethod = proto[$name]; 285 let initMethod = proto[$name];
266 let ctor = function(...args) { initMethod.apply(this, args); }; 286 let ctor = function(...args) { initMethod.apply(this, args); };
287 ctor[$isNamedConstructor] = true;
267 ctor.prototype = proto; 288 ctor.prototype = proto;
268 // Use defineProperty so we don't hit a property defined on Function, 289 // Use defineProperty so we don't hit a property defined on Function,
269 // like `caller` and `arguments`. 290 // like `caller` and `arguments`.
270 $defineProperty($clazz, $name, { value: ctor, configurable: true }); 291 $defineProperty($clazz, $name, { value: ctor, configurable: true });
271 })()'''); 292 })()''');
272 293
273
274 final _extensionType = JS('', 'Symbol("extensionType")'); 294 final _extensionType = JS('', 'Symbol("extensionType")');
275 295
276 getExtensionType(obj) => JS('', '#[#]', obj, _extensionType); 296 getExtensionType(obj) => JS('', '#[#]', obj, _extensionType);
277 297
278 final dartx = JS('', 'dartx'); 298 final dartx = JS('', 'dartx');
279 299
280 getExtensionSymbol(name) { 300 getExtensionSymbol(name) {
281 var sym = JS('', 'dartx[#]', name); 301 var sym = JS('', 'dartx[#]', name);
282 if (sym == null) { 302 if (sym == null) {
283 sym = JS('', 'Symbol("dartx." + #.toString())', name); 303 sym = JS('', 'Symbol("dartx." + #.toString())', name);
284 JS('', 'dartx[#] = #', name, sym); 304 JS('', 'dartx[#] = #', name, sym);
285 } 305 }
286 return sym; 306 return sym;
287 } 307 }
288 308
289 defineExtensionNames(names) => 309 defineExtensionNames(names) =>
290 JS('', '#.forEach(#)', names, getExtensionSymbol); 310 JS('', '#.forEach(#)', names, getExtensionSymbol);
291 311
292
293 /// Install properties in prototype-first order. Properties / descriptors from 312 /// Install properties in prototype-first order. Properties / descriptors from
294 /// more specific types should overwrite ones from less specific types. 313 /// more specific types should overwrite ones from less specific types.
295 void _installProperties(jsProto, extProto) { 314 void _installProperties(jsProto, extProto) {
296
297 // This relies on the Dart type literal evaluating to the JavaScript 315 // This relies on the Dart type literal evaluating to the JavaScript
298 // constructor. 316 // constructor.
299 var coreObjProto = JS('', '#.prototype', Object); 317 var coreObjProto = JS('', '#.prototype', Object);
300 318
301 var parentsExtension = 319 var parentsExtension = JS('', '(#.__proto__)[#]', jsProto, _extensionType);
302 JS('', '(#.__proto__)[#]', jsProto, _extensionType);
303 var installedParent = 320 var installedParent =
304 JS('', '# && #.prototype', parentsExtension, parentsExtension); 321 JS('', '# && #.prototype', parentsExtension, parentsExtension);
305 322
306 _installProperties2(jsProto, extProto, coreObjProto, installedParent); 323 _installProperties2(jsProto, extProto, coreObjProto, installedParent);
307 } 324 }
308 325
309 void _installProperties2(jsProto, extProto, coreObjProto, installedParent) { 326 void _installProperties2(jsProto, extProto, coreObjProto, installedParent) {
310 if (JS('bool', '# === #', extProto, coreObjProto)) { 327 if (JS('bool', '# === #', extProto, coreObjProto)) {
311 _installPropertiesForObject(jsProto, coreObjProto); 328 _installPropertiesForObject(jsProto, coreObjProto);
312 return; 329 return;
313 } 330 }
314 if (JS('bool', '# !== #', jsProto, extProto)) { 331 if (JS('bool', '# !== #', jsProto, extProto)) {
315 var extParent = JS('', '#.__proto__', extProto); 332 var extParent = JS('', '#.__proto__', extProto);
316 333
317 // If the extension methods of the parent have been installed on the parent 334 // If the extension methods of the parent have been installed on the parent
318 // of [jsProto], the methods will be available via prototype inheritance. 335 // of [jsProto], the methods will be available via prototype inheritance.
319 336
320 if(JS('bool', '# !== #', installedParent, extParent)) { 337 if (JS('bool', '# !== #', installedParent, extParent)) {
321 _installProperties2(jsProto, extParent, coreObjProto, installedParent); 338 _installProperties2(jsProto, extParent, coreObjProto, installedParent);
322 } 339 }
323 } 340 }
324 copyTheseProperties(jsProto, extProto, getOwnPropertySymbols(extProto)); 341 copyTheseProperties(jsProto, extProto, getOwnPropertySymbols(extProto));
325 } 342 }
326 343
327 void _installPropertiesForObject(jsProto, coreObjProto) { 344 void _installPropertiesForObject(jsProto, coreObjProto) {
328 // core.Object members need to be copied from the non-symbol name to the 345 // core.Object members need to be copied from the non-symbol name to the
329 // symbol name. 346 // symbol name.
330 var names = getOwnPropertyNames(coreObjProto); 347 var names = getOwnPropertyNames(coreObjProto);
331 for (int i = 0; i < JS('int', '#.length', names); ++i) { 348 for (int i = 0; i < JS('int', '#.length', names); ++i) {
332 var name = JS('', '#[#]', names, i); 349 var name = JS('', '#[#]', names, i);
333 var desc = getOwnPropertyDescriptor(coreObjProto, name); 350 var desc = getOwnPropertyDescriptor(coreObjProto, name);
334 defineProperty(jsProto, getExtensionSymbol(name), desc); 351 defineProperty(jsProto, getExtensionSymbol(name), desc);
335 } 352 }
336 return; 353 return;
337 } 354 }
338 355
339 /// Copy symbols from the prototype of the source to destination. 356 /// Copy symbols from the prototype of the source to destination.
340 /// These are the only properties safe to copy onto an existing public 357 /// These are the only properties safe to copy onto an existing public
341 /// JavaScript class. 358 /// JavaScript class.
342 registerExtension(jsType, dartExtType) => JS('', '''(() => { 359 registerExtension(jsType, dartExtType) => JS(
360 '',
361 '''(() => {
343 // TODO(vsm): Not all registered js types are real. 362 // TODO(vsm): Not all registered js types are real.
344 if (!jsType) return; 363 if (!jsType) return;
345 364
346 let extProto = $dartExtType.prototype; 365 let extProto = $dartExtType.prototype;
347 let jsProto = $jsType.prototype; 366 let jsProto = $jsType.prototype;
348 367
349 // Mark the JS type's instances so we can easily check for extensions. 368 // Mark the JS type's instances so we can easily check for extensions.
350 jsProto[$_extensionType] = $dartExtType; 369 jsProto[$_extensionType] = $dartExtType;
351 $_installProperties(jsProto, extProto); 370 $_installProperties(jsProto, extProto);
352 let originalSigFn = $getOwnPropertyDescriptor($dartExtType, $_methodSig).get; 371 let originalSigFn = $getOwnPropertyDescriptor($dartExtType, $_methodSig).get;
(...skipping 13 matching lines...) Expand all
366 /// 385 ///
367 /// Results in: 386 /// Results in:
368 /// 387 ///
369 /// MyType.prototype[dartx.add] = MyType.prototype.add; 388 /// MyType.prototype[dartx.add] = MyType.prototype.add;
370 /// MyType.prototype[dartx.remove] = MyType.prototype.remove; 389 /// MyType.prototype[dartx.remove] = MyType.prototype.remove;
371 /// 390 ///
372 // TODO(jmesserly): essentially this gives two names to the same method. 391 // TODO(jmesserly): essentially this gives two names to the same method.
373 // This benefit is roughly equivalent call performance either way, but the 392 // This benefit is roughly equivalent call performance either way, but the
374 // cost is we need to call defineExtensionMembers any time a subclass 393 // cost is we need to call defineExtensionMembers any time a subclass
375 // overrides one of these methods. 394 // overrides one of these methods.
376 defineExtensionMembers(type, methodNames) => JS('', '''(() => { 395 defineExtensionMembers(type, methodNames) => JS(
396 '',
397 '''(() => {
377 let proto = $type.prototype; 398 let proto = $type.prototype;
378 for (let name of $methodNames) { 399 for (let name of $methodNames) {
379 let method = $getOwnPropertyDescriptor(proto, name); 400 let method = $getOwnPropertyDescriptor(proto, name);
380 // TODO(vsm): We should be able to generate code to avoid this case. 401 // TODO(vsm): We should be able to generate code to avoid this case.
381 // The method may be null if this type implements a potentially native 402 // The method may be null if this type implements a potentially native
382 // interface but isn't native itself. For a field on this type, we're not 403 // interface but isn't native itself. For a field on this type, we're not
383 // generating a corresponding getter/setter method - it's just a field. 404 // generating a corresponding getter/setter method - it's just a field.
384 if (!method) continue; 405 if (!method) continue;
385 $defineProperty(proto, $getExtensionSymbol(name), method); 406 $defineProperty(proto, $getExtensionSymbol(name), method);
386 } 407 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 JS('', '#.__proto__ = #.__proto__', callableCtor, classExpr); 466 JS('', '#.__proto__ = #.__proto__', callableCtor, classExpr);
446 return callableCtor; 467 return callableCtor;
447 } 468 }
448 469
449 /// Given a class and an initializer method name and a call method, creates a 470 /// Given a class and an initializer method name and a call method, creates a
450 /// constructor function with the same name. 471 /// constructor function with the same name.
451 /// 472 ///
452 /// For example it can be called with `new SomeClass.name(args)`. 473 /// For example it can be called with `new SomeClass.name(args)`.
453 /// 474 ///
454 /// The constructor 475 /// The constructor
455 defineNamedConstructorCallable(clazz, name, ctor) => JS('', '''(() => { 476 defineNamedConstructorCallable(clazz, name, ctor) => JS(
477 '',
478 '''(() => {
456 ctor.prototype = $clazz.prototype; 479 ctor.prototype = $clazz.prototype;
457 // Use defineProperty so we don't hit a property defined on Function, 480 // Use defineProperty so we don't hit a property defined on Function,
458 // like `caller` and `arguments`. 481 // like `caller` and `arguments`.
459 $defineProperty($clazz, $name, { value: ctor, configurable: true }); 482 $defineProperty($clazz, $name, { value: ctor, configurable: true });
460 })()'''); 483 })()''');
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698