| 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 |