Lots of improvements

This commit is contained in:
2018-12-12 22:29:47 +01:00
parent c7b8ef3463
commit d1c0a61bd1
17 changed files with 406 additions and 65 deletions

View File

@@ -1,8 +1,9 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Upsilon.Binder.VariableSymbols;
using Upsilon.BoundTypes;
using Upsilon.StandardLibraries;
using Type = Upsilon.BaseTypes.Type;
namespace UpsilonLanguageServer
@@ -24,18 +25,123 @@ namespace UpsilonLanguageServer
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()
if (string.Equals("function", type, StringComparison.InvariantCultureIgnoreCase))
{
Name = propertyName,
ActualType = type,
Comment = comment,
Type = ParseType(type)
});
ParseMethod(value, dic, propertyName, type, comment);
}
else
{
dic.Add(propertyName.ToLowerInvariant(), new UserDataBoundProperty()
{
Name = propertyName,
ActualType = type,
Comment = comment,
Type = ParseType(type)
});
}
}
BoundTypeHandler.LoadUserDataTypeDefinition(new UserDataBoundTypeDefinition(typeName, dic));
}
}
private static void ParseMethod(JObject value, IDictionary<string, UserDataBoundProperty> dic, string propertyName, string type, string comment)
{
var returnType = value.GetValue("returns", StringComparison.InvariantCultureIgnoreCase)?.ToString();
var parameters = new List<UserDataBoundFunctionParameter>();
if (value.GetValue("Parameters", StringComparison.InvariantCultureIgnoreCase) is JObject parameterJson)
{
var properties = parameterJson.Properties();
foreach (var property in properties)
{
var parameterName = property.Name;
var parameterValue = (JObject) property.Value;
var parType = parameterValue.GetValue("type", StringComparison.InvariantCultureIgnoreCase)
?.ToString();
var parComment = parameterValue.GetValue("comment", StringComparison.InvariantCultureIgnoreCase)
?.ToString();
var isOptional = parameterValue.GetValue("IsOptional", StringComparison.InvariantCultureIgnoreCase)
?.ToObject<bool>();
parameters.Add(new UserDataBoundFunctionParameter()
{
Name = parameterName,
Type = ParseType(parType),
Comment = parComment,
IsOptional = isOptional.HasValue && isOptional.Value
});
}
}
dic.Add(propertyName.ToLowerInvariant(), new UserDataBoundMethod()
{
Name = propertyName,
ActualType = type,
Comment = comment,
Type = ParseType(type),
ResultType = ParseType(returnType),
Parameters = parameters.ToArray()
});
}
public static void LoadStaticVariables(string fileContent)
{
StaticScope.BoundScope = StaticScope.CreateStandardLibrary().Item2;
var json = JObject.Parse(fileContent);
foreach (var property in json.Properties())
{
var name = property.Name;
var obj = (JObject)property.Value;
var stringType = obj.GetValue("type", StringComparison.InvariantCultureIgnoreCase).ToString().ToLowerInvariant();
var comments = obj.GetValue("comment", StringComparison.InvariantCultureIgnoreCase)?.ToString()
.Split('\n');
var type = ParseType(stringType);
if (type == Type.UserData)
{
var boundType = BoundTypeHandler.GetTypeDefinition(stringType);
if (boundType != null)
{
StaticScope.BoundScope.AssignToNearest(new UserDataVariableSymbol(name, boundType){CommentValue = comments});
}
else
{
StaticScope.BoundScope.AssignToNearest(new UserDataVariableSymbol(name, Type.Unknown){CommentValue = comments});
}
}
else if (type == Type.Function)
{
var returnType = obj.GetValue("returns", StringComparison.InvariantCultureIgnoreCase).ToString().ToLowerInvariant();
var parameters = new List<InternalFunctionVariableSymbol.InternalFunctionParameter>();
if (obj.GetValue("Parameters", StringComparison.InvariantCultureIgnoreCase) is JObject parameterJson)
{
var properties = parameterJson.Properties();
foreach (var prop in properties)
{
var parameterValue = (JObject) prop.Value;
var parType = parameterValue.GetValue("type", StringComparison.InvariantCultureIgnoreCase)
?.ToString();
var parsedType = ParseType(parType);
var isOptional = parameterValue.GetValue("IsOptional", StringComparison.InvariantCultureIgnoreCase)
?.ToObject<bool>();
parameters.Add(new InternalFunctionVariableSymbol.InternalFunctionParameter(parsedType,
isOptional.HasValue && isOptional.Value));
}
}
var parsedReturnType = ParseType(returnType);
StaticScope.BoundScope.AssignToNearest(new InternalFunctionVariableSymbol(name, false,
parsedReturnType, parameters.ToArray())
{
CommentValue = comments
});
}
else
{
StaticScope.BoundScope.AssignToNearest(new VariableSymbol(property.Name,
type, false)
{
CommentValue = comments
});
}
}
}
private static Type ParseType(string input)

