Skip to content

Commit b976590

Browse files
migrated to use incremental source generators and remove cache infrastructure!
1 parent 89ff3c9 commit b976590

File tree

56 files changed

+5378
-3409
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+5378
-3409
lines changed

.nuke/temp/build-attempt.log

+7
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,10 @@ f616dd427f6d04e544c56c7cd9ecd956
22
Clean
33
DotnetToolRestore
44
Restore
5+
Build
6+
Test
7+
GenerateCodeCoverageReportCobertura
8+
GenerateCodeCoverageBadges
9+
GenerateCodeCoverageSummary
10+
GenerateCodeCoverageReport
11+
Pack

.nuke/temp/build.log

+4,199-1,733
Large diffs are not rendered by default.

src/JsonRpc.Generators/AssemblyCapabilityKeyAttributeGenerator.cs

+60-89
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,84 @@
11
using System.Collections.Generic;
2+
using System.Collections.Immutable;
23
using System.Linq;
34
using System.Text;
45
using Microsoft.CodeAnalysis;
56
using Microsoft.CodeAnalysis.CSharp;
67
using Microsoft.CodeAnalysis.CSharp.Syntax;
7-
using OmniSharp.Extensions.JsonRpc.Generators.Cache;
8+
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
89

910
namespace OmniSharp.Extensions.JsonRpc.Generators
1011
{
1112
[Generator]
12-
public class AssemblyCapabilityKeyAttributeGenerator : CachedSourceGenerator<AssemblyCapabilityKeyAttributeGenerator.SyntaxReceiver, TypeDeclarationSyntax>
13+
public class AssemblyCapabilityKeyAttributeGenerator : IIncrementalGenerator
1314
{
14-
protected override void Execute(
15-
GeneratorExecutionContext context, SyntaxReceiver syntaxReceiver, AddCacheSource<TypeDeclarationSyntax> addCacheSource,
16-
ReportCacheDiagnostic<TypeDeclarationSyntax> cacheDiagnostic
17-
)
15+
public void Initialize(IncrementalGeneratorInitializationContext context)
1816
{
19-
var namespaces = new HashSet<string>() { "OmniSharp.Extensions.LanguageServer.Protocol" };
20-
var types = syntaxReceiver.FoundNodes
21-
.Concat(syntaxReceiver.Handlers)
22-
.Select(
23-
options => {
24-
var semanticModel = context.Compilation.GetSemanticModel(options.SyntaxTree);
25-
foreach (var item in options.SyntaxTree.GetCompilationUnitRoot()
26-
.Usings
27-
.Where(z => z.Alias == null)
28-
.Select(z => z.Name.ToFullString()))
29-
{
30-
namespaces.Add(item);
31-
}
32-
33-
var typeSymbol = semanticModel.GetDeclaredSymbol(options)!;
17+
var syntaxProvider = context.SyntaxProvider.CreateSyntaxProvider(
18+
predicate: (syntaxNode, token) =>
19+
{
20+
if (syntaxNode.Parent is TypeDeclarationSyntax) return false;
21+
if (syntaxNode is TypeDeclarationSyntax { Arity: 0, BaseList: { } bl } typeDeclarationSyntax
22+
and (ClassDeclarationSyntax or RecordDeclarationSyntax)
23+
&& !typeDeclarationSyntax.Modifiers.Any(SyntaxKind.AbstractKeyword)
24+
&& typeDeclarationSyntax.AttributeLists.ContainsAttribute("CapabilityKey")
25+
&& bl.Types.Any(
26+
z => z.Type switch
27+
{
28+
SimpleNameSyntax
29+
{
30+
Identifier: { Text: "ICapability" or "DynamicCapability" or "IDynamicCapability" or "LinkSupportCapability" }, Arity: 0
31+
} => true,
32+
_ => false
33+
}
34+
))
35+
{
36+
return true;
37+
}
3438

35-
return SyntaxFactory.Attribute(
36-
SyntaxFactory.IdentifierName("AssemblyCapabilityKey"), SyntaxFactory.AttributeArgumentList(
37-
SyntaxFactory.SeparatedList(
38-
new[] {
39-
SyntaxFactory.AttributeArgument(
40-
SyntaxFactory.TypeOfExpression(SyntaxFactory.ParseName(typeSymbol.ToDisplayString()))
41-
),
42-
}.Concat(options.AttributeLists.GetAttribute("CapabilityKey")!.ArgumentList!.Arguments)
43-
)
44-
)
45-
);
46-
}
47-
)
48-
.ToArray();
49-
if (types.Any())
50-
{
51-
var cu = SyntaxFactory.CompilationUnit()
52-
.WithUsings(SyntaxFactory.List(namespaces.OrderBy(z => z).Select(z => SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(z)))))
53-
.AddAttributeLists(
54-
SyntaxFactory.AttributeList(
55-
target: SyntaxFactory.AttributeTargetSpecifier(SyntaxFactory.Token(SyntaxKind.AssemblyKeyword)), SyntaxFactory.SeparatedList(types)
56-
)
57-
)
58-
.WithLeadingTrivia(SyntaxFactory.Comment(Preamble.GeneratedByATool))
59-
.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed);
39+
return false;
40+
},
41+
transform: (syntaxContext, token) =>
42+
{
43+
var namespaces = new HashSet<string>() { "OmniSharp.Extensions.LanguageServer.Protocol" };
44+
var tds = (TypeDeclarationSyntax)syntaxContext.Node;
45+
46+
foreach (var item in syntaxContext.Node.SyntaxTree.GetCompilationUnitRoot()
47+
.Usings.Where(z => z.Alias == null)
48+
.Select(z => z.Name.ToFullString()))
49+
{
50+
namespaces.Add(item);
51+
}
6052

61-
context.AddSource("AssemblyCapabilityKeys.cs", cu.NormalizeWhitespace().GetText(Encoding.UTF8));
62-
}
63-
}
53+
var typeSymbol = syntaxContext.SemanticModel.GetDeclaredSymbol(syntaxContext.Node)!;
6454

65-
public AssemblyCapabilityKeyAttributeGenerator() : base(() => new SyntaxReceiver(Cache))
66-
{
55+
return (namespaces, Attribute(IdentifierName("AssemblyCapabilityKey"), AttributeArgumentList(SeparatedList(new[] { AttributeArgument(TypeOfExpression(ParseName(typeSymbol.ToDisplayString()))), }.Concat(tds.AttributeLists.GetAttribute("CapabilityKey")!.ArgumentList!.Arguments)))));
56+
}
57+
).Collect();
58+
59+
context.RegisterSourceOutput(syntaxProvider, GenerateAssemblyCapabilityKeys);
6760
}
6861

