Skip to content
This repository was archived by the owner on Dec 22, 2021. It is now read-only.

Commit 3aba16a

Browse files
authored
Merge pull request #6 from matarillo/develop
v3.0.0
2 parents 799af83 + bd8cffd commit 3aba16a

33 files changed

+502
-426
lines changed
Lines changed: 114 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,146 @@
1-
using LanguageServer.Json;
2-
using Newtonsoft.Json;
1+
using Newtonsoft.Json;
32
using Newtonsoft.Json.Linq;
43
using System;
4+
using System.Collections.Generic;
55
using System.Reflection;
6+
using LanguageServer.Json;
7+
using LanguageServer.Parameters;
8+
using LanguageServer.Parameters.General;
9+
using LanguageServer.Parameters.TextDocument;
610

711
namespace LanguageServer.Infrastructure.JsonDotNet
812
{
9-
internal class EitherConverter : JsonConverter
13+
public class EitherConverter : JsonConverter
1014
{
15+
private readonly Dictionary<Type, Func<JToken, object>> table;
16+
17+
public EitherConverter()
18+
{
19+
table = new Dictionary<Type, Func<JToken, object>>();
20+
table[typeof(NumberOrString)] = token => (object)ToNumberOrString(token);
21+
table[typeof(LocationSingleOrArray)] = token => (object)ToLocationSingleOrArray(token);
22+
table[typeof(TextDocumentSync)] = token => (object)ToTextDocumentSync(token);
23+
table[typeof(CompletionResult)] = token => (object)ToCompletionResult(token);
24+
table[typeof(HoverContents)] = token => (object)ToHoverContents(token);
25+
}
26+
1127
public override bool CanConvert(Type objectType)
1228
{
13-
return typeof(IEither).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo());
29+
return typeof(Either).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo());
30+
}
31+
32+
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
33+
{
34+
var convert = table[objectType] ??
35+
throw new NotImplementedException($"Could not deserialize '{objectType.FullName}'.");
36+
var token = JToken.Load(reader);
37+
return convert(token);
1438
}
1539

16-
private static JsonDataType Convert(JsonToken token)
40+
#region Deserialization
41+
42+
private NumberOrString ToNumberOrString(JToken token)
1743
{
18-
switch (token)
44+
switch (token.Type)
1945
{
20-
case JsonToken.Null:
21-
return JsonDataType.Null;
22-
case JsonToken.Boolean:
23-
return JsonDataType.Boolean;
24-
case JsonToken.Float:
25-
return JsonDataType.Number;
26-
case JsonToken.Integer:
27-
return JsonDataType.Number;
28-
case JsonToken.String:
29-
return JsonDataType.String;
30-
case JsonToken.StartArray:
31-
return JsonDataType.Array;
32-
case JsonToken.StartObject:
33-
return JsonDataType.Object;
46+
case JTokenType.Null:
47+
return null;
48+
case JTokenType.Integer:
49+
return new NumberOrString(token.ToObject<long>());
50+
case JTokenType.String:
51+
return new NumberOrString(token.ToObject<string>());
3452
default:
35-
return default(JsonDataType);
53+
throw new JsonSerializationException();
3654
}
3755
}
3856

39-
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
57+
private LocationSingleOrArray ToLocationSingleOrArray(JToken token)
4058
{
41-
var either = Activator.CreateInstance(objectType) as IEither;
42-
var jsonType = Convert(reader.TokenType);
43-
var tag = either.OnDeserializing(jsonType);
44-
if (tag == EitherTag.Left)
59+
switch (token.Type)
4560
{
46-
var left = serializer.Deserialize(reader, either.LeftType);
47-
either.Left = left;
48-
return either;
61+
case JTokenType.Null:
62+
return null;
63+
case JTokenType.Object:
64+
return new LocationSingleOrArray(token.ToObject<Location>());
65+
case JTokenType.Array:
66+
return new LocationSingleOrArray(token.ToObject<Location[]>());
67+
default:
68+
throw new JsonSerializationException();
4969
}
50-
else if (tag == EitherTag.Right)
70+
}
71+
72+
private TextDocumentSync ToTextDocumentSync(JToken token)
73+
{
74+
switch (token.Type)
5175
{
52-
var right = serializer.Deserialize(reader, either.RightType);
53-
either.Right = right;
54-
return either;
76+
case JTokenType.Null:
77+
return null;
78+
case JTokenType.Integer:
79+
return new TextDocumentSync(token.ToObject<TextDocumentSyncKind>());
80+
case JTokenType.Object:
81+
return new TextDocumentSync(token.ToObject<TextDocumentSyncOptions>());
82+
default:
83+
throw new JsonSerializationException();
5584
}
56-
return null;
5785
}
5886

