Support for setting userdata types, validating them and autocompleting them
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Upsilon.BoundTypes;
|
||||
using Type = Upsilon.BaseTypes.Type;
|
||||
|
||||
namespace UpsilonLanguageServer
|
||||
{
|
||||
public static class BoundTypeParser
|
||||
{
|
||||
public static void LoadBoundTypes(string fileContent)
|
||||
{
|
||||
BoundTypeHandler.Reset();
|
||||
var json = JObject.Parse(fileContent);
|
||||
foreach (var prop in json.Properties())
|
||||
{
|
||||
var typeName = prop.Name;
|
||||
var dic = new Dictionary<string, UserDataBoundProperty>();
|
||||
var innerProperties = ((JObject)prop.Value).Properties();
|
||||
foreach (var innerProperty in innerProperties)
|
||||
{
|
||||
var propertyName = innerProperty.Name;
|
||||
var value = (JObject)innerProperty.Value;
|
||||
var type = value.GetValue("type", StringComparison.InvariantCultureIgnoreCase)?.ToString();
|
||||
var comment = value.GetValue("comment", StringComparison.InvariantCultureIgnoreCase)?.ToString();
|
||||
dic.Add(propertyName, new UserDataBoundProperty()
|
||||
{
|
||||
Name = propertyName,
|
||||
ActualType = type,
|
||||
Comment = comment,
|
||||
//TODO
|
||||
Type = ParseType(type)
|
||||
});
|
||||
}
|
||||
|
||||
BoundTypeHandler.LoadUserDataTypeDefinition(new UserDataBoundTypeDefinition(typeName, dic));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Type ParseType(string input)
|
||||
{
|
||||
if (string.Equals(input, "string", StringComparison.InvariantCultureIgnoreCase))
|
||||
return Type.String;
|
||||
if (string.Equals(input, "number", StringComparison.InvariantCultureIgnoreCase))
|
||||
return Type.Number;
|
||||
if (string.Equals(input, "bool", StringComparison.InvariantCultureIgnoreCase))
|
||||
return Type.Boolean;
|
||||
if (string.Equals(input, "table", StringComparison.InvariantCultureIgnoreCase))
|
||||
return Type.Table;
|
||||
if (string.Equals(input, "function", StringComparison.InvariantCultureIgnoreCase))
|
||||
return Type.Function;
|
||||
|
||||
return Type.UserData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using JsonRpc.Standard;
|
||||
using JsonRpc.Standard.Contracts;
|
||||
@@ -16,6 +17,15 @@ namespace UpsilonLanguageServer.Services
|
||||
public InitializeResult Initialize(int processId, Uri rootUri, ClientCapabilities capabilities,
|
||||
JToken initializationOptions = null, string trace = null)
|
||||
{
|
||||
if (rootUri != null)
|
||||
{
|
||||
var configPath = rootUri.AbsolutePath + "/.upsilon";
|
||||
var typesConfigFile = configPath + "/types.json";
|
||||
if (File.Exists(typesConfigFile))
|
||||
{
|
||||
BoundTypeParser.LoadBoundTypes(File.ReadAllText(typesConfigFile));
|
||||
}
|
||||
}
|
||||
return new InitializeResult(new ServerCapabilities
|
||||
{
|
||||
HoverProvider = true,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -6,9 +7,8 @@ using System.Threading.Tasks;
|
||||
using JsonRpc.Standard.Contracts;
|
||||
using LanguageServer.VsCode;
|
||||
using LanguageServer.VsCode.Contracts;
|
||||
using LanguageServer.VsCode.Server;
|
||||
using Upsilon.Binder;
|
||||
using Upsilon.Parser;
|
||||
using Upsilon.BoundTypes;
|
||||
using Upsilon.Utilities;
|
||||
|
||||
namespace UpsilonLanguageServer.Services
|
||||
@@ -62,16 +62,24 @@ namespace UpsilonLanguageServer.Services
|
||||
[JsonRpcMethod]
|
||||
public SignatureHelp SignatureHelp(TextDocumentIdentifier textDocument, Position position)
|
||||
{
|
||||
// TODO
|
||||
return new SignatureHelp(new List<SignatureInformation>
|
||||
{
|
||||
new SignatureInformation("**Function1**", "Documentation1"),
|
||||
new SignatureInformation("**Function2** <strong>test</strong>", "Documentation2"),
|
||||
});
|
||||
}
|
||||
|
||||
[JsonRpcMethod(IsNotification = true)]
|
||||
public async Task DidOpen(TextDocumentItem textDocument)
|
||||
{
|
||||
if (textDocument.Uri.IsUntitled())
|
||||
{
|
||||
var workspace = Session.Client.Workspace;
|
||||
if (workspace != null)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var doc = new SessionDocument(textDocument);
|
||||
var session = Session;
|
||||
doc.DocumentChanged += async (sender, args) =>
|
||||
@@ -126,6 +134,17 @@ namespace UpsilonLanguageServer.Services
|
||||
var findNode = doc.Bound.GetBottomNodeAtPosition(linePos + position.Character - 2);
|
||||
if (findNode is BoundVariableSymbol variableSymbol)
|
||||
{
|
||||
if (variableSymbol.VariableSymbol is FunctionParameterSymbol parameterSymbol &&
|
||||
parameterSymbol.BoundTypeDefinition is UserDataBoundTypeDefinition udBoundDef)
|
||||
{
|
||||
return new CompletionList(
|
||||
udBoundDef.Properties.Select(x =>
|
||||
{
|
||||
var (key, value) = x;
|
||||
return new CompletionItem(key, CompletionItemKind.Variable,
|
||||
$"{value.ActualType}({value.Type})", $"{value.Comment}", null);
|
||||
}));
|
||||
}
|
||||
if (variableSymbol.VariableSymbol is TableVariableSymbol tableSymbol)
|
||||
{
|
||||
return new CompletionList(
|
||||
@@ -136,7 +155,7 @@ namespace UpsilonLanguageServer.Services
|
||||
CompletionItemKind.Variable, value.Type.ToString(),
|
||||
x.Value.CommentValue == null
|
||||
? ""
|
||||
: $"\n\n{string.Join(" \n", value.CommentValue)}");
|
||||
: $"{string.Join(" \n", value.CommentValue)}", null);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using JsonRpc.Standard.Contracts;
|
||||
using LanguageServer.VsCode.Contracts;
|
||||
using Upsilon.BoundTypes;
|
||||
|
||||
namespace UpsilonLanguageServer.Services
|
||||
{
|
||||
@@ -46,7 +47,24 @@ namespace UpsilonLanguageServer.Services
|
||||
await Client.Document.PublishDiagnostics(change.Uri, new Diagnostic[0]);
|
||||
}
|
||||
}
|
||||
|
||||
else if (string.Equals(Path.GetExtension(localPath), ".json",
|
||||
StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
var name = Path.GetFileName(localPath);
|
||||
if (string.Equals(Path.GetFileName(localPath), "types.json",
|
||||
StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
if (change.Type == FileChangeType.Created || change.Type == FileChangeType.Changed)
|
||||
{
|
||||
BoundTypeParser.LoadBoundTypes(File.ReadAllText(localPath));
|
||||
foreach (var doc in Session.Documents.Values)
|
||||
{
|
||||
var diag = await DiagnosticProvider.LintDocument(doc.Document, doc, Session.Settings.MaxNumberOfProblems);
|
||||
await Client.Document.PublishDiagnostics(doc.Document.Uri, diag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user