diff --git a/PublicTypes/RScriptInjectVariable.cs b/PublicTypes/RScriptInjectVariable.cs new file mode 100644 index 0000000..e464dfc --- /dev/null +++ b/PublicTypes/RScriptInjectVariable.cs @@ -0,0 +1,72 @@ +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() != null + select method; + foreach (var method in scriptMethods) + { + var attr = method.GetCustomAttribute(); + 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 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"); + } + } +}