Skip to content

Commit

Permalink
Merge pull request #4 from eNeRGy164/Improve
Browse files Browse the repository at this point in the history
Improve
  • Loading branch information
eNeRGy164 authored Jul 5, 2019
2 parents c728573 + 61dc0f0 commit 016917c
Show file tree
Hide file tree
Showing 24 changed files with 201 additions and 138 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -263,4 +263,4 @@ paket-files/
*.sln.iml
pub/

Properties/launchSettings.json
**/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public IReadOnlyDictionary<string, string> Render()
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine("@startuml");
stringBuilder.AppendLine("skinparam MinClassWidth 160");
stringBuilder.AppendLine("skinparam Linetype ortho");
stringBuilder.AppendLine($"namespace {aggregateName} <<aggregate>> {{");

var rootBuilder = this.RenderClass(aggregate);
Expand Down
3 changes: 1 addition & 2 deletions src/LivingDocumentation.Abstractions/IHaveMethodBody.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;

namespace LivingDocumentation
{
Expand Down
5 changes: 3 additions & 2 deletions src/LivingDocumentation.Abstractions/IHaveModifiers.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using System.Collections.Generic;
using Newtonsoft.Json;

namespace LivingDocumentation
{
public interface IHaveModifiers
{
List<string> Modifiers { get; }
[JsonProperty(Order = -2)]
Modifier Modifiers { get; set; }
}
}
4 changes: 2 additions & 2 deletions src/LivingDocumentation.Abstractions/IMemberable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ namespace LivingDocumentation
{
public interface IMemberable : IHaveModifiers
{
[JsonProperty(Order = 1)]
[JsonIgnore]
MemberType MemberType { get; }

[JsonProperty(Order = 2)]
[JsonProperty(Order = -3)]
string Name { get; }

string Documentation { get; }
Expand Down
25 changes: 14 additions & 11 deletions src/LivingDocumentation.Abstractions/Modifier.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
namespace LivingDocumentation
using System;

namespace LivingDocumentation
{
public static class Modifier
[Flags]
public enum Modifier
{
public const string Public = "public";
Internal = 1 << 0,

public const string Static = "static";
Public = 1 << 1,

public const string Internal = "internal";
Private = 1 << 2,

public const string Protected = "protected";
Protected = 1 << 3,

public const string Abstract = "abstract";
Static = 1 << 4,

public const string Private = "private";
Abstract = 1 << 5,

public const string Async = "async";
Override = 1 << 6,

public const string Override = "override";
Readonly = 1 << 7,

public const string Readonly = "readonly";
Async = 1 << 8,
}
}
21 changes: 13 additions & 8 deletions src/LivingDocumentation.Analyzer/Analyzers/SourceAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public override void VisitFieldDeclaration(FieldDeclarationSyntax node)
var fieldDescription = new FieldDescription(semanticModel.GetTypeDisplayString(node.Declaration.Type), node.Declaration.Variables.First().Identifier.ValueText);
this.currentType.AddMember(fieldDescription);

fieldDescription.Modifiers.AddRange(node.Modifiers.Select(m => m.ValueText));
fieldDescription.Modifiers |= ParseModifiers(node.Modifiers);
this.EnsureMemberDefaultAccessModifier(fieldDescription);

fieldDescription.Initializer = node.Declaration.Variables.First().Initializer?.Value.ToString(); // Assumption: Field has only a single initializer
Expand All @@ -78,7 +78,7 @@ public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node)
var propertyDescription = new PropertyDescription(semanticModel.GetTypeDisplayString(node.Type), node.Identifier.ToString());
this.currentType.AddMember(propertyDescription);

propertyDescription.Modifiers.AddRange(node.Modifiers.Select(m => m.ValueText));
propertyDescription.Modifiers |= ParseModifiers(node.Modifiers);
this.EnsureMemberDefaultAccessModifier(propertyDescription);

propertyDescription.Initializer = node.Initializer?.Value.ToString();
Expand All @@ -92,7 +92,7 @@ public override void VisitEnumMemberDeclaration(EnumMemberDeclarationSyntax node
var enumMemberDescription = new EnumMemberDescription(node.Identifier.ToString(), node.EqualsValue?.Value.ToString());
this.currentType.AddMember(enumMemberDescription);

enumMemberDescription.Modifiers.Add(Modifier.Public);
enumMemberDescription.Modifiers |= Modifier.Public;
enumMemberDescription.Documentation = ExtractDocumentation(node);

base.VisitEnumMemberDeclaration(node);
Expand Down Expand Up @@ -131,7 +131,7 @@ private void ExtractBaseTypeDeclaration(TypeType type, BaseTypeDeclarationSyntax
this.currentType.BaseTypes.AddRange(node.BaseList.Types.Select(t => semanticModel.GetTypeDisplayString(t.Type)));
}

this.currentType.Modifiers.AddRange(node.Modifiers.Select(m => m.ValueText));
this.currentType.Modifiers |= ParseModifiers(node.Modifiers);
this.EnsureTypeDefaultAccessModifier(node);

this.currentType.Documentation = ExtractDocumentation(node);
Expand All @@ -149,15 +149,15 @@ private void EnsureTypeDefaultAccessModifier(BaseTypeDeclarationSyntax node)
// Not nested, default is internal
if (!this.currentType.IsPublic() && !this.currentType.IsInternal())
{
this.currentType.Modifiers.Add(Modifier.Internal);
this.currentType.Modifiers |= Modifier.Internal;
}
}
else
{
// Nested, default is private
if (!this.currentType.IsPublic() && !this.currentType.IsInternal() && !this.currentType.IsPrivate() && !this.currentType.IsProtected())
{
this.currentType.Modifiers.Add(Modifier.Private);
this.currentType.Modifiers |= Modifier.Private;
}
}
}
Expand All @@ -167,7 +167,7 @@ private void EnsureMemberDefaultAccessModifier(IHaveModifiers member)
// Default is private
if (!member.IsPublic() && !member.IsInternal() && !member.IsPrivate() && !member.IsProtected())
{
member.Modifiers.Add(Modifier.Private);
member.Modifiers |= Modifier.Private;
}
}

