Mercurial > projects > dil
annotate trunk/src/cmd/ImportGraph.d @ 431:7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Thu, 04 Oct 2007 09:55:07 +0200 |
parents | e2bbc6406a14 |
children | 0df647660e76 |
rev | line source |
---|---|
364 | 1 /++ |
2 Author: Aziz Köksal | |
3 License: GPL3 | |
4 +/ | |
5 module cmd.ImportGraph; | |
6 import dil.SyntaxTree; | |
7 import dil.Declarations; | |
8 import dil.Token; | |
9 import dil.Parser, dil.Lexer; | |
10 import dil.File; | |
11 import dil.Module; | |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
12 import dil.Settings; |
391
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
13 import tango.text.Regex : RegExp = Regex; |
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
14 import tango.io.FilePath; |
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
15 import tango.io.FileConst; |
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
16 import tango.text.Util; |
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
17 import common; |
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
18 |
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
19 alias FileConst.PathSeparatorChar dirSep; |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
20 |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
21 enum IGraphOption |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
22 { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
23 None, |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
24 IncludeUnlocatableModules = 1, |
427
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
25 PrintDot = 1<<1, |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
26 HighlightCyclicEdges = 1<<2, |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
27 HighlightCyclicVertices = 1<<3, |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
28 GroupByPackageNames = 1<<4, |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
29 GroupByFullPackageName = 1<<5, |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
30 PrintPaths = 1<<6, |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
31 PrintList = 1<<7, |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
32 MarkCyclicModules = 1<<8, |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
33 } |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
34 |
370 | 35 string findModulePath(string moduleFQN, string[] importPaths) |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
36 { |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
37 string modulePath; |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
38 foreach (path; importPaths) |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
39 { |
391
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
40 modulePath = path ~ (path[$-1] == dirSep ? "" : [dirSep]) ~ moduleFQN ~ ".d"; |
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
41 // TODO: also check for *.di? |
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
42 if ((new FilePath(modulePath)).exists()) |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
43 return modulePath; |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
44 } |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
45 return null; |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
46 } |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
47 |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
48 class Edge |
370 | 49 { |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
50 Vertex outgoing; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
51 Vertex incoming; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
52 bool isCyclic; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
53 this(Vertex o, Vertex i) |
370 | 54 { |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
55 this.outgoing = o; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
56 this.incoming = i; |
370 | 57 } |
58 } | |
59 | |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
60 class Vertex : Module |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
61 { |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
62 uint id; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
63 Vertex[] incoming; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
64 bool isCyclic; /// Whether this vertex is in a cyclic relationship with other vertices. |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
65 |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
66 this(string filePath) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
67 { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
68 super(filePath, true); |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
69 } |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
70 |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
71 Vertex[] outgoing() |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
72 { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
73 return cast(Vertex[])super.modules; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
74 } |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
75 } |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
76 |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
77 void execute(string filePath, string[] importPaths, string[] strRegexps, uint levels, IGraphOption options) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
78 { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
79 // Init regular expressions. |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
80 RegExp[] regexps; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
81 foreach (strRegexp; strRegexps) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
82 regexps ~= new RegExp(strRegexp); |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
83 |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
84 // Add directory of file and global directories to import paths. |
391
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
85 auto fileDir = (new FilePath(filePath)).folder(); |
370 | 86 if (fileDir.length) |
87 importPaths ~= fileDir; | |
88 importPaths ~= GlobalSettings.importPaths; | |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
89 |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
90 Vertex[string] loadedModules; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
91 Vertex[] loadedModulesList; // Ordered list of loaded modules. |
370 | 92 Edge edges[]; |
364 | 93 |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
94 Vertex loadModule(string moduleFQNPath) |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
95 { |
370 | 96 auto mod_ = moduleFQNPath in loadedModules; |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
97 if (mod_ !is null) |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
98 return *mod_; // Return already loaded module. |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
99 |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
100 // Ignore module names matching regular expressions. |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
101 foreach (rx; regexps) |
391
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
102 if (rx.test(replace(moduleFQNPath, dirSep, '.'))) |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
103 return null; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
104 |
370 | 105 auto modulePath = findModulePath(moduleFQNPath, importPaths); |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
106 Vertex mod; |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
107 if (modulePath is null) |
370 | 108 { |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
109 if (options & IGraphOption.IncludeUnlocatableModules) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
110 { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
111 mod = new Vertex(null); |
391
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
112 mod.setFQN(replace(moduleFQNPath, dirSep, '.')); |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
113 loadedModules[moduleFQNPath] = mod; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
114 loadedModulesList ~= mod; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
115 mod.id = loadedModulesList.length -1; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
116 } |
370 | 117 } |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
118 else |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
119 { |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
120 // writefln(modulePath); |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
121 mod = new Vertex(modulePath); |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
122 mod.parse(); |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
123 |
370 | 124 loadedModules[moduleFQNPath] = mod; |
125 loadedModulesList ~= mod; | |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
126 mod.id = loadedModulesList.length -1; |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
127 |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
128 auto moduleFQNs = mod.getImports(); |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
129 |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
130 foreach (moduleFQN_; moduleFQNs) |
370 | 131 { |
132 auto loaded_mod = loadModule(moduleFQN_); | |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
133 if (loaded_mod !is null) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
134 { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
135 edges ~= new Edge(mod, loaded_mod); |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
136 mod.modules ~= loaded_mod; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
137 loaded_mod.incoming ~= mod; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
138 } |
370 | 139 } |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
140 } |
370 | 141 return mod; |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
142 } |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
143 |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
144 auto mod = new Vertex(filePath); |
365 | 145 mod.parse(); |
364 | 146 |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
147 auto moduleFQNs = mod.getImports(); |
364 | 148 |
370 | 149 loadedModules[mod.getFQNPath()] = mod; |
150 loadedModulesList ~= mod; | |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
151 mod.id = 0; // loadedModulesList.length -1 |
370 | 152 |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
153 foreach (moduleFQN_; moduleFQNs) |
370 | 154 { |
155 auto loaded_mod = loadModule(moduleFQN_); | |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
156 if (loaded_mod !is null) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
157 { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
158 edges ~= new Edge(mod, loaded_mod); |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
159 mod.modules ~= loaded_mod; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
160 loaded_mod.incoming ~= mod; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
161 } |
370 | 162 } |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
163 // Finished loading modules. |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
164 |
431
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
165 // Check that every module has at least one incoming or outgoing edge. |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
166 assert( |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
167 delegate { |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
168 foreach (mod; loadedModulesList) |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
169 if (mod.incoming.length == 0 && mod.outgoing.length == 0) |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
170 throw new Exception("module "~mod.getFQN()~" has no edges in the graph."); |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
171 return true; |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
172 }() == true |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
173 ); |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
174 |
427
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
175 if (options & (IGraphOption.PrintList | IGraphOption.PrintPaths)) |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
176 { |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
177 if (options & IGraphOption.MarkCyclicModules) |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
178 analyzeGraph(loadedModulesList, edges.dup); |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
179 |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
180 if (options & IGraphOption.PrintPaths) |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
181 printPaths(loadedModulesList, levels+1, ""); |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
182 else |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
183 printList(loadedModulesList, levels+1, ""); |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
184 } |
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
185 else |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
186 printDot(loadedModulesList, edges, options); |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
187 } |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
188 |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
189 void printPaths(Vertex[] vertices, uint level, char[] indent) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
190 { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
191 if (!level) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
192 return; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
193 foreach (vertex; vertices) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
194 { |
427
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
195 Stdout(indent)((vertex.isCyclic?"*":"")~vertex.filePath).newline; |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
196 if (vertex.outgoing.length) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
197 printPaths(vertex.outgoing, level-1, indent~" "); |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
198 } |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
199 } |
370 | 200 |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
201 void printList(Vertex[] vertices, uint level, char[] indent) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
202 { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
203 if (!level) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
204 return; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
205 foreach (vertex; vertices) |
370 | 206 { |
427
e2bbc6406a14
Added a new option '-m' to the igraph command.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
391
diff
changeset
|
207 Stdout(indent)((vertex.isCyclic?"*":"")~vertex.getFQN()).newline; |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
208 if (vertex.outgoing.length) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
209 printList(vertex.outgoing, level-1, indent~" "); |
370 | 210 } |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
211 } |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
212 |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
213 void printDot(Vertex[] loadedModulesList, Edge[] edges, IGraphOption options) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
214 { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
215 Vertex[][string] verticesByPckgName; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
216 if (options & IGraphOption.GroupByFullPackageName) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
217 foreach (module_; loadedModulesList) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
218 verticesByPckgName[module_.packageName] ~= module_; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
219 |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
220 if (options & (IGraphOption.HighlightCyclicVertices | |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
221 IGraphOption.HighlightCyclicEdges)) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
222 analyzeGraph(loadedModulesList, edges.dup); |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
223 |
391
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
224 Stdout("Digraph ModuleDependencies\n{\n"); |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
225 |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
226 if (options & IGraphOption.HighlightCyclicVertices) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
227 foreach (i, module_; loadedModulesList) |
391
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
228 Stdout.format(` n{0} [label="{1}"{2}];`, i, module_.getFQN(), (module_.isCyclic ? ",style=filled,fillcolor=tomato" : "")).newline; |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
229 else |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
230 foreach (i, module_; loadedModulesList) |
391
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
231 Stdout.format(` n{0} [label="{1}"];`, i, module_.getFQN()).newline; |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
232 |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
233 foreach (edge; edges) |
391
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
234 Stdout.format(` n{0} -> n{1}{2};`, edge.outgoing.id, edge.incoming.id, (edge.isCyclic ? "[color=red]" : "")).newline; |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
235 |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
236 if (options & IGraphOption.GroupByFullPackageName) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
237 foreach (packageName, vertices; verticesByPckgName) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
238 { |
391
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
239 Stdout.format(` subgraph "cluster_{0}" {`\n` label="{1}";color=blue;`"\n ", packageName, packageName); |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
240 foreach (module_; vertices) |
391
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
241 Stdout.format(`n{0};`, module_.id); |
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
242 Stdout("\n }\n"); |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
243 } |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
244 |
391
33b566df6af4
Migrated project to Tango.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
375
diff
changeset
|
245 Stdout("}\n"); |
364 | 246 } |
370 | 247 |
431
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
248 void analyzeGraph(Vertex[] vertices_init, Edge[] edges) |
370 | 249 { |
431
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
250 void recursive(Vertex[] vertices) |
370 | 251 { |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
252 foreach (idx, vertex; vertices) |
370 | 253 { |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
254 uint outgoing, incoming; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
255 foreach (j, edge; edges) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
256 { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
257 if (edge.outgoing is vertex) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
258 outgoing++; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
259 if (edge.incoming is vertex) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
260 incoming++; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
261 } |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
262 |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
263 if (outgoing == 0) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
264 { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
265 if (incoming != 0) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
266 { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
267 // Vertex is a sink. |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
268 alias outgoing i; // Reuse |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
269 alias incoming j; // Reuse |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
270 // Remove edges. |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
271 for (i=j=0; i < edges.length; i++) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
272 if (edges[i].incoming !is vertex) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
273 edges[j++] = edges[i]; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
274 edges.length = j; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
275 vertices = vertices[0..idx] ~ vertices[idx+1..$]; |
431
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
276 recursive(vertices); |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
277 return; |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
278 } |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
279 else |
431
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
280 { |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
281 // Edges to this vertex were removed previously. |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
282 // Only remove vertex now. |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
283 vertices = vertices[0..idx] ~ vertices[idx+1..$]; |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
284 recursive(vertices); |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
285 return; |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
286 } |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
287 } |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
288 else if (incoming == 0) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
289 { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
290 // Vertex is a source |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
291 alias outgoing i; // Reuse |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
292 alias incoming j; // Reuse |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
293 // Remove edges. |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
294 for (i=j=0; i < edges.length; i++) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
295 if (edges[i].outgoing !is vertex) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
296 edges[j++] = edges[i]; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
297 edges.length = j; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
298 vertices = vertices[0..idx] ~ vertices[idx+1..$]; |
431
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
299 recursive(vertices); |
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
300 return; |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
301 } |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
302 // else |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
303 // { |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
304 // // source && sink |
431
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
305 // // continue loop. |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
306 // } |
370 | 307 } |
308 | |
375
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
309 // When reaching this point it means only cylic edges and vertices are left. |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
310 foreach (vertex; vertices) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
311 vertex.isCyclic = true; |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
312 foreach (edge; edges) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
313 if (edge) |
0bd21b746a04
- Added code to main() for recognizing options to the importgraph command.
aziz
parents:
370
diff
changeset
|
314 edge.isCyclic = true; |
370 | 315 } |
431
7a6bfa569a52
Fix: analyzeGraph() should work correctly now.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
427
diff
changeset
|
316 recursive(vertices_init); |
370 | 317 } |