| Index: pkg/compiler/tool/status_files/rank_stacks.dart
|
| diff --git a/pkg/compiler/tool/status_files/rank_stacks.dart b/pkg/compiler/tool/status_files/rank_stacks.dart
|
| index 31345e037b721d68eb82ca505a6f4a586e4aabe7..5d5f72a73b36f35dcce10d51c46793eb93949efb 100644
|
| --- a/pkg/compiler/tool/status_files/rank_stacks.dart
|
| +++ b/pkg/compiler/tool/status_files/rank_stacks.dart
|
| @@ -18,47 +18,70 @@ Usage:
|
|
|
| import 'dart:io';
|
|
|
| +import 'package:args/args.dart';
|
| +
|
| import 'log_parser.dart';
|
| import 'record.dart';
|
|
|
| -// TODO(sra): Allow command-line setting of these parameters.
|
| -const STACK_PRINT_LENGTH = 12;
|
| -const HOW_MANY_STACKS = 30;
|
| +int stackPrintLength;
|
| +int howManyStacks;
|
| +
|
| +void die(String why) {
|
| + print(why);
|
| + print('Usage:\n'
|
| + 'dart rank_stacks.dart [options] test-logs\n\n'
|
| + '${argParser.usage}');
|
| + exit(1);
|
| +}
|
| +
|
| +ArgParser argParser = new ArgParser()
|
| + ..addOption('stacks',
|
| + abbr: 's',
|
| + defaultsTo: '30',
|
| + help: 'Number of highest ranking stacks to print.')
|
| + ..addOption('length',
|
| + abbr: 'l', defaultsTo: '12', help: 'Number of stack frames printed.');
|
| +
|
| +int intOption(ArgResults args, String name) {
|
| + onError(String text) {
|
| + die("Value '$text' is not an integer. "
|
| + "Option '$name' requires an integer value.");
|
| + }
|
| +
|
| + return int.parse(args[name], onError: onError);
|
| +}
|
|
|
| main(args) {
|
| - String text;
|
| -
|
| - for (String arg in args) {
|
| - // Parse options.
|
| -
|
| - if (text == null) {
|
| - var uri = Uri.base.resolve(arg);
|
| - var file = new File.fromUri(uri);
|
| - if (!file.existsSync()) {
|
| - print('File not found: $file.');
|
| - exit(1);
|
| - }
|
| - text = file.readAsStringSync();
|
| - } else {
|
| - print("Extra file argument '$arg'.");
|
| - exit(1);
|
| - }
|
| + List<String> rest;
|
| + try {
|
| + var argResults = argParser.parse(args);
|
| + howManyStacks = intOption(argResults, 'stacks');
|
| + stackPrintLength = intOption(argResults, 'length');
|
| + rest = argResults.rest;
|
| + } catch (e) {
|
| + die('$e');
|
| }
|
|
|
| - if (text == null) {
|
| - print('No input file.');
|
| - exit(1);
|
| + if (rest.isEmpty) die('No input file.');
|
| + var records = <Record>[];
|
| + for (String input in rest) {
|
| + var uri = Uri.base.resolve(input);
|
| + var file = new File.fromUri(uri);
|
| + if (!file.existsSync()) {
|
| + die("File not found: '$input'.");
|
| + }
|
| + String text = file.readAsStringSync();
|
| + records.addAll(parse(text));
|
| }
|
|
|
| - var records = parse(text);
|
| var trie = new TrieNode(null);
|
| for (var record in records) {
|
| enter(record, 0, trie);
|
| }
|
|
|
| var leaves = trieLeaves(trie).toList();
|
| - leaves.sort((a, b) => b.length.compareTo(a.length));
|
| - for (var leaf in leaves.take(HOW_MANY_STACKS)) {
|
| + leaves.sort(compareNodesByCountAndStack);
|
| + for (var leaf in howManyStacks == 0 ? leaves : leaves.take(howManyStacks)) {
|
| print('');
|
| var examples = leaf.members.map((r) => r.fullReason).toSet().toList();
|
| examples.sort();
|
| @@ -71,12 +94,26 @@ main(args) {
|
| print('${countAligned}${indentedExample}');
|
| }
|
|
|
| - for (var line in leaf.members.first.stack.take(STACK_PRINT_LENGTH)) {
|
| + for (var line in leaf.members.first.stack.take(stackPrintLength)) {
|
| print(' $line');
|
| }
|
| }
|
| }
|
|
|
| +int compareNodesByCountAndStack(TrieNode a, TrieNode b) {
|
| + int r = b.length.compareTo(a.length);
|
| + if (r != 0) return r;
|
| + List<String> stackA = a.members.first.stack;
|
| + List<String> stackB = b.members.first.stack;
|
| + int lengthA = stackA.length;
|
| + int lengthB = stackB.length;
|
| + for (int i = 0; i < lengthA && i < lengthB; i++) {
|
| + r = stackA[i].compareTo(stackB[i]);
|
| + if (r != 0) return r;
|
| + }
|
| + return lengthA.compareTo(lengthB);
|
| +}
|
| +
|
| class TrieNode {
|
| final int depth;
|
| final String key;
|
|
|