OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 package com.google.dart.compiler.backend.js; | 5 package com.google.dart.compiler.backend.js; |
6 | 6 |
| 7 import java.util.ArrayList; |
| 8 import java.util.Arrays; |
| 9 import java.util.Collections; |
| 10 import java.util.HashSet; |
| 11 import java.util.List; |
| 12 import java.util.Set; |
| 13 |
7 import com.google.common.collect.Lists; | 14 import com.google.common.collect.Lists; |
8 import com.google.dart.compiler.InternalCompilerException; | 15 import com.google.dart.compiler.InternalCompilerException; |
9 import com.google.dart.compiler.ast.DartArrayAccess; | 16 import com.google.dart.compiler.ast.DartArrayAccess; |
10 import com.google.dart.compiler.ast.DartBinaryExpression; | 17 import com.google.dart.compiler.ast.DartBinaryExpression; |
11 import com.google.dart.compiler.ast.DartBlock; | 18 import com.google.dart.compiler.ast.DartBlock; |
12 import com.google.dart.compiler.ast.DartCase; | 19 import com.google.dart.compiler.ast.DartCase; |
13 import com.google.dart.compiler.ast.DartClass; | 20 import com.google.dart.compiler.ast.DartClass; |
14 import com.google.dart.compiler.ast.DartClassMember; | 21 import com.google.dart.compiler.ast.DartClassMember; |
15 import com.google.dart.compiler.ast.DartContext; | 22 import com.google.dart.compiler.ast.DartContext; |
16 import com.google.dart.compiler.ast.DartDefault; | 23 import com.google.dart.compiler.ast.DartDefault; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 import com.google.dart.compiler.resolver.Elements; | 66 import com.google.dart.compiler.resolver.Elements; |
60 import com.google.dart.compiler.resolver.EnclosingElement; | 67 import com.google.dart.compiler.resolver.EnclosingElement; |
61 import com.google.dart.compiler.resolver.FieldElement; | 68 import com.google.dart.compiler.resolver.FieldElement; |
62 import com.google.dart.compiler.resolver.LabelElement; | 69 import com.google.dart.compiler.resolver.LabelElement; |
63 import com.google.dart.compiler.resolver.MethodElement; | 70 import com.google.dart.compiler.resolver.MethodElement; |
64 import com.google.dart.compiler.resolver.SyntheticDefaultConstructorElement; | 71 import com.google.dart.compiler.resolver.SyntheticDefaultConstructorElement; |
65 import com.google.dart.compiler.resolver.VariableElement; | 72 import com.google.dart.compiler.resolver.VariableElement; |
66 import com.google.dart.compiler.type.InterfaceType; | 73 import com.google.dart.compiler.type.InterfaceType; |
67 import com.google.dart.compiler.type.Types; | 74 import com.google.dart.compiler.type.Types; |
68 | 75 |
69 import java.util.ArrayList; | |
70 import java.util.Arrays; | |
71 import java.util.Collections; | |
72 import java.util.HashSet; | |
73 import java.util.List; | |
74 import java.util.Set; | |
75 | |
76 /** | 76 /** |
77 * Normalization phase of Dart compiler. Rewrites the AST to simplify later | 77 * Normalization phase of Dart compiler. Rewrites the AST to simplify later |
78 * phases. | 78 * phases. |
79 * <ul> | 79 * <ul> |
80 * <li>Split 'type' declarations such as "int a = 0, b = 0" | 80 * <li>Split 'type' declarations such as "int a = 0, b = 0" |
81 * <li>Introduce block statements for control structures such as IF, WHILE, and | 81 * <li>Introduce block statements for control structures such as IF, WHILE, and |
82 * FOR | 82 * FOR |
83 * <li>normalize case statements, including adding FallThroughError throws | 83 * <li>normalize case statements, including adding FallThroughError throws |
84 * <li>pull initializers out of FOR loops | 84 * <li>pull initializers out of FOR loops |
85 * <li>remove useless statement labels | 85 * <li>remove useless statement labels |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 if (Elements.needsImplicitDefaultConstructor(classElement)) { | 594 if (Elements.needsImplicitDefaultConstructor(classElement)) { |
595 DartMethodDefinition method = createImplicitDefaultConstructor(classElem
ent); | 595 DartMethodDefinition method = createImplicitDefaultConstructor(classElem
ent); |
596 // TODO - We should really normalize the class itself. | 596 // TODO - We should really normalize the class itself. |
597 node.getMembers().add(method); | 597 node.getMembers().add(method); |
598 } | 598 } |
599 return super.visitClass(node); | 599 return super.visitClass(node); |
600 } | 600 } |
601 | 601 |
602 private DartMethodDefinition createImplicitDefaultConstructor(final ClassEle
ment classElement) { | 602 private DartMethodDefinition createImplicitDefaultConstructor(final ClassEle
ment classElement) { |
603 assert (Elements.needsImplicitDefaultConstructor(classElement)); | 603 assert (Elements.needsImplicitDefaultConstructor(classElement)); |
604 DartFunction function = new DartFunction(Collections.<DartParameter>emptyL
ist(), | 604 DartFunction function = new DartFunction(Collections.<DartParameter>emptyL
ist(), |
605 new DartBlock(Collections.<DartStatement>emptyList()), null); | 605 new DartBlock(Collections.<DartStatement>emptyList()), null); |
606 final DartMethodDefinition method = | 606 final DartMethodDefinition method = |
607 DartMethodDefinition.create(new DartIdentifier(""), function, Modifier
s.NONE, null, null); | 607 DartMethodDefinition.create(new DartIdentifier(""), function, Modifier
s.NONE, null); |
608 method.setSymbol(new SyntheticDefaultConstructorElement(method, classEleme
nt, null)); | 608 method.setSymbol(new SyntheticDefaultConstructorElement(method, classEleme
nt, null)); |
609 return method; | 609 return method; |
610 } | 610 } |
611 | 611 |
612 @Override | 612 @Override |
613 public DartExpression visitBinaryExpression(DartBinaryExpression node) { | 613 public DartExpression visitBinaryExpression(DartBinaryExpression node) { |
614 node.visitChildren(this); | 614 node.visitChildren(this); |
615 Token operator = node.getOperator(); | 615 Token operator = node.getOperator(); |
616 if (operator.isAssignmentOperator() && operator != Token.ASSIGN | 616 if (operator.isAssignmentOperator() && operator != Token.ASSIGN |
617 && shouldNormalizeOperator(node)) { | 617 && shouldNormalizeOperator(node)) { |
(...skipping 12 matching lines...) Expand all Loading... |
630 DartExpression lhs = node.getArg().getNormalizedNode(); | 630 DartExpression lhs = node.getArg().getNormalizedNode(); |
631 DartIntegerLiteral rhs = DartIntegerLiteral.one(); | 631 DartIntegerLiteral rhs = DartIntegerLiteral.one(); |
632 node.setNormalizedNode(normalizeCompoundAssignment(mapAssignableOp(opera
tor), | 632 node.setNormalizedNode(normalizeCompoundAssignment(mapAssignableOp(opera
tor), |
633 !node.isPrefix(), lhs
, rhs)); | 633 !node.isPrefix(), lhs
, rhs)); |
634 } | 634 } |
635 return node; | 635 return node; |
636 } | 636 } |
637 | 637 |
638 static class NeedsImplicitSuperInvocationDeterminant extends DartNodeTravers
er<Void> { | 638 static class NeedsImplicitSuperInvocationDeterminant extends DartNodeTravers
er<Void> { |
639 private boolean needsSuperInvocation = true; | 639 private boolean needsSuperInvocation = true; |
640 | 640 |
641 @Override | 641 @Override |
642 public Void visitSuperConstructorInvocation(DartSuperConstructorInvocation
node) { | 642 public Void visitSuperConstructorInvocation(DartSuperConstructorInvocation
node) { |
643 needsSuperInvocation = false; | 643 needsSuperInvocation = false; |
644 return super.visitSuperConstructorInvocation(node); | 644 return super.visitSuperConstructorInvocation(node); |
645 } | 645 } |
646 | 646 |
647 @Override | 647 @Override |
648 public Void visitRedirectConstructorInvocation(DartRedirectConstructorInvo
cation node) { | 648 public Void visitRedirectConstructorInvocation(DartRedirectConstructorInvo
cation node) { |
649 needsSuperInvocation = false; | 649 needsSuperInvocation = false; |
650 return super.visitRedirectConstructorInvocation(node); | 650 return super.visitRedirectConstructorInvocation(node); |
651 } | 651 } |
652 | 652 |
653 @Override | 653 @Override |
654 public Void visitMethodDefinition(DartMethodDefinition node) { | 654 public Void visitMethodDefinition(DartMethodDefinition node) { |
655 // Ignore everything except the initializers | 655 // Ignore everything except the initializers |
656 for (DartInitializer initializer : node.getInitializers()) { | 656 for (DartInitializer initializer : node.getInitializers()) { |
657 initializer.accept(this); | 657 initializer.accept(this); |
658 } | 658 } |
659 return null; | 659 return null; |
660 } | 660 } |
661 } | 661 } |
662 | 662 |
663 @Override | 663 @Override |
664 public DartMethodDefinition visitMethodDefinition(DartMethodDefinition node)
{ | 664 public DartMethodDefinition visitMethodDefinition(DartMethodDefinition node)
{ |
665 super.visitMethodDefinition(node); | 665 super.visitMethodDefinition(node); |
666 if (Elements.isNonFactoryConstructor(node.getSymbol())) { | 666 if (Elements.isNonFactoryConstructor(node.getSymbol())) { |
667 normalizeParameterInitializer(node); | 667 normalizeParameterInitializer(node); |
668 } | 668 } |
669 | 669 |
670 return node; | 670 return node; |
671 } | 671 } |
672 | 672 |
673 @Override | 673 @Override |
674 public DartNode visitNewExpression(DartNewExpression node) { | 674 public DartNode visitNewExpression(DartNewExpression node) { |
675 ConstructorElement symbol = node.getSymbol(); | 675 ConstructorElement symbol = node.getSymbol(); |
676 if (symbol == null) { | 676 if (symbol == null) { |
677 InterfaceType constructorType = Types.constructorType(node); | 677 InterfaceType constructorType = Types.constructorType(node); |
678 if (!constructorType.getElement().isDynamic() && node.getArgs().isEmpty(
)) { | 678 if (!constructorType.getElement().isDynamic() && node.getArgs().isEmpty(
)) { |
679 // HACK use proper normalized node | 679 // HACK use proper normalized node |
680 ClassElement classToInstantiate = constructorType.getElement(); | 680 ClassElement classToInstantiate = constructorType.getElement(); |
681 if (classToInstantiate.getDefaultClass() != null) { | 681 if (classToInstantiate.getDefaultClass() != null) { |
682 classToInstantiate = classToInstantiate.getDefaultClass().getElement
(); | 682 classToInstantiate = classToInstantiate.getDefaultClass().getElement
(); |
683 } | 683 } |
684 | 684 |
685 if (classToInstantiate != null | 685 if (classToInstantiate != null |
686 && Elements.needsImplicitDefaultConstructor(classToInstantiate)) { | 686 && Elements.needsImplicitDefaultConstructor(classToInstantiate)) { |
687 DartMethodDefinition implicitDefaultConstructor = | 687 DartMethodDefinition implicitDefaultConstructor = |
688 createImplicitDefaultConstructor(classToInstantiate); | 688 createImplicitDefaultConstructor(classToInstantiate); |
689 node.setSymbol(implicitDefaultConstructor.getSymbol()); | 689 node.setSymbol(implicitDefaultConstructor.getSymbol()); |
690 } | 690 } |
691 } | 691 } |
692 } | 692 } |
693 | 693 |
694 return super.visitNewExpression(node); | 694 return super.visitNewExpression(node); |
695 } | 695 } |
696 | 696 |
697 @Override | 697 @Override |
698 public DartNode visitSwitchStatement(DartSwitchStatement node) { | 698 public DartNode visitSwitchStatement(DartSwitchStatement node) { |
699 node.getExpression().accept(this); | 699 node.getExpression().accept(this); |
700 for (DartNode member : node.getMembers()) { | 700 for (DartNode member : node.getMembers()) { |
701 member.accept(this); | 701 member.accept(this); |
702 } | 702 } |
703 return node; | 703 return node; |
704 } | 704 } |
705 | 705 |
706 // Normalize parameter initializer. | 706 // Normalize parameter initializer. |
(...skipping 23 matching lines...) Expand all Loading... |
730 | 730 |
731 EnclosingElement enclosingElement = node.getSymbol().getEnclosingElement()
; | 731 EnclosingElement enclosingElement = node.getSymbol().getEnclosingElement()
; |
732 if (ElementKind.of(enclosingElement) == ElementKind.CLASS) { | 732 if (ElementKind.of(enclosingElement) == ElementKind.CLASS) { |
733 ClassElement classElement = (ClassElement) enclosingElement; | 733 ClassElement classElement = (ClassElement) enclosingElement; |
734 if (!classElement.isObject()) { | 734 if (!classElement.isObject()) { |
735 NeedsImplicitSuperInvocationDeterminant superLocator = new NeedsImplic
itSuperInvocationDeterminant(); | 735 NeedsImplicitSuperInvocationDeterminant superLocator = new NeedsImplic
itSuperInvocationDeterminant(); |
736 node.accept(superLocator); | 736 node.accept(superLocator); |
737 if (superLocator.needsSuperInvocation) { | 737 if (superLocator.needsSuperInvocation) { |
738 DartSuperConstructorInvocation superInvocation = new DartSuperConstr
uctorInvocation( | 738 DartSuperConstructorInvocation superInvocation = new DartSuperConstr
uctorInvocation( |
739 new DartIdentifier(""), Collections.<DartExpression>emptyList())
; | 739 new DartIdentifier(""), Collections.<DartExpression>emptyList())
; |
740 superInvocation.setSymbol(new SyntheticDefaultConstructorElement(nul
l, | 740 superInvocation.setSymbol(new SyntheticDefaultConstructorElement(nul
l, |
741 classElement.getSupertype().getElement(), null)); | 741 classElement.getSupertype().getElement(), null)); |
742 nInit.add(new DartInitializer(null, superInvocation)); | 742 nInit.add(new DartInitializer(null, superInvocation)); |
743 } | 743 } |
744 } | 744 } |
745 } | 745 } |
746 | 746 |
747 if (!nInit.isEmpty()) { | 747 if (!nInit.isEmpty()) { |
748 if (!node.getInitializers().isEmpty()) { | 748 if (!node.getInitializers().isEmpty()) { |
749 nInit.addAll(0, node.getInitializers()); | 749 nInit.addAll(0, node.getInitializers()); |
750 } | 750 } |
751 | 751 |
752 DartMethodDefinition nConstructor = DartMethodDefinition.create( | 752 DartMethodDefinition nConstructor = DartMethodDefinition.create( |
753 node.getName(), node.getFunction(), node.getModifiers(), nInit,
null); | 753 node.getName(), node.getFunction(), node.getModifiers(), nInit); |
754 nConstructor.setSymbol(node.getSymbol()); | 754 nConstructor.setSymbol(node.getSymbol()); |
755 nConstructor.setSourceInfo(node.getSourceInfo()); | 755 nConstructor.setSourceInfo(node.getSourceInfo()); |
756 node.setNormalizedNode(nConstructor); | 756 node.setNormalizedNode(nConstructor); |
757 } | 757 } |
758 } | 758 } |
759 | 759 |
760 private DartExpression normalizeCompoundAssignment(Token operator, | 760 private DartExpression normalizeCompoundAssignment(Token operator, |
761 boolean isPostfix, | 761 boolean isPostfix, |
762 DartExpression operand1, | 762 DartExpression operand1, |
763 DartExpression operand2)
{ | 763 DartExpression operand2)
{ |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1013 case ASSIGN_TRUNC: return Token.TRUNC; | 1013 case ASSIGN_TRUNC: return Token.TRUNC; |
1014 case INC: return Token.ADD; | 1014 case INC: return Token.ADD; |
1015 case DEC: return Token.SUB; | 1015 case DEC: return Token.SUB; |
1016 | 1016 |
1017 default: | 1017 default: |
1018 throw new InternalCompilerException("Invalid assignment operator"); | 1018 throw new InternalCompilerException("Invalid assignment operator"); |
1019 } | 1019 } |
1020 } | 1020 } |
1021 } | 1021 } |
1022 } | 1022 } |
OLD | NEW |