Expand Down Expand Up @@ -233,7 +233,7 @@ private string ExtractDocumentation(SyntaxNode node)

private void ExtractBaseMethodDeclaration(BaseMethodDeclarationSyntax node, IHaveAMethodBody method)
{
method.Modifiers.AddRange(node.Modifiers.Select(m => m.ValueText));
method.Modifiers |= ParseModifiers(node.Modifiers);
this.EnsureMemberDefaultAccessModifier(method);

foreach (var parameter in node.ParameterList.Parameters)
Expand All @@ -247,5 +247,10 @@ private void ExtractBaseMethodDeclaration(BaseMethodDeclarationSyntax node, IHav
var invocationAnalyzer = new InvocationsAnalyzer(semanticModel, method.Statements);
invocationAnalyzer.Visit((SyntaxNode)node.Body ?? node.ExpressionBody);
}

private static Modifier ParseModifiers(SyntaxTokenList modifiers)
{
return (Modifier)modifiers.Select(m => Enum.TryParse(typeof(Modifier), m.ValueText, true, out var value) ? (int)value : 0).Sum();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Buildalyzer.Workspaces" Version="2.3.0" />
<PackageReference Include="CommandLineParser" Version="2.5.0" />
<PackageReference Include="Microsoft.Build.Locator" Version="1.2.2" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="3.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup>

Expand Down
55 changes: 27 additions & 28 deletions src/LivingDocumentation.Analyzer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Buildalyzer;
using Buildalyzer.Workspaces;
using CommandLine;
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.MSBuild;
using Newtonsoft.Json;

namespace LivingDocumentation
Expand Down Expand Up @@ -66,44 +66,43 @@ private static async Task RunApplicationAsync(Options options)

private static async Task AnalyzeSolutionAsync(IList<TypeDescription> types, string solutionFile)
{
MSBuildLocator.RegisterDefaults();
var manager = new AnalyzerManager(solutionFile);
var workspace = manager.GetWorkspace();
var assembliesInSolution = workspace.CurrentSolution.Projects.Select(p => p.AssemblyName).ToList();

using (var workspace = MSBuildWorkspace.Create())
{
var solution = await workspace.OpenSolutionAsync(solutionFile);
var assembliesInSolution = solution.Projects.Select(p => p.AssemblyName).ToList();
// Every project in the solution, except unit test projects
var projects = workspace.CurrentSolution.Projects
.Where(p => !manager.Projects.First(mp => p.Id.Id == mp.Value.ProjectGuid).Value.ProjectFile.PackageReferences.Any(pr => pr.Name.Contains("Test")));

// Every project in the solution, except unit test projects
var projects = workspace.CurrentSolution.Projects.Where(p => !p.Name.Contains("Test", StringComparison.OrdinalIgnoreCase));
foreach (var project in projects)
{
var compilation = await project.GetCompilationAsync();
var referencedAssemblies = compilation.ReferencedAssemblyNames.Where(a => !assembliesInSolution.Contains(a.Name)).ToList();

foreach (var project in projects)
if (RuntimeOptions.VerboseOutput)
{
var compilation = await project.GetCompilationAsync();
var referencedAssemblies = compilation.ReferencedAssemblyNames.Where(a => !assembliesInSolution.Contains(a.Name)).ToList();

if (RuntimeOptions.VerboseOutput)
var diagnostics = compilation.GetDiagnostics();
if (diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error))
{
var diagnostics = compilation.GetDiagnostics();
if (diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error))
Console.WriteLine($"The following errors occured during compilation of project '{project.FilePath}'");
foreach (var diagnostic in diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error))
{
Console.WriteLine($"The following errors occured during compilation of project '{project.FilePath}'");
foreach (var diagnostic in diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error))
{
Console.WriteLine("- " + diagnostic.ToString());
}
Console.WriteLine("- " + diagnostic.ToString());
}
}
}

// Every file in the project
foreach (var syntaxTree in compilation.SyntaxTrees)
{
var semanticModel = compilation.GetSemanticModel(syntaxTree, true);
// Every file in the project
foreach (var syntaxTree in compilation.SyntaxTrees)
{
var semanticModel = compilation.GetSemanticModel(syntaxTree, true);

var visitor = new SourceAnalyzer(semanticModel, types, referencedAssemblies);
visitor.Visit(syntaxTree.GetRoot());
}
var visitor = new SourceAnalyzer(semanticModel, types, referencedAssemblies);
visitor.Visit(syntaxTree.GetRoot());
}
}

