cod8a 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cod8a/__init__.py +3 -0
- cod8a/cli.py +93 -0
- cod8a/cod8a.py +4 -0
- cod8a/dotnet/CodeAnalysis/CodeAnalyzer.csproj +14 -0
- cod8a/dotnet/CodeAnalysis/CodeAnalyzer.csproj.lscache +262 -0
- cod8a/dotnet/CodeAnalysis/Parsers/BaseParser.cs +17 -0
- cod8a/dotnet/CodeAnalysis/Parsers/FileParser.cs +150 -0
- cod8a/dotnet/CodeAnalysis/Parsers/ProjectParser.cs +37 -0
- cod8a/dotnet/CodeAnalysis/Parsers/SolutionParser.cs +17 -0
- cod8a/dotnet/CodeAnalysis/Program.cs +58 -0
- cod8a/dotnet/CodeAnalysis/models/FileStructure.cs +92 -0
- cod8a/dotnet/CodeAnalysis/models/ProjectStructure.cs +29 -0
- cod8a/dotnet/CodeAnalysis/models/SolutionStructure.cs +28 -0
- cod8a/dotnet/Test/CodeAnalyzerTest.csproj +25 -0
- cod8a/dotnet/Test/Mermaid/ClassDiagramTest.cs +71 -0
- cod8a/enums/__init__.py +0 -0
- cod8a/enums/diagram_type.py +10 -0
- cod8a/generators/mermaid/class_diagram.py +165 -0
- cod8a/generators/mermaid/flowchart_diagram.py +51 -0
- cod8a/generators/mermaid/sequence_diagram.py +80 -0
- cod8a/helpers/__init__.py +0 -0
- cod8a/helpers/cli_helper.py +79 -0
- cod8a/models/__init__.py +0 -0
- cod8a/models/models.py +60 -0
- cod8a/parsers/dotnet_parser.py +100 -0
- cod8a/parsers/python_parser.py +138 -0
- cod8a-0.1.0.dist-info/METADATA +134 -0
- cod8a-0.1.0.dist-info/RECORD +31 -0
- cod8a-0.1.0.dist-info/WHEEL +4 -0
- cod8a-0.1.0.dist-info/entry_points.txt +4 -0
- cod8a-0.1.0.dist-info/licenses/LICENSE +21 -0
cod8a/__init__.py
ADDED
cod8a/cli.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import click
|
|
2
|
+
import os
|
|
3
|
+
from dataclasses import asdict
|
|
4
|
+
|
|
5
|
+
from cod8a.generators.mermaid.class_diagram import generate_class_diagram
|
|
6
|
+
from cod8a.generators.mermaid.flowchart_diagram import generate_flowchart_diagram
|
|
7
|
+
from cod8a.generators.mermaid.sequence_diagram import generate_sequence_diagram
|
|
8
|
+
from cod8a.helpers.cli_helper import extract_structure, save_diagram
|
|
9
|
+
from cod8a.enums.diagram_type import DiagramType
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ExpandedHelpGroup(click.Group):
|
|
13
|
+
def format_help(self, ctx, formatter):
|
|
14
|
+
# 1. Main help (Group docstring)
|
|
15
|
+
self.format_usage(ctx, formatter)
|
|
16
|
+
self.format_help_text(ctx, formatter)
|
|
17
|
+
self.format_options(ctx, formatter)
|
|
18
|
+
|
|
19
|
+
# 2. Subcommands and their options
|
|
20
|
+
for command_name in self.list_commands(ctx):
|
|
21
|
+
command = self.get_command(ctx, command_name)
|
|
22
|
+
if command and not command.hidden:
|
|
23
|
+
formatter.write_paragraph()
|
|
24
|
+
with formatter.section(f"Command: {command_name}"):
|
|
25
|
+
# Usage and help text
|
|
26
|
+
formatter.write_text(command.help or "")
|
|
27
|
+
command.format_options(ctx, formatter)
|
|
28
|
+
|
|
29
|
+
@click.group(cls=ExpandedHelpGroup)
|
|
30
|
+
def cli():
|
|
31
|
+
"""cod8a (pronounced codetta) is a tool for analyzing and visualizing code structure.
|
|
32
|
+
|
|
33
|
+
It supports both Python and C# projects, generating Mermaid-compatible diagrams.
|
|
34
|
+
"""
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
# Generation of UML Diagrams
|
|
38
|
+
@cli.command(help="Generate a Mermaid diagram from the source code structure.")
|
|
39
|
+
@click.option('-p', '--path', required=True,
|
|
40
|
+
help='The path to the file or directory to analyze.')
|
|
41
|
+
@click.option('-d', '--diagram', 'diagram_type', default='class',
|
|
42
|
+
type=click.Choice(["seq", "s", "sequence", "flow", "f", "flowchart", "c", "class"]),
|
|
43
|
+
help='The type of diagram to generate (default: class).')
|
|
44
|
+
@click.option('-o', '--output',
|
|
45
|
+
help='Optional output file path. If not provided, you will be prompted to save to the Downloads folder.')
|
|
46
|
+
def uml(path, diagram_type, output):
|
|
47
|
+
"""Generate UML diagram (Mermaid format)."""
|
|
48
|
+
struct = extract_structure(path)
|
|
49
|
+
base_name = os.path.basename(path or os.getcwd())
|
|
50
|
+
# print(struct)
|
|
51
|
+
|
|
52
|
+
if not struct:
|
|
53
|
+
click.echo("Error: Could not extract structure.")
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
canon_type = "class"
|
|
57
|
+
if DiagramType.FLOWCHART.value.startswith(diagram_type):
|
|
58
|
+
diagram = generate_flowchart_diagram(struct, base_name)
|
|
59
|
+
canon_type = "flowchart"
|
|
60
|
+
elif DiagramType.SEQUENCE.value.startswith(diagram_type):
|
|
61
|
+
diagram = generate_sequence_diagram(struct)
|
|
62
|
+
canon_type = "sequence"
|
|
63
|
+
else:
|
|
64
|
+
diagram = generate_class_diagram(struct)
|
|
65
|
+
canon_type = "class"
|
|
66
|
+
|
|
67
|
+
print(diagram)
|
|
68
|
+
|
|
69
|
+
# Save diagram
|
|
70
|
+
save_diagram(struct, canon_type, diagram, output, path)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# TODO Generating code documentation
|
|
74
|
+
@click.command(help="[TODO] Generate documentation (Markdown format) from code structure.")
|
|
75
|
+
@click.option('-p', '--path', help='Specific path of file(s) to analyze')
|
|
76
|
+
@click.option('--json', 'output_json', is_flag=True, help='Output in JSON format')
|
|
77
|
+
def doc_cli(path, output_json):
|
|
78
|
+
"""Generate documentation (Markdown format)."""
|
|
79
|
+
target = path or os.getcwd()
|
|
80
|
+
struct = extract_structure(target)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# Main entry point for cod8a
|
|
84
|
+
def main():
|
|
85
|
+
cli.add_command(doc_cli, name="doc")
|
|
86
|
+
cli()
|
|
87
|
+
|
|
88
|
+
# Separate entry point for code8a
|
|
89
|
+
def doc_main():
|
|
90
|
+
doc_cli()
|
|
91
|
+
|
|
92
|
+
if __name__ == "__main__":
|
|
93
|
+
main()
|
cod8a/cod8a.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
|
2
|
+
|
|
3
|
+
<PropertyGroup>
|
|
4
|
+
<OutputType>Exe</OutputType>
|
|
5
|
+
<TargetFramework>net10.0</TargetFramework>
|
|
6
|
+
<ImplicitUsings>enable</ImplicitUsings>
|
|
7
|
+
<Nullable>enable</Nullable>
|
|
8
|
+
</PropertyGroup>
|
|
9
|
+
|
|
10
|
+
<ItemGroup>
|
|
11
|
+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="5.3.0" />
|
|
12
|
+
</ItemGroup>
|
|
13
|
+
|
|
14
|
+
</Project>
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
version=1
|
|
2
|
+
|
|
3
|
+
# This file caches language service data to improve the performance of C# Dev Kit.
|
|
4
|
+
# It is not intended for manual editing. It can safely be deleted and will be
|
|
5
|
+
# regenerated automatically. For more information, see https://aka.ms/lscache
|
|
6
|
+
#
|
|
7
|
+
# To control where cache files are stored, use the following VS Code setting:
|
|
8
|
+
# "dotnet.projectsystem.cacheInProjectFolder": true
|
|
9
|
+
|
|
10
|
+
[project]
|
|
11
|
+
language=C#
|
|
12
|
+
primary
|
|
13
|
+
lastDtbSucceeded
|
|
14
|
+
|
|
15
|
+
[properties]
|
|
16
|
+
AssemblyName=CodeAnalyzer
|
|
17
|
+
CommandLineArgsForDesignTimeEvaluation=-langversion:14.0 -define:TRACE
|
|
18
|
+
CompilerGeneratedFilesOutputPath=
|
|
19
|
+
MaxSupportedLangVersion=14.0
|
|
20
|
+
ProjectAssetsFile=<PATH>obj/project.assets.json
|
|
21
|
+
RootNamespace=CodeAnalyzer
|
|
22
|
+
RunAnalyzers=
|
|
23
|
+
RunAnalyzersDuringLiveAnalysis=
|
|
24
|
+
SolutionPath=<PATH>../../../../cod8a.sln
|
|
25
|
+
TargetFrameworkIdentifier=.NETCoreApp
|
|
26
|
+
TargetPath=<PATH>bin/Debug/net10.0/CodeAnalyzer.dll
|
|
27
|
+
TargetRefPath=<PATH>obj/Debug/net10.0/ref/CodeAnalyzer.dll
|
|
28
|
+
TemporaryDependencyNodeTargetIdentifier=net10.0
|
|
29
|
+
|
|
30
|
+
[commandLineArguments]
|
|
31
|
+
/noconfig
|
|
32
|
+
/unsafe-
|
|
33
|
+
/checked-
|
|
34
|
+
/nowarn:1701,1702,1701,1702
|
|
35
|
+
/fullpaths
|
|
36
|
+
/nostdlib+
|
|
37
|
+
/errorreport:prompt
|
|
38
|
+
/warn:10
|
|
39
|
+
/define:TRACE;DEBUG;NET;NET10_0;NETCOREAPP;NET5_0_OR_GREATER;NET6_0_OR_GREATER;NET7_0_OR_GREATER;NET8_0_OR_GREATER;NET9_0_OR_GREATER;NET10_0_OR_GREATER;NETCOREAPP1_0_OR_GREATER;NETCOREAPP1_1_OR_GREATER;NETCOREAPP2_0_OR_GREATER;NETCOREAPP2_1_OR_GREATER;NETCOREAPP2_2_OR_GREATER;NETCOREAPP3_0_OR_GREATER;NETCOREAPP3_1_OR_GREATER
|
|
40
|
+
/highentropyva+
|
|
41
|
+
/nullable:enable
|
|
42
|
+
/features:"InterceptorsNamespaces=;Microsoft.Extensions.Validation.Generated"
|
|
43
|
+
/debug+
|
|
44
|
+
/debug:portable
|
|
45
|
+
/filealign:512
|
|
46
|
+
/optimize-
|
|
47
|
+
/out:obj/Debug/net10.0/CodeAnalyzer.dll
|
|
48
|
+
/refout:obj/Debug/net10.0/refint/CodeAnalyzer.dll
|
|
49
|
+
/target:exe
|
|
50
|
+
/warnaserror-
|
|
51
|
+
/utf8output
|
|
52
|
+
/deterministic+
|
|
53
|
+
/langversion:14.0
|
|
54
|
+
/warnaserror+:NU1605,SYSLIB0011
|
|
55
|
+
|
|
56
|
+
[sourceFiles]
|
|
57
|
+
models/
|
|
58
|
+
FileStructure.cs
|
|
59
|
+
ProjectStructure.cs
|
|
60
|
+
SolutionStructure.cs
|
|
61
|
+
obj/Debug/net10.0/
|
|
62
|
+
.NETCoreApp,Version=v10.0.AssemblyAttributes.cs
|
|
63
|
+
CodeAnalyzer.AssemblyInfo.cs
|
|
64
|
+
CodeAnalyzer.GlobalUsings.g.cs
|
|
65
|
+
Parsers/
|
|
66
|
+
BaseParser.cs
|
|
67
|
+
FileParser.cs
|
|
68
|
+
ProjectParser.cs
|
|
69
|
+
SolutionParser.cs
|
|
70
|
+
Program.cs
|
|
71
|
+
|
|
72
|
+
[metadataReferences]
|
|
73
|
+
<DOTNET>/packs/Microsoft.NETCore.App.Ref/10.0.3/ref/net10.0/
|
|
74
|
+
Microsoft.CSharp.dll
|
|
75
|
+
Microsoft.VisualBasic.Core.dll
|
|
76
|
+
Microsoft.VisualBasic.dll
|
|
77
|
+
Microsoft.Win32.Primitives.dll
|
|
78
|
+
Microsoft.Win32.Registry.dll
|
|
79
|
+
mscorlib.dll
|
|
80
|
+
netstandard.dll
|
|
81
|
+
System.AppContext.dll
|
|
82
|
+
System.Buffers.dll
|
|
83
|
+
System.Collections.Concurrent.dll
|
|
84
|
+
System.Collections.dll
|
|
85
|
+
System.Collections.Immutable.dll
|
|
86
|
+
System.Collections.NonGeneric.dll
|
|
87
|
+
System.Collections.Specialized.dll
|
|
88
|
+
System.ComponentModel.Annotations.dll
|
|
89
|
+
System.ComponentModel.DataAnnotations.dll
|
|
90
|
+
System.ComponentModel.dll
|
|
91
|
+
System.ComponentModel.EventBasedAsync.dll
|
|
92
|
+
System.ComponentModel.Primitives.dll
|
|
93
|
+
System.ComponentModel.TypeConverter.dll
|
|
94
|
+
System.Configuration.dll
|
|
95
|
+
System.Console.dll
|
|
96
|
+
System.Core.dll
|
|
97
|
+
System.Data.Common.dll
|
|
98
|
+
System.Data.DataSetExtensions.dll
|
|
99
|
+
System.Data.dll
|
|
100
|
+
System.Diagnostics.Contracts.dll
|
|
101
|
+
System.Diagnostics.Debug.dll
|
|
102
|
+
System.Diagnostics.DiagnosticSource.dll
|
|
103
|
+
System.Diagnostics.FileVersionInfo.dll
|
|
104
|
+
System.Diagnostics.Process.dll
|
|
105
|
+
System.Diagnostics.StackTrace.dll
|
|
106
|
+
System.Diagnostics.TextWriterTraceListener.dll
|
|
107
|
+
System.Diagnostics.Tools.dll
|
|
108
|
+
System.Diagnostics.TraceSource.dll
|
|
109
|
+
System.Diagnostics.Tracing.dll
|
|
110
|
+
System.dll
|
|
111
|
+
System.Drawing.dll
|
|
112
|
+
System.Drawing.Primitives.dll
|
|
113
|
+
System.Dynamic.Runtime.dll
|
|
114
|
+
System.Formats.Asn1.dll
|
|
115
|
+
System.Formats.Tar.dll
|
|
116
|
+
System.Globalization.Calendars.dll
|
|
117
|
+
System.Globalization.dll
|
|
118
|
+
System.Globalization.Extensions.dll
|
|
119
|
+
System.IO.Compression.Brotli.dll
|
|
120
|
+
System.IO.Compression.dll
|
|
121
|
+
System.IO.Compression.FileSystem.dll
|
|
122
|
+
System.IO.Compression.ZipFile.dll
|
|
123
|
+
System.IO.dll
|
|
124
|
+
System.IO.FileSystem.AccessControl.dll
|
|
125
|
+
System.IO.FileSystem.dll
|
|
126
|
+
System.IO.FileSystem.DriveInfo.dll
|
|
127
|
+
System.IO.FileSystem.Primitives.dll
|
|
128
|
+
System.IO.FileSystem.Watcher.dll
|
|
129
|
+
System.IO.IsolatedStorage.dll
|
|
130
|
+
System.IO.MemoryMappedFiles.dll
|
|
131
|
+
System.IO.Pipelines.dll
|
|
132
|
+
System.IO.Pipes.AccessControl.dll
|
|
133
|
+
System.IO.Pipes.dll
|
|
134
|
+
System.IO.UnmanagedMemoryStream.dll
|
|
135
|
+
System.Linq.AsyncEnumerable.dll
|
|
136
|
+
System.Linq.dll
|
|
137
|
+
System.Linq.Expressions.dll
|
|
138
|
+
System.Linq.Parallel.dll
|
|
139
|
+
System.Linq.Queryable.dll
|
|
140
|
+
System.Memory.dll
|
|
141
|
+
System.Net.dll
|
|
142
|
+
System.Net.Http.dll
|
|
143
|
+
System.Net.Http.Json.dll
|
|
144
|
+
System.Net.HttpListener.dll
|
|
145
|
+
System.Net.Mail.dll
|
|
146
|
+
System.Net.NameResolution.dll
|
|
147
|
+
System.Net.NetworkInformation.dll
|
|
148
|
+
System.Net.Ping.dll
|
|
149
|
+
System.Net.Primitives.dll
|
|
150
|
+
System.Net.Quic.dll
|
|
151
|
+
System.Net.Requests.dll
|
|
152
|
+
System.Net.Security.dll
|
|
153
|
+
System.Net.ServerSentEvents.dll
|
|
154
|
+
System.Net.ServicePoint.dll
|
|
155
|
+
System.Net.Sockets.dll
|
|
156
|
+
System.Net.WebClient.dll
|
|
157
|
+
System.Net.WebHeaderCollection.dll
|
|
158
|
+
System.Net.WebProxy.dll
|
|
159
|
+
System.Net.WebSockets.Client.dll
|
|
160
|
+
System.Net.WebSockets.dll
|
|
161
|
+
System.Numerics.dll
|
|
162
|
+
System.Numerics.Vectors.dll
|
|
163
|
+
System.ObjectModel.dll
|
|
164
|
+
System.Reflection.DispatchProxy.dll
|
|
165
|
+
System.Reflection.dll
|
|
166
|
+
System.Reflection.Emit.dll
|
|
167
|
+
System.Reflection.Emit.ILGeneration.dll
|
|
168
|
+
System.Reflection.Emit.Lightweight.dll
|
|
169
|
+
System.Reflection.Extensions.dll
|
|
170
|
+
System.Reflection.Metadata.dll
|
|
171
|
+
System.Reflection.Primitives.dll
|
|
172
|
+
System.Reflection.TypeExtensions.dll
|
|
173
|
+
System.Resources.Reader.dll
|
|
174
|
+
System.Resources.ResourceManager.dll
|
|
175
|
+
System.Resources.Writer.dll
|
|
176
|
+
System.Runtime.CompilerServices.Unsafe.dll
|
|
177
|
+
System.Runtime.CompilerServices.VisualC.dll
|
|
178
|
+
System.Runtime.dll
|
|
179
|
+
System.Runtime.Extensions.dll
|
|
180
|
+
System.Runtime.Handles.dll
|
|
181
|
+
System.Runtime.InteropServices.dll
|
|
182
|
+
System.Runtime.InteropServices.JavaScript.dll
|
|
183
|
+
System.Runtime.InteropServices.RuntimeInformation.dll
|
|
184
|
+
System.Runtime.Intrinsics.dll
|
|
185
|
+
System.Runtime.Loader.dll
|
|
186
|
+
System.Runtime.Numerics.dll
|
|
187
|
+
System.Runtime.Serialization.dll
|
|
188
|
+
System.Runtime.Serialization.Formatters.dll
|
|
189
|
+
System.Runtime.Serialization.Json.dll
|
|
190
|
+
System.Runtime.Serialization.Primitives.dll
|
|
191
|
+
System.Runtime.Serialization.Xml.dll
|
|
192
|
+
System.Security.AccessControl.dll
|
|
193
|
+
System.Security.Claims.dll
|
|
194
|
+
System.Security.Cryptography.Algorithms.dll
|
|
195
|
+
System.Security.Cryptography.Cng.dll
|
|
196
|
+
System.Security.Cryptography.Csp.dll
|
|
197
|
+
System.Security.Cryptography.dll
|
|
198
|
+
System.Security.Cryptography.Encoding.dll
|
|
199
|
+
System.Security.Cryptography.OpenSsl.dll
|
|
200
|
+
System.Security.Cryptography.Primitives.dll
|
|
201
|
+
System.Security.Cryptography.X509Certificates.dll
|
|
202
|
+
System.Security.dll
|
|
203
|
+
System.Security.Principal.dll
|
|
204
|
+
System.Security.Principal.Windows.dll
|
|
205
|
+
System.Security.SecureString.dll
|
|
206
|
+
System.ServiceModel.Web.dll
|
|
207
|
+
System.ServiceProcess.dll
|
|
208
|
+
System.Text.Encoding.CodePages.dll
|
|
209
|
+
System.Text.Encoding.dll
|
|
210
|
+
System.Text.Encoding.Extensions.dll
|
|
211
|
+
System.Text.Encodings.Web.dll
|
|
212
|
+
System.Text.Json.dll
|
|
213
|
+
System.Text.RegularExpressions.dll
|
|
214
|
+
System.Threading.AccessControl.dll
|
|
215
|
+
System.Threading.Channels.dll
|
|
216
|
+
System.Threading.dll
|
|
217
|
+
System.Threading.Overlapped.dll
|
|
218
|
+
System.Threading.Tasks.Dataflow.dll
|
|
219
|
+
System.Threading.Tasks.dll
|
|
220
|
+
System.Threading.Tasks.Extensions.dll
|
|
221
|
+
System.Threading.Tasks.Parallel.dll
|
|
222
|
+
System.Threading.Thread.dll
|
|
223
|
+
System.Threading.ThreadPool.dll
|
|
224
|
+
System.Threading.Timer.dll
|
|
225
|
+
System.Transactions.dll
|
|
226
|
+
System.Transactions.Local.dll
|
|
227
|
+
System.ValueTuple.dll
|
|
228
|
+
System.Web.dll
|
|
229
|
+
System.Web.HttpUtility.dll
|
|
230
|
+
System.Windows.dll
|
|
231
|
+
System.Xml.dll
|
|
232
|
+
System.Xml.Linq.dll
|
|
233
|
+
System.Xml.ReaderWriter.dll
|
|
234
|
+
System.Xml.Serialization.dll
|
|
235
|
+
System.Xml.XDocument.dll
|
|
236
|
+
System.Xml.XmlDocument.dll
|
|
237
|
+
System.Xml.XmlSerializer.dll
|
|
238
|
+
System.Xml.XPath.dll
|
|
239
|
+
System.Xml.XPath.XDocument.dll
|
|
240
|
+
WindowsBase.dll
|
|
241
|
+
<NUGET>/
|
|
242
|
+
microsoft.codeanalysis.common/5.3.0/lib/net10.0/Microsoft.CodeAnalysis.dll
|
|
243
|
+
microsoft.codeanalysis.csharp/5.3.0/lib/net10.0/Microsoft.CodeAnalysis.CSharp.dll
|
|
244
|
+
|
|
245
|
+
[analyzerReferences]
|
|
246
|
+
<DOTNET>/packs/Microsoft.NETCore.App.Ref/10.0.3/analyzers/dotnet/cs/
|
|
247
|
+
Microsoft.Interop.ComInterfaceGenerator.dll
|
|
248
|
+
Microsoft.Interop.JavaScript.JSImportGenerator.dll
|
|
249
|
+
Microsoft.Interop.LibraryImportGenerator.dll
|
|
250
|
+
Microsoft.Interop.SourceGeneration.dll
|
|
251
|
+
System.Text.Json.SourceGeneration.dll
|
|
252
|
+
System.Text.RegularExpressions.Generator.dll
|
|
253
|
+
<DOTNET>/sdk/10.0.103/Sdks/Microsoft.NET.Sdk/analyzers/
|
|
254
|
+
Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll
|
|
255
|
+
Microsoft.CodeAnalysis.NetAnalyzers.dll
|
|
256
|
+
<NUGET>/microsoft.codeanalysis.analyzers/5.3.0-2.25625.1/analyzers/dotnet/cs/
|
|
257
|
+
Microsoft.CodeAnalysis.Analyzers.dll
|
|
258
|
+
Microsoft.CodeAnalysis.CSharp.Analyzers.dll
|
|
259
|
+
|
|
260
|
+
[analyzerConfigFiles]
|
|
261
|
+
<DOTNET>/sdk/10.0.103/Sdks/Microsoft.NET.Sdk/analyzers/build/config/analysislevel_10_default.globalconfig
|
|
262
|
+
obj/Debug/net10.0/CodeAnalyzer.GeneratedMSBuildEditorConfig.editorconfig
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
using CodeAnalyzer.Models;
|
|
2
|
+
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
using System.Text;
|
|
6
|
+
|
|
7
|
+
namespace CodeAnalyzer.Parsers
|
|
8
|
+
{
|
|
9
|
+
public abstract class BaseParser<T>
|
|
10
|
+
{
|
|
11
|
+
/// <summary>
|
|
12
|
+
/// Gets the name of the file associated with this instance.
|
|
13
|
+
/// </summary>
|
|
14
|
+
public abstract string Name { get; init; }
|
|
15
|
+
public abstract T Parse();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
using CodeAnalyzer.Models;
|
|
2
|
+
using Microsoft.CodeAnalysis;
|
|
3
|
+
using Microsoft.CodeAnalysis.CSharp;
|
|
4
|
+
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
5
|
+
using System;
|
|
6
|
+
using System.Collections.Generic;
|
|
7
|
+
using System.Text;
|
|
8
|
+
using System.Text.Json;
|
|
9
|
+
|
|
10
|
+
namespace CodeAnalyzer.Parsers
|
|
11
|
+
{
|
|
12
|
+
/// <summary>
|
|
13
|
+
/// Provides functionality to parse C# source code files and extract their structural information, such as using
|
|
14
|
+
/// directives and class definitions.
|
|
15
|
+
/// </summary>
|
|
16
|
+
/// <remarks>Use this class to analyze the contents of a C# file by supplying its code and file name. The
|
|
17
|
+
/// parser returns a structured representation of the file, which includes details about its using directives and
|
|
18
|
+
/// classes. This class is not thread-safe.</remarks>
|
|
19
|
+
public sealed partial class FileParser<T> : BaseParser<T> where T : FileStructure
|
|
20
|
+
{
|
|
21
|
+
|
|
22
|
+
public override string Name { get; init; }
|
|
23
|
+
|
|
24
|
+
/// <summary>
|
|
25
|
+
/// Gets the code associated with this instance.
|
|
26
|
+
/// </summary>
|
|
27
|
+
public string FilePath { get; init; }
|
|
28
|
+
public override T Parse()
|
|
29
|
+
{
|
|
30
|
+
try
|
|
31
|
+
{
|
|
32
|
+
var code = File.ReadAllText(FilePath);
|
|
33
|
+
// Parse the code into a SyntaxTree
|
|
34
|
+
SyntaxTree tree = CSharpSyntaxTree.ParseText(code);
|
|
35
|
+
|
|
36
|
+
// Get the root node of the tree
|
|
37
|
+
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
var directory = Directory.GetCurrentDirectory();
|
|
41
|
+
var fileName = Path.GetFileName(directory);
|
|
42
|
+
var id = 0;
|
|
43
|
+
var usings = root.Usings.Select(b =>
|
|
44
|
+
{
|
|
45
|
+
var name = GetName(b.Name);
|
|
46
|
+
return new UsingDirective(++id, name);
|
|
47
|
+
});
|
|
48
|
+
var fileStructure = new FileStructure
|
|
49
|
+
{
|
|
50
|
+
Id = 1,
|
|
51
|
+
Name = fileName,
|
|
52
|
+
UsingDirectives = usings.ToList(),
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
fileStructure.Classes = GetClassDeclaration(root);
|
|
57
|
+
|
|
58
|
+
return (T)fileStructure;
|
|
59
|
+
}
|
|
60
|
+
catch (Exception ex)
|
|
61
|
+
{
|
|
62
|
+
throw;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private string GetName(NameSyntax? nameSyntax)
|
|
67
|
+
{
|
|
68
|
+
try
|
|
69
|
+
{
|
|
70
|
+
return nameSyntax switch
|
|
71
|
+
{
|
|
72
|
+
null => string.Empty,
|
|
73
|
+
SimpleNameSyntax simpleName => simpleName.Identifier.Text,
|
|
74
|
+
QualifiedNameSyntax qualifiedName => qualifiedName.Right.Identifier.Text,
|
|
75
|
+
AliasQualifiedNameSyntax aliasQualifiedName => aliasQualifiedName.Name.Identifier.Text,
|
|
76
|
+
_ => string.Empty
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
catch( Exception ex )
|
|
80
|
+
{
|
|
81
|
+
throw;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private List<ClassStructure> GetClassDeclaration(CompilationUnitSyntax root)
|
|
86
|
+
{
|
|
87
|
+
var classes = new List<ClassStructure>();
|
|
88
|
+
try
|
|
89
|
+
{
|
|
90
|
+
var typeDeclarationSyntaxes = root.DescendantNodes().OfType<TypeDeclarationSyntax>();
|
|
91
|
+
|
|
92
|
+
foreach (var classDeclaration in typeDeclarationSyntaxes)
|
|
93
|
+
{
|
|
94
|
+
var methodStructures = new List<MethodStructure>();
|
|
95
|
+
var parameterStructures = new List<ParameterStructure>();
|
|
96
|
+
var fieldStructures = new List<FieldStructure>();
|
|
97
|
+
|
|
98
|
+
var relationships = new List<RelationShip>();
|
|
99
|
+
|
|
100
|
+
var baseTypes = classDeclaration.BaseList?.Types;
|
|
101
|
+
int id = 0;
|
|
102
|
+
|
|
103
|
+
if(baseTypes is not null)
|
|
104
|
+
{
|
|
105
|
+
|
|
106
|
+
relationships.AddRange(
|
|
107
|
+
baseTypes.Value.Select(b => {
|
|
108
|
+
string parent = b.Type switch
|
|
109
|
+
{
|
|
110
|
+
SimpleNameSyntax simpleName => simpleName.Identifier.Text,
|
|
111
|
+
QualifiedNameSyntax qualifiedName => qualifiedName.Right.Identifier.Text,
|
|
112
|
+
_ => b.Type.ToString().Split('<')[0]
|
|
113
|
+
};
|
|
114
|
+
var type = parent.StartsWith("I") && parent.Length > 1 && char.IsUpper(parent[1]) ? "Interface" : "Class";
|
|
115
|
+
return new RelationShip (++id, type, parent);
|
|
116
|
+
})
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Extract standard fields and properties
|
|
121
|
+
fieldStructures.AddRange(classDeclaration.DescendantNodes().OfType<FieldDeclarationSyntax>().Select(f => new FieldStructure(default, f.Declaration.Variables.First().Identifier.Text, f.Modifiers.ToFullString().Trim(), f.Declaration.Type.ToString(), f.GetLeadingTrivia().ToString().Trim())));
|
|
122
|
+
fieldStructures.AddRange(classDeclaration.DescendantNodes().OfType<PropertyDeclarationSyntax>().Select(f => new FieldStructure(default, f.Identifier.Text, f.Modifiers.ToFullString().Trim(), f.Type.ToString(), f.GetLeadingTrivia().ToString().Trim())));
|
|
123
|
+
|
|
124
|
+
// Extract record positional parameters as properties
|
|
125
|
+
if (classDeclaration is RecordDeclarationSyntax recordDecl && recordDecl.ParameterList != null)
|
|
126
|
+
{
|
|
127
|
+
fieldStructures.AddRange(recordDecl.ParameterList.Parameters.Select(p => new FieldStructure(default, p.Identifier.Text, "public", p.Type?.ToString() ?? "", p.GetLeadingTrivia().ToString().Trim())));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
foreach (var method in classDeclaration.Members.OfType<MethodDeclarationSyntax>())
|
|
131
|
+
{
|
|
132
|
+
var parameters = method.ParameterList.Parameters.Select(p => new ParameterStructure(p.Identifier.Text, p.Modifiers.ToFullString().Trim(), p.Type?.ToString() ?? "", p.GetLeadingTrivia().ToString().Trim())).ToList();
|
|
133
|
+
parameterStructures.AddRange(parameters);
|
|
134
|
+
|
|
135
|
+
methodStructures.Add(new MethodStructure(default, method.Identifier.Text, method.Modifiers.ToFullString().Trim(), method.ReturnType.ToString(), parameters, method.GetLeadingTrivia().ToString().Trim()));
|
|
136
|
+
}
|
|
137
|
+
classes.Add(new ClassStructure(default, classDeclaration.Identifier.Text, methodStructures, fieldStructures, classDeclaration.Keyword.ToFullString().Trim(), relationships, classDeclaration.GetLeadingTrivia().ToString().Trim()));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return classes;
|
|
141
|
+
}
|
|
142
|
+
catch (Exception ex)
|
|
143
|
+
{
|
|
144
|
+
throw;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
using CodeAnalyzer.Models;
|
|
2
|
+
using Microsoft.CodeAnalysis;
|
|
3
|
+
using Microsoft.CodeAnalysis.CSharp;
|
|
4
|
+
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
5
|
+
using System;
|
|
6
|
+
using System.Collections.Generic;
|
|
7
|
+
using System.Text;
|
|
8
|
+
|
|
9
|
+
namespace CodeAnalyzer.Parsers
|
|
10
|
+
{
|
|
11
|
+
public sealed partial class ProjectParser<T> : BaseParser<T> where T : ProjectStructure
|
|
12
|
+
{
|
|
13
|
+
public override string Name { get; init; }
|
|
14
|
+
|
|
15
|
+
public string[] FilePaths { get; init; }
|
|
16
|
+
|
|
17
|
+
public override T Parse()
|
|
18
|
+
{
|
|
19
|
+
try
|
|
20
|
+
{
|
|
21
|
+
var projectStructure = new ProjectStructure
|
|
22
|
+
{
|
|
23
|
+
Id = 1,
|
|
24
|
+
Name = Name,
|
|
25
|
+
Files = FilePaths.Select(b => new FileParser<FileStructure> { FilePath = b, Name = Path.GetFileName(b) }.Parse()).ToList(),
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
return (T) projectStructure;
|
|
29
|
+
}
|
|
30
|
+
catch (Exception ex)
|
|
31
|
+
{
|
|
32
|
+
throw;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
using CodeAnalyzer.Models;
|
|
2
|
+
using System;
|
|
3
|
+
using System.Collections.Generic;
|
|
4
|
+
using System.Text;
|
|
5
|
+
|
|
6
|
+
namespace CodeAnalyzer.Parsers
|
|
7
|
+
{
|
|
8
|
+
public sealed partial class SolutionParser<T> : BaseParser<T> where T : SolutionStructure
|
|
9
|
+
{
|
|
10
|
+
public override string Name { get; init; }
|
|
11
|
+
|
|
12
|
+
public override T Parse()
|
|
13
|
+
{
|
|
14
|
+
throw new NotImplementedException();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.IO;
|
|
3
|
+
using System.Linq;
|
|
4
|
+
using System.Text.Json;
|
|
5
|
+
using CodeAnalyzer.Models;
|
|
6
|
+
using CodeAnalyzer.Parsers;
|
|
7
|
+
|
|
8
|
+
class Program
|
|
9
|
+
{
|
|
10
|
+
static void Main(string[] args)
|
|
11
|
+
{
|
|
12
|
+
Console.WriteLine("Starting code analysis...");
|
|
13
|
+
var fileName = args.Length > 0 ? args[0] : null;
|
|
14
|
+
//Check if path is directory
|
|
15
|
+
var fileAttr = File.GetAttributes(fileName!);
|
|
16
|
+
var isDirectory = fileAttr.HasFlag(FileAttributes.Directory);
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
if(string.IsNullOrEmpty(fileName))
|
|
20
|
+
{
|
|
21
|
+
Console.Error.WriteLine(@"No file or project specified. Please provide a file/directory
|
|
22
|
+
containing ...cs, .csproj, or .sln file.");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!File.Exists(fileName) && !isDirectory){
|
|
27
|
+
Console.Error.WriteLine($"File not found: {fileName}");
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
string json = "";
|
|
32
|
+
|
|
33
|
+
if (isDirectory || fileName.EndsWith(".csproj") || fileName.EndsWith(".sln") || fileName.EndsWith(".slnx"))
|
|
34
|
+
{
|
|
35
|
+
var csFiles = Directory.GetFiles(Path.GetDirectoryName(fileName)!, "*.cs", SearchOption.AllDirectories).Where(f => !f.Contains("obj", StringComparison.CurrentCultureIgnoreCase)).ToArray();
|
|
36
|
+
|
|
37
|
+
BaseParser<ProjectStructure> projectStructure = new ProjectParser<ProjectStructure>()
|
|
38
|
+
{
|
|
39
|
+
FilePaths = csFiles,
|
|
40
|
+
Name = Path.GetFileName(fileName),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
json = JsonSerializer.Serialize(projectStructure.Parse(), new JsonSerializerOptions { WriteIndented = false });
|
|
44
|
+
}
|
|
45
|
+
else
|
|
46
|
+
{
|
|
47
|
+
BaseParser<FileStructure> fileStructure = new FileParser<FileStructure>()
|
|
48
|
+
{
|
|
49
|
+
FilePath = fileName,
|
|
50
|
+
Name = Path.GetFileName(fileName),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
json = JsonSerializer.Serialize(fileStructure.Parse(), new JsonSerializerOptions { WriteIndented = false });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
Console.WriteLine(json);
|
|
57
|
+
}
|
|
58
|
+
}
|