| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library dump_info; | 5 library dump_info; |
| 6 | 6 |
| 7 import 'dart:convert' show | 7 import 'dart:convert' show |
| 8 HtmlEscape, | 8 HtmlEscape, |
| 9 JsonEncoder, | 9 JsonEncoder, |
| 10 StringConversionSink, | 10 StringConversionSink, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 if (elementJson != null) { | 73 if (elementJson != null) { |
| 74 innerMapper["$k"] = elementJson; | 74 innerMapper["$k"] = elementJson; |
| 75 } | 75 } |
| 76 }); | 76 }); |
| 77 json[mapper.name] = innerMapper; | 77 json[mapper.name] = innerMapper; |
| 78 } | 78 } |
| 79 return json; | 79 return json; |
| 80 } | 80 } |
| 81 } | 81 } |
| 82 | 82 |
| 83 class ElementToJsonVisitor extends ElementVisitor<Map<String, dynamic>> { | 83 class ElementToJsonVisitor |
| 84 extends BaseElementVisitor<Map<String, dynamic>, dynamic> { |
| 84 final GroupedIdMapper mapper = new GroupedIdMapper(); | 85 final GroupedIdMapper mapper = new GroupedIdMapper(); |
| 85 final Compiler compiler; | 86 final Compiler compiler; |
| 86 | 87 |
| 87 final Map<Element, Map<String, dynamic>> jsonCache = {}; | 88 final Map<Element, Map<String, dynamic>> jsonCache = {}; |
| 88 | 89 |
| 89 String dart2jsVersion; | 90 String dart2jsVersion; |
| 90 | 91 |
| 91 ElementToJsonVisitor(this.compiler); | 92 ElementToJsonVisitor(this.compiler); |
| 92 | 93 |
| 93 void run() { | 94 void run() { |
| 94 Backend backend = compiler.backend; | 95 Backend backend = compiler.backend; |
| 95 | 96 |
| 96 dart2jsVersion = compiler.hasBuildId ? compiler.buildId : null; | 97 dart2jsVersion = compiler.hasBuildId ? compiler.buildId : null; |
| 97 | 98 |
| 98 for (var library in compiler.libraryLoader.libraries.toList()) { | 99 for (var library in compiler.libraryLoader.libraries.toList()) { |
| 99 library.accept(this); | 100 visit(library); |
| 100 } | 101 } |
| 101 } | 102 } |
| 102 | 103 |
| 104 Map<String, dynamic> visit(Element e, [_]) => e.accept(this, null); |
| 105 |
| 103 // If keeping the element is in question (like if a function has a size | 106 // If keeping the element is in question (like if a function has a size |
| 104 // of zero), only keep it if it holds dependencies to elsewhere. | 107 // of zero), only keep it if it holds dependencies to elsewhere. |
| 105 bool shouldKeep(Element element) { | 108 bool shouldKeep(Element element) { |
| 106 return compiler.dumpInfoTask.selectorsFromElement.containsKey(element) | 109 return compiler.dumpInfoTask.selectorsFromElement.containsKey(element) |
| 107 || compiler.dumpInfoTask.inlineCount.containsKey(element); | 110 || compiler.dumpInfoTask.inlineCount.containsKey(element); |
| 108 } | 111 } |
| 109 | 112 |
| 110 Map<String, dynamic> toJson() { | 113 Map<String, dynamic> toJson() { |
| 111 return mapper._toJson(this); | 114 return mapper._toJson(this); |
| 112 } | 115 } |
| 113 | 116 |
| 114 // Memoization of the JSON creating process. | 117 // Memoization of the JSON creating process. |
| 115 Map<String, dynamic> process(Element element) { | 118 Map<String, dynamic> process(Element element) { |
| 116 return jsonCache.putIfAbsent(element, () => element.accept(this)); | 119 return jsonCache.putIfAbsent(element, () => visit(element)); |
| 117 } | 120 } |
| 118 | 121 |
| 119 // Returns the id of an [element] if it has already been processed. | 122 // Returns the id of an [element] if it has already been processed. |
| 120 // If the element has not been processed, this function does not | 123 // If the element has not been processed, this function does not |
| 121 // process it, and simply returns null instead. | 124 // process it, and simply returns null instead. |
| 122 String idOf(Element element) { | 125 String idOf(Element element) { |
| 123 if (jsonCache.containsKey(element) && jsonCache[element] != null) { | 126 if (jsonCache.containsKey(element) && jsonCache[element] != null) { |
| 124 return jsonCache[element]['id']; | 127 return jsonCache[element]['id']; |
| 125 } else { | 128 } else { |
| 126 return null; | 129 return null; |
| 127 } | 130 } |
| 128 } | 131 } |
| 129 | 132 |
| 130 Map<String, dynamic> visitElement(Element element) { | 133 Map<String, dynamic> visitElement(Element element, _) { |
| 131 return null; | 134 return null; |
| 132 } | 135 } |
| 133 | 136 |
| 134 Map<String, dynamic> visitConstructorBodyElement(ConstructorBodyElement e) { | 137 Map<String, dynamic> visitConstructorBodyElement( |
| 135 return visitFunctionElement(e.constructor); | 138 ConstructorBodyElement e, _) { |
| 139 return visitFunctionElement(e.constructor, _); |
| 136 } | 140 } |
| 137 | 141 |
| 138 Map<String, dynamic> visitLibraryElement(LibraryElement element) { | 142 Map<String, dynamic> visitLibraryElement(LibraryElement element, _) { |
| 139 var id = mapper._library.add(element); | 143 var id = mapper._library.add(element); |
| 140 List<String> children = <String>[]; | 144 List<String> children = <String>[]; |
| 141 | 145 |
| 142 String libname = element.getLibraryName(); | 146 String libname = element.getLibraryName(); |
| 143 libname = libname == "" ? "<unnamed>" : libname; | 147 libname = libname == "" ? "<unnamed>" : libname; |
| 144 | 148 |
| 145 int size = compiler.dumpInfoTask.sizeOf(element); | 149 int size = compiler.dumpInfoTask.sizeOf(element); |
| 146 | 150 |
| 147 LibraryElement contentsOfLibrary = element.isPatched | 151 LibraryElement contentsOfLibrary = element.isPatched |
| 148 ? element.patch : element; | 152 ? element.patch : element; |
| 149 contentsOfLibrary.forEachLocalMember((Element member) { | 153 contentsOfLibrary.forEachLocalMember((Element member) { |
| 150 Map<String, dynamic> childJson = this.process(member); | 154 Map<String, dynamic> childJson = this.process(member); |
| 151 if (childJson == null) return; | 155 if (childJson == null) return; |
| 152 children.add(childJson['id']); | 156 children.add(childJson['id']); |
| 153 }); | 157 }); |
| 154 | 158 |
| 155 if (children.length == 0 && !shouldKeep(element)) { | 159 if (children.length == 0 && !shouldKeep(element)) { |
| 156 return null; | 160 return null; |
| 157 } | 161 } |
| 158 | 162 |
| 159 return { | 163 return { |
| 160 'kind': 'library', | 164 'kind': 'library', |
| 161 'name': libname, | 165 'name': libname, |
| 162 'size': size, | 166 'size': size, |
| 163 'id': id, | 167 'id': id, |
| 164 'children': children | 168 'children': children |
| 165 }; | 169 }; |
| 166 } | 170 } |
| 167 | 171 |
| 168 Map<String, dynamic> visitTypedefElement(TypedefElement element) { | 172 Map<String, dynamic> visitTypedefElement(TypedefElement element, _) { |
| 169 String id = mapper._typedef.add(element); | 173 String id = mapper._typedef.add(element); |
| 170 return element.alias == null | 174 return element.alias == null |
| 171 ? null | 175 ? null |
| 172 : { | 176 : { |
| 173 'id': id, | 177 'id': id, |
| 174 'type': element.alias.toString(), | 178 'type': element.alias.toString(), |
| 175 'kind': 'typedef', | 179 'kind': 'typedef', |
| 176 'name': element.name | 180 'name': element.name |
| 177 }; | 181 }; |
| 178 } | 182 } |
| 179 | 183 |
| 180 Map<String, dynamic> visitFieldElement(FieldElement element) { | 184 Map<String, dynamic> visitFieldElement(FieldElement element, _) { |
| 181 String id = mapper._field.add(element); | 185 String id = mapper._field.add(element); |
| 182 List<String> children = []; | 186 List<String> children = []; |
| 183 StringBuffer emittedCode = compiler.dumpInfoTask.codeOf(element); | 187 StringBuffer emittedCode = compiler.dumpInfoTask.codeOf(element); |
| 184 | 188 |
| 185 TypeMask inferredType = | 189 TypeMask inferredType = |
| 186 compiler.typesTask.getGuaranteedTypeOfElement(element); | 190 compiler.typesTask.getGuaranteedTypeOfElement(element); |
| 187 // If a field has an empty inferred type it is never used. | 191 // If a field has an empty inferred type it is never used. |
| 188 if (inferredType == null || inferredType.isEmpty || element.isConst) { | 192 if (inferredType == null || inferredType.isEmpty || element.isConst) { |
| 189 return null; | 193 return null; |
| 190 } | 194 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 216 'type': element.type.toString(), | 220 'type': element.type.toString(), |
| 217 'inferredType': inferredType.toString(), | 221 'inferredType': inferredType.toString(), |
| 218 'name': element.name, | 222 'name': element.name, |
| 219 'children': children, | 223 'children': children, |
| 220 'size': size, | 224 'size': size, |
| 221 'code': code, | 225 'code': code, |
| 222 'outputUnit': mapper._outputUnit.add(outputUnit) | 226 'outputUnit': mapper._outputUnit.add(outputUnit) |
| 223 }; | 227 }; |
| 224 } | 228 } |
| 225 | 229 |
| 226 Map<String, dynamic> visitClassElement(ClassElement element) { | 230 Map<String, dynamic> visitClassElement(ClassElement element, _) { |
| 227 String id = mapper._class.add(element); | 231 String id = mapper._class.add(element); |
| 228 List<String> children = []; | 232 List<String> children = []; |
| 229 | 233 |
| 230 int size = compiler.dumpInfoTask.sizeOf(element); | 234 int size = compiler.dumpInfoTask.sizeOf(element); |
| 231 JavaScriptBackend backend = compiler.backend; | 235 JavaScriptBackend backend = compiler.backend; |
| 232 | 236 |
| 233 Map<String, dynamic> modifiers = { 'abstract': element.isAbstract }; | 237 Map<String, dynamic> modifiers = { 'abstract': element.isAbstract }; |
| 234 | 238 |
| 235 element.forEachLocalMember((Element member) { | 239 element.forEachLocalMember((Element member) { |
| 236 Map<String, dynamic> childJson = this.process(member); | 240 Map<String, dynamic> childJson = this.process(member); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 'name': element.name, | 279 'name': element.name, |
| 276 'size': size, | 280 'size': size, |
| 277 'kind': 'class', | 281 'kind': 'class', |
| 278 'modifiers': modifiers, | 282 'modifiers': modifiers, |
| 279 'children': children, | 283 'children': children, |
| 280 'id': id, | 284 'id': id, |
| 281 'outputUnit': mapper._outputUnit.add(outputUnit) | 285 'outputUnit': mapper._outputUnit.add(outputUnit) |
| 282 }; | 286 }; |
| 283 } | 287 } |
| 284 | 288 |
| 285 Map<String, dynamic> visitFunctionElement(FunctionElement element) { | 289 Map<String, dynamic> visitFunctionElement(FunctionElement element, _) { |
| 286 String id = mapper._function.add(element); | 290 String id = mapper._function.add(element); |
| 287 String name = element.name; | 291 String name = element.name; |
| 288 String kind = "function"; | 292 String kind = "function"; |
| 289 List<String> children = []; | 293 List<String> children = []; |
| 290 List<Map<String, dynamic>> parameters = []; | 294 List<Map<String, dynamic>> parameters = []; |
| 291 String inferredReturnType = null; | 295 String inferredReturnType = null; |
| 292 String returnType = null; | 296 String returnType = null; |
| 293 String sideEffects = null; | 297 String sideEffects = null; |
| 294 String code = ""; | 298 String code = ""; |
| 295 | 299 |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 662 ChunkedConversionSink<Object> sink = | 666 ChunkedConversionSink<Object> sink = |
| 663 encoder.startChunkedConversion( | 667 encoder.startChunkedConversion( |
| 664 new StringConversionSink.fromStringSink(buffer)); | 668 new StringConversionSink.fromStringSink(buffer)); |
| 665 sink.add(outJson); | 669 sink.add(outJson); |
| 666 compiler.reportInfo(NO_LOCATION_SPANNABLE, | 670 compiler.reportInfo(NO_LOCATION_SPANNABLE, |
| 667 const MessageKind( | 671 const MessageKind( |
| 668 "View the dumped .info.json file at " | 672 "View the dumped .info.json file at " |
| 669 "https://dart-lang.github.io/dump-info-visualizer")); | 673 "https://dart-lang.github.io/dump-info-visualizer")); |
| 670 } | 674 } |
| 671 } | 675 } |
| OLD | NEW |