新增预定义输出(未作验证的一次保存)

This commit is contained in:
2025-10-25 21:45:31 +08:00
parent b7ccc387fc
commit 104a80e527
2 changed files with 154 additions and 23 deletions

View File

@@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Convention.RScript.Variable.CStyle
{
public class RScriptInjectVariable : Variable.RScriptInjectVariable
{
public static string GetTypename(Type type)
{
var name = type.Name.Replace('`', '_');
return name;
}
private int layer = 0;
private string Prefix => new('\t', layer);
public RScriptInjectVariable(Type targetType, [MaybeNull] Generater generater, string name) : base(targetType, generater, name)
{
}
protected override string WriteClassBodyEnter(Type currentType)
{
string result = $"{Prefix}{"{public:"}";
layer++;
return result;
}
protected override string WriteClassBodyExit(Type currentType)
{
layer--;
return $"{Prefix}{"{"}";
}
protected override string WriteClassHead(Type currentType)
{
string suffix = currentType.BaseType == typeof(object) ? string.Empty : $" : public {GetTypename(currentType.BaseType)}";
string result = $"{Prefix}class {GetTypename(currentType)}{suffix}";
layer++;
return result;
}
protected override string WriteClassMethod(Type returnType, string methodName, string[] parameterNames, Type[] parameterTypes)
{
List<string> parameters = new();
for(int i=0,e=parameterNames.Length;i<e;i++)
{
parameters.Add($"{GetTypename(parameterTypes[i])} {parameterNames[i]}");
}
return $"{Prefix}{GetTypename(returnType)} {methodName}({string.Join(", ", parameters)});";
}
protected override string WriteClassTail(Type currentType)
{
return "";
}
protected override string WriteEnumBodyEnter(Type currentType)
{
string result = $"{Prefix}{"{"}";
layer++;
return result;
}
protected override string WriteEnumBodyExit(Type currentType)
{
layer--;
return $"{Prefix}{"{"}";
}
protected override string WriteEnumHead(Type currentEnum)
{
return $"{Prefix}enum {GetTypename(currentEnum)}";
}
protected override string WriteEnumName(string enumName)
{
return $"{Prefix}{enumName},";
}
protected override string WriteEnumTail(Type currentType)
{
return "";
}
protected override string WritePageEnd(Type currentType)
{
return "";
}
protected override string WritePageHead(Type currentType)
{
return $"#include\"{GetFilename(currentType)}\"";
}
public override string GetFilename(Type currentType)
{
return GetTypename(currentType);
}
}
}

View File

@@ -4,25 +4,19 @@ using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace Convention.RScript.Variable namespace Convention.RScript.Variable
{ {
namespace Attr namespace Attr
{ {
[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = false)]
public class SerializeAttribute : Attribute
{
public string Description { get; set; }
}
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public sealed class MethodAttribute : SerializeAttribute public sealed class MethodAttribute : Attribute
{ {
} }
[System.AttributeUsage(AttributeTargets.Enum, Inherited = true, AllowMultiple = false)] [AttributeUsage(AttributeTargets.Enum, Inherited = true, AllowMultiple = false)]
public sealed class EnumAttribute : SerializeAttribute public sealed class EnumAttribute : Attribute
{ {
} }
} }
@@ -31,13 +25,15 @@ namespace Convention.RScript.Variable
{ {
public string RScriptString { get; private set; } public string RScriptString { get; private set; }
public abstract string GetFilename(Type currentType);
protected abstract string WritePageHead(Type currentType); protected abstract string WritePageHead(Type currentType);
#region Enum #region Enum
protected abstract string WriteEnumHead(Type currentEnum); protected abstract string WriteEnumHead(Type currentEnum);
protected abstract string WriteEnumBodyEnter(Type currentType); protected abstract string WriteEnumBodyEnter(Type currentType);
protected abstract string WriteEnumName(string enumName, Type valueType); protected abstract string WriteEnumName(string enumName);
protected abstract string WriteEnumBodyExit(Type currentType); protected abstract string WriteEnumBodyExit(Type currentType);
protected abstract string WriteEnumTail(Type currentType); protected abstract string WriteEnumTail(Type currentType);
@@ -47,7 +43,7 @@ namespace Convention.RScript.Variable
protected abstract string WriteClassHead(Type currentType); protected abstract string WriteClassHead(Type currentType);
protected abstract string WriteClassBodyEnter(Type currentType); protected abstract string WriteClassBodyEnter(Type currentType);
protected abstract string WriteClassMethod(Type returnType, string methodName, string[] parameterNames, Type[] parameterTypes, string description); protected abstract string WriteClassMethod(Type returnType, string methodName, string[] parameterNames, Type[] parameterTypes);
protected abstract string WriteClassBodyExit(Type currentType); protected abstract string WriteClassBodyExit(Type currentType);
protected abstract string WriteClassTail(Type currentType); protected abstract string WriteClassTail(Type currentType);
@@ -65,6 +61,7 @@ namespace Convention.RScript.Variable
public readonly static Dictionary<string, RScriptInjectVariable> AllRScriptInjectVariables = new(); public readonly static Dictionary<string, RScriptInjectVariable> AllRScriptInjectVariables = new();
public readonly Type targetType;
public readonly string name; public readonly string name;
public readonly string script; public readonly string script;
@@ -73,11 +70,19 @@ namespace Convention.RScript.Variable
return MyGenerater(); return MyGenerater();
} }
public RScriptInjectVariable(Type targetType, [MaybeNull]Generater generater, string name) public RScriptInjectVariable(Type targetType, [MaybeNull] Generater generater, string name)
{
if (AllRScriptInjectVariables.TryGetValue(name, out var exist_var))
{
if (exist_var.MyGenerater != generater || exist_var.targetType != targetType)
{ {
if (AllRScriptInjectVariables.ContainsKey(name))
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.script = exist_var.script;
}
else
{ {
StringBuilder builder = new(); StringBuilder builder = new();
builder.AppendLine(this.WritePageHead(targetType)); builder.AppendLine(this.WritePageHead(targetType));
@@ -91,12 +96,19 @@ namespace Convention.RScript.Variable
foreach (var enumItem in scriptEnums) foreach (var enumItem in scriptEnums)
{ {
var attr = enumItem.GetCustomAttribute<Attr.EnumAttribute>(); 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) var scriptMethods = from method in targetType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
where method.GetCustomAttribute<Attr.MethodAttribute>() != null where method.GetCustomAttribute<Attr.MethodAttribute>() != null
select method; select method;
foreach (var method in scriptMethods) foreach (var method in scriptMethods)
@@ -107,7 +119,7 @@ namespace Convention.RScript.Variable
var parameters = method.GetParameters(); var parameters = method.GetParameters();
var parameterNames = from item in parameters select item.Name; var parameterNames = from item in parameters select item.Name;
var parameterTypes = from item in parameters select item.ParameterType; var parameterTypes = from item in parameters select item.ParameterType;
builder.AppendLine(this.WriteClassMethod(returnType, methodName, parameterNames.ToArray(), parameterTypes.ToArray(), attr.Description)); builder.AppendLine(this.WriteClassMethod(returnType, methodName, parameterNames.ToArray(), parameterTypes.ToArray()));
} }
} }
builder.AppendLine(this.WriteClassBodyExit(targetType)); builder.AppendLine(this.WriteClassBodyExit(targetType));
@@ -116,18 +128,33 @@ namespace Convention.RScript.Variable
this.script = builder.ToString(); this.script = builder.ToString();
} }
this.targetType = targetType;
this.MyGenerater = generater; this.MyGenerater = generater;
this.name = name; this.name = name;
} }
public static object GenerateRScriptVariable(string name, Dictionary<string, RScriptInjectVariable> classes) public static object GenerateRScriptVariable(string name)
{ {
if (classes.TryGetValue(name, out var variable)) if (AllRScriptInjectVariables.TryGetValue(name, out var variable))
{ {
if (variable.MyGenerater != null) if (variable.MyGenerater != null)
return variable.Generate(); {
var result = variable.Generate();
if (result.GetType().IsSubclassOf(variable.targetType) || result.GetType() == variable.targetType)
return result;
else
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 class RScriptVariableGenerater
{
public static object New(string name)
{
return RScriptInjectVariable.GenerateRScriptVariable(name);
}
}
} }