Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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); |
| OLD | NEW |