-
-
Notifications
You must be signed in to change notification settings - Fork 134
/
Copy pathPlantUmlSourceGenerator.cs
73 lines (62 loc) · 2.82 KB
/
PlantUmlSourceGenerator.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using PlantUmlClassDiagramGenerator.SourceGenerator.Extensions;
using PlantUmlClassDiagramGenerator.SourceGenerator.Options;
using System.Collections.Immutable;
namespace PlantUmlClassDiagramGenerator.SourceGenerator;
[Generator(LanguageNames.CSharp)]
public partial class PlantUmlSourceGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
RegisterAttributes(context);
RegisterClassDiagram(context);
}
private static void RegisterClassDiagram(IncrementalGeneratorInitializationContext context)
{
var assemblyName = context.CompilationProvider
.Select((compilation, _) => compilation.AssemblyName);
var options = context.AnalyzerConfigOptionsProvider
.Combine(assemblyName)
.Select(static (config, _) => new GeneratorOptions(config.Left, config.Right??""))
.Combine(context.ParseOptionsProvider
.Select(static (options, _) => options.PreprocessorSymbolNames));
var typeDeclarations = context.SyntaxProvider
.CreateSyntaxProvider(
predicate: static (node, _) => node is BaseTypeDeclarationSyntax,
transform: static (context, _) => context.SemanticModel.GetDeclaredSymbol(context.Node))
.Collect();
var generateSource = options.Combine(typeDeclarations);
context.RegisterImplementationSourceOutput(generateSource, static (context, source) =>
{
var ((options, preprocessors), targetSymbols) = source;
if (!preprocessors.Any(s => s == "GENERATE_PLANTUML"))
{
return;
}
InitiarizeOutputDirectory(Path.Combine(options.OutputDir, options.AssemblyName));
var symbols = targetSymbols
.OfType<INamedTypeSymbol>()
.Where(predicate: GeneratorAttributes.DeclaredTypeFilter)
.SelectMany(symbol => symbol.EnumerateNestedTypeSymbols()) //Include nested types
.ToImmutableHashSet<INamedTypeSymbol>(SymbolEqualityComparer.Default);
foreach (var symbol in symbols)
{
context.CancellationToken.ThrowIfCancellationRequested();
var builder = new PlantUmlDiagramBuilder(symbol, options);
builder.Build(symbols);
context.CancellationToken.ThrowIfCancellationRequested();
builder.Write();
}
});
}
private static void InitiarizeOutputDirectory(string baseDir)
{
var info = Directory.CreateDirectory(baseDir);
foreach (var dir in info.GetDirectories())
{
dir.Delete(true);
}
}
}