Skip to content

Commit 73efad8

Browse files
wip updates
1 parent fc6c943 commit 73efad8

File tree

52 files changed

+2181
-67
lines changed

Some content is hidden

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

52 files changed

+2181
-67
lines changed

src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,11 +201,14 @@ private static ImmutableArray<ICompilationUnitGeneratorStrategy> GetCompilationU
201201
new OnRequestMethodGeneratorWithoutRegistrationOptionsStrategy(false),
202202
new OnRequestMethodGeneratorWithoutRegistrationOptionsStrategy(true),
203203
new OnRequestTypedResolveMethodGeneratorWithoutRegistrationOptionsStrategy(),
204+
// new OnRequestTypedMethodGeneratorWithoutRegistrationOptionsStrategy(),
204205
new OnRequestMethodGeneratorWithRegistrationOptionsStrategy(false),
205206
new OnRequestMethodGeneratorWithRegistrationOptionsStrategy(true),
206207
new OnRequestTypedResolveMethodGeneratorWithRegistrationOptionsStrategy(),
208+
// new OnRequestTypedMethodGeneratorWithRegistrationOptionsStrategy(),
207209
new SendMethodNotificationStrategy(),
208-
new SendMethodRequestStrategy()
210+
new SendMethodRequestStrategy(),
211+
new SendMethodTypedResolveRequestStrategy()
209212
);
210213
var actionStrategies = ImmutableArray.Create<IExtensionMethodGeneratorStrategy>(
211214
new EnsureNamespaceStrategy(),

src/JsonRpc.Generators/Helpers.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,34 @@ public static ArrowExpressionClauseSyntax GetRequestInvokeExpression() =>
883883
)
884884
);
885885

886+
public static ArrowExpressionClauseSyntax GetRequestReturningInvokeExpression(ExpressionSyntax requestName, TypeSyntax responseType) =>
887+
ArrowExpressionClause(
888+
InvocationExpression(
889+
MemberAccessExpression(
890+
SyntaxKind.SimpleMemberAccessExpression,
891+
InvocationExpression(
892+
MemberAccessExpression(
893+
SyntaxKind.SimpleMemberAccessExpression,
894+
IdentifierName("client"),
895+
IdentifierName("SendRequest")))
896+
.WithArgumentList(
897+
ArgumentList(
898+
SeparatedList(
899+
new []{
900+
Argument(requestName),
901+
Argument((IdentifierName(@"request")))}))),
902+
GenericName(
903+
Identifier("Returning"))
904+
.WithTypeArgumentList(
905+
TypeArgumentList(
906+
SingletonSeparatedList(responseType)))))
907+
.WithArgumentList(
908+
ArgumentList(
909+
SingletonSeparatedList(
910+
Argument(
911+
IdentifierName("cancellationToken")))))
912+
);
913+
886914
public static ArrowExpressionClauseSyntax GetPartialInvokeExpression(
887915
TypeSyntax responseType, TypeSyntax? partialItemType, bool partialItemTypeInheritsFromSelf
888916
)

src/JsonRpc.Generators/Strategies/SendMethodNotificationStrategy.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,19 @@ public IEnumerable<MemberDeclarationSyntax> Apply(SourceProductionContext contex
2525
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
2626

2727
yield return method
28-
.WithParameterList(
29-
ParameterList(
30-
SeparatedList(
31-
new[] {
32-
Parameter(Identifier("mediator"))
33-
.WithType(extensionMethodContext.Item)
34-
.WithModifiers(TokenList(Token(SyntaxKind.ThisKeyword))),
35-
Parameter(Identifier("request"))
36-
.WithType(notification.Request.Syntax)
37-
}
38-
)
39-
)
40-
);
28+
.WithParameterList(
29+
ParameterList(
30+
SeparatedList(
31+
new[] {
32+
Parameter(Identifier("mediator"))
33+
.WithType(extensionMethodContext.Item)
34+
.WithModifiers(TokenList(Token(SyntaxKind.ThisKeyword))),
35+
Parameter(Identifier("request"))
36+
.WithType(notification.Request.Syntax)
37+
}
38+
)
39+
)
40+
);
4141
}
4242
}
4343
}

