Skip to content

Commit

Permalink
Added new FileOperations and updated to work with latest annotations (#…
Browse files Browse the repository at this point in the history
…470)

* Added new FileOperations and updated to work with latest annotations
* updated sha reference
* prevent send from throwing
* Change how partial results are handled (ForkJoin vs Amb).  this should help with the race condition where the request 'finishes' first but was handled partially, and therefore returns no results
  • Loading branch information
david-driscoll committed Dec 15, 2020
1 parent 9cadf26 commit 1c1117d
Show file tree
Hide file tree
Showing 76 changed files with 1,336 additions and 433 deletions.
4 changes: 2 additions & 2 deletions language-server-protocol.sha.txt
@@ -1,4 +1,4 @@
-- This is the last commit we caught up with https://github.com/Microsoft/language-server-protocol/commits/gh-pages
lastSha: c485961250d0eb41e53b148b55262ec180b63273
lastSha: bdcc0f2

https://github.com/Microsoft/language-server-protocol/compare/c485961250d0eb41e53b148b55262ec180b63273..gh-pages
https://github.com/Microsoft/language-server-protocol/compare/bdcc0f2..gh-pages
6 changes: 6 additions & 0 deletions src/Client/LanguageClientRegistrationManager.cs
Expand Up @@ -143,6 +143,7 @@ private Registration Register(Registration registration)
if (registrationType == null)
{
// vscode client throws if given an unknown registration type
_logger.LogError("Unknown Registration Type {Method} {@Registration}", registration.Method, registration);
throw new NotSupportedException($"Unknown Registration Type '{registration.Method}'");
}

Expand All @@ -154,6 +155,11 @@ private Registration Register(Registration registration)
: registration.RegisterOptions
};

if (_logger.IsEnabled(LogLevel.Trace))
{
_logger.LogTrace("Registered handler for {Method} {@Registration}", deserializedRegistration.Method, deserializedRegistration.RegisterOptions );
}

return deserializedRegistration;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Dap.Protocol/Dap.Protocol.csproj
Expand Up @@ -14,7 +14,7 @@

<ItemGroup>
<ProjectReference Include="..\JsonRpc\JsonRpc.csproj" />
<ProjectReference Include="..\JsonRpc.Generators\JsonRpc.Generators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" PrivateAssets="all" />
<ProjectReference Include="..\JsonRpc.Generators\JsonRpc.Generators.csproj" IncludeAssets="analyzers" ExcludeAssets="compile;runtime;native" PrivateAssets="contentfiles;build;buildMultitargeting;buildTransitive" OutputItemType="Analyzer" />
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
<_Parameter1>OmniSharp.Extensions.DebugAdapter.Server, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f</_Parameter1>
</AssemblyAttribute>
Expand Down
14 changes: 10 additions & 4 deletions src/JsonRpc.Generators/AssemblyCapabilityKeyAttributeGenerator.cs
Expand Up @@ -36,7 +36,9 @@ ReportCacheDiagnostic<TypeDeclarationSyntax> cacheDiagnostic
SyntaxFactory.IdentifierName("AssemblyCapabilityKey"), SyntaxFactory.AttributeArgumentList(
SyntaxFactory.SeparatedList(
new[] {
SyntaxFactory.AttributeArgument(SyntaxFactory.TypeOfExpression(SyntaxFactory.ParseName(typeSymbol.ToDisplayString()))),
SyntaxFactory.AttributeArgument(
SyntaxFactory.TypeOfExpression(SyntaxFactory.ParseName(typeSymbol.ToDisplayString()))
),
}.Concat(options.AttributeLists.GetAttribute("CapabilityKey")!.ArgumentList!.Arguments)
)
)
Expand All @@ -48,7 +50,11 @@ ReportCacheDiagnostic<TypeDeclarationSyntax> cacheDiagnostic
{
var cu = SyntaxFactory.CompilationUnit()
.WithUsings(SyntaxFactory.List(namespaces.OrderBy(z => z).Select(z => SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(z)))))
.AddAttributeLists(SyntaxFactory.AttributeList(target: SyntaxFactory.AttributeTargetSpecifier(SyntaxFactory.Token(SyntaxKind.AssemblyKeyword)), SyntaxFactory.SeparatedList(types)))
.AddAttributeLists(
SyntaxFactory.AttributeList(
target: SyntaxFactory.AttributeTargetSpecifier(SyntaxFactory.Token(SyntaxKind.AssemblyKeyword)), SyntaxFactory.SeparatedList(types)
)
)
.WithLeadingTrivia(SyntaxFactory.Comment(Preamble.GeneratedByATool))
.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed);

