新增默认脚本内容
This commit is contained in:
175
PublicTypes/RScriptInjectVariableGenerater.cs
Normal file
175
PublicTypes/RScriptInjectVariableGenerater.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace Convention.RScript.Variable
|
||||
{
|
||||
namespace Attr
|
||||
{
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
|
||||
public sealed class MethodAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Enum, Inherited = true, AllowMultiple = false)]
|
||||
public sealed class EnumAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct, Inherited = false, AllowMultiple = false)]
|
||||
public sealed class DefaultAttribute : Attribute
|
||||
{
|
||||
public string defaultScript;
|
||||
public DefaultAttribute(string defaultScript)
|
||||
{
|
||||
this.defaultScript = defaultScript;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class RScriptInjectVariableGenerater
|
||||
{
|
||||
public string RScriptString { get; private set; }
|
||||
|
||||
public abstract string GetFilename(Type currentType);
|
||||
|
||||
protected abstract string WritePageHead(Type currentType);
|
||||
|
||||
#region Enum
|
||||
|
||||
protected abstract string WriteEnumHead(Type currentEnum);
|
||||
protected abstract string WriteEnumBodyEnter(Type currentType);
|
||||
protected abstract string WriteEnumName(string enumName);
|
||||
protected abstract string WriteEnumBodyExit(Type currentType);
|
||||
protected abstract string WriteEnumTail(Type currentType);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Class
|
||||
|
||||
protected abstract string WriteClassHead(Type currentType);
|
||||
protected abstract string WriteClassBodyEnter(Type currentType);
|
||||
protected abstract string WriteClassMethod(Type returnType, string methodName, string[] parameterNames, Type[] parameterTypes);
|
||||
protected abstract string WriteClassBodyExit(Type currentType);
|
||||
protected abstract string WriteClassTail(Type currentType);
|
||||
|
||||
#endregion
|
||||
|
||||
protected abstract string WritePageEnd(Type currentType);
|
||||
|
||||
/// <summary>
|
||||
/// 生成targetType类型的实体
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public delegate object Generater();
|
||||
|
||||
private Generater MyGenerater;
|
||||
|
||||
public readonly static Dictionary<string, RScriptInjectVariableGenerater> AllRScriptInjectVariables = new();
|
||||
|
||||
public readonly Type targetType;
|
||||
public readonly string name;
|
||||
public readonly string scriptIndicator;
|
||||
public readonly string defaultScript;
|
||||
|
||||
public object Generate()
|
||||
{
|
||||
return MyGenerater();
|
||||
}
|
||||
|
||||
public RScriptInjectVariableGenerater(Type targetType, [MaybeNull] Generater generater, string name)
|
||||
{
|
||||
if (AllRScriptInjectVariables.TryGetValue(name, out var exist_var))
|
||||
{
|
||||
if (exist_var.MyGenerater != generater || exist_var.targetType != targetType)
|
||||
{
|
||||
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.MyGenerater = generater;
|
||||
this.name = name;
|
||||
var defaultAttr = targetType.GetCustomAttribute<Attr.DefaultAttribute>();
|
||||
this.defaultScript = defaultAttr?.defaultScript;
|
||||
}
|
||||
|
||||
public static object GenerateRScriptVariable(string name)
|
||||
{
|
||||
if (AllRScriptInjectVariables.TryGetValue(name, out var variable))
|
||||
{
|
||||
if (variable.MyGenerater != null)
|
||||
{
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
public static class RScriptVariableGenerater
|
||||
{
|
||||
public static object New(string name)
|
||||
{
|
||||
return RScriptInjectVariableGenerater.GenerateRScriptVariable(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user