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

Side by Side Diff: lib/compiler/implementation/emitter.dart

Issue 10831154: Make field-get/set work without elements. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed comments. Created 8 years, 4 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /** 5 /**
6 * A function element that represents a closure call. The signature is copied 6 * A function element that represents a closure call. The signature is copied
7 * from the given element. 7 * from the given element.
8 */ 8 */
9 class ClosureInvocationElement extends FunctionElement { 9 class ClosureInvocationElement extends FunctionElement {
10 ClosureInvocationElement(SourceString name, 10 ClosureInvocationElement(SourceString name,
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 defineInstanceMember(namer.getName(member), codeBuffer); 418 defineInstanceMember(namer.getName(member), codeBuffer);
419 codeBuffer = compiler.codegenWorld.generatedBailoutCode[member]; 419 codeBuffer = compiler.codegenWorld.generatedBailoutCode[member];
420 if (codeBuffer !== null) { 420 if (codeBuffer !== null) {
421 defineInstanceMember(compiler.namer.getBailoutName(member), codeBuffer); 421 defineInstanceMember(compiler.namer.getBailoutName(member), codeBuffer);
422 } 422 }
423 FunctionElement function = member; 423 FunctionElement function = member;
424 FunctionSignature parameters = function.computeSignature(compiler); 424 FunctionSignature parameters = function.computeSignature(compiler);
425 if (!parameters.optionalParameters.isEmpty()) { 425 if (!parameters.optionalParameters.isEmpty()) {
426 addParameterStubs(member, defineInstanceMember); 426 addParameterStubs(member, defineInstanceMember);
427 } 427 }
428 } else if (member.kind === ElementKind.FIELD) { 428 } else if (member.kind !== ElementKind.FIELD) {
429 SourceString name = member.name;
430 ClassElement cls = member.getEnclosingClass();
431 if (cls.lookupSuperMember(name) !== null) {
432 String fieldName = namer.instanceFieldName(cls, name);
433 CodeBuffer getterBuffer = new CodeBuffer();
434 getterBuffer.add('function() {\n return this.$fieldName;\n }');
435 defineInstanceMember(namer.getterName(cls.getLibrary(), name),
436 getterBuffer);
437 CodeBuffer setterBuffer = new CodeBuffer();
438 setterBuffer.add('function(x) {\n this.$fieldName = x;\n }');
439 defineInstanceMember(namer.setterName(cls.getLibrary(), name),
440 setterBuffer);
441 }
442 } else {
443 compiler.internalError('unexpected kind: "${member.kind}"', 429 compiler.internalError('unexpected kind: "${member.kind}"',
444 element: member); 430 element: member);
445 } 431 }
446 emitExtraAccessors(member, defineInstanceMember); 432 emitExtraAccessors(member, defineInstanceMember);
447 } 433 }
448 434
449 Set<Element> emitClassFields(ClassElement classElement, CodeBuffer buffer) { 435 Set<Element> emitClassFields(ClassElement classElement, CodeBuffer buffer) {
450 // If the class is never instantiated we still need to set it up for 436 // If the class is never instantiated we still need to set it up for
451 // inheritance purposes, but we can simplify its JavaScript constructor. 437 // inheritance purposes, but we can simplify its JavaScript constructor.
452 bool isInstantiated = 438 bool isInstantiated =
453 compiler.codegenWorld.instantiatedClasses.contains(classElement); 439 compiler.codegenWorld.instantiatedClasses.contains(classElement);
454 440
455 bool isFirstField = true; 441 bool isFirstField = true;
456 void addField(ClassElement enclosingClass, Element member) { 442 void addField(ClassElement enclosingClass, Element member) {
457 assert(!member.isNative()); 443 assert(!member.isNative());
444
445 LibraryElement library = member.getLibrary();
446 SourceString name = member.name;
447 bool isPrivate = name.isPrivate();
458 // See if we can dynamically create getters and setters. 448 // See if we can dynamically create getters and setters.
459 // We can only generate getters and setters for [classElement] since 449 // We can only generate getters and setters for [classElement] since
460 // the fields of super classes could be overwritten with getters or 450 // the fields of super classes could be overwritten with getters or
461 // setters. 451 // setters.
462 bool needsDynamicGetter = false; 452 bool needsDynamicGetter = false;
463 bool needsDynamicSetter = false; 453 bool needsDynamicSetter = false;
454 // We need to name shadowed fields differently, so they don't clash with
455 // the non-shadowed field.
456 bool isShadowed = false;
464 if (enclosingClass === classElement) { 457 if (enclosingClass === classElement) {
465 needsDynamicGetter = instanceFieldNeedsGetter(member); 458 needsDynamicGetter = instanceFieldNeedsGetter(member);
466 needsDynamicSetter = instanceFieldNeedsSetter(member); 459 needsDynamicSetter = instanceFieldNeedsSetter(member);
460 } else {
461 isShadowed = classElement.isShadowedByField(member);
467 } 462 }
468 463
469 if ((isInstantiated && !enclosingClass.isNative()) 464 if ((isInstantiated && !enclosingClass.isNative())
470 || needsDynamicGetter 465 || needsDynamicGetter
471 || needsDynamicSetter) { 466 || needsDynamicSetter) {
472 if (isFirstField) { 467 if (isFirstField) {
473 isFirstField = false; 468 isFirstField = false;
474 } else { 469 } else {
475 buffer.add(", "); 470 buffer.add(", ");
476 } 471 }
477 SourceString name = member.name; 472 String fieldName = isShadowed
478 String fieldName = namer.instanceFieldName(member.getEnclosingClass(), 473 ? namer.shadowedFieldName(member)
479 name); 474 : namer.instanceFieldName(library, name);
480 // Getters and setters with suffixes will be generated dynamically. 475 // Getters and setters with suffixes will be generated dynamically.
481 buffer.add('"$fieldName'); 476 buffer.add('"$fieldName');
482 if (needsDynamicGetter || needsDynamicSetter) { 477 if (needsDynamicGetter || needsDynamicSetter) {
483 if (needsDynamicGetter && needsDynamicSetter) { 478 if (needsDynamicGetter && needsDynamicSetter) {
484 buffer.add(GETTER_SETTER_SUFFIX); 479 buffer.add(GETTER_SETTER_SUFFIX);
485 } else if (needsDynamicGetter) { 480 } else if (needsDynamicGetter) {
486 buffer.add(GETTER_SUFFIX); 481 buffer.add(GETTER_SUFFIX);
487 } else { 482 } else {
488 buffer.add(SETTER_SUFFIX); 483 buffer.add(SETTER_SUFFIX);
489 } 484 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 } 517 }
523 }); 518 });
524 519
525 generateTypeTests(classElement, (Element other) { 520 generateTypeTests(classElement, (Element other) {
526 String code; 521 String code;
527 if (nativeEmitter.requiresNativeIsCheck(other)) { 522 if (nativeEmitter.requiresNativeIsCheck(other)) {
528 code = 'function() { return true; }'; 523 code = 'function() { return true; }';
529 } else { 524 } else {
530 code = 'true'; 525 code = 'true';
531 } 526 }
532 CodeBuffer buffer = new CodeBuffer(); 527 CodeBuffer typeTestBuffer = new CodeBuffer();
533 buffer.add(code); 528 typeTestBuffer.add(code);
534 defineInstanceMember(namer.operatorIs(other), buffer); 529 defineInstanceMember(namer.operatorIs(other), typeTestBuffer);
535 }); 530 });
536 531
537 if (classElement === compiler.objectClass && compiler.enabledNoSuchMethod) { 532 if (classElement === compiler.objectClass && compiler.enabledNoSuchMethod) {
538 // Emit the noSuchMethod handlers on the Object prototype now, 533 // Emit the noSuchMethod handlers on the Object prototype now,
539 // so that the code in the dynamicFunction helper can find 534 // so that the code in the dynamicFunction helper can find
540 // them. Note that this helper is invoked before analyzing the 535 // them. Note that this helper is invoked before analyzing the
541 // full JS script. 536 // full JS script.
542 emitNoSuchMethodHandlers(defineInstanceMember); 537 emitNoSuchMethodHandlers(defineInstanceMember);
543 } 538 }
544 } 539 }
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 defineInstanceMember(getterName, getterBuffer); 770 defineInstanceMember(getterName, getterBuffer);
776 } 771 }
777 772
778 void emitCallStubForGetter(Element member, 773 void emitCallStubForGetter(Element member,
779 Set<Selector> selectors, 774 Set<Selector> selectors,
780 DefineMemberFunction defineInstanceMember) { 775 DefineMemberFunction defineInstanceMember) {
781 String getter; 776 String getter;
782 if (member.kind == ElementKind.GETTER) { 777 if (member.kind == ElementKind.GETTER) {
783 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()"; 778 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()";
784 } else { 779 } else {
785 String name = namer.instanceFieldName(member.getEnclosingClass(), 780 String name = namer.instanceFieldName(member.getLibrary(), member.name);
786 member.name);
787 getter = "this.$name"; 781 getter = "this.$name";
788 } 782 }
789 for (Selector selector in selectors) { 783 for (Selector selector in selectors) {
790 if (selector.applies(member, compiler)) { 784 if (selector.applies(member, compiler)) {
791 String invocationName = 785 String invocationName =
792 namer.instanceMethodInvocationName(member.getLibrary(), member.name, 786 namer.instanceMethodInvocationName(member.getLibrary(), member.name,
793 selector); 787 selector);
794 SourceString callName = namer.CLOSURE_INVOCATION_NAME; 788 SourceString callName = namer.CLOSURE_INVOCATION_NAME;
795 String closureCallName = 789 String closureCallName =
796 namer.instanceMethodInvocationName(member.getLibrary(), callName, 790 namer.instanceMethodInvocationName(member.getLibrary(), callName,
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 sourceName = token.slowToString(); 1163 sourceName = token.slowToString();
1170 } 1164 }
1171 int totalOffset = bufferOffset + offset; 1165 int totalOffset = bufferOffset + offset;
1172 sourceMapBuilder.addMapping( 1166 sourceMapBuilder.addMapping(
1173 sourceFile, token.charOffset, sourceName, totalOffset); 1167 sourceFile, token.charOffset, sourceName, totalOffset);
1174 }); 1168 });
1175 } 1169 }
1176 } 1170 }
1177 1171
1178 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition); 1172 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition);
OLDNEW
« no previous file with comments | « lib/compiler/implementation/elements/elements.dart ('k') | lib/compiler/implementation/namer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698