src/JsonRpc.Generators/Strategies/SendMethodRequestStrategy.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ public IEnumerable<MemberDeclarationSyntax> Apply(SourceProductionContext contex
125125
.WithParameterList(parameterList)
126126
.WithExpressionBody(Helpers.GetRequestInvokeExpression())
127127
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
128+
128129
}
129130
}
130131
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
using System.Net;
2+
using Microsoft.CodeAnalysis;
3+
using Microsoft.CodeAnalysis.CSharp;
4+
using Microsoft.CodeAnalysis.CSharp.Syntax;
5+
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
6+
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
7+
8+
namespace OmniSharp.Extensions.JsonRpc.Generators.Strategies;
9+
10+
internal class SendMethodTypedResolveRequestStrategy : IExtensionMethodContextGeneratorStrategy
11+
{
12+
public IEnumerable<MemberDeclarationSyntax> Apply(SourceProductionContext context, ExtensionMethodContext extensionMethodContext, GeneratorData item)
13+
{
14+
if (item is not RequestItem request) yield break;
15+
if (extensionMethodContext is not { IsProxy: true }) yield break;
16+
if (item.JsonRpcAttributes.AllowDerivedRequests) yield break;
17+
if (item is not { LspAttributes: { Resolver: { } } }) yield break;
18+
if (request.Response.Syntax.GetSyntaxName() == "Unit") yield break;
19+
// if (request.Request.Symbol.Name != "OutlayHintParams") yield break;
20+
21+
TypeSyntax requestType = item.Request.Syntax;
22+
TypeSyntax responseType = GenericName(Identifier(request.Response.Symbol.Name))
23+
.WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList<TypeSyntax>(IdentifierName("T"))));
24+
25+
responseType = request.Response.Syntax is NullableTypeSyntax ? NullableType(responseType) : responseType;
26+
27+
var parameterList = ParameterList(
28+
SeparatedList(
29+
new[]
30+
{
31+
Parameter(Identifier("mediator"))
32+
.WithType(extensionMethodContext.Item)
33+
.WithModifiers(TokenList(Token(SyntaxKind.ThisKeyword))),
34+
Parameter(Identifier("request"))
35+
.WithType(requestType),
36+
Parameter(Identifier("cancellationToken"))
37+
.WithType(IdentifierName("CancellationToken"))
38+
.WithDefault(
39+
EqualsValueClause(
40+
LiteralExpression(SyntaxKind.DefaultLiteralExpression, Token(SyntaxKind.DefaultKeyword))
41+
)
42+
)
43+
}
44+
)
45+
);
46+
//
47+
// if (request.PartialItem is not null)
48+
// {
49+
// request.AdditionalUsings.Add("OmniSharp.Extensions.LanguageServer.Protocol.Progress");
50+
// yield return MethodDeclaration(
51+
// GenericName(
52+
// Identifier("IRequestProgressObservable")
53+
// )
54+
// .WithTypeArgumentList(
55+
// TypeArgumentList(
56+
// SeparatedList(
57+
// new[]
58+
// {
59+
// request.PartialItem.Syntax,
60+
// responseType
61+
// }
62+
// )
63+
// )
64+
// ),
65+
// Identifier(item.JsonRpcAttributes.RequestMethodName)
66+
// )
67+
// .WithModifiers(
68+
// TokenList(
69+
// Token(SyntaxKind.PublicKeyword),
70+
// Token(SyntaxKind.StaticKeyword)
71+
// )
72+
// )
73+
// .WithParameterList(parameterList)
74+
// .WithExpressionBody(
75+
// Helpers.GetPartialInvokeExpression(
76+
// request.Response.Syntax,
77+
// request.PartialHasInitialValue ? null : request.PartialItem.Syntax,
78+
// request.PartialItemInheritsFromSelf
79+
// )
80+
// )
81+
// .WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
82+
// yield break;
83+
// }
84+
//
85+
// if (request.PartialItems is not null)
86+
// {
87+
// request.AdditionalUsings.Add("OmniSharp.Extensions.LanguageServer.Protocol.Progress");
88+
// var partialItemsSyntax =
89+
// GenericName("IEnumerable").WithTypeArgumentList(TypeArgumentList(SeparatedList(new[] { request.PartialItems!.Syntax })));
90+
// yield return MethodDeclaration(
91+
// GenericName(
92+
// Identifier("IRequestProgressObservable")
93+
// )
94+
// .WithTypeArgumentList(
95+
// TypeArgumentList(
96+
// SeparatedList(
97+
// new[]
98+
// {
99+
// partialItemsSyntax,
100+
// responseType
101+
// }
102+
// )
103+
// )
104+
// ),
105+
// Identifier(item.JsonRpcAttributes.RequestMethodName)
106+
// )
107+
// .WithModifiers(
108+
// TokenList(
109+
// Token(SyntaxKind.PublicKeyword),
110+
// Token(SyntaxKind.StaticKeyword)
111+
// )
112+
// )
113+
// .WithParameterList(parameterList)
114+
// .WithExpressionBody(Helpers.GetPartialInvokeExpression(responseType, default, false))
115+
// .WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
116+
// yield break;
117+
// }
118+
119+
120+
var responseSyntax = GenericName("Task").WithTypeArgumentList(TypeArgumentList(SeparatedList(new[] { responseType })));
121+
yield return MethodDeclaration(responseSyntax, item.JsonRpcAttributes.RequestMethodName)
122+
.WithModifiers(
123+
TokenList(
124+
Token(SyntaxKind.PublicKeyword),
125+
Token(SyntaxKind.StaticKeyword)
126+
)
127+
)
128+
.WithTypeParameterList(TypeParameterList(SingletonSeparatedList(TypeParameter("T"))))
129+
.WithParameterList(parameterList)
130+
.WithExpressionBody(Helpers.GetRequestReturningInvokeExpression(Helpers.GetJsonRpcMethodName(item.TypeDeclaration), responseType))
131+
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
132+
}
133+
}

