Skip to content

Added support for open generic params and handler interfaces. Added ExecuteCommandParams<> #479

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/Dap.Protocol/Models/ProgressToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ public record ProgressToken : IEquatable<long>, IEquatable<string>
private long? _long;
private string? _string;

public ProgressToken(Guid value)
{
_string = value.ToString();
_long = null;
}

public ProgressToken(long value)
{
_long = value;
Expand Down Expand Up @@ -46,6 +52,7 @@ public string String
public static implicit operator ProgressToken(long value) => new ProgressToken(value);

public static implicit operator ProgressToken(string value) => new ProgressToken(value);
public static implicit operator ProgressToken(Guid value) => new ProgressToken(value);

public bool Equals(long other) => IsLong && Long == other;
public bool Equals(string other) => IsString && String == other;
Expand Down
28 changes: 28 additions & 0 deletions src/Dap.Protocol/Serialization/ProgressTokenConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using Newtonsoft.Json;
using OmniSharp.Extensions.DebugAdapter.Protocol.Models;

namespace OmniSharp.Extensions.DebugAdapter.Protocol.Serialization
{
internal class ProgressTokenConverter : JsonConverter<ProgressToken?>
{
public override void WriteJson(JsonWriter writer, ProgressToken? value, JsonSerializer serializer)
{
if (value == null) writer.WriteNull();
else if (value.IsLong) serializer.Serialize(writer, value.Long);
else if (value.IsString) serializer.Serialize(writer, value.String);
else writer.WriteNull();
}

public override ProgressToken? ReadJson(JsonReader reader, Type objectType, ProgressToken? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return reader.TokenType switch {
JsonToken.Integer => new ProgressToken((long) reader.Value),
JsonToken.String when reader.Value is string str && !string.IsNullOrWhiteSpace(str) => new ProgressToken(str),
_ => null
};
}

public override bool CanRead => true;
}
}
1 change: 1 addition & 0 deletions src/Dap.Protocol/Serialization/Serializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ protected override void AddOrReplaceConverters(ICollection<JsonConverter> conver
ReplaceConverter(converters, new DapClientResponseConverter(this));
ReplaceConverter(converters, new DapClientRequestConverter());
ReplaceConverter(converters, new DapRpcErrorConverter(this));
ReplaceConverter(converters, new ProgressTokenConverter());
}

protected override JsonSerializer CreateSerializer()
Expand Down
2 changes: 1 addition & 1 deletion src/JsonRpc.Generators/Contexts/SyntaxSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace OmniSharp.Extensions.JsonRpc.Generators.Contexts
{
record SyntaxSymbol(TypeSyntax Syntax, INamedTypeSymbol Symbol);
record SyntaxSymbol(TypeSyntax Syntax, ITypeSymbol Symbol);

record SyntaxAttributeData(AttributeSyntax Syntax, AttributeData Data)
{
Expand Down
1 change: 1 addition & 0 deletions src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ ReportCacheDiagnostic<TypeDeclarationSyntax> cacheDiagnostic
.Where(z => z.Alias == null)
.Select(z => z.Name.ToFullString())
)
.Except(new [] { "<global namespace>" }) // I think there is a better way... but for now..
.Distinct()
.Select(z => UsingDirective(IdentifierName(z)))
)
Expand Down
30 changes: 19 additions & 11 deletions src/JsonRpc.Generators/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,21 @@ public static SyntaxSymbol GetResponseType(TypeDeclarationSyntax syntax, INamedT
{ Identifier: { Text: "IRequest" }, Arity: 1 } => gns.TypeArgumentList.Arguments[0],
_ => null
},
SimpleNameSyntax and { Identifier: { Text: "IRequest" } } => ParseName("MediatR.Unit"),
SimpleNameSyntax and { Identifier: { Text: "IRequest" } } => ParseName("MediatR.Unit"),
SimpleNameSyntax and { Identifier: { Text: "IJsonRpcRequest" } } => ParseName("MediatR.Unit"),
_ => null
};
if (type != null) break;
}

if (type == null) throw new ArgumentException($"Response Type {symbol.ToDisplayString()} is not a name symbol", nameof(symbol));
if (type == null) throw new ArgumentException($"Response Syntax {syntax.ToString()} is not a name syntax", nameof(syntax));

