OLD | NEW |
1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dartino 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
4 | 4 |
5 library fletchc.fletch_system_printer; | 5 library dartino_compiler.dartino_system_printer; |
6 | 6 |
7 import '../fletch_system.dart' show | 7 import '../dartino_system.dart' show |
8 FletchClass, | 8 DartinoClass, |
9 FletchFunction, | 9 DartinoFunction, |
10 FletchSystem; | 10 DartinoSystem; |
11 | 11 |
12 import 'package:compiler/src/util/uri_extras.dart' show | 12 import 'package:compiler/src/util/uri_extras.dart' show |
13 relativize; | 13 relativize; |
14 | 14 |
15 import 'fletch_selector.dart' show | 15 import 'dartino_selector.dart' show |
16 FletchSelector, | 16 DartinoSelector, |
17 SelectorKind; | 17 SelectorKind; |
18 | 18 |
19 import 'package:compiler/src/elements/elements.dart' show | 19 import 'package:compiler/src/elements/elements.dart' show |
20 Element, | 20 Element, |
21 CompilationUnitElement; | 21 CompilationUnitElement; |
22 | 22 |
23 class FletchSystemPrinter { | 23 class DartinoSystemPrinter { |
24 final FletchSystem system; | 24 final DartinoSystem system; |
25 final Uri base; | 25 final Uri base; |
26 final StringBuffer buffer = new StringBuffer(); | 26 final StringBuffer buffer = new StringBuffer(); |
27 final String baseIndentation = " "; | 27 final String baseIndentation = " "; |
28 | 28 |
29 bool beginningOfLine = true; | 29 bool beginningOfLine = true; |
30 | 30 |
31 int indentationLevel = 0; | 31 int indentationLevel = 0; |
32 | 32 |
33 FletchSystemPrinter(this.system, this.base); | 33 DartinoSystemPrinter(this.system, this.base); |
34 | 34 |
35 void indent() { | 35 void indent() { |
36 for (int i = 0; i < indentationLevel; i++) { | 36 for (int i = 0; i < indentationLevel; i++) { |
37 buffer.write(baseIndentation); | 37 buffer.write(baseIndentation); |
38 } | 38 } |
39 } | 39 } |
40 | 40 |
41 void indented(f()) { | 41 void indented(f()) { |
42 ++indentationLevel; | 42 ++indentationLevel; |
43 try { | 43 try { |
44 f(); | 44 f(); |
45 } finally { | 45 } finally { |
46 --indentationLevel; | 46 --indentationLevel; |
47 } | 47 } |
48 } | 48 } |
49 | 49 |
50 void write(String text) { | 50 void write(String text) { |
51 if (beginningOfLine) { | 51 if (beginningOfLine) { |
52 indent(); | 52 indent(); |
53 beginningOfLine = false; | 53 beginningOfLine = false; |
54 } | 54 } |
55 buffer.write(text); | 55 buffer.write(text); |
56 } | 56 } |
57 | 57 |
58 void writeLine([String line = ""]) { | 58 void writeLine([String line = ""]) { |
59 write("$line\n"); | 59 write("$line\n"); |
60 beginningOfLine = true; | 60 beginningOfLine = true; |
61 } | 61 } |
62 | 62 |
63 void writeFletchFunctionAsBody(FletchFunction function) { | 63 void writeDartinoFunctionAsBody(DartinoFunction function) { |
64 if (function.element != null) { | 64 if (function.element != null) { |
65 writeLine("=> ${function.element};"); | 65 writeLine("=> ${function.element};"); |
66 } else { | 66 } else { |
67 writeLine("{"); | 67 writeLine("{"); |
68 indented(() { | 68 indented(() { |
69 for (String line in function.verboseToString().trim().split("\n")) { | 69 for (String line in function.verboseToString().trim().split("\n")) { |
70 writeLine("// $line"); | 70 writeLine("// $line"); |
71 } | 71 } |
72 }); | 72 }); |
73 writeLine("}"); | 73 writeLine("}"); |
74 } | 74 } |
75 } | 75 } |
76 | 76 |
77 void writeMethodTableEntry( | 77 void writeMethodTableEntry( |
78 DecodedFletchSelector selector, int functionId) { | 78 DecodedDartinoSelector selector, int functionId) { |
79 switch (selector.kind) { | 79 switch (selector.kind) { |
80 case SelectorKind.Method: | 80 case SelectorKind.Method: |
81 write("${selector.symbol}#${selector.arity}()"); | 81 write("${selector.symbol}#${selector.arity}()"); |
82 break; | 82 break; |
83 | 83 |
84 case SelectorKind.Getter: | 84 case SelectorKind.Getter: |
85 assert(selector.arity == 0); | 85 assert(selector.arity == 0); |
86 if (selector.symbol.startsWith("?is?")) { | 86 if (selector.symbol.startsWith("?is?")) { |
87 writeLine("type test ${selector.symbol.substring(4)}"); | 87 writeLine("type test ${selector.symbol.substring(4)}"); |
88 return; | 88 return; |
89 } | 89 } |
90 write("get ${selector.symbol}"); | 90 write("get ${selector.symbol}"); |
91 break; | 91 break; |
92 | 92 |
93 case SelectorKind.Setter: | 93 case SelectorKind.Setter: |
94 assert(selector.arity == 1); | 94 assert(selector.arity == 1); |
95 write("set ${selector.symbol}"); | 95 write("set ${selector.symbol}"); |
96 break; | 96 break; |
97 } | 97 } |
98 write(" "); | 98 write(" "); |
99 FletchFunction function = system.functionsById[functionId]; | 99 DartinoFunction function = system.functionsById[functionId]; |
100 writeFletchFunctionAsBody(function); | 100 writeDartinoFunctionAsBody(function); |
101 } | 101 } |
102 | 102 |
103 void writeFletchClass(FletchClass cls, Set<FletchFunction> unseen) { | 103 void writeDartinoClass(DartinoClass cls, Set<DartinoFunction> unseen) { |
104 // TODO(ahe): Important if class is builtin or not. Information lost in | 104 // TODO(ahe): Important if class is builtin or not. Information lost in |
105 // FletchNewClassBuilder.finalizeClass. | 105 // DartinoNewClassBuilder.finalizeClass. |
106 if (cls.element != null) { | 106 if (cls.element != null) { |
107 writeLine("class ${cls.element.name} {"); | 107 writeLine("class ${cls.element.name} {"); |
108 } else { | 108 } else { |
109 writeLine("$cls {"); | 109 writeLine("$cls {"); |
110 } | 110 } |
111 indented(() { | 111 indented(() { |
112 Map<DecodedFletchSelector, int> methodTable = | 112 Map<DecodedDartinoSelector, int> methodTable = |
113 <DecodedFletchSelector, int>{}; | 113 <DecodedDartinoSelector, int>{}; |
114 for (var pair in cls.methodTable) { | 114 for (var pair in cls.methodTable) { |
115 DecodedFletchSelector selector = | 115 DecodedDartinoSelector selector = |
116 new DecodedFletchSelector.fromEncodedSelector(pair.fst, system); | 116 new DecodedDartinoSelector.fromEncodedSelector(pair.fst, system); |
117 methodTable[selector] = pair.snd; | 117 methodTable[selector] = pair.snd; |
118 } | 118 } |
119 List<DecodedFletchSelector> selectors = methodTable.keys.toList()..sort(); | 119 List<DecodedDartinoSelector> selectors = methodTable.keys.toList()..sort()
; |
120 for (DecodedFletchSelector selector in selectors) { | 120 for (DecodedDartinoSelector selector in selectors) { |
121 int methodId = methodTable[selector]; | 121 int methodId = methodTable[selector]; |
122 unseen.remove(system.lookupFunctionById(methodId)); | 122 unseen.remove(system.lookupFunctionById(methodId)); |
123 writeMethodTableEntry(selector, methodId); | 123 writeMethodTableEntry(selector, methodId); |
124 } | 124 } |
125 }); | 125 }); |
126 writeLine("}"); | 126 writeLine("}"); |
127 } | 127 } |
128 | 128 |
129 String generateDebugString() { | 129 String generateDebugString() { |
130 buffer.clear(); | 130 buffer.clear(); |
131 | 131 |
132 Map<String, List<Element>> elementsByPath = <String, List<Element>>{}; | 132 Map<String, List<Element>> elementsByPath = <String, List<Element>>{}; |
133 Set<FletchFunction> unseenFunctions = new Set<FletchFunction>(); | 133 Set<DartinoFunction> unseenFunctions = new Set<DartinoFunction>(); |
134 | 134 |
135 for (var pair in system.functionsById) { | 135 for (var pair in system.functionsById) { |
136 unseenFunctions.add(pair.snd); | 136 unseenFunctions.add(pair.snd); |
137 } | 137 } |
138 | 138 |
139 groupByPath(pair) { | 139 groupByPath(pair) { |
140 Element element = pair.fst; | 140 Element element = pair.fst; |
141 String path = | 141 String path = |
142 relativize(base, element.compilationUnit.script.resourceUri, false); | 142 relativize(base, element.compilationUnit.script.resourceUri, false); |
143 List<Element> elements = | 143 List<Element> elements = |
144 elementsByPath.putIfAbsent(path, () => <Element>[]); | 144 elementsByPath.putIfAbsent(path, () => <Element>[]); |
145 elements.add(element); | 145 elements.add(element); |
146 } | 146 } |
147 system.functionsByElement.forEach(groupByPath); | 147 system.functionsByElement.forEach(groupByPath); |
148 system.classesByElement.forEach(groupByPath); | 148 system.classesByElement.forEach(groupByPath); |
149 List paths = elementsByPath.keys.toList(); | 149 List paths = elementsByPath.keys.toList(); |
150 paths.sort(); | 150 paths.sort(); |
151 for (String path in paths) { | 151 for (String path in paths) { |
152 writeLine("$path"); | 152 writeLine("$path"); |
153 indented(() { | 153 indented(() { |
154 List<Element> elements = elementsByPath[path]; | 154 List<Element> elements = elementsByPath[path]; |
155 elements.sort((a, b) => "$a".compareTo("$b")); | 155 elements.sort((a, b) => "$a".compareTo("$b")); |
156 for (Element element in elements) { | 156 for (Element element in elements) { |
157 if (element.isClass) { | 157 if (element.isClass) { |
158 writeFletchClass(system.classesByElement[element], unseenFunctions); | 158 writeDartinoClass(system.classesByElement[element], unseenFunctions)
; |
159 } else if (!element.isInstanceMember) { | 159 } else if (!element.isInstanceMember) { |
160 unseenFunctions.remove(system.functionsByElement[element]); | 160 unseenFunctions.remove(system.functionsByElement[element]); |
161 // TODO(ahe): It would probably be better to call | 161 // TODO(ahe): It would probably be better to call |
162 // writeFletchFunctionAsBody here, but we have an element, not an | 162 // writeDartinoFunctionAsBody here, but we have an element, not an |
163 // ID. | 163 // ID. |
164 writeLine("$element"); | 164 writeLine("$element"); |
165 } | 165 } |
166 } | 166 } |
167 }); | 167 }); |
168 } | 168 } |
169 | 169 |
170 writeLine("Classes without an element:"); | 170 writeLine("Classes without an element:"); |
171 indented(() { | 171 indented(() { |
172 for (var pair in system.classesById) { | 172 for (var pair in system.classesById) { |
173 FletchClass fletchClass = pair.snd; | 173 DartinoClass dartinoClass = pair.snd; |
174 if (system.classesByElement[fletchClass.element] != fletchClass) { | 174 if (system.classesByElement[dartinoClass.element] != dartinoClass) { |
175 writeFletchClass(fletchClass, unseenFunctions); | 175 writeDartinoClass(dartinoClass, unseenFunctions); |
176 } | 176 } |
177 } | 177 } |
178 }); | 178 }); |
179 | 179 |
180 writeLine("Other functions:"); | 180 writeLine("Other functions:"); |
181 indented(() { | 181 indented(() { |
182 for (var pair in system.functionsById) { | 182 for (var pair in system.functionsById) { |
183 FletchFunction fletchFunction = pair.snd; | 183 DartinoFunction dartinoFunction = pair.snd; |
184 if (unseenFunctions.remove(fletchFunction)) { | 184 if (unseenFunctions.remove(dartinoFunction)) { |
185 write("$fletchFunction "); | 185 write("$dartinoFunction "); |
186 writeFletchFunctionAsBody(fletchFunction); | 186 writeDartinoFunctionAsBody(dartinoFunction); |
187 } | 187 } |
188 } | 188 } |
189 }); | 189 }); |
190 | 190 |
191 return "$buffer"; | 191 return "$buffer"; |
192 } | 192 } |
193 | 193 |
194 int compareUnits(CompilationUnitElement a, CompilationUnitElement b) { | 194 int compareUnits(CompilationUnitElement a, CompilationUnitElement b) { |
195 String aPath = relativize(base, a.script.resourceUri, false); | 195 String aPath = relativize(base, a.script.resourceUri, false); |
196 String bPath = relativize(base, b.script.resourceUri, false); | 196 String bPath = relativize(base, b.script.resourceUri, false); |
197 return aPath.compareTo(bPath); | 197 return aPath.compareTo(bPath); |
198 } | 198 } |
199 } | 199 } |
200 | 200 |
201 class DecodedFletchSelector implements Comparable<DecodedFletchSelector> { | 201 class DecodedDartinoSelector implements Comparable<DecodedDartinoSelector> { |
202 final FletchSelector selector; | 202 final DartinoSelector selector; |
203 | 203 |
204 final String symbol; | 204 final String symbol; |
205 | 205 |
206 const DecodedFletchSelector(this.selector, this.symbol); | 206 const DecodedDartinoSelector(this.selector, this.symbol); |
207 | 207 |
208 factory DecodedFletchSelector.fromEncodedSelector( | 208 factory DecodedDartinoSelector.fromEncodedSelector( |
209 int encodedSelector, | 209 int encodedSelector, |
210 FletchSystem system) { | 210 DartinoSystem system) { |
211 FletchSelector selector = new FletchSelector(encodedSelector); | 211 DartinoSelector selector = new DartinoSelector(encodedSelector); |
212 return new DecodedFletchSelector( | 212 return new DecodedDartinoSelector( |
213 selector, system.symbolByFletchSelectorId[selector.id]); | 213 selector, system.symbolByDartinoSelectorId[selector.id]); |
214 } | 214 } |
215 | 215 |
216 int get id => selector.id; | 216 int get id => selector.id; |
217 | 217 |
218 SelectorKind get kind => selector.kind; | 218 SelectorKind get kind => selector.kind; |
219 | 219 |
220 int get arity => selector.arity; | 220 int get arity => selector.arity; |
221 | 221 |
222 String toString() => "DecodedFletchSelector($id, $symbol, $kind, $arity)"; | 222 String toString() => "DecodedDartinoSelector($id, $symbol, $kind, $arity)"; |
223 | 223 |
224 int compareTo(DecodedFletchSelector other) { | 224 int compareTo(DecodedDartinoSelector other) { |
225 int result = this.symbol.compareTo(other.symbol); | 225 int result = this.symbol.compareTo(other.symbol); |
226 if (result != 0) return result; | 226 if (result != 0) return result; |
227 result = this.kind.index.compareTo(other.kind.index); | 227 result = this.kind.index.compareTo(other.kind.index); |
228 if (result != 0) return result; | 228 if (result != 0) return result; |
229 return this.arity.compareTo(other.arity); | 229 return this.arity.compareTo(other.arity); |
230 } | 230 } |
231 } | 231 } |
OLD | NEW |