src/JsonRpc.Generators/StronglyTypedGenerator.cs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
using System.Collections.Immutable;
23
using System.IO;
34
using System.Linq;
45
using System.Text;
@@ -48,6 +49,15 @@ TypeDeclarationSyntax typeDeclarationSyntax and (ClassDeclarationSyntax or Recor
4849
}, (syntaxContext, _) => syntaxContext
4950
);
5051

52+
var typedParamsCandidatesSyntaxProvider = context.SyntaxProvider.CreateSyntaxProvider(
53+
(syntaxNode, _) => syntaxNode switch
54+
{
55+
TypeDeclarationSyntax typeDeclarationSyntax and (ClassDeclarationSyntax or RecordDeclarationSyntax) when typeDeclarationSyntax
56+
.AttributeLists.ContainsAttribute("GenerateRequestMethods") => true,
57+
_ => false
58+
}, (syntaxContext, _) => syntaxContext
59+
);
60+
5161
var canBeResolvedSyntaxProvider = context.SyntaxProvider.CreateSyntaxProvider(
5262
(syntaxNode, _) =>
5363
syntaxNode is TypeDeclarationSyntax { BaseList: { } } typeDeclarationSyntax and (ClassDeclarationSyntax or RecordDeclarationSyntax)
@@ -64,8 +74,14 @@ TypeDeclarationSyntax typeDeclarationSyntax and (ClassDeclarationSyntax or Recor
6474
&& typeDeclarationSyntax.Members.OfType<PropertyDeclarationSyntax>().Any(z => z.Identifier.Text == "Data")
6575
&& typeDeclarationSyntax.BaseList.Types.Any(z => z.Type.GetSyntaxName() == "ICanHaveData"), (syntaxContext, _) => syntaxContext
6676
);
67-
77+
6878
context.RegisterSourceOutput(createContainersSyntaxProvider.Combine(attributes), GenerateContainerClass);
79+
context.RegisterSourceOutput(typedParamsCandidatesSyntaxProvider
80+
.Combine(canBeResolvedSyntaxProvider.Select((z, _) => (TypeDeclarationSyntax)z.Node).Collect())
81+
.Combine(canHaveDataSyntaxProvider.Select((z, _) => (TypeDeclarationSyntax)z.Node).Collect())
82+
.Combine(createContainersSyntaxProvider.Select((z, _) => (TypeDeclarationSyntax)z.Node).Collect())
83+
.Select((tuple, token) => (candidate: tuple.Left.Left.Left, resolvedItems: tuple.Left.Left.Right.Concat(tuple.Left.Right).Concat(tuple.Right).ToImmutableArray())),
84+
GenerateTypedParams);
6985
context.RegisterSourceOutput(canBeResolvedSyntaxProvider.Combine(attributes), GenerateCanBeResolvedClass);
7086
context.RegisterSourceOutput(canHaveDataSyntaxProvider.Combine(attributes), GenerateCanHaveDataClass);
7187
}
@@ -119,6 +135,63 @@ private void GenerateContainerClass(SourceProductionContext context, (GeneratorS
119135
);
120136
}
121137