var handlerInterface = symbol.AllInterfaces.FirstOrDefault(z => z.Name == "IRequestHandler" && z.TypeArguments.Length == 2);
if (handlerInterface?.TypeArguments[1] is INamedTypeSymbol ns)
return new SyntaxSymbol(type, ns);
if (handlerInterface?.TypeArguments[1] is INamedTypeSymbol || handlerInterface?.TypeArguments[1] is ITypeParameterSymbol)
return new SyntaxSymbol(type, handlerInterface.TypeArguments[1]);
handlerInterface = symbol.AllInterfaces.FirstOrDefault(z => z.Name == "IRequest" && z.Arity == 1);
if (handlerInterface?.TypeArguments[0] is INamedTypeSymbol ns2)
return new SyntaxSymbol(type, ns2);
if (handlerInterface?.TypeArguments[0] is INamedTypeSymbol || handlerInterface?.TypeArguments[0] is ITypeParameterSymbol)
return new SyntaxSymbol(type, handlerInterface.TypeArguments[0]);
throw new ArgumentException($"Response Type {symbol.ToDisplayString()} is not a name symbol", nameof(symbol));
}

Expand Down Expand Up @@ -103,11 +103,12 @@ public static SyntaxSymbol GetResponseType(TypeDeclarationSyntax syntax, INamedT
{ Identifier: { Text: "IJsonRpcRequestHandler" } } => gns.TypeArgumentList.Arguments[0],
{ Identifier: { Text: "IJsonRpcNotificationHandler" } } => gns.TypeArgumentList.Arguments[0],
{ Identifier: { Text: "ICanBeResolvedHandler" }, Arity: 1 } => gns.TypeArgumentList.Arguments[0],
{ Identifier: { Text: "IRequest" } } => ParseTypeName(syntax.Identifier.Text),
{ Identifier: { Text: "IJsonRpcRequest" } } => ParseTypeName(syntax.Identifier.Text),
{ Identifier: { Text: "IPartialItemRequest" }, Arity: 2 } => ParseTypeName(syntax.Identifier.Text),
{ Identifier: { Text: "IPartialItemsRequest" }, Arity: 2 } => ParseTypeName(syntax.Identifier.Text),
_ => null,
{ Identifier: { Text: "IRequest" }, Arity: 1 } => IdentifierName(syntax.Identifier.Text),
{ Identifier: { Text: "IRequest" }, Arity: 0 } => IdentifierName(syntax.Identifier.Text),
{ Identifier: { Text: "IJsonRpcRequest" } } => IdentifierName(syntax.Identifier.Text),
{ Identifier: { Text: "IPartialItemRequest" }, Arity: 2 } => IdentifierName(syntax.Identifier.Text),
{ Identifier: { Text: "IPartialItemsRequest" }, Arity: 2 } => IdentifierName(syntax.Identifier.Text),
_ => null,
},
_ => null,
};
Expand All @@ -116,6 +117,13 @@ public static SyntaxSymbol GetResponseType(TypeDeclarationSyntax syntax, INamedT
}

if (type == null) return null;
if (type is IdentifierNameSyntax ins && ins.Identifier.Text == syntax.Identifier.Text && syntax.TypeParameterList is { Parameters: { Count: > 0 } })
{
type = GenericName(syntax.Identifier.Text)
.WithTypeArgumentList(
TypeArgumentList(SeparatedList<TypeSyntax>(syntax.TypeParameterList?.Parameters.Select(z => IdentifierName(z.Identifier.Text))))
);
}

var handlerInterface = symbol.AllInterfaces
.FirstOrDefault(z => z.Name == "IRequestHandler" && z.TypeArguments.Length == 2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public IEnumerable<MemberDeclarationSyntax> Apply(GeneratorData item)
}
);

var className = item.JsonRpcAttributes.HandlerName + "Extensions";
var className = item.JsonRpcAttributes.HandlerName + "Extensions" + ( item.TypeDeclaration.Arity == 0 ? "" : item.TypeDeclaration.Arity.ToString() );

var obsoleteAttribute = item.TypeDeclaration.AttributeLists
.SelectMany(z => z.Attributes)
Expand Down
18 changes: 16 additions & 2 deletions src/JsonRpc.Generators/Strategies/HandlerGeneratorStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public IEnumerable<MemberDeclarationSyntax> Apply(GeneratorData item)
.WithModifiers(item.TypeDeclaration.Modifiers)
.AddBaseListTypes(SimpleBaseType(GetBaseHandlerInterface(item)));

