# HG changeset patch # User Aziz K?ksal # Date 1205077186 -3600 # Node ID 7e84472f4e917462e4682a8b532825a725120e09 # Parent 28e1ff1dcfcf7f9be1c345e80bf9ef267593ac80 Refactored the importgraph command. diff -r 28e1ff1dcfcf -r 7e84472f4e91 src/cmd/ImportGraph.d --- a/src/cmd/ImportGraph.d Sun Mar 09 16:10:25 2008 +0100 +++ b/src/cmd/ImportGraph.d Sun Mar 09 16:39:46 2008 +0100 @@ -20,19 +20,79 @@ alias FileConst.PathSeparatorChar dirSep; -/// Options for the importgraph command. -enum IGraphOption +/// The importgraph command. +struct IGraphCommand { - None, - IncludeUnlocatableModules = 1, - PrintDot = 1<<1, - HighlightCyclicEdges = 1<<2, - HighlightCyclicVertices = 1<<3, - GroupByPackageNames = 1<<4, - GroupByFullPackageName = 1<<5, - PrintPaths = 1<<6, - PrintList = 1<<7, - MarkCyclicModules = 1<<8, + /// Options for the command. + enum Option + { + None, + IncludeUnlocatableModules = 1, + PrintDot = 1<<1, + HighlightCyclicEdges = 1<<2, + HighlightCyclicVertices = 1<<3, + GroupByPackageNames = 1<<4, + GroupByFullPackageName = 1<<5, + PrintPaths = 1<<6, + PrintList = 1<<7, + MarkCyclicModules = 1<<8, + } + alias Option Options; + + Options options; /// Command options. + string filePath; /// File path to the root module. + string[] regexps; /// Regular expressions. + string siStyle = "dashed"; /// Static import style. + string piStyle = "bold"; /// Public import style. + uint levels; /// How many levels to print. + + CompilationContext context; + + /// Adds o to the options. + void add(Option o) + { + options |= o; + } + + void run() + { + // Init regular expressions. + RegExp[] regexps; + foreach (strRegexp; this.regexps) + regexps ~= new RegExp(strRegexp); + + // Add the directory of the file to the import paths. + auto filePath = new FilePath(this.filePath); + auto fileDir = filePath.folder(); + context.importPaths ~= fileDir; + + auto gbuilder = new GraphBuilder; + + gbuilder.importPaths = context.importPaths; + gbuilder.options = options; + gbuilder.filterPredicate = (string moduleFQNPath) { + foreach (rx; regexps) + // Replace slashes: dil/ast/Node -> dil.ast.Node + if (rx.test(replace(moduleFQNPath.dup, dirSep, '.'))) + return true; + return false; + }; + + auto graph = gbuilder.start(filePath.name()); + + if (options & (Option.PrintList | Option.PrintPaths)) + { + if (options & Option.MarkCyclicModules) + graph.detectCycles(); + + if (options & Option.PrintPaths) + printModulePaths(graph.vertices, levels+1, ""); + else + printModuleList(graph.vertices, levels+1, ""); + } + else + printDotDocument(graph, siStyle, piStyle, options); + } } /// Represents a module dependency graph. @@ -148,7 +208,7 @@ class GraphBuilder { Graph graph; - IGraphOption options; + IGraphCommand.Options options; string[] importPaths; /// Where to look for modules. Vertex[string] loadedModulesTable; /// Maps FQN paths to modules. bool delegate(string) filterPredicate; @@ -192,7 +252,7 @@ if (moduleFilePath is null) { // Module not found. - if (options & IGraphOption.IncludeUnlocatableModules) + if (options & IGraphCommand.Option.IncludeUnlocatableModules) { // Include module nevertheless. vertex = new Vertex; vertex.modul = new Module(""); @@ -234,48 +294,6 @@ } } -/// Executes the importgraph command. -void execute(string filePathString, CompilationContext context, string[] strRegexps, - uint levels, string siStyle, string piStyle, IGraphOption options) -{ - // Init regular expressions. - RegExp[] regexps; - foreach (strRegexp; strRegexps) - regexps ~= new RegExp(strRegexp); - - // Add the directory of the file to the import paths. - auto filePath = new FilePath(filePathString); - auto fileDir = filePath.folder(); - context.importPaths ~= fileDir; - - auto gbuilder = new GraphBuilder; - - gbuilder.importPaths = context.importPaths; - gbuilder.options = options; - gbuilder.filterPredicate = (string moduleFQNPath) { - foreach (rx; regexps) - // Replace slashes: dil/ast/Node -> dil.ast.Node - if (rx.test(replace(moduleFQNPath.dup, dirSep, '.'))) - return true; - return false; - }; - - auto graph = gbuilder.start(filePath.name()); - - if (options & (IGraphOption.PrintList | IGraphOption.PrintPaths)) - { - if (options & IGraphOption.MarkCyclicModules) - graph.detectCycles(); - - if (options & IGraphOption.PrintPaths) - printModulePaths(graph.vertices, levels+1, ""); - else - printModuleList(graph.vertices, levels+1, ""); - } - else - printDotDocument(graph, siStyle, piStyle, options); -} - /// Prints the file paths to the modules. void printModulePaths(Vertex[] vertices, uint level, char[] indent) { @@ -304,15 +322,15 @@ /// Prints the graph as a graphviz dot document. void printDotDocument(Graph graph, string siStyle, string piStyle, - IGraphOption options) + IGraphCommand.Options options) { Vertex[][string] verticesByPckgName; - if (options & IGraphOption.GroupByFullPackageName) + if (options & IGraphCommand.Option.GroupByFullPackageName) foreach (vertex; graph.vertices) verticesByPckgName[vertex.modul.packageName] ~= vertex; - if (options & (IGraphOption.HighlightCyclicVertices | - IGraphOption.HighlightCyclicEdges)) + if (options & (IGraphCommand.Option.HighlightCyclicVertices | + IGraphCommand.Option.HighlightCyclicEdges)) graph.detectCycles(); // Output header of the dot document. @@ -338,7 +356,7 @@ Stdout.formatln(` n{} -> n{} {};`, edge.from.id, edge.to.id, edgeStyles); } - if (options & IGraphOption.GroupByFullPackageName) + if (options & IGraphCommand.Option.GroupByFullPackageName) foreach (packageName, vertices; verticesByPckgName) { // Output nodes in a cluster. Stdout.format(` subgraph "cluster_{}" {`\n` label="{}";color=blue;`"\n ", packageName, packageName); diff -r 28e1ff1dcfcf -r 7e84472f4e91 src/main.d --- a/src/main.d Sun Mar 09 16:10:25 2008 +0100 +++ b/src/main.d Sun Mar 09 16:39:46 2008 +0100 @@ -156,53 +156,52 @@ infoMan.hasInfo && printErrors(infoMan); break; case "importgraph", "igraph": - string filePath; - string[] regexps; - string siStyle = "dashed"; // static import style - string piStyle = "bold"; // public import style - uint levels; - IGraphOption options; - auto context = newCompilationContext(); + if (args.length < 3) + return printHelp("hl"); + + IGraphCommand cmd; + cmd.context = newCompilationContext(); + foreach (arg; args[2..$]) { - if (parseDebugOrVersion(arg, context)) + if (parseDebugOrVersion(arg, cmd.context)) {} else if (strbeg(arg, "-I")) - context.importPaths ~= arg[2..$]; - else if(strbeg(arg, "-r")) - regexps ~= arg[2..$]; + cmd.context.importPaths ~= arg[2..$]; + else if(strbeg(arg, "-x")) + cmd.regexps ~= arg[2..$]; else if(strbeg(arg, "-l")) - levels = Integer.toInt(arg[2..$]); + cmd.levels = Integer.toInt(arg[2..$]); else if(strbeg(arg, "-si")) - siStyle = arg[3..$]; + cmd.siStyle = arg[3..$]; else if(strbeg(arg, "-pi")) - piStyle = arg[3..$]; + cmd.piStyle = arg[3..$]; else switch (arg) { case "--dot": - options |= IGraphOption.PrintDot; break; + cmd.add(IGraphCommand.Option.PrintDot); break; case "--paths": - options |= IGraphOption.PrintPaths; break; + cmd.add(IGraphCommand.Option.PrintPaths); break; case "--list": - options |= IGraphOption.PrintList; break; + cmd.add(IGraphCommand.Option.PrintList); break; case "-i": - options |= IGraphOption.IncludeUnlocatableModules; break; + cmd.add(IGraphCommand.Option.IncludeUnlocatableModules); break; case "-hle": - options |= IGraphOption.HighlightCyclicEdges; break; + cmd.add(IGraphCommand.Option.HighlightCyclicEdges); break; case "-hlv": - options |= IGraphOption.HighlightCyclicVertices; break; + cmd.add(IGraphCommand.Option.HighlightCyclicVertices); break; case "-gbp": - options |= IGraphOption.GroupByPackageNames; break; + cmd.add(IGraphCommand.Option.GroupByPackageNames); break; case "-gbf": - options |= IGraphOption.GroupByFullPackageName; break; + cmd.add(IGraphCommand.Option.GroupByFullPackageName); break; case "-m": - options |= IGraphOption.MarkCyclicModules; break; + cmd.add(IGraphCommand.Option.MarkCyclicModules); break; default: - filePath = arg; + cmd.filePath = arg; } } - cmd.ImportGraph.execute(filePath, context, regexps, levels, siStyle, piStyle, options); + cmd.run(); break; case "stats", "statistics": char[][] filePaths; @@ -503,7 +502,7 @@ Options: -Ipath : add 'path' to the list of import paths where modules are looked for - -rREGEXP : exclude modules whose names match the regular expression + -xREGEXP : exclude modules whose names match the regular expression REGEXP -i : include unlocatable modules