public CodeAnalysisGraph AnalyzeCode() { CodeAnalysisGraph graph = new CodeAnalysisGraph(); // first examine all types that belong to the assembly foreach (Type type in assembly.GetTypes()) { AnalyzeType(type, graph); } return(graph); }
private ICodeEntity AnalyzeType(Type type, CodeAnalysisGraph graph) { if (false == ShouldBeIncluded(type)) { return(null); } if (type.IsClass) { ClassEntity analyzedClass = new ClassEntity(type.Name, type.FullName, type.IsAbstract); analyzedClass = (ClassEntity)graph.GetEntity(analyzedClass); // skip already analyzed entities if (analyzedClass.AnalysisState != CodeEntityAnalysisState.NotAnalyzed) { return(analyzedClass); } analyzedClass.AnalysisState = CodeEntityAnalysisState.InAnalysis; // find direct ancestor if (type.BaseType != null) { ICodeEntity ancestor = AnalyzeType(type.BaseType, graph); if (ancestor != null) { analyzedClass.AddAncestor(ancestor); } } foreach (Type inheritedInterface in type.GetInterfaces()) { ICodeEntity ancestor = AnalyzeType(inheritedInterface, graph); if (ancestor != null) { analyzedClass.AddAncestor(ancestor); } } foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)) { ICodeEntity association = AnalyzeType(field.FieldType, graph); if (association != null) { analyzedClass.AddAssociation(association); } } analyzedClass.AnalysisState = CodeEntityAnalysisState.Analyzed; return(analyzedClass); } else if (type.IsInterface) { InterfaceEntity analyzedInterface = new InterfaceEntity(type.Name, type.FullName); analyzedInterface = (InterfaceEntity)graph.GetEntity(analyzedInterface); // skip already analyzed entities if (analyzedInterface.AnalysisState != CodeEntityAnalysisState.NotAnalyzed) { return(analyzedInterface); } analyzedInterface.AnalysisState = CodeEntityAnalysisState.InAnalysis; foreach (Type inheritedInterface in type.GetInterfaces()) { ICodeEntity ancestor = AnalyzeType(inheritedInterface, graph); if (ancestor != null) { analyzedInterface.AddAncestor(ancestor); } } analyzedInterface.AnalysisState = CodeEntityAnalysisState.Analyzed; return(analyzedInterface); } return(null); }
public void GenerateDiagram(CodeAnalysisGraph graph, Stream outputStream) { using (StreamWriter writer = new StreamWriter(outputStream)) { string fontName = "Tahoma"; writer.WriteLine("digraph"); writer.WriteLine("{"); writer.WriteLine(@"node [shape = ""record"" fontsize=""7""]"); foreach (ICodeEntity entity in graph.Entities.Values) { if (entity is ClassEntity) { ClassEntity classEntity = (ClassEntity)entity; writer.WriteLine( "node{0} [label = \"{1}\" fontname=\"{2}\"]", classEntity.UniqueId, classEntity.EntityShortName, fontName); foreach (ICodeEntity association in classEntity.Associations) { writer.WriteLine(@"edge [arrowhead = ""none""]"); writer.WriteLine( "\"node{0}\" -> \"node{1}\"", association.UniqueId, entity.UniqueId); } } else if (entity is InterfaceEntity) { InterfaceEntity classEntity = (InterfaceEntity)entity; writer.WriteLine( "node{0} [label = \"{1}\" fontname=\"{2} Italic\"]", classEntity.UniqueId, classEntity.EntityShortName, fontName); } foreach (ICodeEntity ancestor in entity.Ancestors) { if (entity is InterfaceEntity && ancestor is InterfaceEntity) { writer.WriteLine(@"edge [arrowhead = ""empty"" style=""dashed"" ]"); } else { writer.WriteLine(@"edge [arrowhead = ""empty""]"); } writer.WriteLine( "\"node{0}\" -> \"node{1}\"", ancestor.UniqueId, entity.UniqueId); } } writer.WriteLine("}"); } }