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 /// Always emit a newline, even under `enableMinification`. | |
35 void forceLine() { | |
36 out("\n"); | |
37 } | |
38 /// Emits a newline for readability. | |
39 void lineOut() { | |
40 if (!shouldCompressOutput) forceLine(); | |
41 } | |
34 void spaceOut() { | 42 void spaceOut() { |
35 if (!shouldCompressOutput) out(" "); | 43 if (!shouldCompressOutput) out(" "); |
36 } | 44 } |
37 void lineOut() { | |
38 if (!shouldCompressOutput) out("\n"); | |
39 } | |
40 | 45 |
41 String lastAddedString = null; | 46 String lastAddedString = null; |
42 int get lastCharCode { | 47 int get lastCharCode { |
43 if (lastAddedString == null) return 0; | 48 if (lastAddedString == null) return 0; |
44 assert(lastAddedString.length != ""); | 49 assert(lastAddedString.length != ""); |
45 return lastAddedString.charCodeAt(lastAddedString.length - 1); | 50 return lastAddedString.charCodeAt(lastAddedString.length - 1); |
46 } | 51 } |
47 | 52 |
48 void out(String str) { | 53 void out(String str) { |
49 if (str != "") { | 54 if (str != "") { |
(...skipping 13 matching lines...) Expand all Loading... | |
63 | 68 |
64 void outLn(String str) { | 69 void outLn(String str) { |
65 out(str); | 70 out(str); |
66 lineOut(); | 71 lineOut(); |
67 } | 72 } |
68 | 73 |
69 void outSemicolonLn() { | 74 void outSemicolonLn() { |
70 if (shouldCompressOutput) { | 75 if (shouldCompressOutput) { |
71 pendingSemicolon = true; | 76 pendingSemicolon = true; |
72 } else { | 77 } else { |
73 out(";\n"); | 78 out(";"); |
79 forceLine(); | |
74 } | 80 } |
75 } | 81 } |
76 | 82 |
77 void outIndent(String str) { indent(); out(str); } | 83 void outIndent(String str) { indent(); out(str); } |
78 void outIndentLn(String str) { indent(); outLn(str); } | 84 void outIndentLn(String str) { indent(); outLn(str); } |
79 void indent() { | 85 void indent() { |
80 if (!shouldCompressOutput) { | 86 if (!shouldCompressOutput) { |
81 for (int i = 0; i < indentLevel; i++) out(" "); | 87 for (int i = 0; i < indentLevel; i++) out(" "); |
82 } | 88 } |
83 } | 89 } |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
665 // TODO(floitsch): allow more characters. | 671 // TODO(floitsch): allow more characters. |
666 int charCode = field.charCodeAt(i); | 672 int charCode = field.charCodeAt(i); |
667 if (!(charCodes.$a <= charCode && charCode <= charCodes.$z || | 673 if (!(charCodes.$a <= charCode && charCode <= charCodes.$z || |
668 charCodes.$A <= charCode && charCode <= charCodes.$Z || | 674 charCodes.$A <= charCode && charCode <= charCodes.$Z || |
669 charCode == charCodes.$$ || | 675 charCode == charCodes.$$ || |
670 charCode == charCodes.$_ || | 676 charCode == charCodes.$_ || |
671 i != 1 && isDigit(charCode))) { | 677 i != 1 && isDigit(charCode))) { |
672 return false; | 678 return false; |
673 } | 679 } |
674 } | 680 } |
675 // TODO(floitsch): normally we should also check that the field is not | 681 // TODO(floitsch): normally we should also check that the field is not a |
676 // a reserved word. | 682 // reserved word. We don't generate fields with reserved word names except |
683 // for 'super'. | |
684 if (field == '"super"') return false; | |
ngeoffray
2013/01/10 10:40:07
Using super breaks android AFAIR. Why did you need
sra1
2013/01/10 16:32:42
Without this line, we get
super: "X",
with the l
| |
677 return true; | 685 return true; |
678 } | 686 } |
679 | 687 |
680 visitAccess(PropertyAccess access) { | 688 visitAccess(PropertyAccess access) { |
681 visitNestedExpression(access.receiver, CALL, | 689 visitNestedExpression(access.receiver, CALL, |
682 newInForInit: inForInit, | 690 newInForInit: inForInit, |
683 newAtStatementBegin: atStatementBegin); | 691 newAtStatementBegin: atStatementBegin); |
684 Node selector = access.selector; | 692 Node selector = access.selector; |
685 if (selector is LiteralString) { | 693 if (selector is LiteralString) { |
686 LiteralString selectorString = selector; | 694 LiteralString selectorString = selector; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
751 } | 759 } |
752 } | 760 } |
753 out("]"); | 761 out("]"); |
754 } | 762 } |
755 | 763 |
756 visitArrayElement(ArrayElement node) { | 764 visitArrayElement(ArrayElement node) { |
757 throw "Unreachable"; | 765 throw "Unreachable"; |
758 } | 766 } |
759 | 767 |
760 visitObjectInitializer(ObjectInitializer node) { | 768 visitObjectInitializer(ObjectInitializer node) { |
769 // Print all the properties on one line until we see a function-valued | |
770 // property. Ideally, we would use a proper pretty-printer to make the | |
771 // decision based on layout. | |
772 bool onePerLine = false; | |
773 List<Property> properties = node.properties; | |
761 out("{"); | 774 out("{"); |
762 List<Property> properties = node.properties; | 775 ++indentLevel; |
763 for (int i = 0; i < properties.length; i++) { | 776 for (int i = 0; i < properties.length; i++) { |
777 Expression value = properties[i].value; | |
778 if (value is Fun || value is NamedFunction) onePerLine = true; | |
764 if (i != 0) { | 779 if (i != 0) { |
765 out(","); | 780 out(","); |
766 spaceOut(); | 781 if (!onePerLine) spaceOut(); |
782 } | |
783 if (onePerLine) { | |
784 forceLine(); | |
785 indent(); | |
767 } | 786 } |
768 visitProperty(properties[i]); | 787 visitProperty(properties[i]); |
769 } | 788 } |
789 --indentLevel; | |
790 if (onePerLine) lineOut(); | |
770 out("}"); | 791 out("}"); |
771 } | 792 } |
772 | 793 |
773 visitProperty(Property node) { | 794 visitProperty(Property node) { |
774 if (node.name is LiteralString) { | 795 if (node.name is LiteralString) { |
775 LiteralString nameString = node.name; | 796 LiteralString nameString = node.name; |
776 String name = nameString.value; | 797 String name = nameString.value; |
777 if (isValidJavaScriptId(name)) { | 798 if (isValidJavaScriptId(name)) { |
778 out(name.substring(1, name.length - 1)); | 799 out(name.substring(1, name.length - 1)); |
779 } else { | 800 } else { |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1065 codes.add(nthLetter((n ~/ nameSpaceSize) % LETTERS)); | 1086 codes.add(nthLetter((n ~/ nameSpaceSize) % LETTERS)); |
1066 } | 1087 } |
1067 codes.add(charCodes.$0 + digit); | 1088 codes.add(charCodes.$0 + digit); |
1068 newName = new String.fromCharCodes(codes); | 1089 newName = new String.fromCharCodes(codes); |
1069 } | 1090 } |
1070 assert(new RegExp(r'[a-zA-Z][a-zA-Z0-9]*').hasMatch(newName)); | 1091 assert(new RegExp(r'[a-zA-Z][a-zA-Z0-9]*').hasMatch(newName)); |
1071 maps.last[oldName] = newName; | 1092 maps.last[oldName] = newName; |
1072 return newName; | 1093 return newName; |
1073 } | 1094 } |
1074 } | 1095 } |
OLD | NEW |