View File

@@ -39,7 +39,8 @@ namespace UpsilonLanguageServer
private static readonly ScriptOptions Options = new ScriptOptions()
{
ThrowExceptionOnError = false,
SaveDataComments = true
SaveDataComments = true,
};
private static async Task RealLint(TextDocument document, int maxNumberOfProblems, SessionDocument session,

View File

@@ -16,9 +16,9 @@ using Microsoft.Extensions.Logging.Debug;
namespace UpsilonLanguageServer
{
static class Program
internal static class Program
{
static void Main(string[] args)
private static void Main(string[] args)
{
var debugMode = args.Any(a => a.Equals("--debug", StringComparison.OrdinalIgnoreCase));
#if WAIT_FOR_DEBUGGER

View File

@@ -25,6 +25,11 @@ namespace UpsilonLanguageServer.Services
{
BoundTypeParser.LoadBoundTypes(File.ReadAllText(typesConfigFile));
}
var staticConfigFile = configPath + "/static.json";
if (File.Exists(staticConfigFile))
{
BoundTypeParser.LoadStaticVariables(File.ReadAllText(staticConfigFile));
}
}
return new InitializeResult(new ServerCapabilities
{

View File

@@ -8,6 +8,7 @@ using JsonRpc.Standard.Contracts;
using LanguageServer.VsCode;
using LanguageServer.VsCode.Contracts;
using Upsilon.Binder;
using Upsilon.Binder.VariableSymbols;
using Upsilon.BoundTypes;
using Upsilon.Utilities;
using Type = Upsilon.BaseTypes.Type;
@@ -148,7 +149,7 @@ namespace UpsilonLanguageServer.Services
if (node is BoundFullStopIndexExpression indexExpression)
{
var expression = indexExpression.Expression;
var variableSymbol = ResolveVariable(expression);
var variableSymbol = Binder.ResolveVariable(expression, null);
var result = await GetListFromVariableSymbol(variableSymbol);
if (result != null)
{
@@ -166,7 +167,7 @@ namespace UpsilonLanguageServer.Services
variables.Select(x =>
{
var (key, value) = x;
return new CompletionItem(key,
return new CompletionItem(value.Name,
CompletionItemKind.Variable, value.Type.ToString(),
x.Value.CommentValue == null
? ""
@@ -179,7 +180,7 @@ namespace UpsilonLanguageServer.Services
private static async Task<CompletionList> GetListFromVariableSymbol(VariableSymbol variableSymbol)
{
if (variableSymbol is FunctionParameterSymbol parameterSymbol &&
if (variableSymbol is UserDataVariableSymbol parameterSymbol &&
parameterSymbol.BoundTypeDefinition is UserDataBoundTypeDefinition udBoundDef)
{
return new CompletionList(
@@ -206,34 +207,5 @@ namespace UpsilonLanguageServer.Services
return null;
}
private VariableSymbol ResolveVariable(BoundExpression expression)
{
if (expression.Kind == BoundKind.VariableExpression)
{
var variableExpression = (BoundVariableExpression) expression;
return variableExpression.Variable.VariableSymbol;
}
if (expression.Kind == BoundKind.BoundFullstopIndexExpression)
{
var fullStopIndexExpression = (BoundFullStopIndexExpression) expression;
var indexerExpression = fullStopIndexExpression.Expression;
var indexerVariable = ResolveVariable(indexerExpression);
if (indexerVariable.Type == Type.Table)
{
return ((TableVariableSymbol)indexerVariable).Variables[fullStopIndexExpression.Index];
}
if (indexerVariable.Type == Type.UserData)
{
var bDefProperty = ((UserDataBoundTypeDefinition) ((FunctionParameterSymbol) indexerVariable)
.BoundTypeDefinition).Properties[fullStopIndexExpression.Index];
var boundDef = BoundTypeHandler.GetTypeDefinition(bDefProperty.ActualType);
return new FunctionParameterSymbol(fullStopIndexExpression.Index, boundDef);
}
}
return null;
}
}
}

View File

@@ -51,7 +51,7 @@ namespace UpsilonLanguageServer.Services
StringComparison.InvariantCultureIgnoreCase))
{
var name = Path.GetFileName(localPath);
if (string.Equals(Path.GetFileName(localPath), "types.json",
if (string.Equals(name, "types.json",
StringComparison.InvariantCultureIgnoreCase))
{
if (change.Type == FileChangeType.Created || change.Type == FileChangeType.Changed)
@@ -64,6 +64,19 @@ namespace UpsilonLanguageServer.Services
}
}
}
else if (string.Equals(name, "static.json",
StringComparison.InvariantCultureIgnoreCase))
{
if (change.Type == FileChangeType.Created || change.Type == FileChangeType.Changed)
{
BoundTypeParser.LoadStaticVariables(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);
}
}
}
}
}
}