Mercurial > projects > dil
annotate trunk/src/cmd/ImportGraph.d @ 370:ae4afb66768f
- Renamed findModule() to findModulePath().
- Added struct Edge.
- Fix: don't append fileDir to importPaths when it's empty.
- Added function findCyclicEdges().
- Added method getFQN() to class ModuleDeclaration.
- Added member moduleFQN to class Module.
- Renamed Module.fileName to filePath.
- Added method setFQN() to class Module.
- Fix in Lexer.scanspecialTokenSequence(): corrected MID.
author | aziz |
---|---|
date | Mon, 03 Sep 2007 16:29:02 +0000 |
parents | 2adf808343d6 |
children | 0bd21b746a04 |
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; |
366 | 13 import std.stdio : writefln; |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
14 import std.path : getDirName, dirSep = sep; |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
15 import std.file : exists; |
370 | 16 import std.string : replace; |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
17 |
370 | 18 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
|
19 { |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
20 string modulePath; |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
21 foreach (path; importPaths) |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
22 { |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
23 modulePath = path ~ (path[$-1] == dirSep[0] ? "" : dirSep) ~ moduleFQN ~ ".d"; |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
24 if (exists(modulePath)) |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
25 return modulePath; |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
26 } |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
27 return null; |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
28 } |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
29 |
370 | 30 struct Edge |
31 { | |
32 Module outgoing; | |
33 Module incoming; | |
34 static Edge opCall(Module o, Module i) | |
35 { | |
36 Edge e; | |
37 e.outgoing = o; | |
38 e.incoming = i; | |
39 return e; | |
40 } | |
41 } | |
42 | |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
43 void execute(string fileName, string[] importPaths) |
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 // Add directory of file and global directories to import paths. |
370 | 46 auto fileDir = getDirName(fileName); |
47 if (fileDir.length) | |
48 importPaths ~= fileDir; | |
49 importPaths ~= GlobalSettings.importPaths; | |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
50 |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
51 Module[string] loadedModules; |
370 | 52 Module[] loadedModulesList; // Ordered list of loaded modules. |
53 Edge edges[]; | |
364 | 54 |
370 | 55 Module loadModule(string moduleFQNPath) |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
56 { |
370 | 57 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
|
58 if (mod_ !is null) |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
59 return *mod_; |
368 | 60 // writefln(moduleFQN); |
370 | 61 auto modulePath = findModulePath(moduleFQNPath, importPaths); |
62 Module mod; | |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
63 if (modulePath is null) |
370 | 64 { |
65 // writefln("Warning: Module %s.d couldn't be found.", moduleFQNPath); | |
66 mod = new Module(null, true); | |
67 mod.setFQN(replace(moduleFQNPath, dirSep, ".")); | |
68 loadedModules[moduleFQNPath] = mod; | |
69 loadedModulesList ~= mod; | |
70 } | |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
71 else |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
72 { |
370 | 73 mod = new Module(modulePath, true); |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
74 mod.parse(); |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
75 |
370 | 76 loadedModules[moduleFQNPath] = mod; |
77 loadedModulesList ~= mod; | |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
78 |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
79 auto moduleFQNs = mod.getImports(); |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
80 |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
81 foreach (moduleFQN_; moduleFQNs) |
370 | 82 { |
83 auto loaded_mod = loadModule(moduleFQN_); | |
84 edges ~= Edge(mod, loaded_mod); | |
85 mod.modules ~= loaded_mod; | |
86 } | |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
87 return mod; |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
88 } |
370 | 89 return mod; |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
90 } |
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
91 |
368 | 92 auto mod = new Module(fileName, true); |
365 | 93 mod.parse(); |
364 | 94 |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
95 auto moduleFQNs = mod.getImports(); |
364 | 96 |
370 | 97 loadedModules[mod.getFQNPath()] = mod; |
98 loadedModulesList ~= mod; | |
99 | |
367
dda55fae37de
- ImportGraph.execute() can parse all modules depending on the imports of the root module.
aziz
parents:
366
diff
changeset
|
100 foreach (moduleFQN_; moduleFQNs) |
370 | 101 { |
102 auto loaded_mod = loadModule(moduleFQN_); | |
103 edges ~= Edge(mod, loaded_mod); | |
104 mod.modules ~= loaded_mod; | |
105 } | |
106 | |
107 writefln("digraph module_dependencies\n{"); | |
108 foreach (edge; edges) | |
109 { | |
110 writefln(` "%s" -> "%s"`, edge.outgoing.getFQN(), edge.incoming.getFQN()); | |
111 } | |
112 writefln("}"); | |
364 | 113 } |
370 | 114 |
115 Edge[] findCyclicEdges(Module[] modules, Edge[] edges) | |
116 { | |
117 foreach (module_; modules) | |
118 { | |
119 uint outgoing, incoming; | |
120 foreach (edge; edges) | |
121 { | |
122 if (edge.outgoing == module_) | |
123 outgoing++; | |
124 if (edge.incoming == module_) | |
125 incoming++; | |
126 } | |
127 | |
128 if (outgoing == 0) | |
129 { | |
130 if (incoming != 0) | |
131 { | |
132 // sink | |
133 } | |
134 else | |
135 assert(0); // orphaned vertex (module) in graph | |
136 } | |
137 else if (incoming == 0) | |
138 { | |
139 // source | |
140 } | |
141 else | |
142 { | |
143 // source && sink | |
144 } | |
145 } | |
146 return null; | |
147 } |