181 lines
8.8 KiB
C#
181 lines
8.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Newtonsoft.Json.Linq;
|
|
using Upsilon.Binder.VariableSymbols;
|
|
using Upsilon.BoundTypes;
|
|
using Upsilon.StandardLibraries;
|
|
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;
|
|
if (!(prop.Value is JObject obj))
|
|
continue;
|
|
|
|
var dic = new Dictionary<string, UserDataBoundProperty>();
|
|
var specialMod = obj.GetValue("__type", StringComparison.InvariantCultureIgnoreCase)?.ToString();
|
|
if (string.Equals(specialMod, "enum", StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
var values = obj.GetValue("values", StringComparison.InvariantCultureIgnoreCase)?.ToObject<string[]>();
|
|
if (values == null)
|
|
continue;
|
|
BoundTypeHandler.LoadUserDataTypeDefinition(new UserDataBoundEnumDefinition(values, typeName));
|
|
continue;
|
|
}
|
|
var innerProperties = obj.Properties();
|
|
foreach (var innerProperty in innerProperties)
|
|
{
|
|
var propertyName = innerProperty.Name;
|
|
if (!(innerProperty.Value is JObject value))
|
|
continue;
|
|
var type = value.GetValue("type", StringComparison.InvariantCultureIgnoreCase)?.ToString();
|
|
var comment = value.GetValue("comment", StringComparison.InvariantCultureIgnoreCase)?.ToString();
|
|
if (string.Equals("function", type, StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
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)
|
|
{
|
|
// We call the evaluation scope so that it initializes, and won't overwrite the bound scope later on
|
|
// DONT REMOVE
|
|
var _ = StaticScope.Scope;
|
|
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 parName = parameterValue.GetValue("name", StringComparison.InvariantCultureIgnoreCase)
|
|
?.ToString();
|
|
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(parName, 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)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
} |