Giter VIP home page Giter VIP logo

livingdocumentation's People

Contributors

asmorger avatar energy164 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

livingdocumentation's Issues

Review the way projects can be included/excluded from a solution

When using the AnalyzerManager with a solution file path, the method has the ability to apply a ProjectFilter by using AnalyzerManagerOptions.
Using the optional parameter will allow for example for an exclusion of certain projects before they are added to the Workspace.

Example:

var managerOptions = new AnalyzerManagerOptions
        {
            ProjectFilter = x => !x.AbsolutePath.Contains("Tests")
        };
var solutionManager = new AnalyzerManager(solutionFilePath, managerOptions);

Newtonsoft.Json.JsonSerializationException:

LivingDocumentation.Descriptions, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null' is not compatible with 'ConsoleApp1.Statement, ConsoleApp1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Path '[0].Constructors[0].Statements[0].$type', line 1, position 524.'
analysis.txt

json output not reliable

The generated output file does not always result in the same json file. It seems certain type descriptions are missing.
In case something is wrong it is better to let it fail rather than continuing with incomplete data.

Unable to Access Controller Constructor's Statements

analysis.txt
How can I access the items in the Controller Statements? These items generally are the same as the constructor parameters. I sometimes add statements that are not constructor parameters. These are LivingDocumentation.InvocationDescription type. The BowlController is an example.

Thank you for LivingDocument is a huge asset. It solves my lack of documentation problem that a lot of developers experience. I am incorporating it in all my projects. I have to figure out how to document Razor pages, but that's a later task.
Bill

Deserialization Issue: Could not load assembly 'LivingDocumentation.Statements'

I am attempting to work Living Documentation into my Nuke.build CI pipeline, but I'm getting stuck pretty quickly. I am able to generate the analysis file, but the deserialization of it fails.

  • As far as I can tell, I am referencing the right packages.
  • LivingDocumentation.Statements is identified as a transitive dependency by default
  • Adding this as a direct dependency does not resolve the issue
  • I have confirmed that everything is net7.0 all the way down

Nuget references from my Nuke csproj:

  <ItemGroup>
    <PackageReference Include="LivingDocumentation.Json" Version="0.4.0" />
    <PackageReference Include="LivingDocumentation.RenderExtensions" Version="0.4.0" />
    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
  </ItemGroup>

  <ItemGroup>
    <PackageDownload Include="LivingDocumentation.Analyzer" Version="[0.4.0]" />
  </ItemGroup>

Nuke setup:

    [NuGetPackage(
        packageId: "LivingDocumentation.Analyzer",
        packageExecutable: "LivingDocumentation.Analyzer.dll",
        Framework = "net7.0")]
    readonly Tool Documentation;

    Target Document => _ => _
        .Executes(() =>
        {
            Documentation($"--solution {Solution.Path} --output {Paths.Artifacts.LivingDocumentation}");

            string fileContent = File.ReadAllText(Paths.Artifacts.LivingDocumentation);
            var types = JsonConvert.DeserializeObject<List<TypeDescription>>(fileContent,  JsonDefaults.DeserializerSettings());
        });

Execution summary

