新增UndefinedIdentifiersAsStrings选项并完善变量控制器
This commit is contained in:
@@ -95,6 +95,8 @@ namespace Convention.RScript.Parser
|
|||||||
public ExpressionParser(ExpressionContext context)
|
public ExpressionParser(ExpressionContext context)
|
||||||
{
|
{
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
// 默认启用未定义标识符作为字符串的功能
|
||||||
|
this.context.Options.UndefinedIdentifiersAsStrings = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Dictionary<string, Type> CompileGenericExpressionTypen = new();
|
private readonly Dictionary<string, Type> CompileGenericExpressionTypen = new();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Convention.RScript.Variable.CStyle
|
namespace Convention.RScript.Variable.CStyle
|
||||||
{
|
{
|
||||||
public class RScriptVariableGenerater : RScriptInjectVariableGenerater
|
public class CScriptRScriptVariableGenerater : RScriptInjectVariableGenerater
|
||||||
{
|
{
|
||||||
public static string GetTypename(Type type)
|
public static string GetTypename(Type type)
|
||||||
{
|
{
|
||||||
@@ -15,16 +15,25 @@ namespace Convention.RScript.Variable.CStyle
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int layer = 0;
|
private int m_layer = 0;
|
||||||
private string Prefix => new('\t', layer);
|
private int layer
|
||||||
|
{
|
||||||
|
get=>m_layer;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_layer = value;
|
||||||
|
Prefix = new('\t', layer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private string Prefix = "";
|
||||||
|
|
||||||
public RScriptVariableGenerater(Type targetType, [MaybeNull] Generater generater, string name) : base(targetType, generater, name)
|
public CScriptRScriptVariableGenerater(Type targetType, Generater generater, Destorier destorier, string name) : base(targetType, generater, destorier, name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string WriteClassBodyEnter(Type currentType)
|
protected override string WriteClassBodyEnter(Type currentType)
|
||||||
{
|
{
|
||||||
string result = $"{Prefix}{"{public:"}";
|
string result = $"{Prefix}{"{"}\n{Prefix}public:";
|
||||||
layer++;
|
layer++;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -32,21 +41,21 @@ namespace Convention.RScript.Variable.CStyle
|
|||||||
protected override string WriteClassBodyExit(Type currentType)
|
protected override string WriteClassBodyExit(Type currentType)
|
||||||
{
|
{
|
||||||
layer--;
|
layer--;
|
||||||
return $"{Prefix}{"{"}";
|
return $"{Prefix}{"};"}";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string WriteClassHead(Type currentType)
|
protected override string WriteClassHead(Type currentType)
|
||||||
{
|
{
|
||||||
|
string description = string.IsNullOrEmpty(this.description) ? "" : string.Join("", from item in this.description.Split('\n') where string.IsNullOrEmpty(item) == false select $"{Prefix}{item}\n");
|
||||||
string suffix = currentType.BaseType == typeof(object) ? string.Empty : $" : public {GetTypename(currentType.BaseType)}";
|
string suffix = currentType.BaseType == typeof(object) ? string.Empty : $" : public {GetTypename(currentType.BaseType)}";
|
||||||
string result = $"{Prefix}class {GetTypename(currentType)}{suffix}";
|
string result = $"{Prefix}\\*{description}*\\\n{Prefix}{Prefix}class {GetTypename(currentType)}{suffix}";
|
||||||
layer++;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string WriteClassMethod(Type returnType, string methodName, string[] parameterNames, Type[] parameterTypes)
|
protected override string WriteClassMethod(Type returnType, string methodName, string[] parameterNames, Type[] parameterTypes)
|
||||||
{
|
{
|
||||||
List<string> parameters = new();
|
List<string> parameters = new();
|
||||||
for(int i=0,e=parameterNames.Length;i<e;i++)
|
for (int i = 0, e = parameterNames.Length; i < e; i++)
|
||||||
{
|
{
|
||||||
parameters.Add($"{GetTypename(parameterTypes[i])} {parameterNames[i]}");
|
parameters.Add($"{GetTypename(parameterTypes[i])} {parameterNames[i]}");
|
||||||
}
|
}
|
||||||
@@ -68,7 +77,7 @@ namespace Convention.RScript.Variable.CStyle
|
|||||||
protected override string WriteEnumBodyExit(Type currentType)
|
protected override string WriteEnumBodyExit(Type currentType)
|
||||||
{
|
{
|
||||||
layer--;
|
layer--;
|
||||||
return $"{Prefix}{"{"}";
|
return $"{Prefix}{"};"}";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string WriteEnumHead(Type currentEnum)
|
protected override string WriteEnumHead(Type currentEnum)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Flee.InternalTypes;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -29,6 +30,16 @@ namespace Convention.RScript.Variable
|
|||||||
this.defaultScript = defaultScript;
|
this.defaultScript = defaultScript;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)]
|
||||||
|
public sealed class DescriptionAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string description;
|
||||||
|
public DescriptionAttribute(string description)
|
||||||
|
{
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class RScriptInjectVariableGenerater
|
public abstract class RScriptInjectVariableGenerater
|
||||||
@@ -67,7 +78,11 @@ namespace Convention.RScript.Variable
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public delegate object Generater();
|
public delegate object Generater();
|
||||||
|
|
||||||
private Generater MyGenerater;
|
public delegate void Destorier(object o);
|
||||||
|
|
||||||
|
private readonly Generater MyGenerater;
|
||||||
|
private readonly Destorier MyDestorier;
|
||||||
|
private readonly HashSet<object> GenerateObjects = new();
|
||||||
|
|
||||||
public readonly static Dictionary<string, RScriptInjectVariableGenerater> AllRScriptInjectVariables = new();
|
public readonly static Dictionary<string, RScriptInjectVariableGenerater> AllRScriptInjectVariables = new();
|
||||||
|
|
||||||
@@ -75,77 +90,87 @@ namespace Convention.RScript.Variable
|
|||||||
public readonly string name;
|
public readonly string name;
|
||||||
public readonly string scriptIndicator;
|
public readonly string scriptIndicator;
|
||||||
public readonly string defaultScript;
|
public readonly string defaultScript;
|
||||||
|
public readonly string description;
|
||||||
|
|
||||||
public object Generate()
|
public object Generate()
|
||||||
{
|
{
|
||||||
return MyGenerater();
|
return MyGenerater();
|
||||||
}
|
}
|
||||||
|
|
||||||
public RScriptInjectVariableGenerater(Type targetType, [MaybeNull] Generater generater, string name)
|
public RScriptInjectVariableGenerater(Type targetType, [MaybeNull] Generater generater, [MaybeNull] Destorier destorier, string name)
|
||||||
{
|
{
|
||||||
if (AllRScriptInjectVariables.TryGetValue(name, out var exist_var))
|
if (AllRScriptInjectVariables.TryGetValue(name, out var exist_var))
|
||||||
{
|
{
|
||||||
if (exist_var.MyGenerater != generater || exist_var.targetType != targetType)
|
throw new InvalidOperationException($"{name} is been used");
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"{name} is been used");
|
|
||||||
}
|
|
||||||
this.targetType = exist_var.targetType;
|
|
||||||
this.name = exist_var.name;
|
|
||||||
this.scriptIndicator = exist_var.scriptIndicator;
|
|
||||||
this.defaultScript = exist_var.defaultScript;
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StringBuilder builder = new();
|
|
||||||
builder.AppendLine(this.WritePageHead(targetType));
|
|
||||||
builder.AppendLine(this.WriteClassHead(targetType));
|
|
||||||
builder.AppendLine(this.WriteClassBodyEnter(targetType));
|
|
||||||
// 绘制枚举
|
|
||||||
{
|
|
||||||
var scriptEnums = from enumItem in targetType.GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Public)
|
|
||||||
where enumItem.GetCustomAttribute<Attr.EnumAttribute>() != null
|
|
||||||
select enumItem;
|
|
||||||
foreach (var enumItem in scriptEnums)
|
|
||||||
{
|
|
||||||
var attr = enumItem.GetCustomAttribute<Attr.EnumAttribute>();
|
|
||||||
this.WriteEnumHead(targetType);
|
|
||||||
this.WriteEnumBodyEnter(targetType);
|
|
||||||
foreach (var enumName in enumItem.GetEnumNames())
|
|
||||||
{
|
|
||||||
this.WriteEnumName(enumName);
|
|
||||||
}
|
|
||||||
this.WriteEnumBodyExit(targetType);
|
|
||||||
this.WriteEnumTail(targetType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 绘制方法
|
|
||||||
{
|
|
||||||
var scriptMethods = from method in targetType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
|
|
||||||
where method.GetCustomAttribute<Attr.MethodAttribute>() != null
|
|
||||||
select method;
|
|
||||||
foreach (var method in scriptMethods)
|
|
||||||
{
|
|
||||||
var attr = method.GetCustomAttribute<Attr.MethodAttribute>();
|
|
||||||
var returnType = method.ReturnType;
|
|
||||||
var methodName = method.Name;
|
|
||||||
var parameters = method.GetParameters();
|
|
||||||
var parameterNames = from item in parameters select item.Name;
|
|
||||||
var parameterTypes = from item in parameters select item.ParameterType;
|
|
||||||
builder.AppendLine(this.WriteClassMethod(returnType, methodName, parameterNames.ToArray(), parameterTypes.ToArray()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.AppendLine(this.WriteClassBodyExit(targetType));
|
|
||||||
builder.AppendLine(this.WriteClassTail(targetType));
|
|
||||||
builder.AppendLine(this.WritePageEnd(targetType));
|
|
||||||
this.scriptIndicator = builder.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.targetType = targetType;
|
this.targetType = targetType;
|
||||||
this.MyGenerater = generater;
|
this.MyGenerater = generater;
|
||||||
|
this.MyDestorier = destorier;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
var defaultAttr = targetType.GetCustomAttribute<Attr.DefaultAttribute>();
|
var defaultAttr = targetType.GetCustomAttribute<Attr.DefaultAttribute>();
|
||||||
this.defaultScript = defaultAttr?.defaultScript;
|
this.defaultScript = defaultAttr?.defaultScript ?? "";
|
||||||
|
var descriptionAttr = targetType.GetCustomAttribute<Attr.DescriptionAttribute>();
|
||||||
|
this.description = descriptionAttr?.description ?? "";
|
||||||
|
|
||||||
|
StringBuilder builder = new();
|
||||||
|
builder.AppendLine(this.WritePageHead(targetType));
|
||||||
|
builder.AppendLine(this.WriteClassHead(targetType));
|
||||||
|
builder.AppendLine(this.WriteClassBodyEnter(targetType));
|
||||||
|
// 绘制枚举
|
||||||
|
{
|
||||||
|
var scriptEnums = from enumItem in targetType.GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Public)
|
||||||
|
where enumItem.GetCustomAttribute<Attr.EnumAttribute>() != null
|
||||||
|
select enumItem;
|
||||||
|
foreach (var enumItem in scriptEnums)
|
||||||
|
{
|
||||||
|
var attr = enumItem.GetCustomAttribute<Attr.EnumAttribute>();
|
||||||
|
this.WriteEnumHead(targetType);
|
||||||
|
this.WriteEnumBodyEnter(targetType);
|
||||||
|
foreach (var enumName in enumItem.GetEnumNames())
|
||||||
|
{
|
||||||
|
this.WriteEnumName(enumName);
|
||||||
|
}
|
||||||
|
this.WriteEnumBodyExit(targetType);
|
||||||
|
this.WriteEnumTail(targetType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 绘制方法
|
||||||
|
{
|
||||||
|
var scriptMethods = from method in targetType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
|
||||||
|
where method.GetCustomAttribute<Attr.MethodAttribute>() != null
|
||||||
|
select method;
|
||||||
|
foreach (var method in scriptMethods)
|
||||||
|
{
|
||||||
|
var attr = method.GetCustomAttribute<Attr.MethodAttribute>();
|
||||||
|
var returnType = method.ReturnType;
|
||||||
|
var methodName = method.Name;
|
||||||
|
var parameters = method.GetParameters();
|
||||||
|
var parameterNames = from item in parameters select item.Name;
|
||||||
|
var parameterTypes = from item in parameters select item.ParameterType;
|
||||||
|
builder.AppendLine(this.WriteClassMethod(returnType, methodName, parameterNames.ToArray(), parameterTypes.ToArray()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.AppendLine(this.WriteClassBodyExit(targetType));
|
||||||
|
builder.AppendLine(this.WriteClassTail(targetType));
|
||||||
|
builder.AppendLine(this.WritePageEnd(targetType));
|
||||||
|
this.scriptIndicator = builder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Register()
|
||||||
|
{
|
||||||
|
AllRScriptInjectVariables.Add(name, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Unregister()
|
||||||
|
{
|
||||||
|
if (MyDestorier != null)
|
||||||
|
foreach (var item in GenerateObjects)
|
||||||
|
{
|
||||||
|
MyDestorier(item);
|
||||||
|
}
|
||||||
|
this.GenerateObjects.Clear();
|
||||||
|
return AllRScriptInjectVariables.Remove(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object GenerateRScriptVariable(string name)
|
public static object GenerateRScriptVariable(string name)
|
||||||
@@ -156,13 +181,32 @@ namespace Convention.RScript.Variable
|
|||||||
{
|
{
|
||||||
var result = variable.Generate();
|
var result = variable.Generate();
|
||||||
if (result.GetType().IsSubclassOf(variable.targetType) || result.GetType() == variable.targetType)
|
if (result.GetType().IsSubclassOf(variable.targetType) || result.GetType() == variable.targetType)
|
||||||
|
{
|
||||||
|
variable.GenerateObjects.Add(result);
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
throw new InvalidOperationException($"{name} target is not sub-class of it's target type");
|
throw new InvalidOperationException($"{name} target is not sub-class of it's target type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new InvalidOperationException($"{name} target is not exist or abstract");
|
throw new InvalidOperationException($"{name} target is not exist or abstract");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string DestoryRScriptVariable(object o)
|
||||||
|
{
|
||||||
|
if (o == null)
|
||||||
|
return string.Empty;
|
||||||
|
foreach (var (name,variable) in AllRScriptInjectVariables)
|
||||||
|
{
|
||||||
|
variable.GenerateObjects.RemoveWhere(x => x == null);
|
||||||
|
if(variable.GenerateObjects.Remove(o))
|
||||||
|
{
|
||||||
|
variable.MyDestorier(o);
|
||||||
|
return variable.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RScriptVariableGenerater
|
public static class RScriptVariableGenerater
|
||||||
@@ -171,5 +215,10 @@ namespace Convention.RScript.Variable
|
|||||||
{
|
{
|
||||||
return RScriptInjectVariableGenerater.GenerateRScriptVariable(name);
|
return RScriptInjectVariableGenerater.GenerateRScriptVariable(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string Delete(object o)
|
||||||
|
{
|
||||||
|
return RScriptInjectVariableGenerater.DestoryRScriptVariable(o);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -309,6 +309,7 @@ namespace Convention.RScript
|
|||||||
CurrentLocalSpaceVariableNames.Clear();
|
CurrentLocalSpaceVariableNames.Clear();
|
||||||
CurrentLocalSpaceVariableNames.Push(new());
|
CurrentLocalSpaceVariableNames.Push(new());
|
||||||
JumpPointerCache.Clear();
|
JumpPointerCache.Clear();
|
||||||
|
parser.context.Imports.AddType(typeof(Variable.RScriptVariableGenerater));
|
||||||
foreach (var staticType in Import)
|
foreach (var staticType in Import)
|
||||||
{
|
{
|
||||||
parser.context.Imports.AddType(staticType);
|
parser.context.Imports.AddType(staticType);
|
||||||
|
|||||||
Reference in New Issue
Block a user