Mercurial > projects > dil
diff 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 |
line wrap: on
line diff
--- a/trunk/src/cmd/ImportGraph.d Sat Sep 01 19:58:01 2007 +0000 +++ b/trunk/src/cmd/ImportGraph.d Mon Sep 03 16:29:02 2007 +0000 @@ -13,8 +13,9 @@ import std.stdio : writefln; import std.path : getDirName, dirSep = sep; import std.file : exists; +import std.string : replace; -string findModule(string moduleFQN, string[] importPaths) +string findModulePath(string moduleFQN, string[] importPaths) { string modulePath; foreach (path; importPaths) @@ -26,36 +27,66 @@ return null; } +struct Edge +{ + Module outgoing; + Module incoming; + static Edge opCall(Module o, Module i) + { + Edge e; + e.outgoing = o; + e.incoming = i; + return e; + } +} + void execute(string fileName, string[] importPaths) { // Add directory of file and global directories to import paths. - importPaths ~= getDirName(fileName) ~ GlobalSettings.importPaths; + auto fileDir = getDirName(fileName); + if (fileDir.length) + importPaths ~= fileDir; + importPaths ~= GlobalSettings.importPaths; Module[string] loadedModules; + Module[] loadedModulesList; // Ordered list of loaded modules. + Edge edges[]; - Module loadModule(string moduleFQN) + Module loadModule(string moduleFQNPath) { - auto mod_ = moduleFQN in loadedModules; + auto mod_ = moduleFQNPath in loadedModules; if (mod_ !is null) return *mod_; // writefln(moduleFQN); - auto modulePath = findModule(moduleFQN, importPaths); + auto modulePath = findModulePath(moduleFQNPath, importPaths); + Module mod; if (modulePath is null) - writefln("Warning: Module %s.d couldn't be found.", moduleFQN); + { +// writefln("Warning: Module %s.d couldn't be found.", moduleFQNPath); + mod = new Module(null, true); + mod.setFQN(replace(moduleFQNPath, dirSep, ".")); + loadedModules[moduleFQNPath] = mod; + loadedModulesList ~= mod; + } else { - auto mod = new Module(modulePath, true); + mod = new Module(modulePath, true); mod.parse(); - loadedModules[moduleFQN] = mod; + loadedModules[moduleFQNPath] = mod; + loadedModulesList ~= mod; auto moduleFQNs = mod.getImports(); foreach (moduleFQN_; moduleFQNs) - mod.modules ~= loadModule(moduleFQN_); + { + auto loaded_mod = loadModule(moduleFQN_); + edges ~= Edge(mod, loaded_mod); + mod.modules ~= loaded_mod; + } return mod; } - return null; + return mod; } auto mod = new Module(fileName, true); @@ -63,6 +94,54 @@ auto moduleFQNs = mod.getImports(); + loadedModules[mod.getFQNPath()] = mod; + loadedModulesList ~= mod; + foreach (moduleFQN_; moduleFQNs) - mod.modules ~= loadModule(moduleFQN_); + { + auto loaded_mod = loadModule(moduleFQN_); + edges ~= Edge(mod, loaded_mod); + mod.modules ~= loaded_mod; + } + + writefln("digraph module_dependencies\n{"); + foreach (edge; edges) + { + writefln(` "%s" -> "%s"`, edge.outgoing.getFQN(), edge.incoming.getFQN()); + } + writefln("}"); } + +Edge[] findCyclicEdges(Module[] modules, Edge[] edges) +{ + foreach (module_; modules) + { + uint outgoing, incoming; + foreach (edge; edges) + { + if (edge.outgoing == module_) + outgoing++; + if (edge.incoming == module_) + incoming++; + } + + if (outgoing == 0) + { + if (incoming != 0) + { + // sink + } + else + assert(0); // orphaned vertex (module) in graph + } + else if (incoming == 0) + { + // source + } + else + { + // source && sink + } + } + return null; +}