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 part of js; | 5 part of js; |
6 | 6 |
7 class Printer implements NodeVisitor { | 7 class Printer implements NodeVisitor { |
8 final bool shouldCompressOutput; | 8 final bool shouldCompressOutput; |
9 leg.Compiler compiler; | 9 leg.Compiler compiler; |
10 leg.CodeBuffer outBuffer; | 10 leg.CodeBuffer outBuffer; |
(...skipping 13 matching lines...) Expand all Loading... | |
24 danglingElseVisitor = new DanglingElseVisitor(compiler), | 24 danglingElseVisitor = new DanglingElseVisitor(compiler), |
25 localNamer = determineRenamer(compiler.enableMinification, | 25 localNamer = determineRenamer(compiler.enableMinification, |
26 allowVariableMinification); | 26 allowVariableMinification); |
27 | 27 |
28 static LocalNamer determineRenamer(bool shouldCompressOutput, | 28 static LocalNamer determineRenamer(bool shouldCompressOutput, |
29 bool allowVariableMinification) { | 29 bool allowVariableMinification) { |
30 return (shouldCompressOutput && allowVariableMinification) | 30 return (shouldCompressOutput && allowVariableMinification) |
31 ? new MinifyRenamer() : new IdentityNamer(); | 31 ? new MinifyRenamer() : new IdentityNamer(); |
32 } | 32 } |
33 | 33 |
34 void newLine() { | |
floitsch
2013/01/04 10:31:03
do we really need this?
If yes, please add comment
sra1
2013/01/04 23:47:52
Done.
| |
35 out("\n"); | |
36 } | |
37 | |
34 void spaceOut() { | 38 void spaceOut() { |
35 if (!shouldCompressOutput) out(" "); | 39 if (!shouldCompressOutput) out(" "); |
36 } | 40 } |
37 void lineOut() { | 41 void lineOut() { |
38 if (!shouldCompressOutput) out("\n"); | 42 if (!shouldCompressOutput) newLine(); |
39 } | 43 } |
40 | 44 |
41 String lastAddedString = null; | 45 String lastAddedString = null; |
42 int get lastCharCode { | 46 int get lastCharCode { |
43 if (lastAddedString == null) return 0; | 47 if (lastAddedString == null) return 0; |
44 assert(lastAddedString.length != ""); | 48 assert(lastAddedString.length != ""); |
45 return lastAddedString.charCodeAt(lastAddedString.length - 1); | 49 return lastAddedString.charCodeAt(lastAddedString.length - 1); |
46 } | 50 } |
47 | 51 |
48 void out(String str) { | 52 void out(String str) { |
(...skipping 14 matching lines...) Expand all Loading... | |
63 | 67 |
64 void outLn(String str) { | 68 void outLn(String str) { |
65 out(str); | 69 out(str); |
66 lineOut(); | 70 lineOut(); |
67 } | 71 } |
68 | 72 |
69 void outSemicolonLn() { | 73 void outSemicolonLn() { |
70 if (shouldCompressOutput) { | 74 if (shouldCompressOutput) { |
71 pendingSemicolon = true; | 75 pendingSemicolon = true; |
72 } else { | 76 } else { |
73 out(";\n"); | 77 out(";"); |
78 newLine(); | |
74 } | 79 } |
75 } | 80 } |
76 | 81 |
77 void outIndent(String str) { indent(); out(str); } | 82 void outIndent(String str) { indent(); out(str); } |
78 void outIndentLn(String str) { indent(); outLn(str); } | 83 void outIndentLn(String str) { indent(); outLn(str); } |
79 void indent() { | 84 void indent() { |
80 if (!shouldCompressOutput) { | 85 if (!shouldCompressOutput) { |
81 for (int i = 0; i < indentLevel; i++) out(" "); | 86 for (int i = 0; i < indentLevel; i++) out(" "); |
82 } | 87 } |
83 } | 88 } |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
665 // TODO(floitsch): allow more characters. | 670 // TODO(floitsch): allow more characters. |
666 int charCode = field.charCodeAt(i); | 671 int charCode = field.charCodeAt(i); |
667 if (!(charCodes.$a <= charCode && charCode <= charCodes.$z || | 672 if (!(charCodes.$a <= charCode && charCode <= charCodes.$z || |
668 charCodes.$A <= charCode && charCode <= charCodes.$Z || | 673 charCodes.$A <= charCode && charCode <= charCodes.$Z || |
669 charCode == charCodes.$$ || | 674 charCode == charCodes.$$ || |
670 charCode == charCodes.$_ || | 675 charCode == charCodes.$_ || |
671 i != 1 && isDigit(charCode))) { | 676 i != 1 && isDigit(charCode))) { |
672 return false; | 677 return false; |
673 } | 678 } |
674 } | 679 } |
675 // TODO(floitsch): normally we should also check that the field is not | 680 // TODO(floitsch): normally we should also check that the field is not a |
676 // a reserved word. | 681 // reserved word. We don't generate fields with reserved word names except |
682 // for 'super'. | |
683 if (field == '"super"') return false; | |
677 return true; | 684 return true; |
678 } | 685 } |
679 | 686 |
680 visitAccess(PropertyAccess access) { | 687 visitAccess(PropertyAccess access) { |
681 visitNestedExpression(access.receiver, CALL, | 688 visitNestedExpression(access.receiver, CALL, |
682 newInForInit: inForInit, | 689 newInForInit: inForInit, |
683 newAtStatementBegin: atStatementBegin); | 690 newAtStatementBegin: atStatementBegin); |
684 Node selector = access.selector; | 691 Node selector = access.selector; |
685 if (selector is LiteralString) { | 692 if (selector is LiteralString) { |
686 LiteralString selectorString = selector; | 693 LiteralString selectorString = selector; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
751 } | 758 } |
752 } | 759 } |
753 out("]"); | 760 out("]"); |
754 } | 761 } |
755 | 762 |
756 visitArrayElement(ArrayElement node) { | 763 visitArrayElement(ArrayElement node) { |
757 throw "Unreachable"; | 764 throw "Unreachable"; |
758 } | 765 } |
759 | 766 |
760 visitObjectInitializer(ObjectInitializer node) { | 767 visitObjectInitializer(ObjectInitializer node) { |
768 // Print all the properties on one line until we see a function-valued | |
769 // property. Ideally, we would use a proper pretty-printer to make the | |
770 // decision based on layout. | |
771 bool onePerLine = false; | |
772 List<Property> properties = node.properties; | |
761 out("{"); | 773 out("{"); |
762 List<Property> properties = node.properties; | 774 ++indentLevel; |
763 for (int i = 0; i < properties.length; i++) { | 775 for (int i = 0; i < properties.length; i++) { |
776 Expression value = properties[i].value; | |
777 if (value is Fun || value is NamedFunction) onePerLine = true; | |
764 if (i != 0) { | 778 if (i != 0) { |
765 out(","); | 779 out(","); |
766 spaceOut(); | 780 if (!onePerLine) spaceOut(); |
781 } | |
782 if (onePerLine) { | |
783 newLine(); | |
floitsch
2013/01/04 10:31:03
why "newLine" and not "lineOut" ?
sra1
2013/01/04 23:47:52
To force newlines even under --minify.
We can play
floitsch
2013/01/04 23:58:20
Fine with me, but I wouldn't consider readability
| |
784 indent(); | |
767 } | 785 } |
768 visitProperty(properties[i]); | 786 visitProperty(properties[i]); |
769 } | 787 } |
788 --indentLevel; | |
789 if (onePerLine) lineOut(); | |
770 out("}"); | 790 out("}"); |
771 } | 791 } |
772 | 792 |
773 visitProperty(Property node) { | 793 visitProperty(Property node) { |
774 if (node.name is LiteralString) { | 794 if (node.name is LiteralString) { |
775 LiteralString nameString = node.name; | 795 LiteralString nameString = node.name; |
776 String name = nameString.value; | 796 String name = nameString.value; |
777 if (isValidJavaScriptId(name)) { | 797 if (isValidJavaScriptId(name)) { |
778 out(name.substring(1, name.length - 1)); | 798 out(name.substring(1, name.length - 1)); |
779 } else { | 799 } else { |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1065 codes.add(nthLetter((n ~/ nameSpaceSize) % LETTERS)); | 1085 codes.add(nthLetter((n ~/ nameSpaceSize) % LETTERS)); |
1066 } | 1086 } |
1067 codes.add(charCodes.$0 + digit); | 1087 codes.add(charCodes.$0 + digit); |
1068 newName = new String.fromCharCodes(codes); | 1088 newName = new String.fromCharCodes(codes); |
1069 } | 1089 } |
1070 assert(new RegExp(r'[a-zA-Z][a-zA-Z0-9]*').hasMatch(newName)); | 1090 assert(new RegExp(r'[a-zA-Z][a-zA-Z0-9]*').hasMatch(newName)); |
1071 maps.last[oldName] = newName; | 1091 maps.last[oldName] = newName; |
1072 return newName; | 1092 return newName; |
1073 } | 1093 } |
1074 } | 1094 } |
OLD | NEW |