# HG changeset patch # User Aziz K?ksal # Date 1201463479 -3600 # Node ID bf10602159c179ff0baf049c37a768643c35c8bf # Parent e10838e0b18261986713270e6404783bb67dec47 Added static and public import styles to 'igraph' command. diff -r e10838e0b182 -r bf10602159c1 trunk/src/cmd/ImportGraph.d --- a/trunk/src/cmd/ImportGraph.d Sun Jan 27 18:21:42 2008 +0100 +++ b/trunk/src/cmd/ImportGraph.d Sun Jan 27 20:51:19 2008 +0100 @@ -32,23 +32,6 @@ MarkCyclicModules = 1<<8, } -string findModulePath(string moduleFQNPath, string[] importPaths) -{ - auto filePath = new FilePath(); - foreach (importPath; importPaths) - { - filePath.set(importPath); - filePath.append(moduleFQNPath); - foreach (moduleSuffix; [".d", ".di"/*interface file*/]) - { - filePath.suffix(moduleSuffix); - if (filePath.exists()) - return filePath.toString(); - } - } - return null; -} - class Graph { Vertex[] vertices; @@ -134,6 +117,23 @@ Status status; /// Used by the cycle detection algorithm. } +string findModuleFilePath(string moduleFQNPath, string[] importPaths) +{ + auto filePath = new FilePath(); + foreach (importPath; importPaths) + { + filePath.set(importPath); + filePath.append(moduleFQNPath); + foreach (moduleSuffix; [".d", ".di"/*interface file*/]) + { + filePath.suffix(moduleSuffix); + if (filePath.exists()) + return filePath.toString(); + } + } + return null; +} + class GraphBuilder { Graph graph; @@ -174,7 +174,7 @@ } // Locate the module in the file system. - auto moduleFilePath = findModulePath(moduleFQNPath, importPaths); + auto moduleFilePath = findModuleFilePath(moduleFQNPath, importPaths); Vertex vertex; @@ -222,7 +222,8 @@ } } -void execute(string filePathString, string[] importPaths, string[] strRegexps, uint levels, IGraphOption options) +void execute(string filePathString, string[] importPaths, string[] strRegexps, + uint levels, string siStyle, string piStyle, IGraphOption options) { // Init regular expressions. RegExp[] regexps; @@ -262,7 +263,7 @@ printModuleList(graph.vertices, levels+1, ""); } else - printDotDocument(graph, options); + printDotDocument(graph, siStyle, piStyle, options); } void printModulePaths(Vertex[] vertices, uint level, char[] indent) @@ -289,7 +290,8 @@ } } -void printDotDocument(Graph graph, IGraphOption options) +void printDotDocument(Graph graph, string siStyle, string piStyle, + IGraphOption options) { Vertex[][string] verticesByPckgName; if (options & IGraphOption.GroupByFullPackageName) @@ -306,9 +308,22 @@ // 'i' and vertex.id should be the same. foreach (i, vertex; graph.vertices) Stdout.formatln(` n{} [label="{}"{}];`, i, vertex.modul.getFQN(), (vertex.isCyclic ? ",style=filled,fillcolor=tomato" : "")); + // Output edges. foreach (edge; graph.edges) - Stdout.formatln(` n{} -> n{}{};`, edge.from.id, edge.to.id, (edge.isCyclic ? "[color=red]" : "")); + { + string edgeStyles = ""; + if (edge.isStatic || edge.isPublic) + { + edgeStyles = `[style="`; + edge.isStatic && (edgeStyles ~= siStyle ~ ","); + edge.isPublic && (edgeStyles ~= piStyle); + edgeStyles[$-1] == ',' && (edgeStyles = edgeStyles[0..$-1]); // Remove last comma. + edgeStyles ~= `"]`; + } + edge.isCyclic && (edgeStyles ~= "[color=red]"); + Stdout.formatln(` n{} -> n{} {};`, edge.from.id, edge.to.id, edgeStyles); + } if (options & IGraphOption.GroupByFullPackageName) foreach (packageName, vertices; verticesByPckgName) diff -r e10838e0b182 -r bf10602159c1 trunk/src/main.d --- a/trunk/src/main.d Sun Jan 27 18:21:42 2008 +0100 +++ b/trunk/src/main.d Sun Jan 27 20:51:19 2008 +0100 @@ -106,6 +106,8 @@ string filePath; string[] includePaths; string[] regexps; + string siStyle = "dashed"; // static import style + string piStyle = "bold"; // public import style uint levels; IGraphOption options; foreach (arg; args[2..$]) @@ -116,6 +118,10 @@ regexps ~= arg[2..$]; else if(strbeg(arg, "-l")) levels = Integer.toInt(arg[2..$]); + else if(strbeg(arg, "-si")) + siStyle = arg[3..$]; + else if(strbeg(arg, "-pi")) + piStyle = arg[3..$]; else switch (arg) { @@ -141,7 +147,7 @@ filePath = arg; } } - cmd.ImportGraph.execute(filePath, includePaths, regexps, levels, options); + cmd.ImportGraph.execute(filePath, includePaths, regexps, levels, siStyle, piStyle, options); break; case "stats", "statistics": char[][] filePaths; @@ -307,7 +313,40 @@ msg = GetMsg(MID.HelpGenerate); break; case "importgraph", "igraph": - msg = GetMsg(MID.HelpImportGraph); +// msg = GetMsg(MID.HelpImportGraph); + msg = `Parse a module and build a module dependency graph based on its imports. +Usage: + dil igraph file.d Format [Options] + + The directory of file.d is implicitly added to the list of import paths. + +Format: + --dot : generate a dot document + Options related to --dot: + -gbp : Group modules by package names + -gbf : Group modules by full package name + -hle : highlight cyclic edges in the graph + -hlv : highlight modules in cyclic relationships + -siSTYLE : the edge style to use for static imports + -piSTYLE : the edge style to use for public imports + STYLE can be: "dashed", "dotted", "solid", "invis" or "bold" + + --paths : print the file paths of the modules in the graph + + --list : print the names of the module in the graph + Options common to --paths and --list: + -lN : print N levels. + -m : use '*' to mark modules in cyclic relationships + +Options: + -Ipath : add 'path' to the list of import paths where modules are + looked for + -rREGEXP : exclude modules whose names match the regular expression + REGEXP + -i : include unlocatable modules + +Example: + dil igraph src/main.d`; break; case "tok", "tokenize": msg = `Print the tokens of a D source file.