OLD | NEW |
| (Empty) |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 /// Command-line tool to query for code dependencies. | |
6 library compiler.tool.code_deps; | |
7 | |
8 import 'dart:collection'; | |
9 import 'dart:convert'; | |
10 import 'dart:io'; | |
11 | |
12 import 'package:compiler/src/info/info.dart'; | |
13 import 'graph.dart'; | |
14 import 'util.dart'; | |
15 | |
16 main(args) { | |
17 if (args.length < 2) { | |
18 print('usage: dart tool/code_deps.dart path-to-info.json <query>'); | |
19 print(' where <query> can be:'); | |
20 print(' - some_path elementA elementB'); | |
21 // TODO(sigmund): add other queries, such as 'all_paths'. | |
22 exit(1); | |
23 } | |
24 | |
25 var json = JSON.decode(new File(args[0]).readAsStringSync()); | |
26 var info = AllInfo.parseFromJson(json); | |
27 var graph = graphFromInfo(info); | |
28 | |
29 var queryName = args[1]; | |
30 if (queryName == 'some_path') { | |
31 if (args.length < 4) { | |
32 print('missing arguments for `some_path`'); | |
33 exit(1); | |
34 } | |
35 var source = | |
36 info.functions.firstWhere(_longNameMatcher(new RegExp(args[2])), | |
37 orElse: () => null); | |
38 var target = | |
39 info.functions.firstWhere(_longNameMatcher(new RegExp(args[3])), | |
40 orElse: () => null); | |
41 print('query: some_path'); | |
42 if (source == null) { | |
43 print("source '${args[2]}' not found in '${args[0]}'"); | |
44 exit(1); | |
45 } | |
46 print('source: ${longName(source)}'); | |
47 if (target == null) { | |
48 print("target '${args[3]}' not found in '${args[0]}'"); | |
49 exit(1); | |
50 } | |
51 print('target: ${longName(target)}'); | |
52 var path = new SomePathQuery(source, target).run(graph); | |
53 if (path.isEmpty) { | |
54 print('result: no path found'); | |
55 } else { | |
56 print('result:'); | |
57 for (int i = 0; i < path.length; i++) { | |
58 print(' $i. ${longName(path[i])}'); | |
59 } | |
60 } | |
61 } else { | |
62 print('unrecognized query: $queryName'); | |
63 } | |
64 } | |
65 | |
66 /// A query supported by this tool. | |
67 abstract class Query { | |
68 run(Graph<Info> graph); | |
69 } | |
70 | |
71 /// Query that searches for a single path between two elements. | |
72 class SomePathQuery { | |
73 /// The info associated with the source element. | |
74 Info source; | |
75 | |
76 /// The info associated with the target element. | |
77 Info target; | |
78 | |
79 SomePathQuery(this.source, this.target); | |
80 | |
81 List<Info> run(Graph<Info> graph) { | |
82 var seen = {source: null}; | |
83 var queue = new Queue(); | |
84 queue.addLast(source); | |
85 while (queue.isNotEmpty) { | |
86 var node = queue.removeFirst(); | |
87 if (identical(node, target)) { | |
88 var result = new Queue(); | |
89 while (node != null) { | |
90 result.addFirst(node); | |
91 node = seen[node]; | |
92 } | |
93 return result.toList(); | |
94 } | |
95 for (var neighbor in graph.targetsOf(node)) { | |
96 if (seen.containsKey(neighbor)) continue; | |
97 seen[neighbor] = node; | |
98 queue.addLast(neighbor); | |
99 } | |
100 } | |
101 return []; | |
102 } | |
103 } | |
104 | |
105 _longNameMatcher(RegExp regexp) => (e) => regexp.hasMatch(longName(e)); | |
OLD | NEW |