Index: pkg/analyzer/tool/summary/stats.dart |
diff --git a/pkg/analyzer/tool/summary/stats.dart b/pkg/analyzer/tool/summary/stats.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6d6f10b147a76dd223adb1f8313e927e6f619a5f |
--- /dev/null |
+++ b/pkg/analyzer/tool/summary/stats.dart |
@@ -0,0 +1,101 @@ |
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+/** |
+ * This file contains code for collecting statistics about the use of fields in |
+ * a summary file. |
+ */ |
+library analyzer.tool.summary.stats; |
+ |
+import 'dart:io'; |
+ |
+import 'package:analyzer/src/summary/base.dart'; |
+import 'package:analyzer/src/summary/idl.dart'; |
+ |
+main(List<String> args) { |
+ if (args.length != 1) { |
+ _printUsage(); |
+ exitCode = 1; |
+ return; |
+ } |
+ |
+ String inputFilePath = args[0]; |
+ |
+ // Read the input. |
+ SdkBundle bundle = |
+ new SdkBundle.fromBuffer(new File(inputFilePath).readAsBytesSync()); |
+ |
+ // Compute and output stats. |
+ Stats stats = new Stats(); |
+ stats.record(bundle); |
+ stats.dump(); |
+} |
+ |
+/** |
+ * The name of the stats tool. |
+ */ |
+const String BINARY_NAME = "stats"; |
+ |
+/** |
+ * Print information about how to use the stats tool. |
+ */ |
+void _printUsage() { |
+ print('Usage: $BINARY_NAME input_file_path'); |
+} |
+ |
+/** |
+ * An instance of [Stats] keeps track of statistics about the use of fields in |
+ * summary objects. |
+ */ |
+class Stats { |
+ /** |
+ * Map from type to field name to a count of how often the field is used. |
+ */ |
+ Map<Type, Map<String, int>> counts = <Type, Map<String, int>>{}; |
+ |
+ /** |
+ * Print out statistics gathered so far. |
+ */ |
+ void dump() { |
+ counts.forEach((Type type, Map<String, int> typeCounts) { |
+ print(type); |
+ List<String> keys = typeCounts.keys.toList(); |
+ keys.sort((String a, String b) => typeCounts[b].compareTo(typeCounts[a])); |
+ for (String key in keys) { |
+ print(' $key: ${typeCounts[key]}'); |
+ } |
+ print(''); |
+ }); |
+ } |
+ |
+ /** |
+ * Record statistics for [obj] and all objects it refers to. |
+ */ |
+ void record(SummaryClass obj) { |
+ Map<String, int> typeCounts = |
+ counts.putIfAbsent(obj.runtimeType, () => <String, int>{}); |
+ obj.toMap().forEach((String key, Object value) { |
+ if (value == null || |
+ value == 0 || |
+ value == false || |
+ value == '' || |
+ value is List && value.isEmpty) { |
+ return; |
+ } |
+ if (!typeCounts.containsKey(key)) { |
+ typeCounts[key] = 0; |
+ } |
+ typeCounts[key]++; |
+ if (value is SummaryClass) { |
+ record(value); |
+ } else if (value is List) { |
+ value.forEach((Object element) { |
+ if (element is SummaryClass) { |
+ record(element); |
+ } |
+ }); |
+ } |
+ }); |
+ } |
+} |