138+
private void GenerateTypedParams(SourceProductionContext context, (GeneratorSyntaxContext syntaxContext, ImmutableArray<TypeDeclarationSyntax> resolvedItems) valueTuple)
139+
{
140+
var (syntaxContext, resolvedItems) = valueTuple;
141+
var classToContain = (TypeDeclarationSyntax)syntaxContext.Node;
142+
var typeSymbol = syntaxContext.SemanticModel.GetDeclaredSymbol(classToContain);
143+
144+
if (typeSymbol == null) return;
145+
var handlerInterface = typeSymbol.AllInterfaces.FirstOrDefault(z => z.Name == "IRequest" && z.Arity == 1);
146+
if (handlerInterface is null) return;
147+
var responseSymbol = handlerInterface?.TypeArguments[0];
148+
149+
var isTyped = resolvedItems
150+
.Any(
151+
item =>
152+
{
153+
var symbol = syntaxContext.SemanticModel.GetDeclaredSymbol(item);
154+
return symbol is not null && SymbolEqualityComparer.Default.Equals(responseSymbol, symbol);
155+
}
156+
);
157+
158+
// TODO: Start here to finish creating strongly typed params
159+
var paramsType = CreateContainerClass(classToContain, containerName)
160+
.AddAttributeLists(
161+
AttributeList(
162+
SeparatedList(
163+
new[]
164+
{
165+
Attribute(ParseName("System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute")),
166+
Attribute(ParseName("System.Runtime.CompilerServices.CompilerGeneratedAttribute"))
167+
}
168+
)
169+
)
170+
);
171+
172+
var cu = CompilationUnit()
173+
.WithUsings(classToContain.SyntaxTree.GetCompilationUnitRoot().Usings)
174+
.AddMembers(
175+
NamespaceDeclaration(ParseName(typeSymbol.ContainingNamespace.ToDisplayString()))
176+
.AddMembers(container)
177+
.WithLeadingTrivia(TriviaList(Trivia(NullableDirectiveTrivia(Token(SyntaxKind.EnableKeyword), true))))
178+
.WithTrailingTrivia(TriviaList(Trivia(NullableDirectiveTrivia(Token(SyntaxKind.RestoreKeyword), true))))
179+
);
180+
181+
foreach (var ns in RequiredUsings)
182+
{
183+
if (cu.Usings.All(z => z.Name.ToFullString() != ns))
184+
{
185+
cu = cu.AddUsings(UsingDirective(ParseName(ns)));
186+
}
187+
}
188+
189+
context.AddSource(
190+
$"{containerName ?? classToContain.Identifier.Text + "Container"}.cs",
191+
cu.NormalizeWhitespace().GetText(Encoding.UTF8)
192+
);
193+
}
194+
122195
private void GenerateCanBeResolvedClass(SourceProductionContext context, (GeneratorSyntaxContext syntaxContext, AttributeData attributeData) valueTuple)
123196
{
124197
var (syntaxContext, attributeData) = valueTuple;

src/Protocol/Features/Document/CodeActionFeature.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace Models
3030
[RegistrationOptions(typeof(CodeActionRegistrationOptions))]
3131
[Capability(typeof(CodeActionCapability))]
3232
[Resolver(typeof(CodeAction))]
33-
public partial record CodeActionParams : ITextDocumentIdentifierParams, IPartialItemsRequest<CommandOrCodeActionContainer, CommandOrCodeAction>,
33+
public partial record CodeActionParams : ITextDocumentIdentifierParams, IPartialItemsRequest<CommandOrCodeActionContainer?, CommandOrCodeAction>,
3434
IWorkDoneProgressParams
3535
{
3636
/// <summary>
@@ -49,6 +49,9 @@ public partial record CodeActionParams : ITextDocumentIdentifierParams, IPartial
4949
public CodeActionContext Context { get; init; } = null!;
5050
}
5151

52+
// marker class is required
53+
public partial class CommandOrCodeActionContainer {}
54+
5255
/// <summary>
5356
/// Contains additional diagnostic information about the context in which
5457
/// a code action is run.

0 commit comments

Comments
 (0)