from pathlib import Path from textwrap import dedent from typing import Dict, List from pyTooling.Graph import Graph, Vertex from pyVHDLModel import ( DependencyGraphVertexKind, DependencyGraphEdgeKind, Library as VHDLModel_Library, Document as VHDLModel_Document, ) class DependencyGraphFormatter: _graph: Graph NODE_COLORS = { DependencyGraphVertexKind.Document: "#999999", DependencyGraphVertexKind.Library: "#99ccff", DependencyGraphVertexKind.Package: "#ff9900", DependencyGraphVertexKind.PackageBody: "#ff9900", DependencyGraphVertexKind.Context: "#cc99ff", DependencyGraphVertexKind.Entity: "#ffff99", DependencyGraphVertexKind.Architecture: "#ff99cc", DependencyGraphVertexKind.Configuration: "#ff9900", } EDGE_COLORS = { DependencyGraphEdgeKind.SourceFile: "#000000", DependencyGraphEdgeKind.CompileOrder: "#ff0000", DependencyGraphEdgeKind.LibraryClause: "#000000", DependencyGraphEdgeKind.UseClause: "#000000", DependencyGraphEdgeKind.ContextReference: "#000000", DependencyGraphEdgeKind.EntityImplementation: "#99ccff", DependencyGraphEdgeKind.PackageImplementation: "#99ccff", DependencyGraphEdgeKind.EntityInstantiation: "#000000", DependencyGraphEdgeKind.ComponentInstantiation: "#000000", DependencyGraphEdgeKind.ConfigurationInstantiation: "#000000", } def __init__(self, graph: Graph): self._graph = graph def WriteGraphML(self, path: Path): with path.open("w") as file: file.write( dedent( f"""\ """ ) ) groups: Dict[str, List[Vertex]] = {} for vertex in self._graph._verticesWithID.values(): if isinstance(vertex.Value, VHDLModel_Library): identifier = vertex.Value.NormalizedIdentifier elif isinstance(vertex.Value, VHDLModel_Document): identifier = vertex.Value.DesignUnits[0].Library.NormalizedIdentifier else: identifier = vertex.Value.Library.NormalizedIdentifier if identifier in groups: groups[identifier].append(vertex) else: groups[identifier] = [vertex] for group, vertices in groups.items(): file.write( dedent( """\ {prefix} {prefix} {value} {prefix} """ ).format(prefix=" ", id=group, value=group) ) for vertex in vertices: if vertex["kind"] is DependencyGraphVertexKind.Architecture: value = f"{vertex.Value.Entity.Identifier}({vertex.Value.Identifier})" elif vertex["kind"] is DependencyGraphVertexKind.Document: value = f"{vertex.ID}" else: value = f"{vertex.Value.Identifier}" file.write( dedent( """\ {prefix} {prefix} {vertex.ID} {prefix} {value} {prefix} {vertex[kind].name} {prefix} {color} {prefix} """ ).format(prefix=" ", vertex=vertex, value=value, color=self.NODE_COLORS[vertex["kind"]]) ) file.write( dedent( """\ {prefix} {prefix} """ ).format(prefix=" ") ) edgeCount = 1 for edge in self._graph._edgesWithoutID: file.write( dedent( """\ {prefix} {prefix} {edge[kind].name} {prefix} {color} {prefix} """ ).format(prefix=" ", edgeCount=edgeCount, edge=edge, color=self.EDGE_COLORS[edge["kind"]]) ) edgeCount += 1 file.write( dedent( """\ """ ) ) class HierarchyGraphFormatter: _graph: Graph NODE_COLORS = { DependencyGraphVertexKind.Document: "#999999", DependencyGraphVertexKind.Library: "#99ccff", DependencyGraphVertexKind.Package: "#ff9900", DependencyGraphVertexKind.PackageBody: "#ff9900", DependencyGraphVertexKind.Context: "#cc99ff", DependencyGraphVertexKind.Entity: "#ffff99", DependencyGraphVertexKind.Architecture: "#ff99cc", DependencyGraphVertexKind.Configuration: "#ff9900", } EDGE_COLORS = { DependencyGraphEdgeKind.SourceFile: "#000000", DependencyGraphEdgeKind.CompileOrder: "#ff0000", DependencyGraphEdgeKind.LibraryClause: "#000000", DependencyGraphEdgeKind.UseClause: "#000000", DependencyGraphEdgeKind.ContextReference: "#000000", DependencyGraphEdgeKind.EntityImplementation: "#99ccff", DependencyGraphEdgeKind.PackageImplementation: "#99ccff", DependencyGraphEdgeKind.EntityInstantiation: "#000000", DependencyGraphEdgeKind.ComponentInstantiation: "#000000", DependencyGraphEdgeKind.ConfigurationInstantiation: "#000000", } def __init__(self, graph: Graph): self._graph = graph def WriteGraphML(self, path: Path): with path.open("w") as file: file.write( dedent( f"""\ """ ) ) for vertex in self._graph._verticesWithID.values(): if vertex["kind"] is DependencyGraphVertexKind.Entity: file.write( dedent( """\ {prefix} {prefix} {vertex.ID} {prefix} {vertex.Value.Identifier} {prefix} {vertex[kind].name} {prefix} {color} {prefix} """ ).format(prefix=" ", vertex=vertex, color=self.NODE_COLORS[vertex["kind"]]) ) elif vertex["kind"] is DependencyGraphVertexKind.Architecture: file.write( dedent( """\ {prefix} {prefix} {vertex.ID} {prefix} {vertex.Value.Identifier} {prefix} {vertex[kind].name} {prefix} {color} {prefix} """ ).format(prefix=" ", vertex=vertex, color=self.NODE_COLORS[vertex["kind"]]) ) edgeCount = 1 for edge in self._graph._edgesWithoutID: file.write( dedent( """\ {prefix} {prefix} {edge[kind].name} {prefix} {color} {prefix} """ ).format(prefix=" ", edgeCount=edgeCount, edge=edge, color=self.EDGE_COLORS[edge["kind"]]) ) edgeCount += 1 file.write( dedent( """\ """ ) ) class CompileOrderGraphFormatter: _graph: Graph NODE_COLORS = { DependencyGraphVertexKind.Document: "#999999", DependencyGraphVertexKind.Library: "#99ccff", DependencyGraphVertexKind.Package: "#ff9900", DependencyGraphVertexKind.PackageBody: "#ff9900", DependencyGraphVertexKind.Context: "#cc99ff", DependencyGraphVertexKind.Entity: "#ffff99", DependencyGraphVertexKind.Architecture: "#ff99cc", DependencyGraphVertexKind.Configuration: "#ff9900", } EDGE_COLORS = { DependencyGraphEdgeKind.SourceFile: "#000000", DependencyGraphEdgeKind.CompileOrder: "#ff0000", DependencyGraphEdgeKind.LibraryClause: "#000000", DependencyGraphEdgeKind.UseClause: "#000000", DependencyGraphEdgeKind.ContextReference: "#000000", DependencyGraphEdgeKind.EntityImplementation: "#99ccff", DependencyGraphEdgeKind.PackageImplementation: "#99ccff", DependencyGraphEdgeKind.EntityInstantiation: "#000000", DependencyGraphEdgeKind.ComponentInstantiation: "#000000", DependencyGraphEdgeKind.ConfigurationInstantiation: "#000000", } def __init__(self, graph: Graph): self._graph = graph def WriteGraphML(self, path: Path): print(path.absolute()) with path.open("w") as file: file.write( dedent( f"""\ """ ) ) for vertex in self._graph._verticesWithID.values(): if vertex["kind"] is DependencyGraphVertexKind.Document: file.write( dedent( """\ {prefix} {prefix} {vertex.ID} {prefix} {vertex.Value.Path.name} {prefix} {vertex[kind].name} {prefix} {color} {prefix} """ ).format(prefix=" ", vertex=vertex, color=self.NODE_COLORS[vertex["kind"]]) ) edgeCount = 1 for edge in self._graph._edgesWithoutID: file.write( dedent( """\ {prefix} {prefix} {edge[kind].name} {prefix} {color} {prefix} """ ).format(prefix=" ", edgeCount=edgeCount, edge=edge, color=self.EDGE_COLORS[edge["kind"]]) ) edgeCount += 1 file.write( dedent( """\ """ ) )