diff --git a/PublicTypes/InjectVariable/CStyle.cs b/PublicTypes/InjectVariable/CStyle.cs new file mode 100644 index 0000000..ba162f1 --- /dev/null +++ b/PublicTypes/InjectVariable/CStyle.cs @@ -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 parameters = new(); + for(int i=0,e=parameterNames.Length;i AllRScriptInjectVariables = new(); + public readonly Type targetType; public readonly string name; public readonly string script; @@ -73,11 +70,19 @@ namespace Convention.RScript.Variable return MyGenerater(); } - public RScriptInjectVariable(Type targetType, [MaybeNull]Generater generater, string name) + public RScriptInjectVariable(Type targetType, [MaybeNull] Generater generater, string name) { - if (AllRScriptInjectVariables.ContainsKey(name)) - throw new InvalidOperationException($"{name} is been used"); - + 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.script = exist_var.script; + } + else { StringBuilder builder = new(); builder.AppendLine(this.WritePageHead(targetType)); @@ -86,17 +91,24 @@ namespace Convention.RScript.Variable // 绘制枚举 { var scriptEnums = from enumItem in targetType.GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Public) - where enumItem.GetCustomAttribute() != null - select enumItem; + where enumItem.GetCustomAttribute() != null + select enumItem; foreach (var enumItem in scriptEnums) { var attr = enumItem.GetCustomAttribute(); - + 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() != null select method; foreach (var method in scriptMethods) @@ -107,7 +119,7 @@ namespace Convention.RScript.Variable 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.WriteClassMethod(returnType, methodName, parameterNames.ToArray(), parameterTypes.ToArray())); } } builder.AppendLine(this.WriteClassBodyExit(targetType)); @@ -116,18 +128,33 @@ namespace Convention.RScript.Variable this.script = builder.ToString(); } + this.targetType = targetType; this.MyGenerater = generater; this.name = name; } - public static object GenerateRScriptVariable(string name, Dictionary 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) - 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"); } } + + public static class RScriptVariableGenerater + { + public static object New(string name) + { + return RScriptInjectVariable.GenerateRScriptVariable(name); + } + } }