OLD | NEW |
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 /// This class should morph into something that makes it easy to build | 7 /// This class should morph into something that makes it easy to build |
8 /// JavaScript representations of libraries, class-sides, and instance-sides. | 8 /// JavaScript representations of libraries, class-sides, and instance-sides. |
9 /// Initially, it is just a placeholder for code that is moved from | 9 /// Initially, it is just a placeholder for code that is moved from |
10 /// [CodeEmitterTask]. | 10 /// [CodeEmitterTask]. |
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name]; | 586 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name]; |
587 if (selectors != null && !selectors.isEmpty) { | 587 if (selectors != null && !selectors.isEmpty) { |
588 emitCallStubForGetter(member, selectors, builder.addProperty); | 588 emitCallStubForGetter(member, selectors, builder.addProperty); |
589 } | 589 } |
590 } else if (member.isFunction()) { | 590 } else if (member.isFunction()) { |
591 if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) { | 591 if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) { |
592 emitDynamicFunctionGetter(member, builder.addProperty); | 592 emitDynamicFunctionGetter(member, builder.addProperty); |
593 } | 593 } |
594 } | 594 } |
595 } | 595 } |
| 596 |
| 597 void addMember(Element member, ClassBuilder builder) { |
| 598 assert(invariant(member, member.isDeclaration)); |
| 599 |
| 600 if (member.isField()) { |
| 601 addMemberField(member, builder); |
| 602 } else if (member.isFunction() || |
| 603 member.isGenerativeConstructorBody() || |
| 604 member.isGenerativeConstructor() || |
| 605 member.isAccessor()) { |
| 606 addMemberMethod(member, builder); |
| 607 } else { |
| 608 compiler.internalErrorOnElement( |
| 609 member, 'unexpected kind: "${member.kind}"'); |
| 610 } |
| 611 if (member.isInstanceMember()) emitExtraAccessors(member, builder); |
| 612 } |
| 613 |
| 614 void addMemberMethod(FunctionElement member, ClassBuilder builder) { |
| 615 if (member.isAbstract(compiler)) return; |
| 616 jsAst.Expression code = backend.generatedCode[member]; |
| 617 if (code == null) return; |
| 618 String name = namer.getNameOfMember(member); |
| 619 if (backend.isInterceptedMethod(member)) { |
| 620 task.interceptorInvocationNames.add(name); |
| 621 } |
| 622 code = extendWithMetadata(member, code); |
| 623 builder.addProperty(name, code); |
| 624 String reflectionName = task.getReflectionName(member, name); |
| 625 if (reflectionName != null) { |
| 626 var reflectable = |
| 627 js(backend.isAccessibleByReflection(member) ? '1' : '0'); |
| 628 builder.addProperty('+$reflectionName', reflectable); |
| 629 jsAst.Node defaultValues = task.reifyDefaultArguments(member); |
| 630 if (defaultValues != null) { |
| 631 String unmangledName = member.name.slowToString(); |
| 632 builder.addProperty('*$unmangledName', defaultValues); |
| 633 } |
| 634 } |
| 635 code = backend.generatedBailoutCode[member]; |
| 636 if (code != null) { |
| 637 builder.addProperty(namer.getBailoutName(member), code); |
| 638 } |
| 639 if (member.isInstanceMember()) { |
| 640 // TODO(ahe): Where is this done for static/top-level methods? |
| 641 FunctionSignature parameters = member.computeSignature(compiler); |
| 642 if (!parameters.optionalParameters.isEmpty) { |
| 643 addParameterStubs(member, builder.addProperty); |
| 644 } |
| 645 } |
| 646 } |
| 647 |
| 648 void addMemberField(VariableElement member, ClassBuilder builder) { |
| 649 // For now, do nothing. |
| 650 } |
| 651 |
| 652 jsAst.Fun extendWithMetadata(FunctionElement element, jsAst.Fun code) { |
| 653 if (!backend.retainMetadataOf(element)) return code; |
| 654 return compiler.withCurrentElement(element, () { |
| 655 List<int> metadata = <int>[]; |
| 656 FunctionSignature signature = element.functionSignature; |
| 657 if (element.isConstructor()) { |
| 658 metadata.add(task.reifyType(element.getEnclosingClass().thisType)); |
| 659 } else { |
| 660 metadata.add(task.reifyType(signature.returnType)); |
| 661 } |
| 662 signature.forEachParameter((Element parameter) { |
| 663 metadata |
| 664 ..add(task.reifyName(parameter.name)) |
| 665 ..add(task.reifyType(parameter.computeType(compiler))); |
| 666 }); |
| 667 Link link = element.metadata; |
| 668 // TODO(ahe): Why is metadata sometimes null? |
| 669 if (link != null) { |
| 670 for (; !link.isEmpty; link = link.tail) { |
| 671 metadata.add(task.reifyMetadata(link.head)); |
| 672 } |
| 673 } |
| 674 code.body.statements.add(js.string(metadata.join(',')).toStatement()); |
| 675 return code; |
| 676 }); |
| 677 } |
596 } | 678 } |
OLD | NEW |