07:43:38 [INF] > /usr/bin/dotnet /home/user/.nuget/packages/livingdocumentation.analyzer/0.4.0/tools/net7.0/any/LivingDocumentation.Analyzer.dll --solution /home/user/dev/work/project/src/api/Bespoke.sln --output /home/user/dev/work/project/.artifacts/analysis.json
07:43:43 [DBG] Living Documentation Analysis output generated in 5313ms at /home/user/dev/work/project/.artifacts/analysis.json
07:43:43 [ERR] Target Document has thrown an exception
Newtonsoft.Json.JsonSerializationException: Error resolving type specified in JSON 'LivingDocumentation.If, LivingDocumentation.Statements'. Path '[1].Methods[0].Statements[4].$type', line 1, position 4124.
 ---> Newtonsoft.Json.JsonSerializationException: Could not load assembly 'LivingDocumentation.Statements'.
   at Newtonsoft.Json.Serialization.DefaultSerializationBinder.GetTypeFromTypeNameKey(StructMultiKey`2 typeNameKey)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Newtonsoft.Json.Utilities.ThreadSafeStore`2.Get(TKey key)
...

Any ideas what I'm doing wrong?

Solution analysis fails when run from docker container

Unhandled Exception: System.AggregateException: One or more errors occurred. (One or more errors occurred. (Could not find build environment)) (One or more errors occurred. (Could not find build environment)) (One or more errors occurred. (Could not find build environment)) (Could not find build environment) (Could not find build environment) (Could not find build environment) ---> System.InvalidOperationException: Could not find build environment
at Buildalyzer.Environment.EnvironmentFactory.GetBuildEnvironment(String targetFramework, EnvironmentOptions options)
at Buildalyzer.ProjectAnalyzer.Build(String targetFramework)
at Buildalyzer.Workspaces.AnalyzerManagerExtensions.<>c.b__0_0(ProjectAnalyzer p)
at System.Linq.Parallel.SelectQueryOperator2.SelectQueryOperatorResults.GetElement(Int32 index) at System.Linq.Parallel.QueryResults1.get_Item(Int32 index)
at System.Linq.Parallel.PartitionedDataSource1.ListContiguousIndexRangeEnumerator.MoveNext(T& currentElement, Int32& currentKey) at System.Linq.Parallel.WhereQueryOperator1.WhereQueryOperatorEnumerator1.MoveNext(TInputOutput& currentElement, TKey& currentKey) at System.Linq.Parallel.StopAndGoSpoolingTask2.SpoolingWork()
at System.Linq.Parallel.SpoolingTaskBase.Work()
at System.Linq.Parallel.QueryTask.BaseWork(Object unused)
at System.Linq.Parallel.QueryTask.<>c.<.cctor>b__10_0(Object o)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
--- End of inner exception stack trace ---
at System.Linq.Parallel.QueryTaskGroupState.QueryEnd(Boolean userInitiatedDispose)
at System.Linq.Parallel.SpoolingTask.SpoolStopAndGo[TInputOutput,TIgnoreKey](QueryTaskGroupState groupState, PartitionedStream2 partitions, SynchronousChannel1[] channels, TaskScheduler taskScheduler)
at System.Linq.Parallel.MergeExecutor1.Execute() at System.Linq.Parallel.MergeExecutor1.Execute[TKey](PartitionedStream2 partitions, Boolean ignoreOutput, ParallelMergeOptions options, TaskScheduler taskScheduler, Boolean isOrdered, CancellationState cancellationState, Int32 queryId) at System.Linq.Parallel.PartitionedStreamMerger1.Receive[TKey](PartitionedStream2 partitionedStream) at System.Linq.Parallel.WhereQueryOperator1.WrapPartitionedStream[TKey](PartitionedStream2 inputStream, IPartitionedStreamRecipient1 recipient, Boolean preferStriping, QuerySettings settings)
at System.Linq.Parallel.UnaryQueryOperator2.UnaryQueryOperatorResults.ChildResultsRecipient.Receive[TKey](PartitionedStream2 inputStream)
at System.Linq.Parallel.UnaryQueryOperator2.UnaryQueryOperatorResults.GivePartitionedStream(IPartitionedStreamRecipient1 recipient)
at System.Linq.Parallel.UnaryQueryOperator2.UnaryQueryOperatorResults.GivePartitionedStream(IPartitionedStreamRecipient1 recipient)
at System.Linq.Parallel.QueryOperator1.GetOpenedEnumerator(Nullable1 mergeOptions, Boolean suppressOrder, Boolean forEffect, QuerySettings querySettings)
at System.Linq.Parallel.QueryOpeningEnumerator1.OpenQuery() at System.Linq.Parallel.QueryOpeningEnumerator1.MoveNext()
at System.Linq.ParallelEnumerable.ToList[TSource](ParallelQuery`1 source)
at Buildalyzer.Workspaces.AnalyzerManagerExtensions.GetWorkspace(AnalyzerManager manager)

Unhandled exception thrown if property has type of `ref T`

I made a specialized collection for mutable large structs. To mutate a struct member by this indexer, it returns a reference. While analyzer processing this file, it thrown an exception and stopped generation.

Here is the repro code snippet:

	public struct ListStruct<T> : IEnumerable<T> where T : unmanaged
	{
		internal int CountInternal;
		private T[] _storage;

		// ...

		public readonly ref T this[int index]
		{
			[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
			get => ref _storage[index];
		}

		// ...

And here is the stack trace:

System.Collections.Generic.KeyNotFoundException: Could not resolve a display name for ref T
at LivingDocumentation.SemanticModelExtensions.GetTypeDisplayString(SemanticModel semanticModel, ExpressionSyntax expression) in /_/src/LivingDocumentation.Analyzer/Extensions/SemanticModelExtensions.cs:line 24
at LivingDocumentation.SourceAnalyzer.VisitPropertyDeclaration(PropertyDeclarationSyntax node) in /_/src/LivingDocumentation.Analyzer/Analyzers/SourceAnalyzer.cs:line 158
at Microsoft.CodeAnalysis.CSharp.Syntax.PropertyDeclarationSyntax.Accept(CSharpSyntaxVisitor visitor)
...

Hope these information will help.

Move build pipeline to GitHub actions

  • Use GitHub actions for build & test
  • Have private previews for pull requests
  • Have main builds publish to NuGet
  • Make publishing to GitHub a manual step or require approval

Deserialized model elements should have a Parent property

Currently it is only possible to navigate from the top down, but not back up.

During/after deserialization, objects like MethodDescription, Statement, etc. should have a Parent property to navigate up the tree.

This would reduce complexity when querying the tree.

ArgumentNullException on InvocationDescription

First, thank you for this great tool!

When I run your tool on the eshop on containers as in your description, I get the following error:

D:\C#\Test\LivingDoc\eShopOnContainers>livingdoc-analyze --solution src/eShopOnContainers-ServicesAndWebApps.sln --output analysis.json
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'containingType')
at LivingDocumentation.InvocationDescription..ctor(String containingType, String name) in //src/LivingDocumentation.Descriptions/InvocationDescription.cs:line 14
at LivingDocumentation.InvocationsAnalyzer.VisitInvocationExpression(InvocationExpressionSyntax node) in /
/src/LivingDocumentation.Analyzer/Analyzers/InvocationsAnalyzer.cs:line 95
at Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax.Accept(CSharpSyntaxVisitor visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitEqualsValueClause(EqualsValueClauseSyntax node)
at Microsoft.CodeAnalysis.CSharp.Syntax.EqualsValueClauseSyntax.Accept(CSharpSyntaxVisitor visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitVariableDeclarator(VariableDeclaratorSyntax node)
at Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclaratorSyntax.Accept(CSharpSyntaxVisitor visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitVariableDeclaration(VariableDeclarationSyntax node)
at Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax.Accept(CSharpSyntaxVisitor visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
at Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax.Accept(CSharpSyntaxVisitor visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitBlock(BlockSyntax node)
at Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax.Accept(CSharpSyntaxVisitor visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node)
at LivingDocumentation.BranchingAnalyzer.VisitIfStatement(IfStatementSyntax node) in //src/LivingDocumentation.Analyzer/Analyzers/BranchingAnalyzer.cs:line 25
at Microsoft.CodeAnalysis.CSharp.Syntax.IfStatementSyntax.Accept(CSharpSyntaxVisitor visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node)
at LivingDocumentation.InvocationsAnalyzer.VisitIfStatement(IfStatementSyntax node) in /
/src/LivingDocumentation.Analyzer/Analyzers/InvocationsAnalyzer.cs:line 51
at Microsoft.CodeAnalysis.CSharp.Syntax.IfStatementSyntax.Accept(CSharpSyntaxVisitor visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitBlock(BlockSyntax node)
at Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax.Accept(CSharpSyntaxVisitor visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node)
at LivingDocumentation.SourceAnalyzer.ExtractBaseMethodDeclaration(BaseMethodDeclarationSyntax node, IHaveAMethodBody method) in //src/LivingDocumentation.Analyzer/Analyzers/SourceAnalyzer.cs:line 326
at LivingDocumentation.SourceAnalyzer.VisitMethodDeclaration(MethodDeclarationSyntax node) in /
/src/LivingDocumentation.Analyzer/Analyzers/SourceAnalyzer.cs:line 203
at Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax.Accept(CSharpSyntaxVisitor visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitClassDeclaration(ClassDeclarationSyntax node)
at LivingDocumentation.SourceAnalyzer.VisitClassDeclaration(ClassDeclarationSyntax node) in //src/LivingDocumentation.Analyzer/Analyzers/SourceAnalyzer.cs:line 22
at Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax.Accept(CSharpSyntaxVisitor visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitFileScopedNamespaceDeclaration(FileScopedNamespaceDeclarationSyntax node)
at Microsoft.CodeAnalysis.CSharp.Syntax.FileScopedNamespaceDeclarationSyntax.Accept(CSharpSyntaxVisitor visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitCompilationUnit(CompilationUnitSyntax node)
at Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax.Accept(CSharpSyntaxVisitor visitor)
at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node)
at LivingDocumentation.Program.AnalyzeProjectAsyc(List1 types, Project project) in /_/src/LivingDocumentation.Analyzer/Program.cs:line 113 at LivingDocumentation.Program.AnalyzeSolutionFileAsync(List1 types, String solutionFile) in /
/src/LivingDocumentation.Analyzer/Program.cs:line 67
at LivingDocumentation.Program.RunApplicationAsync(Options options) in //src/LivingDocumentation.Analyzer/Program.cs:line 33
at LivingDocumentation.Program.Main(String[] args) in /
/src/LivingDocumentation.Analyzer/Program.cs:line 18
at LivingDocumentation.Program.

(String[] args)

Cannot analyse solution

I Guess that this needs to be more robust. Rather skip something than not doing anything

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
at LivingDocumentation.Program.<>c.b__8_3(IPackageReference pr) in /home/vsts/work/1/s/src/LivingDocumentation.Analyzer/Program.cs:line 63
at System.Linq.Enumerable.Any[TSource](IEnumerable1 source, Func2 predicate)
at LivingDocumentation.Program.<>c__DisplayClass8_0.b__1(Project p) in /home/vsts/work/1/s/src/LivingDocumentation.Analyzer/Program.cs:line 63
at System.Linq.Enumerable.WhereEnumerableIterator1.MoveNext() at LivingDocumentation.Program.AnalyzeSolutionAsync(IList1 types, String solutionFile) in /home/vsts/work/1/s/src/LivingDocumentation.Analyzer/Program.cs:line 65
at LivingDocumentation.Program.RunApplicationAsync(Options options) in /home/vsts/work/1/s/src/LivingDocumentation.Analyzer/Program.cs:line 38
at LivingDocumentation.Program.Main(String[] args) in /home/vsts/work/1/s/src/LivingDocumentation.Analyzer/Program.cs:line 25
at LivingDocumentation.Program.

(String[] args)

How to deal with contextual keywords (nameof() or dynamic) in the InvocationExpressionSyntax

Consider the following code snippet:

if (string.IsNullOrWhiteSpace(filename))
                throw new ArgumentException(@"Filename cannot be null or whitespace.", nameof(filename));

Within C#, nameof is a contextual keyword. This means there is no way to distinguish the nameof keyword from a call to a method that happens to be named nameof.

When the previous code gets visited, the nameof(filename) node gets processed by the VisitInvocationExpression as an InvocationExpressionSyntax.
https://github.com/eNeRGy164/LivingDocumentation/blob/main/src/LivingDocumentation.Analyzer/Analyzers/InvocationsAnalyzer.cs

The GetExpressionWithSymbol method returns null (this.semanticModel.GetSymbolInfo(expression).Symbol is null).

When running in verbose, the output will display all the occurences of nameof():
WARN: Could not resolve type of invocation of the following block:

The question is: should these particular cases be ignored altogether, or should they be handled?

Note: a similar situation is encounted with dynamic types:

public void MyMethod(dynamic dynamicPayload)
{
   string realPayload = JsonConvert.SerializeObject(dynamicPayload);
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.