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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart

Issue 266913017: Convert property methods into getters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased Created 6 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 part of dart2js.js_emitter; 5 part of dart2js.js_emitter;
6 6
7 class ClassEmitter extends CodeEmitterHelper { 7 class ClassEmitter extends CodeEmitterHelper {
8 /** 8 /**
9 * Documentation wanted -- johnniwinther 9 * Documentation wanted -- johnniwinther
10 * 10 *
11 * Invariant: [classElement] must be a declaration element. 11 * Invariant: [classElement] must be a declaration element.
12 */ 12 */
13 void generateClass(ClassElement classElement, 13 void generateClass(ClassElement classElement,
14 ClassBuilder properties, 14 ClassBuilder properties,
15 Map<String, jsAst.Expression> additionalProperties) { 15 Map<String, jsAst.Expression> additionalProperties) {
16 final onlyForRti = 16 final onlyForRti =
17 task.typeTestEmitter.rtiNeededClasses.contains(classElement); 17 task.typeTestEmitter.rtiNeededClasses.contains(classElement);
18 18
19 assert(invariant(classElement, classElement.isDeclaration)); 19 assert(invariant(classElement, classElement.isDeclaration));
20 assert(invariant(classElement, !classElement.isNative() || onlyForRti)); 20 assert(invariant(classElement, !classElement.isNative || onlyForRti));
21 21
22 task.needsDefineClass = true; 22 task.needsDefineClass = true;
23 String className = namer.getNameOfClass(classElement); 23 String className = namer.getNameOfClass(classElement);
24 24
25 ClassElement superclass = classElement.superclass; 25 ClassElement superclass = classElement.superclass;
26 String superName = ""; 26 String superName = "";
27 if (superclass != null) { 27 if (superclass != null) {
28 superName = namer.getNameOfClass(superclass); 28 superName = namer.getNameOfClass(superclass);
29 } 29 }
30 30
(...skipping 24 matching lines...) Expand all
55 emitTypeVariableReaders(classElement, builder); 55 emitTypeVariableReaders(classElement, builder);
56 56
57 emitClassBuilderWithReflectionData( 57 emitClassBuilderWithReflectionData(
58 className, classElement, builder, properties); 58 className, classElement, builder, properties);
59 } 59 }
60 60
61 void emitClassConstructor(ClassElement classElement, 61 void emitClassConstructor(ClassElement classElement,
62 ClassBuilder builder, 62 ClassBuilder builder,
63 {bool onlyForRti: false}) { 63 {bool onlyForRti: false}) {
64 List<String> fields = <String>[]; 64 List<String> fields = <String>[];
65 if (!onlyForRti && !classElement.isNative()) { 65 if (!onlyForRti && !classElement.isNative) {
66 visitFields(classElement, false, 66 visitFields(classElement, false,
67 (Element member, 67 (Element member,
68 String name, 68 String name,
69 String accessorName, 69 String accessorName,
70 bool needsGetter, 70 bool needsGetter,
71 bool needsSetter, 71 bool needsSetter,
72 bool needsCheckedSetter) { 72 bool needsCheckedSetter) {
73 fields.add(name); 73 fields.add(name);
74 }); 74 });
75 } 75 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 109 }
110 110
111 /// Returns `true` if fields added. 111 /// Returns `true` if fields added.
112 bool emitFields(Element element, 112 bool emitFields(Element element,
113 ClassBuilder builder, 113 ClassBuilder builder,
114 String superName, 114 String superName,
115 { bool classIsNative: false, 115 { bool classIsNative: false,
116 bool emitStatics: false, 116 bool emitStatics: false,
117 bool onlyForRti: false }) { 117 bool onlyForRti: false }) {
118 assert(!emitStatics || !onlyForRti); 118 assert(!emitStatics || !onlyForRti);
119 if (element.isLibrary()) { 119 if (element.isLibrary) {
120 assert(invariant(element, emitStatics)); 120 assert(invariant(element, emitStatics));
121 } else if (!element.isClass()) { 121 } else if (!element.isClass) {
122 throw new SpannableAssertionFailure( 122 throw new SpannableAssertionFailure(
123 element, 'Must be a ClassElement or a LibraryElement'); 123 element, 'Must be a ClassElement or a LibraryElement');
124 } 124 }
125 if (emitStatics) { 125 if (emitStatics) {
126 assert(invariant(element, superName == null, message: superName)); 126 assert(invariant(element, superName == null, message: superName));
127 } else { 127 } else {
128 assert(invariant(element, superName != null)); 128 assert(invariant(element, superName != null));
129 builder.superName = superName; 129 builder.superName = superName;
130 } 130 }
131 var fieldMetadata = []; 131 var fieldMetadata = [];
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 int getterCode = 0; 171 int getterCode = 0;
172 if (needsAccessor && backend.fieldHasInterceptedGetter(field)) { 172 if (needsAccessor && backend.fieldHasInterceptedGetter(field)) {
173 task.interceptorEmitter.interceptorInvocationNames.add( 173 task.interceptorEmitter.interceptorInvocationNames.add(
174 namer.getterName(field)); 174 namer.getterName(field));
175 } 175 }
176 if (needsAccessor && backend.fieldHasInterceptedGetter(field)) { 176 if (needsAccessor && backend.fieldHasInterceptedGetter(field)) {
177 task.interceptorEmitter.interceptorInvocationNames.add( 177 task.interceptorEmitter.interceptorInvocationNames.add(
178 namer.setterName(field)); 178 namer.setterName(field));
179 } 179 }
180 if (needsGetter) { 180 if (needsGetter) {
181 if (field.isInstanceMember()) { 181 if (field.isInstanceMember) {
182 // 01: function() { return this.field; } 182 // 01: function() { return this.field; }
183 // 10: function(receiver) { return receiver.field; } 183 // 10: function(receiver) { return receiver.field; }
184 // 11: function(receiver) { return this.field; } 184 // 11: function(receiver) { return this.field; }
185 bool isIntercepted = backend.fieldHasInterceptedGetter(field); 185 bool isIntercepted = backend.fieldHasInterceptedGetter(field);
186 getterCode += isIntercepted ? 2 : 0; 186 getterCode += isIntercepted ? 2 : 0;
187 getterCode += backend.isInterceptorClass(element) ? 0 : 1; 187 getterCode += backend.isInterceptorClass(element) ? 0 : 1;
188 // TODO(sra): 'isInterceptorClass' might not be the correct test 188 // TODO(sra): 'isInterceptorClass' might not be the correct test
189 // for methods forced to use the interceptor convention because 189 // for methods forced to use the interceptor convention because
190 // the method's class was elsewhere mixed-in to an interceptor. 190 // the method's class was elsewhere mixed-in to an interceptor.
191 assert(!field.isInstanceMember() || getterCode != 0); 191 assert(!field.isInstanceMember || getterCode != 0);
192 if (isIntercepted) { 192 if (isIntercepted) {
193 task.interceptorEmitter.interceptorInvocationNames.add( 193 task.interceptorEmitter.interceptorInvocationNames.add(
194 namer.getterName(field)); 194 namer.getterName(field));
195 } 195 }
196 } else { 196 } else {
197 getterCode = 1; 197 getterCode = 1;
198 } 198 }
199 } 199 }
200 int setterCode = 0; 200 int setterCode = 0;
201 if (needsSetter) { 201 if (needsSetter) {
202 if (field.isInstanceMember()) { 202 if (field.isInstanceMember) {
203 // 01: function(value) { this.field = value; } 203 // 01: function(value) { this.field = value; }
204 // 10: function(receiver, value) { receiver.field = value; } 204 // 10: function(receiver, value) { receiver.field = value; }
205 // 11: function(receiver, value) { this.field = value; } 205 // 11: function(receiver, value) { this.field = value; }
206 bool isIntercepted = backend.fieldHasInterceptedSetter(field); 206 bool isIntercepted = backend.fieldHasInterceptedSetter(field);
207 setterCode += isIntercepted ? 2 : 0; 207 setterCode += isIntercepted ? 2 : 0;
208 setterCode += backend.isInterceptorClass(element) ? 0 : 1; 208 setterCode += backend.isInterceptorClass(element) ? 0 : 1;
209 assert(!field.isInstanceMember() || setterCode != 0); 209 assert(!field.isInstanceMember || setterCode != 0);
210 if (isIntercepted) { 210 if (isIntercepted) {
211 task.interceptorEmitter.interceptorInvocationNames.add( 211 task.interceptorEmitter.interceptorInvocationNames.add(
212 namer.setterName(field)); 212 namer.setterName(field));
213 } 213 }
214 } else { 214 } else {
215 setterCode = 1; 215 setterCode = 1;
216 } 216 }
217 } 217 }
218 int code = getterCode + (setterCode << 2); 218 int code = getterCode + (setterCode << 2);
219 if (code == 0) { 219 if (code == 0) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 */ 276 */
277 void emitInstanceMembers(ClassElement classElement, 277 void emitInstanceMembers(ClassElement classElement,
278 ClassBuilder builder, 278 ClassBuilder builder,
279 {bool onlyForRti: false}) { 279 {bool onlyForRti: false}) {
280 assert(invariant(classElement, classElement.isDeclaration)); 280 assert(invariant(classElement, classElement.isDeclaration));
281 281
282 if (onlyForRti || classElement.isMixinApplication) return; 282 if (onlyForRti || classElement.isMixinApplication) return;
283 283
284 void visitMember(ClassElement enclosing, Element member) { 284 void visitMember(ClassElement enclosing, Element member) {
285 assert(invariant(classElement, member.isDeclaration)); 285 assert(invariant(classElement, member.isDeclaration));
286 if (member.isInstanceMember()) { 286 if (member.isInstanceMember) {
287 task.containerBuilder.addMember(member, builder); 287 task.containerBuilder.addMember(member, builder);
288 } 288 }
289 } 289 }
290 290
291 classElement.implementation.forEachMember( 291 classElement.implementation.forEachMember(
292 visitMember, 292 visitMember,
293 includeBackendMembers: true); 293 includeBackendMembers: true);
294 294
295 if (identical(classElement, compiler.objectClass) 295 if (identical(classElement, compiler.objectClass)
296 && compiler.enabledNoSuchMethod) { 296 && compiler.enabledNoSuchMethod) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 * When visiting the instance fields of a class, the fields of its superclass 383 * When visiting the instance fields of a class, the fields of its superclass
384 * are also visited if the class is instantiated. 384 * are also visited if the class is instantiated.
385 * 385 *
386 * Invariant: [element] must be a declaration element. 386 * Invariant: [element] must be a declaration element.
387 */ 387 */
388 void visitFields(Element element, bool visitStatics, AcceptField f) { 388 void visitFields(Element element, bool visitStatics, AcceptField f) {
389 assert(invariant(element, element.isDeclaration)); 389 assert(invariant(element, element.isDeclaration));
390 390
391 bool isClass = false; 391 bool isClass = false;
392 bool isLibrary = false; 392 bool isLibrary = false;
393 if (element.isClass()) { 393 if (element.isClass) {
394 isClass = true; 394 isClass = true;
395 } else if (element.isLibrary()) { 395 } else if (element.isLibrary) {
396 isLibrary = true; 396 isLibrary = true;
397 assert(invariant(element, visitStatics)); 397 assert(invariant(element, visitStatics));
398 } else { 398 } else {
399 throw new SpannableAssertionFailure( 399 throw new SpannableAssertionFailure(
400 element, 'Expected a ClassElement or a LibraryElement.'); 400 element, 'Expected a ClassElement or a LibraryElement.');
401 } 401 }
402 402
403 // If the class is never instantiated we still need to set it up for 403 // If the class is never instantiated we still need to set it up for
404 // inheritance purposes, but we can simplify its JavaScript constructor. 404 // inheritance purposes, but we can simplify its JavaScript constructor.
405 bool isInstantiated = 405 bool isInstantiated =
406 compiler.codegenWorld.instantiatedClasses.contains(element); 406 compiler.codegenWorld.instantiatedClasses.contains(element);
407 407
408 void visitField(Element holder, VariableElement field) { 408 void visitField(Element holder, VariableElement field) {
409 assert(invariant(element, field.isDeclaration)); 409 assert(invariant(element, field.isDeclaration));
410 String name = field.name; 410 String name = field.name;
411 411
412 // Keep track of whether or not we're dealing with a field mixin 412 // Keep track of whether or not we're dealing with a field mixin
413 // into a native class. 413 // into a native class.
414 bool isMixinNativeField = 414 bool isMixinNativeField =
415 isClass && element.isNative() && holder.isMixinApplication; 415 isClass && element.isNative && holder.isMixinApplication;
416 416
417 // See if we can dynamically create getters and setters. 417 // See if we can dynamically create getters and setters.
418 // We can only generate getters and setters for [element] since 418 // We can only generate getters and setters for [element] since
419 // the fields of super classes could be overwritten with getters or 419 // the fields of super classes could be overwritten with getters or
420 // setters. 420 // setters.
421 bool needsGetter = false; 421 bool needsGetter = false;
422 bool needsSetter = false; 422 bool needsSetter = false;
423 if (isLibrary || isMixinNativeField || holder == element) { 423 if (isLibrary || isMixinNativeField || holder == element) {
424 needsGetter = fieldNeedsGetter(field); 424 needsGetter = fieldNeedsGetter(field);
425 needsSetter = fieldNeedsSetter(field); 425 needsSetter = fieldNeedsSetter(field);
426 } 426 }
427 427
428 if ((isInstantiated && !holder.isNative()) 428 if ((isInstantiated && !holder.isNative)
429 || needsGetter 429 || needsGetter
430 || needsSetter) { 430 || needsSetter) {
431 String accessorName = namer.fieldAccessorName(field); 431 String accessorName = namer.fieldAccessorName(field);
432 String fieldName = namer.fieldPropertyName(field); 432 String fieldName = namer.fieldPropertyName(field);
433 bool needsCheckedSetter = false; 433 bool needsCheckedSetter = false;
434 if (compiler.enableTypeAssertions 434 if (compiler.enableTypeAssertions
435 && needsSetter 435 && needsSetter
436 && !canAvoidGeneratedCheckedSetter(field)) { 436 && !canAvoidGeneratedCheckedSetter(field)) {
437 needsCheckedSetter = true; 437 needsCheckedSetter = true;
438 needsSetter = false; 438 needsSetter = false;
439 } 439 }
440 // Getters and setters with suffixes will be generated dynamically. 440 // Getters and setters with suffixes will be generated dynamically.
441 f(field, fieldName, accessorName, needsGetter, needsSetter, 441 f(field, fieldName, accessorName, needsGetter, needsSetter,
442 needsCheckedSetter); 442 needsCheckedSetter);
443 } 443 }
444 } 444 }
445 445
446 if (isLibrary) { 446 if (isLibrary) {
447 LibraryElement library = element; 447 LibraryElement library = element;
448 library.implementation.forEachLocalMember((Element member) { 448 library.implementation.forEachLocalMember((Element member) {
449 if (member.isField()) visitField(library, member); 449 if (member.isField) visitField(library, member);
450 }); 450 });
451 } else if (visitStatics) { 451 } else if (visitStatics) {
452 ClassElement cls = element; 452 ClassElement cls = element;
453 cls.implementation.forEachStaticField(visitField); 453 cls.implementation.forEachStaticField(visitField);
454 } else { 454 } else {
455 ClassElement cls = element; 455 ClassElement cls = element;
456 // TODO(kasperl): We should make sure to only emit one version of 456 // TODO(kasperl): We should make sure to only emit one version of
457 // overridden fields. Right now, we rely on the ordering so the 457 // overridden fields. Right now, we rely on the ordering so the
458 // fields pulled in from mixins are replaced with the fields from 458 // fields pulled in from mixins are replaced with the fields from
459 // the class definition. 459 // the class definition.
460 460
461 // If a class is not instantiated then we add the field just so we can 461 // If a class is not instantiated then we add the field just so we can
462 // generate the field getter/setter dynamically. Since this is only 462 // generate the field getter/setter dynamically. Since this is only
463 // allowed on fields that are in [element] we don't need to visit 463 // allowed on fields that are in [element] we don't need to visit
464 // superclasses for non-instantiated classes. 464 // superclasses for non-instantiated classes.
465 cls.implementation.forEachInstanceField( 465 cls.implementation.forEachInstanceField(
466 visitField, includeSuperAndInjectedMembers: isInstantiated); 466 visitField, includeSuperAndInjectedMembers: isInstantiated);
467 } 467 }
468 } 468 }
469 469
470 void recordMangledField(Element member, 470 void recordMangledField(Element member,
471 String accessorName, 471 String accessorName,
472 String memberName) { 472 String memberName) {
473 if (!backend.shouldRetainGetter(member)) return; 473 if (!backend.shouldRetainGetter(member)) return;
474 String previousName; 474 String previousName;
475 if (member.isInstanceMember()) { 475 if (member.isInstanceMember) {
476 previousName = task.mangledFieldNames.putIfAbsent( 476 previousName = task.mangledFieldNames.putIfAbsent(
477 '${namer.getterPrefix}$accessorName', 477 '${namer.getterPrefix}$accessorName',
478 () => memberName); 478 () => memberName);
479 } else { 479 } else {
480 previousName = task.mangledGlobalFieldNames.putIfAbsent( 480 previousName = task.mangledGlobalFieldNames.putIfAbsent(
481 accessorName, 481 accessorName,
482 () => memberName); 482 () => memberName);
483 } 483 }
484 assert(invariant(member, previousName == memberName, 484 assert(invariant(member, previousName == memberName,
485 message: '$previousName != ${memberName}')); 485 message: '$previousName != ${memberName}'));
486 } 486 }
487 487
488 bool fieldNeedsGetter(VariableElement field) { 488 bool fieldNeedsGetter(VariableElement field) {
489 assert(field.isField()); 489 assert(field.isField);
490 if (fieldAccessNeverThrows(field)) return false; 490 if (fieldAccessNeverThrows(field)) return false;
491 return backend.shouldRetainGetter(field) 491 return backend.shouldRetainGetter(field)
492 || compiler.codegenWorld.hasInvokedGetter(field, compiler); 492 || compiler.codegenWorld.hasInvokedGetter(field, compiler);
493 } 493 }
494 494
495 bool fieldNeedsSetter(VariableElement field) { 495 bool fieldNeedsSetter(VariableElement field) {
496 assert(field.isField()); 496 assert(field.isField);
497 if (fieldAccessNeverThrows(field)) return false; 497 if (fieldAccessNeverThrows(field)) return false;
498 return (!field.modifiers.isFinalOrConst()) 498 return (!field.modifiers.isFinalOrConst)
499 && (backend.shouldRetainSetter(field) 499 && (backend.shouldRetainSetter(field)
500 || compiler.codegenWorld.hasInvokedSetter(field, compiler)); 500 || compiler.codegenWorld.hasInvokedSetter(field, compiler));
501 } 501 }
502 502
503 // We never access a field in a closure (a captured variable) without knowing 503 // We never access a field in a closure (a captured variable) without knowing
504 // that it is there. Therefore we don't need to use a getter (that will throw 504 // that it is there. Therefore we don't need to use a getter (that will throw
505 // if the getter method is missing), but can always access the field directly. 505 // if the getter method is missing), but can always access the field directly.
506 static bool fieldAccessNeverThrows(VariableElement field) { 506 static bool fieldAccessNeverThrows(VariableElement field) {
507 return field is ClosureFieldElement; 507 return field is ClosureFieldElement;
508 } 508 }
509 509
510 bool canAvoidGeneratedCheckedSetter(VariableElement member) { 510 bool canAvoidGeneratedCheckedSetter(VariableElement member) {
511 // We never generate accessors for top-level/static fields. 511 // We never generate accessors for top-level/static fields.
512 if (!member.isInstanceMember()) return true; 512 if (!member.isInstanceMember) return true;
513 DartType type = member.type; 513 DartType type = member.type;
514 return type.treatAsDynamic || (type.element == compiler.objectClass); 514 return type.treatAsDynamic || (type.element == compiler.objectClass);
515 } 515 }
516 516
517 void generateCheckedSetter(Element member, 517 void generateCheckedSetter(Element member,
518 String fieldName, 518 String fieldName,
519 String accessorName, 519 String accessorName,
520 ClassBuilder builder) { 520 ClassBuilder builder) {
521 jsAst.Expression code = backend.generatedCode[member]; 521 jsAst.Expression code = backend.generatedCode[member];
522 assert(code != null); 522 assert(code != null);
523 String setterName = namer.setterNameFromAccessorName(accessorName); 523 String setterName = namer.setterNameFromAccessorName(accessorName);
524 builder.addProperty(setterName, code); 524 builder.addProperty(setterName, code);
525 generateReflectionDataForFieldGetterOrSetter( 525 generateReflectionDataForFieldGetterOrSetter(
526 member, setterName, builder, isGetter: false); 526 member, setterName, builder, isGetter: false);
527 } 527 }
528 528
529 void generateGetter(Element member, String fieldName, String accessorName, 529 void generateGetter(Element member, String fieldName, String accessorName,
530 ClassBuilder builder) { 530 ClassBuilder builder) {
531 String getterName = namer.getterNameFromAccessorName(accessorName); 531 String getterName = namer.getterNameFromAccessorName(accessorName);
532 ClassElement cls = member.getEnclosingClass(); 532 ClassElement cls = member.enclosingClass;
533 String className = namer.getNameOfClass(cls); 533 String className = namer.getNameOfClass(cls);
534 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; 534 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this';
535 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; 535 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : [];
536 task.precompiledFunction.add( 536 task.precompiledFunction.add(
537 js('#.prototype.# = function(#) { return #.# }', 537 js('#.prototype.# = function(#) { return #.# }',
538 [className, getterName, args, receiver, fieldName])); 538 [className, getterName, args, receiver, fieldName]));
539 if (backend.isNeededForReflection(member)) { 539 if (backend.isNeededForReflection(member)) {
540 task.precompiledFunction.add( 540 task.precompiledFunction.add(
541 js('#.prototype.#.${namer.reflectableField} = 1', 541 js('#.prototype.#.${namer.reflectableField} = 1',
542 [className, getterName])); 542 [className, getterName]));
543 } 543 }
544 } 544 }
545 545
546 void generateSetter(Element member, String fieldName, String accessorName, 546 void generateSetter(Element member, String fieldName, String accessorName,
547 ClassBuilder builder) { 547 ClassBuilder builder) {
548 String setterName = namer.setterNameFromAccessorName(accessorName); 548 String setterName = namer.setterNameFromAccessorName(accessorName);
549 ClassElement cls = member.getEnclosingClass(); 549 ClassElement cls = member.enclosingClass;
550 String className = namer.getNameOfClass(cls); 550 String className = namer.getNameOfClass(cls);
551 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; 551 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this';
552 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; 552 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : [];
553 task.precompiledFunction.add( 553 task.precompiledFunction.add(
554 // TODO: remove 'return'? 554 // TODO: remove 'return'?
555 js('#.prototype.# = function(#, v) { return #.# = v; }', 555 js('#.prototype.# = function(#, v) { return #.# = v; }',
556 [className, setterName, args, receiver, fieldName])); 556 [className, setterName, args, receiver, fieldName]));
557 if (backend.isNeededForReflection(member)) { 557 if (backend.isNeededForReflection(member)) {
558 task.precompiledFunction.add( 558 task.precompiledFunction.add(
559 js('#.prototype.#.${namer.reflectableField} = 1', 559 js('#.prototype.#.${namer.reflectableField} = 1',
560 [className, setterName])); 560 [className, setterName]));
561 } 561 }
562 } 562 }
563 563
564 void generateReflectionDataForFieldGetterOrSetter(Element member, 564 void generateReflectionDataForFieldGetterOrSetter(Element member,
565 String name, 565 String name,
566 ClassBuilder builder, 566 ClassBuilder builder,
567 {bool isGetter}) { 567 {bool isGetter}) {
568 Selector selector = isGetter 568 Selector selector = isGetter
569 ? new Selector.getter(member.name, member.getLibrary()) 569 ? new Selector.getter(member.name, member.library)
570 : new Selector.setter(member.name, member.getLibrary()); 570 : new Selector.setter(member.name, member.library);
571 String reflectionName = task.getReflectionName(selector, name); 571 String reflectionName = task.getReflectionName(selector, name);
572 if (reflectionName != null) { 572 if (reflectionName != null) {
573 var reflectable = 573 var reflectable =
574 js(backend.isAccessibleByReflection(member) ? '1' : '0'); 574 js(backend.isAccessibleByReflection(member) ? '1' : '0');
575 builder.addProperty('+$reflectionName', reflectable); 575 builder.addProperty('+$reflectionName', reflectable);
576 } 576 }
577 } 577 }
578 578
579 void emitTypeVariableReaders(ClassElement cls, ClassBuilder builder) { 579 void emitTypeVariableReaders(ClassElement cls, ClassBuilder builder) {
580 List typeVariables = []; 580 List typeVariables = [];
(...skipping 29 matching lines...) Expand all
610 computeTypeVariable = 610 computeTypeVariable =
611 js(r'this.$builtinTypeInfo && this.$builtinTypeInfo[#]', index); 611 js(r'this.$builtinTypeInfo && this.$builtinTypeInfo[#]', index);
612 } 612 }
613 jsAst.Expression convertRtiToRuntimeType = 613 jsAst.Expression convertRtiToRuntimeType =
614 namer.elementAccess(compiler.findHelper('convertRtiToRuntimeType')); 614 namer.elementAccess(compiler.findHelper('convertRtiToRuntimeType'));
615 builder.addProperty(name, 615 builder.addProperty(name,
616 js('function () { return #(#) }', 616 js('function () { return #(#) }',
617 [convertRtiToRuntimeType, computeTypeVariable])); 617 [convertRtiToRuntimeType, computeTypeVariable]));
618 } 618 }
619 } 619 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698