59-
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
87+
private CompletionResult ToCompletionResult(JToken token)
6088
{
61-
var either = value as IEither;
62-
if (either == null)
89+
switch (token.Type)
6390
{
64-
return;
91+
case JTokenType.Null:
92+
return null;
93+
case JTokenType.Array:
94+
return new CompletionResult(token.ToObject<CompletionItem[]>());
95+
case JTokenType.Object:
96+
return new CompletionResult(token.ToObject<CompletionList>());
97+
default:
98+
throw new JsonSerializationException();
6599
}
66-
var objectValue = (either.IsLeft) ? either.Left : (either.IsRight) ? either.Right : null;
67-
if (objectValue == null)
100+
}
101+
102+
private HoverContents ToHoverContents(JToken token)
103+
{
104+
switch (token.Type)
68105
{
69-
return;
106+
case JTokenType.Null:
107+
return null;
108+
case JTokenType.String:
109+
return new HoverContents(token.ToObject<string>());
110+
case JTokenType.Object:
111+
return new HoverContents(token.ToObject<MarkedString>());
112+
case JTokenType.Array:
113+
var array = (JArray) token;
114+
if (array.Count == 0)
115+
{
116+
return new HoverContents(new string[0]);
117+
}
118+
119+
var element = (array[0] as JObject) ?? throw new JsonSerializationException();
120+
if (element.Type == JTokenType.String)
121+
{
122+
return new HoverContents(array.ToObject<string[]>());
123+
}
124+
else if (element.Type == JTokenType.Object)
125+
{
126+
return new HoverContents(array.ToObject<MarkedString[]>());
127+
}
128+
else
129+
{
130+
throw new JsonSerializationException();
131+
}
132+
133+
default:
134+
throw new JsonSerializationException();
70135
}
71-
JToken.FromObject(objectValue, serializer).WriteTo(writer);
136+
}
137+
138+
#endregion
139+
140+
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
141+
{
142+
var either = (Either)value;
143+
serializer.Serialize(writer, either?.Value);
72144
}
73145
}
74146
}

LanguageServer/Json/ArrayOrObject.cs

Lines changed: 0 additions & 35 deletions
This file was deleted.

LanguageServer/Json/Either.cs

Lines changed: 24 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,33 @@
11
using System;
2-
using System.Linq;
3-
using System.Reflection;
42

53
namespace LanguageServer.Json
64
{
7-
public abstract class Either<TLeft, TRight> : IEither
5+
/// <summary>
6+
/// Mimic discriminated union types
7+
/// </summary>
8+
/// <remarks>
9+
/// <see cref="Serializer"/> must support these derived types below:
10+
/// <list type="bullet">
11+
/// <item><description><see cref="NumberOrString"/></description></item>
12+
/// <item><description><see cref="LanguageServer.Parameters.LocationSingleOrArray"/></description></item>
13+
/// <item><description><see cref="LanguageServer.Parameters.General.ChangeNotifications"/></description></item>
14+
/// <item><description><see cref="LanguageServer.Parameters.General.ColorProviderCapabilities"/></description></item>
15+
/// <item><description><see cref="LanguageServer.Parameters.General.FoldingRangeProviderCapabilities"/></description></item>
16+
/// <item><description><see cref="LanguageServer.Parameters.General.ProviderCapabilities"/></description></item>
17+
/// <item><description><see cref="LanguageServer.Parameters.General.TextDocumentSync"/></description></item>
18+
/// <item><description><see cref="LanguageServer.Parameters.TextDocument.CodeActionResult"/></description></item>
19+
/// <item><description><see cref="LanguageServer.Parameters.TextDocument.CompletionItemDocumentation"/></description></item>
20+
/// <item><description><see cref="LanguageServer.Parameters.TextDocument.CompletionResult"/></description></item>
21+
/// <item><description><see cref="LanguageServer.Parameters.TextDocument.DocumentSymbolResult"/></description></item>
22+
/// <item><description><see cref="LanguageServer.Parameters.TextDocument.HoverContents"/></description></item>
23+
/// </list>
24+
/// </remarks>
25+
public abstract class Either
826
{
9-
private EitherTag _tag;
10-
private TLeft _left;
11-
private TRight _right;
27+
public object Value { get; protected set; }
1228

13-
public Either()
14-
{
15-
}
29+
public Type Type { get; protected set; }
1630

17-
public Either(TLeft left)
18-
{
19-
_tag = EitherTag.Left;
20-
_left = left;
21-
}
22-
23-
public Either(TRight right)
24-
{
25-
_tag = EitherTag.Right;
26-
_right = right;
27-
}
28-
29-
public bool IsLeft => _tag == EitherTag.Left;
30-
31-
public bool IsRight => _tag == EitherTag.Right;
32-
33-
public TLeft Left => _tag == EitherTag.Left ? _left : throw new InvalidOperationException();
34-
35-
public TRight Right => _tag == EitherTag.Right ? _right : throw new InvalidOperationException();
36-
37-
public Type LeftType => typeof(TLeft);
38-
39-
public Type RightType => typeof(TRight);
40-
41-
protected abstract EitherTag OnDeserializing(JsonDataType jsonType);
42-
43-
object IEither.Left
44-
{
45-
get => this.Left;
46-
set
47-
{
48-
_tag = EitherTag.Left;
49-
_left = (TLeft)value;
50-
_right = default(TRight);
51-
}
52-
}
53-
54-
object IEither.Right
55-
{
56-
get => this.Right;
57-
set
58-
{
59-
_tag = EitherTag.Right;
60-
_left = default(TLeft);
61-
_right = (TRight)value;
62-
}
63-
}
64-
65-
EitherTag IEither.OnDeserializing(JsonDataType jsonType) => this.OnDeserializing(jsonType);
31+
public T GetValue<T>() => (this.Type == typeof(T)) ? (T)Value : throw new InvalidOperationException();
6632
}
6733
}

LanguageServer/Json/EitherTag.cs

Lines changed: 0 additions & 13 deletions
This file was deleted.

LanguageServer/Json/IEither.cs

Lines changed: 0 additions & 17 deletions
This file was deleted.

LanguageServer/Json/JsonDataType.cs

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)