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

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

Issue 2623053004: Fix noSuchMethod handling of methods that are also extension methods. Fix noSuchMethod handling of … (Closed)
Patch Set: respond to code review comments and mission creap Created 3 years, 11 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 ///
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 46
47 // Set the signature of the Mixin class to be the composition 47 // Set the signature of the Mixin class to be the composition
48 // of the signatures of the mixins. 48 // of the signatures of the mixins.
49 $setSignature(Mixin, { 49 $setSignature(Mixin, {
50 methods: () => { 50 methods: () => {
51 let s = {}; 51 let s = {};
52 for (let m of $mixins) { 52 for (let m of $mixins) {
53 $copyProperties(s, m[$_methodSig]); 53 $copyProperties(s, m[$_methodSig]);
54 } 54 }
55 return s; 55 return s;
56 },
57 fields: () => {
Jacob 2017/01/21 01:11:30 hole in propagating metadata
58 let s = {};
59 for (let m of $mixins) {
60 $copyProperties(s, m[$_fieldSig]);
61 }
62 return s;
63 },
64 getters: () => {
65 let s = {};
66 for (let m of $mixins) {
67 $copyProperties(s, m[$_getterSig]);
68 }
69 return s;
70 },
71 setters: () => {
72 let s = {};
73 for (let m of $mixins) {
74 $copyProperties(s, m[$_setterSig]);
75 }
76 return s;
56 } 77 }
57 }); 78 });
58 79
59 // Save mixins for reflection 80 // Save mixins for reflection
60 Mixin[$_mixins] = $mixins; 81 Mixin[$_mixins] = $mixins;
61 return Mixin; 82 return Mixin;
62 })()'''); 83 })()''');
63 84
64 /// The Symbol for storing type arguments on a specialized generic type. 85 /// The Symbol for storing type arguments on a specialized generic type.
65 final _mixins = JS('', 'Symbol("mixins")'); 86 final _mixins = JS('', 'Symbol("mixins")');
66 87
67 getMixins(clazz) => JS('', 'Object.hasOwnProperty.call(#, #) ? #[#] : null', cla zz, _mixins, clazz, _mixins); 88 getMixins(clazz) => JS('', 'Object.hasOwnProperty.call(#, #) ? #[#] : null',
89 clazz, _mixins, clazz, _mixins);
68 90
69 @JSExportName('implements') 91 @JSExportName('implements')
70 final _implements = JS('', 'Symbol("implements")'); 92 final _implements = JS('', 'Symbol("implements")');
71 93
72 getImplements(clazz) => JS('', 'Object.hasOwnProperty.call(#, #) ? #[#] : null', clazz, _implements, clazz, _implements); 94 getImplements(clazz) => JS('', 'Object.hasOwnProperty.call(#, #) ? #[#] : null',
95 clazz, _implements, clazz, _implements);
73 96
74 /// The Symbol for storing type arguments on a specialized generic type. 97 /// The Symbol for storing type arguments on a specialized generic type.
75 final _typeArguments = JS('', 'Symbol("typeArguments")'); 98 final _typeArguments = JS('', 'Symbol("typeArguments")');
76 99
77 final _originalDeclaration = JS('', 'Symbol("originalDeclaration")'); 100 final _originalDeclaration = JS('', 'Symbol("originalDeclaration")');
78 101
79 /// Wrap a generic class builder function with future flattening. 102 /// Wrap a generic class builder function with future flattening.
80 flattenFutures(builder) => JS( 103 flattenFutures(builder) => JS(
81 '', 104 '',
82 '''(() => { 105 '''(() => {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 167
145 getGenericClass(type) => 168 getGenericClass(type) =>
146 JS('', '$safeGetOwnProperty($type, $_originalDeclaration)'); 169 JS('', '$safeGetOwnProperty($type, $_originalDeclaration)');
147 170
148 getGenericArgs(type) => JS('', '$safeGetOwnProperty($type, $_typeArguments)'); 171 getGenericArgs(type) => JS('', '$safeGetOwnProperty($type, $_typeArguments)');
149 172
150 // TODO(vsm): Collapse into one expando. 173 // TODO(vsm): Collapse into one expando.
151 final _constructorSig = JS('', 'Symbol("sigCtor")'); 174 final _constructorSig = JS('', 'Symbol("sigCtor")');
152 final _methodSig = JS('', 'Symbol("sigMethod")'); 175 final _methodSig = JS('', 'Symbol("sigMethod")');
153 final _fieldSig = JS('', 'Symbol("sigField")'); 176 final _fieldSig = JS('', 'Symbol("sigField")');
154 final _getterSig= JS('', 'Symbol("sigGetter")'); 177 final _getterSig = JS('', 'Symbol("sigGetter")');
155 final _setterSig= JS('', 'Symbol("sigSetter")'); 178 final _setterSig = JS('', 'Symbol("sigSetter")');
156 final _staticSig = JS('', 'Symbol("sigStaticMethod")'); 179 final _staticSig = JS('', 'Symbol("sigStaticMethod")');
157 final _staticFieldSig = JS('', 'Symbol("sigStaticField")'); 180 final _staticFieldSig = JS('', 'Symbol("sigStaticField")');
158 final _staticGetterSig= JS('', 'Symbol("sigStaticGetter")'); 181 final _staticGetterSig = JS('', 'Symbol("sigStaticGetter")');
Jacob 2017/01/21 01:11:30 Ran the formatter. Sorry about the formatter relat
159 final _staticSetterSig= JS('', 'Symbol("sigStaticSetter")'); 182 final _staticSetterSig = JS('', 'Symbol("sigStaticSetter")');
160 final _genericTypeCtor = JS('', 'Symbol("genericType")'); 183 final _genericTypeCtor = JS('', 'Symbol("genericType")');
161 184
162 // TODO(vsm): Collapse this as well - just provide a dart map to mirrors code. 185 // TODO(vsm): Collapse this as well - just provide a dart map to mirrors code.
163 // These are queried by mirrors code. 186 // These are queried by mirrors code.
164 getConstructorSig(value) => JS('', '#[#]', value, _constructorSig); 187 getConstructorSig(value) => JS('', '#[#]', value, _constructorSig);
165 getMethodSig(value) => JS('', '#[#]', value, _methodSig); 188 getMethodSig(value) => JS('', '#[#]', value, _methodSig);
166 getFieldSig(value) => JS('', '#[#]', value, _fieldSig); 189 getFieldSig(value) => JS('', '#[#]', value, _fieldSig);
167 getGetterSig(value) => JS('', '#[#]', value, _getterSig); 190 getGetterSig(value) => JS('', '#[#]', value, _getterSig);
168 getSetterSig(value) => JS('', '#[#]', value, _setterSig); 191 getSetterSig(value) => JS('', '#[#]', value, _setterSig);
169 getStaticSig(value) => JS('', '#[#]', value, _staticSig); 192 getStaticSig(value) => JS('', '#[#]', value, _staticSig);
170 getStaticFieldSig(value) => JS('', '#[#]', value, _staticFieldSig); 193 getStaticFieldSig(value) => JS('', '#[#]', value, _staticFieldSig);
171 getStaticGetterSig(value) => JS('', '#[#]', value, _staticGetterSig); 194 getStaticGetterSig(value) => JS('', '#[#]', value, _staticGetterSig);
172 getStaticSetterSig(value) => JS('', '#[#]', value, _staticSetterSig); 195 getStaticSetterSig(value) => JS('', '#[#]', value, _staticSetterSig);
173 196
174 getGenericTypeCtor(value) => JS('', '#[#]', value, _genericTypeCtor); 197 getGenericTypeCtor(value) => JS('', '#[#]', value, _genericTypeCtor);
175 198
176 /// Get the type of a method from an object using the stored signature 199 /// Get the type of a method from an object using the stored signature
177 getMethodType(obj, name) => JS( 200 getType(obj) => JS(
178 '', 201 '',
179 '''(() => { 202 '''(() => {
180 let type = $obj == null ? $Object : $obj.__proto__.constructor; 203 return $obj == null ? $Object : $obj.__proto__.constructor;
181 return $getMethodTypeFromType(type, $name);
182 })()'''); 204 })()''');
183 205
184 /// Get the type of a method from a type using the stored signature 206 /// Get the type of a method from a type using the stored signature
185 getMethodTypeFromType(type, name) => JS( 207 getMethodType(type, name) => JS(
Jacob 2017/01/21 01:11:30 removed the getMethodType call that used an object
186 '', 208 '',
187 '''(() => { 209 '''(() => {
188 let sigObj = $type[$_methodSig]; 210 let sigObj = $type[$_methodSig];
189 if (sigObj === void 0) return void 0; 211 if (sigObj === void 0) return void 0;
190 return sigObj[$name]; 212 return sigObj[$name];
191 })()'''); 213 })()''');
192 214
215 getFieldType(type, name) => JS(
216 '',
217 '''(() => {
218 let sigObj = $type[$_fieldSig];
219 if (sigObj === void 0) return void 0;
220 return sigObj[$name];
221 })()''');
222
223 getSetterType(type, name) => JS(
224 '',
225 '''(() => {
226 let sigObj = $type[$_setterSig];
227 if (sigObj === void 0) return void 0;
228 return sigObj[$name];
229 })()''');
230
193 /// Get the type of a constructor from a class using the stored signature 231 /// Get the type of a constructor from a class using the stored signature
194 /// If name is undefined, returns the type of the default constructor 232 /// If name is undefined, returns the type of the default constructor
195 /// Returns undefined if the constructor is not found. 233 /// Returns undefined if the constructor is not found.
196 classGetConstructorType(cls, name) => JS( 234 classGetConstructorType(cls, name) => JS(
197 '', 235 '',
198 '''(() => { 236 '''(() => {
199 if(!$name) $name = 'new'; 237 if(!$name) $name = 'new';
200 if ($cls === void 0) return void 0; 238 if ($cls === void 0) return void 0;
201 if ($cls == null) return void 0; 239 if ($cls == null) return void 0;
202 let sigCtor = $cls[$_constructorSig]; 240 let sigCtor = $cls[$_constructorSig];
203 if (sigCtor === void 0) return void 0; 241 if (sigCtor === void 0) return void 0;
204 return sigCtor[$name]; 242 return sigCtor[$name];
205 })()'''); 243 })()''');
206 244
207 /// Given an object and a method name, tear off the method. 245 /// Given an object and a method name, tear off the method.
208 /// Sets the runtime type of the torn off method appropriately, 246 /// Sets the runtime type of the torn off method appropriately,
209 /// and also binds the object. 247 /// and also binds the object.
210 /// 248 ///
211 /// If the optional `f` argument is passed in, it will be used as the method. 249 /// If the optional `f` argument is passed in, it will be used as the method.
212 /// This supports cases like `super.foo` where we need to tear off the method 250 /// This supports cases like `super.foo` where we need to tear off the method
213 /// from the superclass, not from the `obj` directly. 251 /// from the superclass, not from the `obj` directly.
214 /// TODO(leafp): Consider caching the tearoff on the object? 252 /// TODO(leafp): Consider caching the tearoff on the object?
215 bind(obj, name, f) => JS( 253 bind(obj, name, f) => JS(
216 '', 254 '',
217 '''(() => { 255 '''(() => {
218 if ($f === void 0) $f = $obj[$name]; 256 if ($f === void 0) $f = $obj[$name];
219 $f = $f.bind($obj); 257 $f = $f.bind($obj);
220 // TODO(jmesserly): track the function's signature on the function, instead 258 // TODO(jmesserly): track the function's signature on the function, instead
221 // of having to go back to the class? 259 // of having to go back to the class?
222 let sig = $getMethodType($obj, $name); 260 let sig = $getMethodType($getType($obj), $name);
223 $assert_(sig); 261 $assert_(sig);
224 $tag($f, sig); 262 $tag($f, sig);
225 return $f; 263 return $f;
226 })()'''); 264 })()''');
227 265
228 /// Instantiate a generic method. 266 /// Instantiate a generic method.
229 /// 267 ///
230 /// We need to apply the type arguments both to the function, as well as its 268 /// We need to apply the type arguments both to the function, as well as its
231 /// associated function type. 269 /// associated function type.
232 gbind(f, @rest typeArgs) { 270 gbind(f, @rest typeArgs) {
233 var result = JS('', '#.apply(null, #)', f, typeArgs); 271 var result = JS('', '#.apply(null, #)', f, typeArgs);
234 var sig = JS('', '#.apply(null, #)', _getRuntimeType(f), typeArgs); 272 var sig = JS('', '#.apply(null, #)', _getRuntimeType(f), typeArgs);
235 tag(result, sig); 273 tag(result, sig);
236 return result; 274 return result;
237 } 275 }
238 276
239 // Set up the method signature field on the constructor 277 // Set up the method signature field on the constructor
240 _setInstanceSignature(f, sigF, kind) => JS( 278 _setInstanceSignature(f, sigF, kind) => JS(
241 '', 279 '',
242 '''(() => { 280 '''(() => {
243 $defineMemoizedGetter($f, $kind, () => { 281 $defineMemoizedGetter($f, $kind, () => {
244 let sigObj = $sigF(); 282 let sigObj = $sigF();
245 sigObj.__proto__ = $f.__proto__[$kind]; 283 let proto = $f.__proto__;
284 // We need to set the root proto to null not undefined.
Jacob 2017/01/21 01:11:30 This bug resulted in our type metadata looking lik
285 sigObj.__proto__ = ($kind in proto) ? proto[$kind] : null;
246 return sigObj; 286 return sigObj;
247 }); 287 });
248 })()'''); 288 })()''');
249 289
250 _setMethodSignature(f, sigF) => _setInstanceSignature(f, sigF, _methodSig); 290 _setMethodSignature(f, sigF) => _setInstanceSignature(f, sigF, _methodSig);
251 _setFieldSignature(f, sigF) => _setInstanceSignature(f, sigF, _fieldSig); 291 _setFieldSignature(f, sigF) => _setInstanceSignature(f, sigF, _fieldSig);
252 _setGetterSignature(f, sigF) => _setInstanceSignature(f, sigF, _getterSig); 292 _setGetterSignature(f, sigF) => _setInstanceSignature(f, sigF, _getterSig);
253 _setSetterSignature(f, sigF) => _setInstanceSignature(f, sigF, _setterSig); 293 _setSetterSignature(f, sigF) => _setInstanceSignature(f, sigF, _setterSig);
254 294
255 // Set up the constructor signature field on the constructor 295 // Set up the constructor signature field on the constructor
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 $_setFieldSignature($f, fields); 363 $_setFieldSignature($f, fields);
324 $_setGetterSignature($f, getters); 364 $_setGetterSignature($f, getters);
325 $_setSetterSignature($f, setters); 365 $_setSetterSignature($f, setters);
326 $_setStaticSignature($f, statics); 366 $_setStaticSignature($f, statics);
327 $_setStaticFieldSignature($f, staticFields); 367 $_setStaticFieldSignature($f, staticFields);
328 $_setStaticGetterSignature($f, staticGetters); 368 $_setStaticGetterSignature($f, staticGetters);
329 $_setStaticSetterSignature($f, staticSetters); 369 $_setStaticSetterSignature($f, staticSetters);
330 $_setStaticTypes($f, names); 370 $_setStaticTypes($f, names);
331 })()'''); 371 })()''');
332 372
333 hasMethod(obj, name) => JS('', '$getMethodType($obj, $name) !== void 0'); 373 _hasSigEntry(type, sigF, name) => JS(
374 '',
375 '''(() => {
376 let sigObj = $type[$sigF];
377 if (sigObj === void 0) return false;
378 return $name in sigObj;
379 })()''');
380
381 hasMethod(type, name) => _hasSigEntry(type, _methodSig, name);
382 hasGetter(type, name) => _hasSigEntry(type, _getterSig, name);
383 hasSetter(type, name) => _hasSigEntry(type, _setterSig, name);
384 hasField(type, name) => _hasSigEntry(type, _fieldSig, name);
334 385
335 /// Given a class and an initializer method name, creates a constructor 386 /// Given a class and an initializer method name, creates a constructor
336 /// function with the same name. 387 /// function with the same name.
337 /// 388 ///
338 /// After we define the named constructor, the class can be constructed with 389 /// After we define the named constructor, the class can be constructed with
339 /// `new SomeClass.name(args)`. 390 /// `new SomeClass.name(args)`.
340 defineNamedConstructor(clazz, name) => JS( 391 defineNamedConstructor(clazz, name) => JS(
341 '', 392 '',
342 '''(() => { 393 '''(() => {
343 let proto = $clazz.prototype; 394 let proto = $clazz.prototype;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 let extProto = $dartExtType.prototype; 475 let extProto = $dartExtType.prototype;
425 let jsProto = $jsType.prototype; 476 let jsProto = $jsType.prototype;
426 477
427 // TODO(vsm): This sometimes doesn't exist on FF. These types will be 478 // TODO(vsm): This sometimes doesn't exist on FF. These types will be
428 // broken. 479 // broken.
429 if (!jsProto) return; 480 if (!jsProto) return;
430 481
431 // Mark the JS type's instances so we can easily check for extensions. 482 // Mark the JS type's instances so we can easily check for extensions.
432 jsProto[$_extensionType] = $dartExtType; 483 jsProto[$_extensionType] = $dartExtType;
433 $_installProperties(jsProto, extProto); 484 $_installProperties(jsProto, extProto);
434 let originalSigFn = $getOwnPropertyDescriptor($dartExtType, $_methodSig).get; 485 function updateSig(sigF) {
Jacob 2017/01/21 01:11:30 We were forgetting to call updateSig on anything b
435 $assert_(originalSigFn); 486 let originalSigFn = $getOwnPropertyDescriptor($dartExtType, sigF).get;
436 $defineMemoizedGetter($jsType, $_methodSig, originalSigFn); 487 $assert_(originalSigFn);
488 $defineMemoizedGetter($jsType, sigF, originalSigFn);
489 }
490 updateSig($_methodSig);
491 updateSig($_fieldSig);
492 updateSig($_getterSig);
493 updateSig($_setterSig);
437 })()'''); 494 })()''');
438 495
439 /// 496 ///
440 /// Mark a concrete type as implementing extension methods. 497 /// Mark a concrete type as implementing extension methods.
441 /// For example: `class MyIter implements Iterable`. 498 /// For example: `class MyIter implements Iterable`.
442 /// 499 ///
443 /// This takes a list of names, which are the extension methods implemented. 500 /// This takes a list of names, which are the extension methods implemented.
444 /// It will add a forwarder, so the extension method name redirects to the 501 /// It will add a forwarder, so the extension method name redirects to the
445 /// normal Dart method name. For example: 502 /// normal Dart method name. For example:
446 /// 503 ///
(...skipping 15 matching lines...) Expand all
462 for (let name of $methodNames) { 519 for (let name of $methodNames) {
463 let method = $getOwnPropertyDescriptor(proto, name); 520 let method = $getOwnPropertyDescriptor(proto, name);
464 $defineProperty(proto, $getExtensionSymbol(name), method); 521 $defineProperty(proto, $getExtensionSymbol(name), method);
465 } 522 }
466 // Ensure the signature is available too. 523 // Ensure the signature is available too.
467 // TODO(jmesserly): not sure if we can do this in a cleaner way. Essentially 524 // TODO(jmesserly): not sure if we can do this in a cleaner way. Essentially
468 // we need to copy the signature (and in the future, other data like 525 // we need to copy the signature (and in the future, other data like
469 // annotations) any time we copy a method as part of our metaprogramming. 526 // annotations) any time we copy a method as part of our metaprogramming.
470 // It might be more friendly to JS metaprogramming if we include this info 527 // It might be more friendly to JS metaprogramming if we include this info
471 // on the function. 528 // on the function.
472 let originalSigFn = $getOwnPropertyDescriptor($type, $_methodSig).get; 529
473 $defineMemoizedGetter(type, $_methodSig, function() { 530 function upgradeSig(sigF) {
474 let sig = originalSigFn(); 531 let originalSigFn = $getOwnPropertyDescriptor($type, sigF).get;
475 for (let name of $methodNames) { 532 $defineMemoizedGetter(type, sigF, function() {
476 sig[$getExtensionSymbol(name)] = sig[name]; 533 let sig = originalSigFn();
477 } 534 let propertyNames = Object.getOwnPropertyNames(sig);
478 return sig; 535 for (let name of methodNames) {
479 }); 536 if (name in sig) {
537 sig[$getExtensionSymbol(name)] = sig[name];
538 }
539 }
540 return sig;
541 });
542 };
543 upgradeSig($_methodSig);
544 upgradeSig($_fieldSig);
545 upgradeSig($_getterSig);
546 upgradeSig($_setterSig);
480 })()'''); 547 })()''');
481 548
482 /// Sets the type of `obj` to be `type` 549 /// Sets the type of `obj` to be `type`
483 setType(obj, type) { 550 setType(obj, type) {
484 JS('', '#.__proto__ = #.prototype', obj, type); 551 JS('', '#.__proto__ = #.prototype', obj, type);
485 return obj; 552 return obj;
486 } 553 }
487 554
488 /// Sets the element type of a list literal. 555 /// Sets the element type of a list literal.
489 list(obj, elementType) => 556 list(obj, elementType) =>
490 JS('', '$setType($obj, ${getGenericClass(JSArray)}($elementType))'); 557 JS('', '$setType($obj, ${getGenericClass(JSArray)}($elementType))');
491 558
492 /// Link the extension to the type it's extending as a base class. 559 /// Link the extension to the type it's extending as a base class.
493 setBaseClass(derived, base) { 560 setBaseClass(derived, base) {
494 JS('', '#.prototype.__proto__ = #.prototype', derived, base); 561 JS('', '#.prototype.__proto__ = #.prototype', derived, base);
495 // We use __proto__ to track the superclass hierarchy (see isSubtype). 562 // We use __proto__ to track the superclass hierarchy (see isSubtype).
496 JS('', '#.__proto__ = #', derived, base); 563 JS('', '#.__proto__ = #', derived, base);
497 } 564 }
498 565
499 /// Like [setBaseClass] but for generic extension types, e.g. `JSArray<E>` 566 /// Like [setBaseClass] but for generic extension types, e.g. `JSArray<E>`
500 setExtensionBaseClass(derived, base) { 567 setExtensionBaseClass(derived, base) {
501 // Mark the generic type as an extension type and link the prototype objects 568 // Mark the generic type as an extension type and link the prototype objects
502 return JS('', '''(() => { 569 return JS(
570 '',
571 '''(() => {
503 if ($base) { 572 if ($base) {
504 $derived.prototype[$_extensionType] = $derived; 573 $derived.prototype[$_extensionType] = $derived;
505 $derived.prototype.__proto__ = $base.prototype 574 $derived.prototype.__proto__ = $base.prototype
506 } 575 }
507 })()'''); 576 })()''');
508 } 577 }
509 578
510 /// Given a special constructor function that creates a function instances, 579 /// Given a special constructor function that creates a function instances,
511 /// and a class with a `call` method, merge them so the constructor function 580 /// and a class with a `call` method, merge them so the constructor function
512 /// will have the correct methods and prototype. 581 /// will have the correct methods and prototype.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 '''(() => { 617 '''(() => {
549 let values = []; 618 let values = [];
550 for (var i = 0; i < $names.length; i++) { 619 for (var i = 0; i < $names.length; i++) {
551 let value = $const_(new $enumClass(i)); 620 let value = $const_(new $enumClass(i));
552 values.push(value); 621 values.push(value);
553 Object.defineProperty($enumClass, $names[i], 622 Object.defineProperty($enumClass, $names[i],
554 { value: value, configurable: true }); 623 { value: value, configurable: true });
555 } 624 }
556 $enumClass.values = $constList(values, $enumClass); 625 $enumClass.values = $constList(values, $enumClass);
557 })()'''); 626 })()''');
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698