69-
public static CacheContainer<TypeDeclarationSyntax> Cache = new();
70-
71-
public class SyntaxReceiver : SyntaxReceiverCache<TypeDeclarationSyntax>
62+
private void GenerateAssemblyCapabilityKeys(SourceProductionContext context, ImmutableArray<(HashSet<string> namespaces, AttributeSyntax attribute)> types)
7263
{
73-
public List<TypeDeclarationSyntax> Handlers { get; } = new();
74-
75-
public override string? GetKey(TypeDeclarationSyntax syntax)
76-
{
77-
var hasher = new CacheKeyHasher();
78-
hasher.Append(syntax.SyntaxTree.FilePath);
79-
hasher.Append(syntax.Keyword.Text);
80-
hasher.Append(syntax.Identifier.Text);
81-
hasher.Append(syntax.TypeParameterList);
82-
hasher.Append(syntax.AttributeLists);
83-
hasher.Append(syntax.BaseList);
84-
85-
return hasher;
86-
}
87-
88-
/// <summary>
89-
/// Called for every syntax node in the compilation, we can inspect the nodes and save any information useful for generation
90-
/// </summary>
91-
public override void OnVisitNode(TypeDeclarationSyntax syntaxNode)
92-
{
93-
if (syntaxNode.Parent is TypeDeclarationSyntax) return;
94-
if (syntaxNode is ClassDeclarationSyntax or RecordDeclarationSyntax
95-
&& syntaxNode.Arity == 0
96-
&& !syntaxNode.Modifiers.Any(SyntaxKind.AbstractKeyword)
97-
&& syntaxNode.AttributeLists.ContainsAttribute("CapabilityKey")
98-
&& syntaxNode.BaseList is { } bl && bl.Types.Any(
99-
z => z.Type switch {
100-
SimpleNameSyntax { Identifier: { Text: "ICapability" or "DynamicCapability" or "IDynamicCapability" or "LinkSupportCapability" }, Arity: 0 } => true,
101-
_ => false
102-
}
103-
))
64+
var namespaces = types.Aggregate(
65+
new HashSet<string>(), (set, tuple) =>
10466
{
105-
Handlers.Add(syntaxNode);
106-
}
107-
}
67+
foreach (var name in tuple.namespaces)
68+
{
69+
set.Add(name);
70+
}
10871

109-
public SyntaxReceiver(CacheContainer<TypeDeclarationSyntax> cache) : base(cache)
72+
return set;
73+
}
74+
);
75+
if (types.Any())
11076
{
77+
var cu = CompilationUnit()
78+
.WithUsings(List(namespaces.OrderBy(z => z).Select(z => UsingDirective(ParseName(z)))))
79+
.AddAttributeLists(AttributeList(target: AttributeTargetSpecifier(Token(SyntaxKind.AssemblyKeyword)), SeparatedList(types.Select(z => z.attribute))));
80+
81+
context.AddSource("AssemblyCapabilityKeys.cs", cu.NormalizeWhitespace().GetText(Encoding.UTF8));
11182
}
11283
}
11384
}

0 commit comments

Comments
 (0)