Expand Down Expand Up @@ -91,8 +97,8 @@ public override void OnVisitNode(TypeDeclarationSyntax syntaxNode)
&& syntaxNode.AttributeLists.ContainsAttribute("CapabilityKey")
&& syntaxNode.BaseList is { } bl && bl.Types.Any(
z => z.Type switch {
SimpleNameSyntax { Identifier: { Text: "ICapability" }, Arity: 0 } => true,
_ => false
SimpleNameSyntax { Identifier: { Text: "ICapability" or "DynamicCapability" or "IDynamicCapability" or "LinkSupportCapability" }, Arity: 0 } => true,
_ => false
}
))
{
Expand Down
Expand Up @@ -36,15 +36,19 @@ ReportCacheDiagnostic<TypeDeclarationSyntax> cacheDiagnostic
{
var cu = CompilationUnit()
.WithUsings(List(namespaces.OrderBy(z => z).Select(z => UsingDirective(ParseName(z)))))
.AddAttributeLists(
AttributeList(
target: AttributeTargetSpecifier(Token(SyntaxKind.AssemblyKeyword)),
SingletonSeparatedList(Attribute(IdentifierName("AssemblyJsonRpcHandlers"), AttributeArgumentList(SeparatedList(types))))
)
)
.WithLeadingTrivia(Comment(Preamble.GeneratedByATool))
.WithTrailingTrivia(CarriageReturnLineFeed);

while (types.Length > 0)
{
var innerTypes = types.Take(10).ToArray();
types = types.Skip(10).ToArray();
cu = cu.AddAttributeLists(
AttributeList(
target: AttributeTargetSpecifier(Token(SyntaxKind.AssemblyKeyword)),
SingletonSeparatedList(Attribute(IdentifierName("AssemblyJsonRpcHandlers"), AttributeArgumentList(SeparatedList(innerTypes))))
)
);
}
context.AddSource("AssemblyJsonRpcHandlers.cs", cu.NormalizeWhitespace().GetText(Encoding.UTF8));
}
}
Expand Down Expand Up @@ -84,6 +88,7 @@ public override void OnVisitNode(TypeDeclarationSyntax syntaxNode)
&& syntaxNode.BaseList is { } bl && bl.Types.Any(
z => z.Type switch {
SimpleNameSyntax { Identifier: { Text: "IJsonRpcNotificationHandler" }, Arity: 0 or 1 } => true,
SimpleNameSyntax { Identifier: { Text: "ICanBeResolvedHandler" }, Arity: 1 } => true,
SimpleNameSyntax { Identifier: { Text: "IJsonRpcRequestHandler" }, Arity: 1 or 2 } => true,
SimpleNameSyntax { Identifier: { Text: "IJsonRpcHandler" }, Arity: 0 } => true,
_ => false
Expand All @@ -99,6 +104,7 @@ public override void OnVisitNode(TypeDeclarationSyntax syntaxNode)
&& syntaxNode.BaseList is { } bl2 && bl2.Types.Any(
z => z.Type switch {
SimpleNameSyntax { Identifier: { Text: "IJsonRpcNotificationHandler" }, Arity: 0 or 1 } => true,
SimpleNameSyntax { Identifier: { Text: "ICanBeResolvedHandler" }, Arity: 1 } => true,
SimpleNameSyntax { Identifier: { Text: "IJsonRpcRequestHandler" }, Arity: 1 or 2 } => true,
SimpleNameSyntax { Identifier: { Text: "IJsonRpcHandler" }, Arity: 0 } => true,
_ => false
Expand Down
64 changes: 50 additions & 14 deletions src/JsonRpc.Generators/Contexts/RegistrationOptionAttributes.cs
@@ -1,13 +1,16 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace OmniSharp.Extensions.JsonRpc.Generators.Contexts
{
record RegistrationOptionAttributes(
SyntaxAttributeData? GenerateRegistrationOptions,
string? Key,
ExpressionSyntax? KeyExpression,
ExpressionSyntax[]? KeyExpression,
bool SupportsWorkDoneProgress,
bool SupportsDocumentSelector,
bool SupportsStaticRegistrationOptions,
Expand All @@ -19,13 +22,16 @@ bool ImplementsStaticRegistrationOptions
{
public static RegistrationOptionAttributes? Parse(GeneratorExecutionContext context, TypeDeclarationSyntax syntax, INamedTypeSymbol symbol)
{
var registrationOptionsAttributeSymbol = context.Compilation.GetTypeByMetadataName($"OmniSharp.Extensions.LanguageServer.Protocol.Generation.GenerateRegistrationOptionsAttribute");
var registrationOptionsConverterAttributeSymbol = context.Compilation.GetTypeByMetadataName($"OmniSharp.Extensions.LanguageServer.Protocol.RegistrationOptionsConverterAttribute");
var registrationOptionsAttributeSymbol =
context.Compilation.GetTypeByMetadataName($"OmniSharp.Extensions.LanguageServer.Protocol.Generation.GenerateRegistrationOptionsAttribute");
var registrationOptionsConverterAttributeSymbol =
context.Compilation.GetTypeByMetadataName($"OmniSharp.Extensions.LanguageServer.Protocol.RegistrationOptionsConverterAttribute");
// var registrationOptionsInterfaceSymbol = context.Compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.IRegistrationOptions");
var textDocumentRegistrationOptionsInterfaceSymbol =
context.Compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.ITextDocumentRegistrationOptions");
var workDoneProgressOptionsInterfaceSymbol = context.Compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.IWorkDoneProgressOptions");
var staticRegistrationOptionsInterfaceSymbol = context.Compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.IStaticRegistrationOptions");
var staticRegistrationOptionsInterfaceSymbol =
context.Compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.IStaticRegistrationOptions");

if (!( symbol.GetAttribute(registrationOptionsAttributeSymbol) is { } data )) return null;
if (!( data.ApplicationSyntaxReference?.GetSyntax() is AttributeSyntax attributeSyntax )) return null;
Expand All @@ -34,12 +40,12 @@ bool ImplementsStaticRegistrationOptions
ITypeSymbol? converter = null;

var supportsDocumentSelector = data.NamedArguments.Any(z => z is { Key: nameof(SupportsDocumentSelector), Value: { Value: true } })
|| symbol.AllInterfaces.Length > 0 && symbol.AllInterfaces.Any(
z => SymbolEqualityComparer.Default.Equals(z, textDocumentRegistrationOptionsInterfaceSymbol)
)
|| textDocumentRegistrationOptionsInterfaceSymbol is { } && syntax.BaseList?.Types.Any(
type => type.Type.GetSyntaxName()?.Contains(textDocumentRegistrationOptionsInterfaceSymbol.Name) == true
) == true;
|| symbol.AllInterfaces.Length > 0 && symbol.AllInterfaces.Any(
z => SymbolEqualityComparer.Default.Equals(z, textDocumentRegistrationOptionsInterfaceSymbol)
)
|| textDocumentRegistrationOptionsInterfaceSymbol is { } && syntax.BaseList?.Types.Any(
type => type.Type.GetSyntaxName()?.Contains(textDocumentRegistrationOptionsInterfaceSymbol.Name) == true
) == true;
var supportsWorkDoneProgress = data.NamedArguments.Any(z => z is { Key: nameof(SupportsWorkDoneProgress), Value: { Value: true } })
|| symbol.AllInterfaces.Length > 0 && symbol.AllInterfaces.Any(
z => SymbolEqualityComparer.Default.Equals(z, workDoneProgressOptionsInterfaceSymbol)
Expand Down Expand Up @@ -82,17 +88,47 @@ bool ImplementsStaticRegistrationOptions
}

string? value = null;
ExpressionSyntax? valueSyntax = null;
ExpressionSyntax[]? valueExpressionSyntaxes = null;
if (data is { ConstructorArguments: { Length: > 0 } arguments } && arguments[0].Kind is TypedConstantKind.Primitive && arguments[0].Value is string)
{
value = arguments[0].Value as string;
valueSyntax = attributeSyntax.ArgumentList!.Arguments[0].Expression;
static IEnumerable<string> getStringValue(TypedConstant constant)
{
if (constant.Kind is TypedConstantKind.Primitive && constant.Value is string s)
{
yield return s;
}

if (constant.Kind is TypedConstantKind.Array)
{
foreach (var i in constant.Values.SelectMany(getStringValue))
{
yield return i;
}
}
}

static IEnumerable<ExpressionSyntax> getStringExpressionSyntaxes(AttributeArgumentSyntax syntax)
{
switch (syntax.Expression)
{
case LiteralExpressionSyntax literalExpressionSyntax when literalExpressionSyntax.Token.IsKind(SyntaxKind.StringLiteralToken):
yield return literalExpressionSyntax;
break;
case InvocationExpressionSyntax
{ Expression: IdentifierNameSyntax { Identifier: { Text: "nameof" } } }:
yield return syntax.Expression;
break;
}
}

value = string.Join(".", arguments.SelectMany(getStringValue));
valueExpressionSyntaxes = attributeSyntax.ArgumentList!.Arguments.SelectMany(getStringExpressionSyntaxes).ToArray();
}

return new RegistrationOptionAttributes(
new SyntaxAttributeData(attributeSyntax, data),
value,
valueSyntax,
valueExpressionSyntaxes,
supportsWorkDoneProgress,
supportsDocumentSelector,
supportsStaticRegistrationOptions,
Expand Down
18 changes: 12 additions & 6 deletions src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs
Expand Up @@ -144,16 +144,22 @@ ReportCacheDiagnostic<TypeDeclarationSyntax> cacheDiagnostic
var namespaces = new HashSet<string>() { "OmniSharp.Extensions.JsonRpc" };
if (handlers.Any())
{
var types = handlers.ToArray();
var cu = CompilationUnit()
.WithUsings(List(namespaces.OrderBy(z => z).Select(z => UsingDirective(ParseName(z)))))
.AddAttributeLists(
AttributeList(
target: AttributeTargetSpecifier(Token(SyntaxKind.AssemblyKeyword)),
SingletonSeparatedList(Attribute(IdentifierName("AssemblyJsonRpcHandlers"), AttributeArgumentList(SeparatedList(handlers))))
)
)
.WithLeadingTrivia(Comment(Preamble.GeneratedByATool))
.WithTrailingTrivia(CarriageReturnLineFeed);
while (types.Length > 0)
{
var innerTypes = types.Take(10).ToArray();
types = types.Skip(10).ToArray();
cu = cu.AddAttributeLists(
AttributeList(
target: AttributeTargetSpecifier(Token(SyntaxKind.AssemblyKeyword)),
SingletonSeparatedList(Attribute(IdentifierName("AssemblyJsonRpcHandlers"), AttributeArgumentList(SeparatedList(innerTypes))))
)
);
}

context.AddSource("GeneratedAssemblyJsonRpcHandlers.cs", cu.NormalizeWhitespace().GetText(Encoding.UTF8));
}
Expand Down
9 changes: 3 additions & 6 deletions src/JsonRpc.Generators/RegistrationOptionsGenerator.cs
Expand Up @@ -86,12 +86,9 @@ ReportCacheDiagnostic<TypeDeclarationSyntax> cacheDiagnostic
AttributeList(
SingletonSeparatedList(
Attribute(
IdentifierName("RegistrationOptionsKey"), AttributeArgumentList(
SingletonSeparatedList(
AttributeArgument(
data.KeyExpression
)
)
IdentifierName("RegistrationOptionsKey"),
AttributeArgumentList(
SeparatedList(data.KeyExpression.Select(AttributeArgument))
)
)
)
Expand Down
2 changes: 1 addition & 1 deletion src/JsonRpc/JsonRpc.csproj
Expand Up @@ -16,7 +16,7 @@
<PackageReference Include="System.IO.Pipelines" />
<PackageReference Include="Nerdbank.Streams" />
<PackageReference Include="DryIoc.Internal" PrivateAssets="All" />
<ProjectReference Include="..\JsonRpc.Generators\JsonRpc.Generators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" PrivateAssets="all" />
<ProjectReference Include="..\JsonRpc.Generators\JsonRpc.Generators.csproj" IncludeAssets="analyzers" ExcludeAssets="compile;runtime;native" PrivateAssets="contentfiles;build;buildMultitargeting;buildTransitive" OutputItemType="Analyzer" />
</ItemGroup>
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
Expand Down
5 changes: 4 additions & 1 deletion src/JsonRpc/JsonRpcServerOptionsBase.cs
Expand Up @@ -30,7 +30,10 @@ public ILoggerFactory LoggerFactory
}

public IEnumerable<Assembly> Assemblies { get; set; } = Enumerable.Empty<Assembly>();
public bool UseAssemblyAttributeScanning { get; set; } = true;
/// <summary>
/// Experimental support for using assembly attributes
/// </summary>
public bool UseAssemblyAttributeScanning { get; set; } = false;
public IRequestProcessIdentifier? RequestProcessIdentifier { get; set; }
public int? Concurrency { get; set; }
public IScheduler InputScheduler { get; set; } = TaskPoolScheduler.Default;
Expand Down

0 comments on commit 1c1117d

Please sign in to comment.