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

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: 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;
kasperl 2012/08/07 08:14:20 Maybe use ?: here?
floitsch 2012/08/07 12:20:16 Done.
478 String fieldName = namer.instanceFieldName(member.getEnclosingClass(), 473 if (isShadowed) {
479 name); 474 fieldName = namer.shadowedFieldName(member);
475 } else {
476 fieldName = namer.instanceFieldName(library, name);
477 }
480 // Getters and setters with suffixes will be generated dynamically. 478 // Getters and setters with suffixes will be generated dynamically.
481 buffer.add('"$fieldName'); 479 buffer.add('"$fieldName');
482 if (needsDynamicGetter || needsDynamicSetter) { 480 if (needsDynamicGetter || needsDynamicSetter) {
483 if (needsDynamicGetter && needsDynamicSetter) { 481 if (needsDynamicGetter && needsDynamicSetter) {
484 buffer.add(GETTER_SETTER_SUFFIX); 482 buffer.add(GETTER_SETTER_SUFFIX);
485 } else if (needsDynamicGetter) { 483 } else if (needsDynamicGetter) {
486 buffer.add(GETTER_SUFFIX); 484 buffer.add(GETTER_SUFFIX);
487 } else { 485 } else {
488 buffer.add(SETTER_SUFFIX); 486 buffer.add(SETTER_SUFFIX);
489 } 487 }
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 defineInstanceMember(getterName, getterBuffer); 773 defineInstanceMember(getterName, getterBuffer);
776 } 774 }
777 775
778 void emitCallStubForGetter(Element member, 776 void emitCallStubForGetter(Element member,
779 Set<Selector> selectors, 777 Set<Selector> selectors,
780 DefineMemberFunction defineInstanceMember) { 778 DefineMemberFunction defineInstanceMember) {
781 String getter; 779 String getter;
782 if (member.kind == ElementKind.GETTER) { 780 if (member.kind == ElementKind.GETTER) {
783 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()"; 781 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()";
784 } else { 782 } else {
785 String name = namer.instanceFieldName(member.getEnclosingClass(), 783 String name = namer.instanceFieldName(member.getLibrary(), member.name);
786 member.name);
787 getter = "this.$name"; 784 getter = "this.$name";
788 } 785 }
789 for (Selector selector in selectors) { 786 for (Selector selector in selectors) {
790 if (selector.applies(member, compiler)) { 787 if (selector.applies(member, compiler)) {
791 String invocationName = 788 String invocationName =
792 namer.instanceMethodInvocationName(member.getLibrary(), member.name, 789 namer.instanceMethodInvocationName(member.getLibrary(), member.name,
793 selector); 790 selector);
794 SourceString callName = namer.CLOSURE_INVOCATION_NAME; 791 SourceString callName = namer.CLOSURE_INVOCATION_NAME;
795 String closureCallName = 792 String closureCallName =
796 namer.instanceMethodInvocationName(member.getLibrary(), callName, 793 namer.instanceMethodInvocationName(member.getLibrary(), callName,
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 sourceName = token.slowToString(); 1083 sourceName = token.slowToString();
1087 } 1084 }
1088 int totalOffset = bufferOffset + offset; 1085 int totalOffset = bufferOffset + offset;
1089 sourceMapBuilder.addMapping( 1086 sourceMapBuilder.addMapping(
1090 sourceFile, token.charOffset, sourceName, totalOffset); 1087 sourceFile, token.charOffset, sourceName, totalOffset);
1091 }); 1088 });
1092 } 1089 }
1093 } 1090 }
1094 1091
1095 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition); 1092 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698