# HG changeset patch # User Jari-Matti M?kel? # Date 1202060633 -7200 # Node ID ec8dd7b8bf0c8bc3a8a40cca7f16abe9615bc9e2 # Parent 41cad5ca4863d2b88c622000b35fc60bb5aeffae Updated graph type. diff -r 41cad5ca4863 -r ec8dd7b8bf0c trunk/src/docgen/docgen.d --- a/trunk/src/docgen/docgen.d Sat Feb 02 23:17:14 2008 +0100 +++ b/trunk/src/docgen/docgen.d Sun Feb 03 19:43:53 2008 +0200 @@ -36,15 +36,19 @@ options.parser.importPaths = args[2..$-1]; options.outputDir = args[$-1]; + alias DepGraph.Vertex Vertex; + alias DepGraph.Edge Edge; + Module[] cachedModules; - Edge[] cachedEdges; - Vertex[char[]] cachedVertices; + DepGraph cachedGraph; - void parser(ref Module[] modules, ref Edge[] edges, ref Vertex[char[]] vertices) { - if (cachedModules != null) { + void parser(ref Module[] modules, ref DepGraph depGraph) { + Edge[] edges; + Vertex[char[]] vertices; + + if (cachedGraph != null) { modules = cachedModules; - edges = cachedEdges; - vertices = cachedVertices; + depGraph = cachedGraph; return; } @@ -61,13 +65,10 @@ if (fqn in vertices) { debug Stdout.format("{} already set.\n", fqn); return; - } auto vertex = new Vertex(fqn, path, id++); - vertex.type = VertexType.UnlocatableModule; vertices[fqn] = vertex; debug Stdout.format("Setting {} = {}.\n", fqn, path); - } else { vertices[m.moduleFQN] = new Vertex(m.moduleFQN, m.filePath, id++); debug Stdout.format("Setting {} = {}.\n", m.moduleFQN, m.filePath); @@ -76,8 +77,7 @@ (Module imported, Module importer, bool isPublic) { debug Stdout.format("Connecting {} - {}.\n", imported.moduleFQN, importer.moduleFQN); auto edge = vertices[imported.moduleFQN].addChild(vertices[importer.moduleFQN]); - edge.type = isPublic ? EdgeType.PublicDependency : EdgeType.Dependency; - edge.type = id % 2 ? EdgeType.PublicDependency : EdgeType.Dependency; // FIXME: temporary feature for demonstrating public imports + edge.isPublic = isPublic; edges ~= edge; }, modules @@ -87,9 +87,11 @@ (Module a, Module b){ return icompare(a.moduleFQN, b.moduleFQN); } ); - cachedVertices = vertices; + depGraph.edges = edges; + depGraph.vertices = vertices.values; + + cachedGraph = depGraph; cachedModules = modules; - cachedEdges = edges; } GraphCache graphcache = new DefaultGraphCache(); diff -r 41cad5ca4863 -r ec8dd7b8bf0c trunk/src/docgen/document/generator.d --- a/trunk/src/docgen/document/generator.d Sat Feb 02 23:17:14 2008 +0100 +++ b/trunk/src/docgen/document/generator.d Sun Feb 03 19:43:53 2008 +0200 @@ -18,7 +18,7 @@ debug import tango.io.Stdout; -alias void delegate(ref Module[], ref Edge[], ref Vertex[char[]]) ParserDg; +alias void delegate(ref Module[], ref DepGraph) ParserDg; abstract class DefaultDocGenerator : DocGenerator { protected: @@ -37,8 +37,7 @@ ModuleDocWriterFactory moduleDocFactory; Module[] modules; - Edge[] edges; - Vertex[char[]] vertices; + DepGraph depGraph; public: @@ -100,7 +99,8 @@ } void parseSources() { - m_parser(modules, edges, vertices); + depGraph = new DepGraph(); + m_parser(modules, depGraph); } //--- diff -r 41cad5ca4863 -r ec8dd7b8bf0c trunk/src/docgen/document/htmlgenerator.d --- a/trunk/src/docgen/document/htmlgenerator.d Sat Feb 02 23:17:14 2008 +0100 +++ b/trunk/src/docgen/document/htmlgenerator.d Sun Feb 03 19:43:53 2008 +0200 @@ -57,7 +57,9 @@ * Generates document skeleton. */ void generateDoc() { - writeSimpleFile(docFileNames[0], { docWriter.generateFirstPage(); }); + writeSimpleFile(docFileNames[0], { + docWriter.generateFirstPage(); + }); /* writeSimpleFile(docFileNames[1], { docWriter.generateTOC(modules); @@ -69,7 +71,9 @@ * Generates a global style sheet. */ void generateStyleSheet() { - writeSimpleFile(styleSheetFile, { docWriter.generateCustomPage("stylesheet"); } ); + writeSimpleFile(styleSheetFile, { + docWriter.generateCustomPage("stylesheet"); + }); } /** @@ -142,7 +146,7 @@ auto imgFile = outputFile(depGraphFile); auto writer = graphFactory.createGraphWriter( docWriter, GraphFormat.Dot ); - writer.generateDepGraph(vertices.values, edges, imgFile); + writer.generateDepGraph(depGraph, imgFile); imgFile.close(); diff -r 41cad5ca4863 -r ec8dd7b8bf0c trunk/src/docgen/document/latexgenerator.d --- a/trunk/src/docgen/document/latexgenerator.d Sat Feb 02 23:17:14 2008 +0100 +++ b/trunk/src/docgen/document/latexgenerator.d Sun Feb 03 19:43:53 2008 +0200 @@ -113,7 +113,7 @@ auto imgFile = outputFile(depGraphFile); auto writer = graphFactory.createGraphWriter( docWriter, GraphFormat.Dot ); - writer.generateDepGraph(vertices.values, edges, imgFile); + writer.generateDepGraph(depGraph, imgFile); imgFile.close(); }); diff -r 41cad5ca4863 -r ec8dd7b8bf0c trunk/src/docgen/document/plaintextgenerator.d --- a/trunk/src/docgen/document/plaintextgenerator.d Sat Feb 02 23:17:14 2008 +0100 +++ b/trunk/src/docgen/document/plaintextgenerator.d Sun Feb 03 19:43:53 2008 +0200 @@ -55,7 +55,9 @@ * Generates document skeleton. */ void generateDoc() { - writeSimpleFile(docFileNames[0], { docWriter.generateFirstPage(); }); + writeSimpleFile(docFileNames[0], { + docWriter.generateFirstPage(); + }); writeSimpleFile(docFileNames[1], { docWriter.generateTOC(modules); @@ -111,7 +113,7 @@ auto imgFile = outputFile(depGraphFile); auto writer = graphFactory.createGraphWriter( docWriter, GraphFormat.Dot ); - writer.generateDepGraph(vertices.values, edges, imgFile); + writer.generateDepGraph(depGraph, imgFile); imgFile.close(); }); diff -r 41cad5ca4863 -r ec8dd7b8bf0c trunk/src/docgen/graphutils/dotwriter.d --- a/trunk/src/docgen/graphutils/dotwriter.d Sat Feb 02 23:17:14 2008 +0100 +++ b/trunk/src/docgen/graphutils/dotwriter.d Sun Feb 03 19:43:53 2008 +0200 @@ -22,21 +22,24 @@ super(factory, writer); } - void generateDepGraph(Vertex[] vertices, Edge[] edges, OutputStream imageFile) { + void generateDepGraph(DepGraph depGraph, OutputStream imageFile) { generateImageTag(imageFile); - auto image = generateDepImageFile(vertices, edges); + auto image = generateDepImageFile(depGraph); auto printer = new Print!(char)(new Layout!(char), imageFile); printer(image); } protected: - char[] generateDepImageFile(Vertex[] vertices, Edge[] edges) { + char[] generateDepImageFile(DepGraph depGraph) { char[] image; auto sprint = new Sprint!(char); + + auto edges = depGraph.edges; + auto vertices = depGraph.vertices; - Vertex[][char[]] verticesByPckgName; + DepGraph.Vertex[][char[]] verticesByPckgName; if (factory.options.graph.groupByFullPackageName || factory.options.graph.groupByPackageNames) { foreach (mod; vertices) { @@ -51,7 +54,7 @@ if (factory.options.graph.highlightCyclicVertices || factory.options.graph.highlightCyclicEdges) - findCycles(vertices, edges); + depGraph.markCycles(); image ~= "Digraph ModuleDependencies {\n"; @@ -65,9 +68,9 @@ ` n{} [label="{}",style=filled,fillcolor={}];`\n, module_.id, nodeName, - module_.isCyclic && factory.options.graph.highlightCyclicVertices ? + module_.cyclic && factory.options.graph.highlightCyclicVertices ? factory.options.graph.cyclicNodeColor : - module_.type == VertexType.UnlocatableModule ? + module_.incoming.length == 0 && module_.outgoing.length == 0 ? factory.options.graph.unlocatableNodeColor : factory.options.graph.nodeColor ); @@ -78,9 +81,9 @@ ` n{} -> n{}[color={}];`\n, edge.outgoing.id, edge.incoming.id, - edge.isCyclic ? + edge.cyclic ? factory.options.graph.cyclicDepColor : - edge.type == EdgeType.PublicDependency ? + edge.isPublic ? factory.options.graph.publicDepColor ~ ",style=bold" : factory.options.graph.depColor ); @@ -148,18 +151,18 @@ this.factory = factory; } - override void generateDepGraph(Vertex[] vertices, Edge[] edges, OutputStream imageFile) { + override void generateDepGraph(DepGraph depGraph, OutputStream imageFile) { generateImageTag(imageFile); - auto cached = factory.graphCache.getCachedGraph(vertices, edges, GraphFormat.Dot); + auto cached = factory.graphCache.getCachedGraph(depGraph, GraphFormat.Dot); auto printer = new Print!(char)(new Layout!(char), imageFile); if (cached) { printer(cached); } else { - auto image = generateDepImageFile(vertices, edges); - factory.graphCache.setCachedGraph(vertices, edges, GraphFormat.Dot, image); + auto image = generateDepImageFile(depGraph); + factory.graphCache.setCachedGraph(depGraph, GraphFormat.Dot, image); printer(image); } } diff -r 41cad5ca4863 -r ec8dd7b8bf0c trunk/src/docgen/graphutils/modulenamewriter.d --- a/trunk/src/docgen/graphutils/modulenamewriter.d Sat Feb 02 23:17:14 2008 +0100 +++ b/trunk/src/docgen/graphutils/modulenamewriter.d Sun Feb 03 19:43:53 2008 +0200 @@ -15,10 +15,13 @@ super(factory, writer); } - void generateDepGraph(Vertex[] vertices, Edge[] edges, OutputStream imageFile) { + void generateDepGraph(DepGraph depGraph, OutputStream imageFile) { char[][] contents; - void doList(Vertex[] v, uint level) { + auto edges = depGraph.edges; + auto vertices = depGraph.vertices; + + void doList(DepGraph.Vertex[] v, uint level) { if (!level) return; contents ~= "("; diff -r 41cad5ca4863 -r ec8dd7b8bf0c trunk/src/docgen/graphutils/modulepathwriter.d --- a/trunk/src/docgen/graphutils/modulepathwriter.d Sat Feb 02 23:17:14 2008 +0100 +++ b/trunk/src/docgen/graphutils/modulepathwriter.d Sun Feb 03 19:43:53 2008 +0200 @@ -15,10 +15,13 @@ super(factory, writer); } - void generateDepGraph(Vertex[] vertices, Edge[] edges, OutputStream imageFile) { + void generateDepGraph(DepGraph depGraph, OutputStream imageFile) { char[][] contents; - void doList(Vertex[] v, uint level) { + auto edges = depGraph.edges; + auto vertices = depGraph.vertices; + + void doList(DepGraph.Vertex[] v, uint level) { if (!level) return; contents ~= "("; diff -r 41cad5ca4863 -r ec8dd7b8bf0c trunk/src/docgen/graphutils/primitives.d --- a/trunk/src/docgen/graphutils/primitives.d Sat Feb 02 23:17:14 2008 +0100 +++ b/trunk/src/docgen/graphutils/primitives.d Sun Feb 03 19:43:53 2008 +0200 @@ -4,99 +4,139 @@ */ module docgen.graphutils.primitives; -enum EdgeType { - Unspecified, - Aggregation, - Association, - Composition, - Dependency, - Generalization, - Inheritance, - PublicDependency -} +/** + * Extendible graph class. Should support separation of concerns now better with mixins. + * Provides a method for cycle marking. + */ +class Graph(alias V, alias E, int capacity = 1) { + static class Edge { + Vertex outgoing, incoming; + //bool cyclic = true; -enum CycleType { - Unspecified, - Cyclefree, - Cyclic, - Reserved -} + this(Vertex o, Vertex i) { + outgoing = o; + incoming = i; + o.outgoingEdges ~= this; + i.incomingEdges ~= this; + } -class Edge { - Vertex outgoing; - Vertex incoming; - EdgeType type; - CycleType cycleType; // used by the cycle algorithm + bool cyclic() { + return outgoing.cyclic && incoming.cyclic; + } - this(Vertex o, Vertex i, EdgeType type = EdgeType.Unspecified) { - this.outgoing = o; - this.incoming = i; - this.type = type; + mixin E; } - bool isCyclic() { - return cycleType == CycleType.Cyclic; + static class Vertex { + Edge[] incomingEdges; + Edge[] outgoingEdges; + bool cyclic = true; + + Edge addChild(Vertex v) { + return new Edge(v, this); + } + + Edge addParent(Vertex v) { + return v.addChild(this); + } + + Vertex[] incoming() { + Vertex[] tmp; + + foreach(edge; incomingEdges) + tmp ~= edge.outgoing; + + return tmp; + } + + Vertex[] outgoing() { + Vertex[] tmp; + + foreach(edge; outgoingEdges) + tmp ~= edge.incoming; + + return tmp; + } + + mixin V; + } + + Vertex[] vertices; + Edge[] edges; + + this() { + vertices.length = capacity; + vertices.length = 0; + edges.length = capacity; + edges.length = 0; + } + + void add(Vertex vertex) { vertices ~= vertex; } + + void add(Edge edge) { edges ~= edge; } + + void connect(Vertex from, Vertex to) { edges ~= from.addParent(to); } + + void connect(int from, int to) { connect(vertices[from], vertices[to]); } + + /** + * Starts from non-cyclic nodes and propagates two both directions. + * Bugs: marks non-cyclic imports between two cycles as cyclic. Could be fixed later if it's really needed (slow) + */ + void markCycles() { + void mark(Vertex v) { + v.cyclic = false; + foreach(o; v.outgoing) { + if (!o.cyclic) continue; + + // propagate + bool cyclic = false; + foreach(p; o.incoming) if (p.cyclic) { cyclic = true; break; } + if (!cyclic) mark(o); + } + } + + void mark2(Vertex v) { + v.cyclic = false; + foreach(o; v.incoming) { + if (!o.cyclic) continue; + + // propagate + bool cyclic = false; + foreach(p; o.outgoing) if (p.cyclic) { cyclic = true; break; } + if (!cyclic) mark2(o); + } + } + + foreach(e; vertices) + if (e.cyclic) { + if (!e.incoming.length) mark(e); + if (!e.outgoing.length) mark2(e); + } } } -enum VertexType { - Module, - UnlocatableModule, - Package, - Class, - Interface, - Trait +template Empty() {} + + +// graph elements used in dep graphs + + +template DepEdge() { + bool isPublic; /// Public import. + bool isStatic; /// Static import. } -class Vertex { +template DepVertex() { char[] name; char[] location; uint id; - Edge[] incomingEdges; - Edge[] outgoingEdges; - VertexType type; - this(char[] name, char[] location, uint id = 0) { this.name = name; this.location = location; this.id = id; } - - Edge addChild(Vertex v, EdgeType type = EdgeType.Unspecified) { - auto edge = new Edge(v, this, type); - incomingEdges ~= edge; - v.outgoingEdges ~= edge; - return edge; - } - - Edge addParent(Vertex v, EdgeType type = EdgeType.Unspecified) { - return v.addChild(this, type); - } - - Vertex[] incoming() { - Vertex[] tmp; - - foreach(edge; incomingEdges) - tmp ~= edge.outgoing; +} - return tmp; - } - - Vertex[] outgoing() { - Vertex[] tmp; - - foreach(edge; outgoingEdges) - tmp ~= edge.incoming; - - return tmp; - } - - bool isCyclic() { - foreach(edge; outgoingEdges) - if (edge.isCyclic) - return true; - - return false; - } -} +alias Graph!(DepVertex, DepEdge, 100) DepGraph; diff -r 41cad5ca4863 -r ec8dd7b8bf0c trunk/src/docgen/graphutils/writer.d --- a/trunk/src/docgen/graphutils/writer.d Sat Feb 02 23:17:14 2008 +0100 +++ b/trunk/src/docgen/graphutils/writer.d Sun Feb 03 19:43:53 2008 +0200 @@ -10,7 +10,7 @@ debug import tango.io.Stdout; interface GraphWriter { - void generateDepGraph(Vertex[] vertices, Edge[] edges, OutputStream imageFile); + void generateDepGraph(DepGraph depGraph, OutputStream imageFile); } interface GraphWriterFactory : WriterFactory { @@ -20,7 +20,7 @@ interface CachingGraphWriterFactory : GraphWriterFactory { GraphCache graphCache(); } - +/+ /** * Marks all cycles in the graph. * @@ -67,6 +67,7 @@ debug Stderr("*\n"); } } ++/ abstract class AbstractGraphWriter : AbstractWriter!(GraphWriterFactory), GraphWriter { protected: @@ -84,31 +85,29 @@ class DefaultGraphCache : GraphCache { private: - char[][Object[]][Object[]][GraphFormat] m_graphCache; + char[][Object][GraphFormat] m_graphCache; public: - char[] getCachedGraph(Object[] vertices, Object[] edges, GraphFormat format) { + char[] getCachedGraph(Object graph, GraphFormat format) { debug Stdout("Starting graph lookup\n"); - debug Stdout(&vertices, &edges, format).newline; + debug Stdout(&graph, format).newline; debug Stdout(&m_graphCache).newline; auto lookup1 = format in m_graphCache; if (lookup1) { - auto lookup2 = edges in *lookup1; + auto lookup2 = graph in *lookup1; if (lookup2) { - auto lookup3 = vertices in *lookup2; - if (lookup3) - return *lookup3; + return *lookup2; } } debug Stdout("Graph cache miss!\n"); return null; } - void setCachedGraph(Object[] vertices, Object[] edges, GraphFormat format, char[] + void setCachedGraph(Object graph, GraphFormat format, char[] contents) { - m_graphCache[format][edges][vertices] = contents; + m_graphCache[format][graph] = contents; debug Stdout("Graph cache updated!\n"); } } diff -r 41cad5ca4863 -r ec8dd7b8bf0c trunk/src/docgen/misc/misc.d --- a/trunk/src/docgen/misc/misc.d Sat Feb 02 23:17:14 2008 +0100 +++ b/trunk/src/docgen/misc/misc.d Sun Feb 03 19:43:53 2008 +0200 @@ -14,8 +14,8 @@ } interface GraphCache { - char[] getCachedGraph(Object[] vertices, Object[] edges, GraphFormat format); - void setCachedGraph(Object[] vertices, Object[] edges, GraphFormat format, char[] contents); + char[] getCachedGraph(Object graph, GraphFormat format); + void setCachedGraph(Object graph, GraphFormat format, char[] contents); } interface CachingDocGenerator : DocGenerator { diff -r 41cad5ca4863 -r ec8dd7b8bf0c trunk/src/docgen/tests/graphs.d --- a/trunk/src/docgen/tests/graphs.d Sat Feb 02 23:17:14 2008 +0100 +++ b/trunk/src/docgen/tests/graphs.d Sun Feb 03 19:43:53 2008 +0200 @@ -11,7 +11,10 @@ import tango.io.FileConduit; import dil.semantic.Module; -void saveDefaultGraph(Vertex[] vertices, Edge[] edges, char[] fname) { +alias DepGraph.Edge Edge; +alias DepGraph.Vertex Vertex; + +void saveDefaultGraph(DepGraph depGraph, char[] fname) { auto gen = new TestDocGenerator; gen.options.graph.highlightCyclicVertices = true; gen.options.graph.imageFormat = ImageFormat.SVG; @@ -28,7 +31,7 @@ GraphFormat.Dot ); - writer.generateDepGraph(vertices, edges, file); + writer.generateDepGraph(depGraph, file); file.close(); file2.close(); @@ -37,71 +40,72 @@ // no edges //@unittest void graph1() { - auto a = new Vertex("mod_a", "path.to.mod_a", 1); - auto b = new Vertex("mod_b", "path.to.mod_b", 2); - auto c = new Vertex("mod_c", "path.to.mod_c", 3); + auto g = new DepGraph; + g.add(new Vertex("mod_a", "path.to.mod_a", 1)); + g.add(new Vertex("mod_b", "path.to.mod_b", 2)); + g.add(new Vertex("mod_c", "path.to.mod_c", 3)); - saveDefaultGraph( [a,b,c], null, "graph1.dot" ); + saveDefaultGraph(g, "graph1.dot"); } // simple tree structure //@unittest void graph2() { - auto a = new Vertex("mod_a", "path.to.mod_a", 1); - auto b = new Vertex("mod_b", "path.to.mod_b", 2); - auto c = new Vertex("mod_c", "path.to.mod_c", 3); - auto d = new Vertex("mod_d", "path.to.mod_d", 4); + auto g = new DepGraph; + g.add(new Vertex("mod_a", "path.to.mod_a", 1)); + g.add(new Vertex("mod_b", "path.to.mod_b", 2)); + g.add(new Vertex("mod_c", "path.to.mod_c", 3)); + g.add(new Vertex("mod_d", "path.to.mod_d", 4)); - Edge[] edges; - edges ~= a.addChild(b); - edges ~= a.addChild(c); - edges ~= c.addChild(d); + g.connect(1, 0); + g.connect(2, 0); + g.connect(3, 2); - saveDefaultGraph( [a,b,c,d], edges, "graph2.dot" ); + saveDefaultGraph(g, "graph2.dot"); } // circular imports //@unittest void graph3() { - auto a = new Vertex("mod_a", "path.to.mod_a", 1); - auto b = new Vertex("mod_b", "path.to.mod_b", 2); - auto c = new Vertex("mod_c", "path.to.mod_c", 3); - auto d = new Vertex("mod_d", "path.to.mod_d", 4); + auto g = new DepGraph; + g.add(new Vertex("mod_a", "path.to.mod_a", 1)); + g.add(new Vertex("mod_b", "path.to.mod_b", 2)); + g.add(new Vertex("mod_c", "path.to.mod_c", 3)); + g.add(new Vertex("mod_d", "path.to.mod_d", 4)); - Edge[] edges; - edges ~= a.addChild(b); - edges ~= b.addChild(c); - edges ~= c.addChild(a); - - saveDefaultGraph( [a,b,c,d], edges, "graph3.dot" ); + g.connect(1, 0); + g.connect(2, 1); + g.connect(0, 2); + + saveDefaultGraph(g, "graph3.dot"); } // more complex graph //@unittest void graph4() { - auto a = new Vertex("mod_a", "path.to.mod_a", 1); - auto b = new Vertex("mod_b", "path.to.mod_b", 2); - auto c = new Vertex("mod_c", "path.to.mod_c", 3); - auto d = new Vertex("mod_d", "path.to.mod_d", 4); - auto e = new Vertex("mod_e", "path.to.mod_e", 5); - auto f = new Vertex("mod_f", "path.to.mod_f", 6); - auto g = new Vertex("mod_g", "path.to.mod_g", 7); + auto g = new DepGraph; + g.add(new Vertex("mod_a", "path.to.mod_a", 1)); + g.add(new Vertex("mod_b", "path.to.mod_b", 2)); + g.add(new Vertex("mod_c", "path.to.mod_c", 3)); + g.add(new Vertex("mod_d", "path.to.mod_d", 4)); + g.add(new Vertex("mod_e", "path.to.mod_e", 5)); + g.add(new Vertex("mod_f", "path.to.mod_f", 6)); + g.add(new Vertex("mod_g", "path.to.mod_g", 7)); - Edge[] edges; - edges ~= a.addChild(b); - edges ~= b.addChild(c); - edges ~= c.addChild(a); - edges ~= d.addChild(a); - edges ~= e.addChild(a); - edges ~= b.addChild(d); - edges ~= b.addChild(e); - edges ~= g.addChild(a); - edges ~= b.addChild(f); - edges ~= g.addChild(f); - edges ~= a.addChild(g); + g.connect(1, 0); + g.connect(2, 1); + g.connect(0, 2); + g.connect(0, 3); + g.connect(0, 4); + g.connect(3, 1); + g.connect(4, 1); + g.connect(0, 6); + g.connect(5, 1); + g.connect(5, 6); + g.connect(6, 0); - saveDefaultGraph( [a,b,c,d,e,f,g], edges, "graph4.dot" ); + saveDefaultGraph(g, "graph4.dot"); } @@ -129,11 +133,11 @@ [ "c" ], [ "docgen/teststuff/" ], null, true, -1, (char[] fqn, char[] path, Module m) { - vertices[m.moduleFQN] = new Vertex(m.moduleFQN, m.filePath, id++); + vertices[m.moduleFQN] = new DepGraph.Vertex(m.moduleFQN, m.filePath, id++); }, (Module imported, Module importer, bool isPublic) { auto edge = vertices[imported.moduleFQN].addChild(vertices[importer.moduleFQN]); - edge.type = isPublic ? EdgeType.PublicDependency : EdgeType.Dependency; + edge.isPublic = isPublic; edges ~= edge; }, modules @@ -144,7 +148,11 @@ GraphFormat.Dot ); - writer.generateDepGraph(vertices.values, edges, imgFile); + auto graph = new DepGraph; + graph.edges = edges; + graph.vertices = vertices.values; + + writer.generateDepGraph(graph, imgFile); file.close(); imgFile.close();