| 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 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 } | 195 } |
| 196 FunctionElement function = member; | 196 FunctionElement function = member; |
| 197 FunctionParameters parameters = function.computeParameters(compiler); | 197 FunctionParameters parameters = function.computeParameters(compiler); |
| 198 if (!parameters.optionalParameters.isEmpty()) { | 198 if (!parameters.optionalParameters.isEmpty()) { |
| 199 addParameterStubs(member, attachTo, buffer); | 199 addParameterStubs(member, attachTo, buffer); |
| 200 } | 200 } |
| 201 } else if (member.kind === ElementKind.FIELD) { | 201 } else if (member.kind === ElementKind.FIELD) { |
| 202 // TODO(ngeoffray): Have another class generate the code for the | 202 // TODO(ngeoffray): Have another class generate the code for the |
| 203 // fields. | 203 // fields. |
| 204 if ((member.modifiers === null || !member.modifiers.isFinal()) && | 204 if ((member.modifiers === null || !member.modifiers.isFinal()) && |
| 205 compiler.universe.invokedSetters.contains(member.name)) { | 205 compiler.universe.hasOneSetter(member, compiler)) { |
| 206 String setterName = namer.setterName(member.getLibrary(), member.name); | 206 String setterName = namer.setterName(member.getLibrary(), member.name); |
| 207 String name = member.isNative() | 207 String name = member.isNative() |
| 208 ? member.name.slowToString() | 208 ? member.name.slowToString() |
| 209 : namer.getName(member); | 209 : namer.getName(member); |
| 210 buffer.add('${attachTo(setterName)} = function(v){\n'); | 210 buffer.add('${attachTo(setterName)} = function(v){\n'); |
| 211 buffer.add(' this.$name = v;\n};\n'); | 211 buffer.add(' this.$name = v;\n};\n'); |
| 212 } | 212 } |
| 213 if (compiler.universe.invokedGetters.contains(member.name)) { | 213 if (compiler.universe.hasOneGetter(member, compiler)) { |
| 214 String getterName = namer.getterName(member.getLibrary(), member.name); | 214 String getterName = namer.getterName(member.getLibrary(), member.name); |
| 215 String name = member.isNative() | 215 String name = member.isNative() |
| 216 ? member.name.slowToString() | 216 ? member.name.slowToString() |
| 217 : namer.getName(member); | 217 : namer.getName(member); |
| 218 buffer.add('${attachTo(getterName)} = function(){\n'); | 218 buffer.add('${attachTo(getterName)} = function(){\n'); |
| 219 buffer.add(' return this.$name;\n};\n'); | 219 buffer.add(' return this.$name;\n};\n'); |
| 220 } | 220 } |
| 221 } else { | 221 } else { |
| 222 compiler.internalError('unexpected kind: "${member.kind}"', | 222 compiler.internalError('unexpected kind: "${member.kind}"', |
| 223 element: member); | 223 element: member); |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 Element member, | 475 Element member, |
| 476 Set<Selector> selectors) { | 476 Set<Selector> selectors) { |
| 477 String getter; | 477 String getter; |
| 478 if (member.kind == ElementKind.GETTER) { | 478 if (member.kind == ElementKind.GETTER) { |
| 479 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()"; | 479 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()"; |
| 480 } else { | 480 } else { |
| 481 getter = | 481 getter = |
| 482 "this.${namer.instanceFieldName(member.getLibrary(), member.name)}"; | 482 "this.${namer.instanceFieldName(member.getLibrary(), member.name)}"; |
| 483 } | 483 } |
| 484 for (Selector selector in selectors) { | 484 for (Selector selector in selectors) { |
| 485 String invocationName = | 485 if (selector.applies(member, compiler)) { |
| 486 namer.instanceMethodInvocationName(member.getLibrary(), member.name, | 486 String invocationName = |
| 487 selector); | 487 namer.instanceMethodInvocationName(member.getLibrary(), member.name, |
| 488 SourceString callName = Namer.CLOSURE_INVOCATION_NAME; | 488 selector); |
| 489 String closureCallName = | 489 SourceString callName = Namer.CLOSURE_INVOCATION_NAME; |
| 490 namer.instanceMethodInvocationName(member.getLibrary(), callName, | 490 String closureCallName = |
| 491 selector); | 491 namer.instanceMethodInvocationName(member.getLibrary(), callName, |
| 492 List<String> arguments = <String>[]; | 492 selector); |
| 493 for (int i = 0; i < selector.argumentCount; i++) { | 493 List<String> arguments = <String>[]; |
| 494 arguments.add("arg$i"); | 494 for (int i = 0; i < selector.argumentCount; i++) { |
| 495 arguments.add("arg$i"); |
| 496 } |
| 497 String joined = Strings.join(arguments, ", "); |
| 498 buffer.add("${attachTo(invocationName)} = function($joined) {\n"); |
| 499 buffer.add(" return $getter.$closureCallName($joined);\n"); |
| 500 buffer.add("};\n"); |
| 495 } | 501 } |
| 496 String joined = Strings.join(arguments, ", "); | |
| 497 buffer.add("${attachTo(invocationName)} = function($joined) {\n"); | |
| 498 buffer.add(" return $getter.$closureCallName($joined);\n"); | |
| 499 buffer.add("};\n"); | |
| 500 } | 502 } |
| 501 } | 503 } |
| 502 | 504 |
| 503 void emitStaticNonFinalFieldInitializations(StringBuffer buffer) { | 505 void emitStaticNonFinalFieldInitializations(StringBuffer buffer) { |
| 504 // Adds initializations inside the Isolate constructor. | 506 // Adds initializations inside the Isolate constructor. |
| 505 // Example: | 507 // Example: |
| 506 // function Isolate() { | 508 // function Isolate() { |
| 507 // this.staticNonFinal = Isolate.prototype.someVal; | 509 // this.staticNonFinal = Isolate.prototype.someVal; |
| 508 // ... | 510 // ... |
| 509 // } | 511 // } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 void emitExtraAccessors(Element member, | 569 void emitExtraAccessors(Element member, |
| 568 String attachTo(String name), | 570 String attachTo(String name), |
| 569 StringBuffer buffer) { | 571 StringBuffer buffer) { |
| 570 if (member.kind == ElementKind.GETTER || member.kind == ElementKind.FIELD) { | 572 if (member.kind == ElementKind.GETTER || member.kind == ElementKind.FIELD) { |
| 571 Set<Selector> selectors = compiler.universe.invokedNames[member.name]; | 573 Set<Selector> selectors = compiler.universe.invokedNames[member.name]; |
| 572 if (selectors !== null && !selectors.isEmpty()) { | 574 if (selectors !== null && !selectors.isEmpty()) { |
| 573 compiler.emitter.emitCallStubForGetter( | 575 compiler.emitter.emitCallStubForGetter( |
| 574 buffer, attachTo, member, selectors); | 576 buffer, attachTo, member, selectors); |
| 575 } | 577 } |
| 576 } else if (member.kind == ElementKind.FUNCTION) { | 578 } else if (member.kind == ElementKind.FUNCTION) { |
| 577 if (compiler.universe.invokedGetters.contains(member.name)) { | 579 if (compiler.universe.hasOneGetter(member, compiler)) { |
| 578 compiler.emitter.emitDynamicFunctionGetter(buffer, attachTo, member); | 580 compiler.emitter.emitDynamicFunctionGetter(buffer, attachTo, member); |
| 579 } | 581 } |
| 580 } | 582 } |
| 581 } | 583 } |
| 582 | 584 |
| 583 void emitNoSuchMethodCalls(StringBuffer buffer) { | 585 void emitNoSuchMethodCalls(StringBuffer buffer) { |
| 584 // Do not generate no such method calls if there is no class. | 586 // Do not generate no such method calls if there is no class. |
| 585 if (compiler.universe.instantiatedClasses.isEmpty()) return; | 587 if (compiler.universe.instantiatedClasses.isEmpty()) return; |
| 586 | 588 |
| 587 ClassElement objectClass = | 589 ClassElement objectClass = |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 } | 629 } |
| 628 } else { | 630 } else { |
| 629 String jsName = | 631 String jsName = |
| 630 namer.instanceMethodInvocationName(null, methodName, selector); | 632 namer.instanceMethodInvocationName(null, methodName, selector); |
| 631 generateMethod(methodName.slowToString(), jsName, selector); | 633 generateMethod(methodName.slowToString(), jsName, selector); |
| 632 } | 634 } |
| 633 } | 635 } |
| 634 } | 636 } |
| 635 }); | 637 }); |
| 636 | 638 |
| 637 compiler.universe.invokedGetters.forEach((SourceString getterName) { | 639 compiler.universe.invokedGetters.forEach((SourceString getterName, |
| 640 Set<Selector> selectors) { |
| 638 if (getterName.isPrivate()) { | 641 if (getterName.isPrivate()) { |
| 639 for (LibraryElement lib in libraries) { | 642 for (LibraryElement lib in libraries) { |
| 640 String jsName = namer.getterName(lib, getterName); | 643 String jsName = namer.getterName(lib, getterName); |
| 641 generateMethod('get ${getterName.slowToString()}', jsName, | 644 generateMethod('get ${getterName.slowToString()}', jsName, |
| 642 Selector.GETTER); | 645 Selector.GETTER); |
| 643 } | 646 } |
| 644 } else { | 647 } else { |
| 645 String jsName = namer.getterName(null, getterName); | 648 String jsName = namer.getterName(null, getterName); |
| 646 generateMethod('get ${getterName.slowToString()}', jsName, | 649 generateMethod('get ${getterName.slowToString()}', jsName, |
| 647 Selector.GETTER); | 650 Selector.GETTER); |
| 648 } | 651 } |
| 649 }); | 652 }); |
| 650 | 653 |
| 651 compiler.universe.invokedSetters.forEach((SourceString setterName) { | 654 compiler.universe.invokedSetters.forEach((SourceString setterName, |
| 655 Set<Selector> selectors) { |
| 652 if (setterName.isPrivate()) { | 656 if (setterName.isPrivate()) { |
| 653 for (LibraryElement lib in libraries) { | 657 for (LibraryElement lib in libraries) { |
| 654 String jsName = namer.setterName(lib, setterName); | 658 String jsName = namer.setterName(lib, setterName); |
| 655 generateMethod('set ${setterName.slowToString()}', jsName, | 659 generateMethod('set ${setterName.slowToString()}', jsName, |
| 656 Selector.SETTER); | 660 Selector.SETTER); |
| 657 } | 661 } |
| 658 } else { | 662 } else { |
| 659 String jsName = namer.setterName(null, setterName); | 663 String jsName = namer.setterName(null, setterName); |
| 660 generateMethod('set ${setterName.slowToString()}', jsName, | 664 generateMethod('set ${setterName.slowToString()}', jsName, |
| 661 Selector.SETTER); | 665 Selector.SETTER); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 739 mainBuffer.add( | 743 mainBuffer.add( |
| 740 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n'); | 744 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n'); |
| 741 nativeEmitter.emitDynamicDispatchMetadata(); | 745 nativeEmitter.emitDynamicDispatchMetadata(); |
| 742 nativeEmitter.assembleCode(mainBuffer); | 746 nativeEmitter.assembleCode(mainBuffer); |
| 743 emitMain(mainBuffer); | 747 emitMain(mainBuffer); |
| 744 compiler.assembledCode = mainBuffer.toString(); | 748 compiler.assembledCode = mainBuffer.toString(); |
| 745 }); | 749 }); |
| 746 return compiler.assembledCode; | 750 return compiler.assembledCode; |
| 747 } | 751 } |
| 748 } | 752 } |
| OLD | NEW |