if (item is RequestItem { Response: { Symbol: ITypeParameterSymbol } } ri)
{
handlerInterface = handlerInterface.AddTypeParameterListParameters(TypeParameter(ri.Response.Symbol.Name));
}

if (item.Request.Symbol.AllInterfaces.Any(z => z.Name == "IDoesNotParticipateInRegistration"))
{
handlerInterface = handlerInterface.AddBaseListTypes(SimpleBaseType(IdentifierName("IDoesNotParticipateInRegistration")));
Expand All @@ -47,7 +52,7 @@ public IEnumerable<MemberDeclarationSyntax> Apply(GeneratorData item)
if (!handlerInterface.Modifiers.Any(z => z.IsKind(SyntaxKind.PartialKeyword)))
{
handlerInterface = handlerInterface.AddModifiers(Token(SyntaxKind.PartialKeyword));
}
}

if (item.JsonRpcAttributes.AllowDerivedRequests)
{
Expand Down Expand Up @@ -107,6 +112,7 @@ public IEnumerable<MemberDeclarationSyntax> Apply(GeneratorData item)
var baseClass = GetBaseHandlerClass(item);
var handlerClass = ClassDeclaration(Identifier($"{item.JsonRpcAttributes.HandlerName}HandlerBase"))
.WithAttributeLists(classAttributes)
.WithTypeParameterList(handlerInterface.TypeParameterList)
.AddModifiers(Token(SyntaxKind.AbstractKeyword))
.AddModifiers(handlerInterface.Modifiers.ToArray());
if (item.JsonRpcAttributes.AllowDerivedRequests)
Expand Down Expand Up @@ -170,7 +176,15 @@ public IEnumerable<MemberDeclarationSyntax> Apply(GeneratorData item)
}
else
{
handlerClass = handlerClass.AddBaseListTypes(SimpleBaseType(IdentifierName($"I{item.JsonRpcAttributes.HandlerName}Handler")));
handlerClass = handlerClass.AddBaseListTypes(
SimpleBaseType(
item is RequestItem { Response: { Symbol: ITypeParameterSymbol s } }
? GenericName($"I{item.JsonRpcAttributes.HandlerName}Handler").WithTypeArgumentList(
TypeArgumentList(SingletonSeparatedList<TypeSyntax>(IdentifierName(s.Name)))
)
: IdentifierName($"I{item.JsonRpcAttributes.HandlerName}Handler")
)
);
}

if (resolver is { })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
Expand Down Expand Up @@ -42,6 +43,12 @@ public IEnumerable<MemberDeclarationSyntax> Apply(ExtensionMethodContext extensi
resolve
)
);

if (item is RequestItem { Response: { Symbol: ITypeParameterSymbol } } ri)
{
method = method.AddTypeParameterListParameters(TypeParameter(ri.Response.Symbol.Name));
}

if (request.IsUnit)
{
method = method
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
Expand Down Expand Up @@ -40,6 +41,11 @@ public IEnumerable<MemberDeclarationSyntax> Apply(ExtensionMethodContext extensi
.WithExpressionBody(GetRequestHandlerExpression(request, GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration)))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));

if (item is RequestItem { Response: { Symbol: ITypeParameterSymbol } } ri)
{
method = method.AddTypeParameterListParameters(TypeParameter(ri.Response.Symbol.Name));
}

var methodFactory = MakeFactory(extensionMethodContext.GetRegistryParameterList());

var factory = methodFactory(method);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
Expand Down Expand Up @@ -57,6 +58,11 @@ public IEnumerable<MemberDeclarationSyntax> Apply(ExtensionMethodContext extensi
)
);

if (item is RequestItem { Response: { Symbol: ITypeParameterSymbol } } ri)
{
method = method.AddTypeParameterListParameters(TypeParameter(ri.Response.Symbol.Name));
}

var methodFactory = MakeFactory(
extensionMethodContext.GetRegistryParameterList(),
registrationOptions.Syntax,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
Expand Down Expand Up @@ -52,6 +53,11 @@ public IEnumerable<MemberDeclarationSyntax> Apply(ExtensionMethodContext extensi
.WithExpressionBody(GetRequestHandlerExpression(request, GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration)))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));

if (item is RequestItem { Response: { Symbol: ITypeParameterSymbol } } ri)
{
method = method.AddTypeParameterListParameters(TypeParameter(ri.Response.Symbol.Name));
}

var methodFactory = MakeFactory(extensionMethodContext.GetRegistryParameterList());

var factory = methodFactory(method);
Expand Down
Loading