73 lines
3.0 KiB
C#
73 lines
3.0 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Diagnostics.CodeAnalysis;
|
|||
|
using System.Linq;
|
|||
|
using System.Reflection;
|
|||
|
using System.Text;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
namespace Convention.RScript.Variable
|
|||
|
{
|
|||
|
[System.AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
|
|||
|
public sealed class RScriptMethodAttribute : Attribute
|
|||
|
{
|
|||
|
public string Description { get; set; }
|
|||
|
}
|
|||
|
|
|||
|
public abstract class RScriptInjectVariable
|
|||
|
{
|
|||
|
public string RScriptString { get; private set; }
|
|||
|
|
|||
|
protected abstract string WriteClassHead(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 WriteClassBodyExit(Type currentType);
|
|||
|
protected abstract string WriteClassTail(Type currentType);
|
|||
|
|
|||
|
public delegate object Generater();
|
|||
|
|
|||
|
private Generater MyGenerater;
|
|||
|
public string name { get; private set; }
|
|||
|
public object Generate()
|
|||
|
{
|
|||
|
return MyGenerater();
|
|||
|
}
|
|||
|
|
|||
|
public RScriptInjectVariable([MaybeNull]Generater generater, string name)
|
|||
|
{
|
|||
|
var currentType = this.GetType();
|
|||
|
StringBuilder builder = new();
|
|||
|
builder.AppendLine(this.WriteClassHead(currentType));
|
|||
|
builder.AppendLine(this.WriteClassBodyEnter(currentType));
|
|||
|
var scriptMethods = from method in currentType.GetMethods(BindingFlags.Instance | BindingFlags.Public)
|
|||
|
where method.GetCustomAttribute<RScriptMethodAttribute>() != null
|
|||
|
select method;
|
|||
|
foreach (var method in scriptMethods)
|
|||
|
{
|
|||
|
var attr = method.GetCustomAttribute<RScriptMethodAttribute>();
|
|||
|
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(), attr.Description));
|
|||
|
}
|
|||
|
builder.AppendLine(this.WriteClassBodyExit(currentType));
|
|||
|
builder.AppendLine(this.WriteClassTail(currentType));
|
|||
|
|
|||
|
this.MyGenerater = generater;
|
|||
|
this.name = name;
|
|||
|
}
|
|||
|
|
|||
|
public static object GenerateRScriptVariable(string name, Dictionary<string, RScriptInjectVariable> classes)
|
|||
|
{
|
|||
|
if (classes.TryGetValue(name, out var variable))
|
|||
|
{
|
|||
|
if (variable.MyGenerater != null)
|
|||
|
return variable.Generate();
|
|||
|
}
|
|||
|
throw new InvalidOperationException($"{name} target is not exist or abstract");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|