public CSharpObjectCollection AnalyzeFiles(IEnumerable <string> files) { var visitor = new CSharpVisitor(); var coll = new CSharpObjectCollection(); // Pass 1 - add all classes and interfaces found in the files. visitor.HandleClass = c => { var name = c.Identifier.ToString(); coll.AddClass(name); log?.Invoke($"Class: {name}"); }; visitor.HandleInterface = i => { var name = i.Identifier.ToString(); coll.AddInterface(name); log?.Invoke($"Interface: {name}"); }; foreach (var file in files) { visitor.Visit(file); } // Pass 2 - handle extension and composition for all classes found in the files. visitor.HandleClass = c => DetermineExtensionAndComposition(c, coll); visitor.HandleInterface = null; foreach (var file in files) { visitor.Visit(file); } return(coll); }
public List <string> GeneratePlantUml(CSharpObjectCollection coll) { var uml = new List <string>(); uml.Add("@startuml"); foreach (var i in coll.Interfaces) { uml.Add($"interface {i.Name}"); } foreach (var cls in coll.Classes) { uml.Add($"class {cls.Name}"); if (cls.Derives != null) { uml.Add($"{cls.Derives.Name} <|-- {cls.Name}"); } foreach (var i in cls.Implements) { uml.Add($"{i.Name} <|-- {cls.Name}"); } foreach (var ia in cls.InterfaceAssociations) { uml.Add($"{ia.Interface.Name} <-- {cls.Name}"); } foreach (var ca in cls.ClassAssociations) { uml.Add($"{ca.Class.Name} <-- {cls.Name}"); } } uml.Add("@enduml"); return(uml); }
public CSharpObjectCollection Clone(string startClass, Settings settings) { var coll = new CSharpObjectCollection(); classes.FirstOrDefault(c => c.Name == startClass)?.Clone(coll, settings); return(coll); }
public static void Main(string[] args) { string dir; if (args.Length == 0) { dir = Directory.GetCurrentDirectory(); Console.WriteLine($"(assuming current directory {dir})"); } else { dir = args[0]; Console.WriteLine($"Processing directory {dir}"); } Analyzer = new CSharpAnalyzer(Console.WriteLine); Generator = new UmlGenerator(); var files = Directory.EnumerateFiles(Path.GetFullPath(dir), "*.cs", SearchOption.AllDirectories); Collection = Analyzer.AnalyzeFiles(files); var settingsFiles = Directory.EnumerateFiles(Path.GetFullPath(dir), "*.dg.cfg", SearchOption.AllDirectories).ToList(); if (settingsFiles.Count == 0) { settingsFiles.Add(dir + @"\default.dg.cfg"); } foreach (var settingsFile in settingsFiles) { Settings = new Settings(settingsFile); var coll = Settings.StartClass == "" ? Collection : Collection.Clone(Settings.StartClass, Settings); SaveFile(Generator.GeneratePlantUml(coll), settingsFile.Replace(".dg.cfg", ".plantuml")); } }
private void DetermineExtensionAndComposition(ClassDeclarationSyntax c, CSharpObjectCollection coll) { if (c.BaseList != null) { foreach (var baseType in c.BaseList.Types) { coll.SetExtends(c.Identifier.ToString(), baseType.Type.ToString()); log?.Invoke($"{c.Identifier.ToString()} extends {baseType.Type.ToString()}"); } } foreach (var member in c.Members) { if (member is FieldDeclarationSyntax) { try { var visibility = GetVisibility(member as FieldDeclarationSyntax); var field = member as FieldDeclarationSyntax; var type = field.Declaration.Type; if (type is IdentifierNameSyntax) { coll.SetAssociation( c.Identifier.ToString(), (type as IdentifierNameSyntax).Identifier.Text, visibility); log?.Invoke( $"{c.Identifier.ToString()} associates to {(type as IdentifierNameSyntax).Identifier.Text}"); } else if (type is GenericNameSyntax) { coll.SetAssociation( c.Identifier.ToString(), (type as GenericNameSyntax).Identifier.Text, visibility); foreach (var arg in (type as GenericNameSyntax).TypeArgumentList.Arguments) { coll.SetAssociation(c.Identifier.ToString(), arg.ToString(), visibility); log?.Invoke($"{c.Identifier.ToString()} associates to {arg.ToString()}"); } } } catch (Exception e) { log?.Invoke(e.ToString()); } } } }
public void Clone(CSharpObjectCollection coll, Settings settings) { coll.AddClass(Name); foreach (var c in ClassAssociations) { if ( (c.Visibility == CSharpVisibility.Public && settings.IncludePublicAssociations) || (c.Visibility == CSharpVisibility.Protected && settings.IncludeProtectedAssociations) || (c.Visibility == CSharpVisibility.Internal && settings.IncludeInternalAssociations) || (c.Visibility == CSharpVisibility.Private && settings.IncludePrivateAssociations) ) { if (!coll.ClassExists(c.Class.Name)) { c.Class.Clone(coll, settings); } coll.SetAssociation(Name, c.Class.Name, c.Visibility); } } if (settings.IncludeInheritance) { foreach (var i in Implements) { if (!coll.InterfaceExists(i.Name)) { coll.AddInterface(i.Name); } coll.SetExtends(Name, i.Name); } if (Derives != null) { if (!coll.ClassExists(Derives.Name)) { Derives.Clone(coll, settings); } coll.SetExtends(Name, Derives.Name); } } }
public void Clone(CSharpObjectCollection coll) { coll.AddInterface(Name); }