workspace.Dispose();
}
}
}

This file was deleted.

11 changes: 8 additions & 3 deletions src/LivingDocumentation.Descriptions/ConstructorDescription.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Diagnostics;

namespace LivingDocumentation
{
[DebuggerDisplay("Constructor {Name}")]
[DebuggerDisplay("Constructor {Name,nq}")]
public class ConstructorDescription : MemberDescription, IHaveAMethodBody
{
[JsonProperty(ItemTypeNameHandling = TypeNameHandling.None)]
[JsonConverter(typeof(ConcreteTypeConverter<List<ParameterDescription>>))]
public List<IParameterDescription> Parameters { get; } = new List<IParameterDescription>();

public List<Statement> Statements { get; } = new List<Statement>();

public override MemberType MemberType => MemberType.Constructor;

public ConstructorDescription(string name)
: base(MemberType.Constructor, name)
: base(name)
{
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/LivingDocumentation.Descriptions/EnumMemberDescription.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
namespace LivingDocumentation
using System.Diagnostics;

namespace LivingDocumentation
{
[DebuggerDisplay("EnumMember {Name,nq}")]
public class EnumMemberDescription : MemberDescription
{
public string Value { get; }

public override MemberType MemberType => MemberType.EnumMember;

public EnumMemberDescription(string name, string value)
: base(MemberType.EnumMember, name)
: base(name)
{
this.Value = value;
}
Expand Down
6 changes: 4 additions & 2 deletions src/LivingDocumentation.Descriptions/FieldDescription.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace LivingDocumentation
{
[DebuggerDisplay("Field {Type} {Name}")]
[DebuggerDisplay("Field {Type,nq} {Name,nq}")]
public class FieldDescription : MemberDescription
{
public string Type { get; }
Expand All @@ -13,8 +13,10 @@ public class FieldDescription : MemberDescription
[JsonIgnore]
public bool HasInitializer => this.Initializer != null;

public override MemberType MemberType => MemberType.Field;

public FieldDescription(string type, string name)
: base(MemberType.Field, name)
: base(name)
{
this.Type = type;
}
Expand Down
23 changes: 23 additions & 0 deletions src/LivingDocumentation.Descriptions/Json/ConcreteTypeConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Newtonsoft.Json;
using System;

namespace LivingDocumentation
{
internal class ConcreteTypeConverter<TConcrete> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return serializer.Deserialize<TConcrete>(reader);
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
}
13 changes: 7 additions & 6 deletions src/LivingDocumentation.Descriptions/MemberDescription.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using System.ComponentModel;

namespace LivingDocumentation
{
public abstract class MemberDescription : IMemberable
{
public MemberType MemberType { get; }
public abstract MemberType MemberType { get; }

public string Name { get; }

public List<string> Modifiers { get; } = new List<string>();

[DefaultValue(Modifier.Private)]
public Modifier Modifiers { get; set; }

public bool IsInherited { get; internal set; } = false;

public string Documentation { get; set; }

public MemberDescription(MemberType memberType, string name)
public MemberDescription(string name)
{
this.MemberType = memberType;
this.Name = name;
}
}
Expand Down
Loading

0 comments on commit 016917c

Please sign in to comment.