Skip to content

Commit

Permalink
Ported to new code
Browse files Browse the repository at this point in the history
  • Loading branch information
LPeter1997 committed Oct 20, 2023
1 parent e1f1aa6 commit d7bbef2
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 86 deletions.
17 changes: 4 additions & 13 deletions src/Draco.Compiler/Internal/Symbols/Metadata/TypeProvider.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
Expand All @@ -21,7 +22,7 @@ internal sealed class TypeProvider : ISignatureTypeProvider<TypeSymbol, Symbol>,
private IntrinsicSymbols IntrinsicSymbols => this.compilation.IntrinsicSymbols;

private readonly Compilation compilation;
private readonly Dictionary<CacheKey, TypeSymbol> cache = new();
private readonly ConcurrentDictionary<CacheKey, TypeSymbol> cache = new();

public TypeProvider(Compilation compilation)
{
Expand Down Expand Up @@ -94,12 +95,7 @@ public TypeSymbol GetGenericTypeParameter(Symbol genericContext, int index)
public TypeSymbol GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
{
var key = new CacheKey(reader, handle);
if (!this.cache.TryGetValue(key, out var type))
{
type = this.BuildTypeFromDefinition(reader, handle, rawTypeKind);
this.cache.Add(key, type);
}
return type;
return this.cache.GetOrAdd(key, _ => this.BuildTypeFromDefinition(reader, handle, rawTypeKind));
}

private TypeSymbol BuildTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
Expand Down Expand Up @@ -137,12 +133,7 @@ private TypeSymbol BuildTypeFromDefinition(MetadataReader reader, TypeDefinition
public TypeSymbol GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
{
var key = new CacheKey(reader, handle);
if (!this.cache.TryGetValue(key, out var type))
{
type = this.BuildTypeFromReference(reader, handle, rawTypeKind);
this.cache.Add(key, type);
}
return type;
return this.cache.GetOrAdd(key, _ => this.BuildTypeFromReference(reader, handle, rawTypeKind));
}

private TypeSymbol BuildTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
Expand Down
148 changes: 75 additions & 73 deletions src/Draco.Lsp/Server/LanguageServerConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,57 +19,103 @@

namespace Draco.Lsp.Server;

internal sealed class LspMessageAdapter : IJsonRpcMessageAdapter<LspMessage, ResponseError>
internal sealed class LanguageServerConnection : JsonRpcConnection<LspMessage, ResponseError>
{
private LspMessageAdapter()
public override IDuplexPipe Transport { get; }

public override JsonSerializerOptions JsonSerializerOptions { get; } = new()
{
Converters =
{
new OneOfConverter(),
new TupleConverter(),
new UriConverter(),
}
};

public override JsonSerializerOptions JsonDeserializerOptions { get; } = new()
{
Converters =
{
new OneOfConverter(),
new TupleConverter(),
new UriConverter(),
new ModelInterfaceConverter(),
}
};

public LanguageServerConnection(IDuplexPipe transport)
{
this.Transport = transport;
}

protected override Task<(LspMessage Message, bool Handled)> TryProcessCustomRequest(LspMessage message) =>
Task.FromResult((message, false));

protected override Task<bool> TryProcessCustomNotification(LspMessage message)
{
// Cancellation
var id = this.GetMessageId(message);
var method = this.GetMessageMethodName(message);
if (method == "$/cancelRequest")
{
this.CancelIncomingRequest(id!);
return Task.FromResult(true);
}

return Task.FromResult(false);
}

public static LspMessage CreateRequest(int id, string method, JsonElement @params) => new RequestMessage
protected override void CancelOutgoingRequest(int id)
{
base.CancelOutgoingRequest(id);
this.SendMessage(this.CreateNotificationMessage(
"$/cancelRequest",
JsonSerializer.SerializeToElement(new CancelParams
{
Id = id,
})));
}

protected override LspMessage CreateRequestMessage(int id, string method, JsonElement @params) => new RequestMessage
{
Jsonrpc = "2.0",
Method = method,
Id = id,
Params = @params,
};
public static LspMessage CreateCancelRequest(int id) => CreateNotification(
"$/cancelRequest",
JsonSerializer.SerializeToElement(new CancelParams
{
Id = id,
}));
public static LspMessage CreateOkResponse(object id, JsonElement okResult) => new ResponseMessage
protected override LspMessage CreateOkResponseMessage(object id, JsonElement okResult) => new ResponseMessage
{
Jsonrpc = "2.0",
Id = ToId(id),
Id = ToMessageId(id),
Result = okResult,
};
public static LspMessage CreateErrorResponse(object id, ResponseError errorResult) => new ResponseMessage
protected override LspMessage CreateErrorResponseMessage(object id, ResponseError errorResult) => new ResponseMessage
{
Jsonrpc = "2.0",
Id = ToId(id),
Id = ToMessageId(id),
Error = errorResult,
};
public static LspMessage CreateNotification(string method, JsonElement @params) => new NotificationMessage
protected override LspMessage CreateNotificationMessage(string method, JsonElement @params) => new NotificationMessage
{
Jsonrpc = "2.0",
Method = method,
Params = @params,
};

private static OneOf<int, string> ToId(object id) => id switch
private static OneOf<int, string> ToMessageId(object id) => id switch
{
int i => i,
string s => s,
OneOf<int, string> o => o,
_ => -1,
};

public static ResponseError CreateExceptionError(Exception exception)
protected override ResponseError CreateExceptionError(Exception exception)
{
// Unwrap
if (exception is TargetInvocationException) exception = exception.InnerException!;
if (exception is JsonException jsonException) return CreateJsonExceptionError(jsonException);
if (exception is JsonException jsonException) return this.CreateJsonExceptionError(jsonException);

var errorCode = exception switch
{
Expand All @@ -86,25 +132,25 @@ public static ResponseError CreateExceptionError(Exception exception)
Data = JsonSerializer.SerializeToElement(exception?.ToString()),
};
}
public static ResponseError CreateHandlerNotRegisteredError(string method) => new()
protected override ResponseError CreateHandlerNotRegisteredError(string method) => new()
{
// MethodNotFound
Code = -32601,
Message = $"A handler for the method '{method}' was not registered.",
};
public static ResponseError CreateHandlerWasRegisteredAsNotificationHandlerError(string method) => new()
protected override ResponseError CreateHandlerWasRegisteredAsNotificationHandlerError(string method) => new()
{
// InternalError
Code = -32603,
Message = $"A handler for the method '{method}' was registered as a notification handler.",
};
public static ResponseError CreateInvalidRequestError() => new()
protected override ResponseError CreateInvalidRequestError() => new()
{
// InvalidRequest
Code = -32600,
Message = "Invalid request.",
};
public static ResponseError CreateJsonExceptionError(JsonException exception)
protected override ResponseError CreateJsonExceptionError(JsonException exception)
{
// Typically, only exceptions from Utf8JsonReader have the position info set
// So, we assume this is a parse error if it's there, and other errors are serialization errors
Expand All @@ -122,14 +168,11 @@ public static ResponseError CreateJsonExceptionError(JsonException exception)
return responseError;
}

public static bool IsRequest(LspMessage message) => message.Is<RequestMessage>();
public static bool IsResponse(LspMessage message) => message.Is<ResponseMessage>();
public static bool IsNotification(LspMessage message) => message.Is<NotificationMessage>();
public static bool IsCancellation(LspMessage message) =>
message.Is<RequestMessage>(out var req)
&& req.Method == "$/cancelRequest";
protected override bool IsRequestMessage(LspMessage message) => message.Is<RequestMessage>();
protected override bool IsResponseMessage(LspMessage message) => message.Is<ResponseMessage>();
protected override bool IsNotificationMessage(LspMessage message) => message.Is<NotificationMessage>();

public static object? GetId(LspMessage message)
protected override object? GetMessageId(LspMessage message)
{
static object? GetRawId(LspMessage message)
{
Expand All @@ -141,64 +184,23 @@ public static bool IsCancellation(LspMessage message) =>
var rawId = GetRawId(message);
return (rawId as IOneOf)?.Value;
}
public static string GetMethodName(LspMessage message)
protected override string GetMessageMethodName(LspMessage message)
{
if (message.Is<RequestMessage>(out var req)) return req.Method;
if (message.Is<NotificationMessage>(out var notif)) return notif.Method;
return string.Empty;
}
public static JsonElement? GetParams(LspMessage message)
protected override JsonElement? GetMessageParams(LspMessage message)
{
if (message.Is<RequestMessage>(out var req)) return req.Params;
if (message.Is<ResponseMessage>(out var resp)) return resp.Result;
if (message.Is<NotificationMessage>(out var notif)) return notif.Params;
return null;
}
public static (ResponseError? Error, bool HasError) GetError(LspMessage message)
protected override (ResponseError? Error, bool HasError) GetMessageError(LspMessage message)
{
if (message.Is<ResponseMessage>(out var resp)) return (resp.Error, resp.Error is not null);
return (null, false);
}
public static string GetErrorMessage(ResponseError error) => error.Message;
}

internal sealed class LanguageServerConnection : JsonRpcConnection<LspMessage, ResponseError, LspMessageAdapter>
{
public override IDuplexPipe Transport { get; }

public override JsonSerializerOptions JsonSerializerOptions { get; } = new()
{
Converters =
{
new OneOfConverter(),
new TupleConverter(),
new UriConverter(),
}
};

public override JsonSerializerOptions JsonDeserializerOptions { get; } = new()
{
Converters =
{
new OneOfConverter(),
new TupleConverter(),
new UriConverter(),
new ModelInterfaceConverter(),
}
};

public LanguageServerConnection(IDuplexPipe transport)
{
this.Transport = transport;
}
}

internal sealed class LspResponseException : Exception
{
public LspResponseException(ResponseError error) : base(error.Message)
{
this.ResponseError = error;
}

public ResponseError ResponseError { get; }
protected override string GetErrorMessage(ResponseError error) => error.Message;
}

0 comments on commit d7bbef2

Please sign in to comment.