internal static List <ConstructorInfo> FilterConstructors(List <ConstructorInfo> ctors, Type i) { return(ctors.ToList().FindAll((CCtorInfo) => { var exports = CCtorInfo.GetCustomAttributes(typeof(CSHotFixMonoTypeExportAttribute), true); if (exports != null && exports.Length > 0) { var export = exports[0] as CSHotFixMonoTypeExportAttribute; if (export.ExportFlag == CSHotFixMonoTypeExportFlagEnum.NoExport) { return false; } } bool hr = CCtorInfo.GetCustomAttributes(typeof(ObsoleteAttribute), true).Length > 0 || MethodBindingGenerator.IsConstructorPtrType(CCtorInfo) || GenConfigPlugins.SpecialBlackTypeList.Exists((_str) => { List <string> strpair = _str; string _class = strpair[0]; string _name = strpair[1]; if (i.FullName.Contains(_class)) { return CCtorInfo.Name.Contains(_name); } else { return false; } }); return !hr; })); }
internal static List <FieldInfo> FilterFields(List <FieldInfo> fields, Type i) { return(fields.ToList().FindAll((field) => { bool hr = field.GetCustomAttributes(typeof(ObsoleteAttribute), true).Length > 0 || MethodBindingGenerator.IsFieldPtrType(field) || GenConfigPlugins.SpecialBlackTypeList.Exists((_str) => { List <string> strpair = _str; string _class = strpair[0]; string _name = strpair[1]; if (i.FullName.Contains(_class)) { return field.Name.Contains(_name); } else { return false; } }); return !hr; })); }
public static void GenerateBindingCode(List <Type> types, string outputPath, HashSet <MethodBase> excludeMethods = null, HashSet <FieldInfo> excludeFields = null, List <Type> valueTypeBinders = null, List <Type> delegateTypes = null) { m_IsGenerateDll = false; if (!System.IO.Directory.Exists(outputPath)) { System.IO.Directory.CreateDirectory(outputPath); } string[] oldFiles = System.IO.Directory.GetFiles(outputPath, "*.cs"); foreach (var i in oldFiles) { System.IO.File.Delete(i); } List <string> clsNames = new List <string>(); foreach (var i in types) { string clsName, realClsName; bool isByRef; if (i.GetCustomAttributes(typeof(ObsoleteAttribute), true).Length > 0) { continue; } i.GetClassName(out clsName, out realClsName, out isByRef); clsNames.Add(clsName); using (System.IO.StreamWriter sw = new System.IO.StreamWriter(outputPath + "/" + clsName + ".cs", false, new UTF8Encoding(false))) { StringBuilder sb = new StringBuilder(); sb.Append(@" #if CSHotFix using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; using CSHotFix.CLR.TypeSystem; using CSHotFix.CLR.Method; using CSHotFix.Runtime.Enviorment; using CSHotFix.Runtime.Intepreter; using CSHotFix.Runtime.Stack; using CSHotFix.Reflection; using CSHotFix.CLR.Utils; using System.Linq; namespace CSHotFix.Runtime.Generated { unsafe class "); sb.AppendLine(clsName); sb.Append(@" { public static void Register(CSHotFix.Runtime.Enviorment.AppDomain app) { "); string flagDef = " BindingFlags flag = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;"; string methodDef = " MethodBase method;"; string methodsDef = " MethodInfo[] methods = type.GetMethods(flag).Where(t => !t.IsGenericMethod).ToArray();"; string fieldDef = " FieldInfo field;"; string argsDef = " Type[] args;"; string typeDef = string.Format(" Type type = typeof({0});", realClsName); bool needMethods; MethodInfo[] methods = i.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); //过滤 methods = methods.ToList().FindAll((methodInfo) => { bool hr = methodInfo.GetCustomAttributes(typeof(ObsoleteAttribute), true).Length > 0 || MethodBindingGenerator.IsMethodPtrType(methodInfo) || GenConfigPlugins.SpecialBlackTypeList.Exists((_str) => { List <string> strpair = _str; string _class = strpair[0]; string _name = strpair[1]; if (i.FullName.Contains(_class)) { return(methodInfo.Name.Contains(_name)); } else { return(false); } }); return(!hr); }).ToArray(); FieldInfo[] fields = i.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); fields = fields.ToList().FindAll((field) => { bool hr = field.GetCustomAttributes(typeof(ObsoleteAttribute), true).Length > 0 || GenConfigPlugins.SpecialBlackTypeList.Exists((_str) => { List <string> strpair = _str; string _class = strpair[0]; string _name = strpair[1]; if (i.FullName.Contains(_class)) { return(field.Name.Contains(_name)); } else { return(false); } }); return(!hr); }).ToArray(); string registerMethodCode = i.GenerateMethodRegisterCode(methods, excludeMethods, out needMethods); string registerFieldCode = i.GenerateFieldRegisterCode(fields, excludeFields); string registerValueTypeCode = i.GenerateValueTypeRegisterCode(realClsName); string registerMiscCode = i.GenerateMiscRegisterCode(realClsName, true, true); string commonCode = i.GenerateCommonCode(realClsName); ConstructorInfo[] ctors = i.GetConstructors(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); string ctorRegisterCode = i.GenerateConstructorRegisterCode(ctors, excludeMethods); string methodWraperCode = i.GenerateMethodWraperCode(methods, realClsName, excludeMethods, valueTypeBinders, null); string fieldWraperCode = i.GenerateFieldWraperCode(fields, realClsName, excludeFields); string cloneWraperCode = i.GenerateCloneWraperCode(fields, realClsName); string ctorWraperCode = i.GenerateConstructorWraperCode(ctors, realClsName, excludeMethods, valueTypeBinders); bool hasMethodCode = !string.IsNullOrEmpty(registerMethodCode); bool hasFieldCode = !string.IsNullOrEmpty(registerFieldCode); bool hasValueTypeCode = !string.IsNullOrEmpty(registerValueTypeCode); bool hasMiscCode = !string.IsNullOrEmpty(registerMiscCode); bool hasCtorCode = !string.IsNullOrEmpty(ctorRegisterCode); bool hasNormalMethod = methods.Where(x => !x.IsGenericMethod).Count() != 0; if ((hasMethodCode && hasNormalMethod) || hasFieldCode || hasCtorCode) { sb.AppendLine(flagDef); } if (hasMethodCode || hasCtorCode) { sb.AppendLine(methodDef); } if (hasFieldCode) { sb.AppendLine(fieldDef); } if (hasMethodCode || hasFieldCode || hasCtorCode) { sb.AppendLine(argsDef); } if (hasMethodCode || hasFieldCode || hasValueTypeCode || hasMiscCode || hasCtorCode) { sb.AppendLine(typeDef); } if (needMethods) { sb.AppendLine(methodsDef); } sb.AppendLine(registerMethodCode); sb.AppendLine(registerFieldCode); sb.AppendLine(registerValueTypeCode); sb.AppendLine(registerMiscCode); sb.AppendLine(ctorRegisterCode); sb.AppendLine(" }"); sb.AppendLine(); sb.AppendLine(commonCode); sb.AppendLine(methodWraperCode); sb.AppendLine(fieldWraperCode); sb.AppendLine(cloneWraperCode); sb.AppendLine(ctorWraperCode); sb.AppendLine(" }"); sb.AppendLine("}"); sb.AppendLine("#endif"); sw.Write(Regex.Replace(sb.ToString(), "(?<!\r)\n", "\r\n")); sw.Flush(); } } var delegateClsNames = GenerateDelegateBinding(delegateTypes, outputPath); clsNames.AddRange(delegateClsNames); GenerateBindingInitializeScript(clsNames, valueTypeBinders, outputPath, "CLRBindings"); }
public static void GenerateBindingCode(List <Type> types, string outputPath, bool deleteOld = true, HashSet <MethodBase> excludeMethods = null, HashSet <FieldInfo> excludeFields = null) { if (!System.IO.Directory.Exists(outputPath)) { System.IO.Directory.CreateDirectory(outputPath); } if (deleteOld) { string[] oldFiles = System.IO.Directory.GetFiles(outputPath, "*.cs"); foreach (var i in oldFiles) { System.IO.File.Delete(i); } } List <string> clsNames = new List <string>(); foreach (var i in types) { string clsName, realClsName; bool isByRef; if (i.GetCustomAttributes(typeof(ObsoleteAttribute), true).Length > 0) { continue; } i.GetClassName(out clsName, out realClsName, out isByRef); clsNames.Add(clsName); using (System.IO.StreamWriter sw = new System.IO.StreamWriter(outputPath + "/" + clsName + ".cs", false, Encoding.UTF8)) { sw.Write(@" using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; using CSHotFix.CLR.TypeSystem; using CSHotFix.CLR.Method; using CSHotFix.Runtime.Enviorment; using CSHotFix.Runtime.Intepreter; using CSHotFix.Runtime.Stack; using CSHotFix.Reflection; using CSHotFix.CLR.Utils; namespace CSHotFix.Runtime.Generated { unsafe class "); sw.WriteLine(clsName); sw.Write(@" { public static void Register(CSHotFix.Runtime.Enviorment.AppDomain app) { BindingFlags flag = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly; MethodBase method; FieldInfo field; Type[] args; Type type = typeof("); sw.Write(realClsName); sw.WriteLine(");"); MethodInfo[] methods = i.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); //过滤 methods = methods.ToList().FindAll((methodInfo) => { bool hr = methodInfo.GetCustomAttributes(typeof(ObsoleteAttribute), true).Length > 0 || MethodBindingGenerator.IsMethodPtrType(methodInfo) || GenConfig.SpecialBlackTypeList.Exists((_str) => { List <string> strpair = _str; string _class = strpair[0]; string _name = strpair[1]; if (i.FullName.Contains(_class)) { return(methodInfo.Name.Contains(_name)); } else { return(false); } }); return(!hr); }).ToArray(); FieldInfo[] fields = i.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); fields = fields.ToList().FindAll((field) => { bool hr = field.GetCustomAttributes(typeof(ObsoleteAttribute), true).Length > 0 || GenConfig.SpecialBlackTypeList.Exists((_str) => { List <string> strpair = _str; string _class = strpair[0]; string _name = strpair[1]; if (i.FullName.Contains(_class)) { return(field.Name.Contains(_name)); } else { return(false); } }); return(!hr); }).ToArray(); string registerMethodCode = i.GenerateMethodRegisterCode(methods, excludeMethods); string registerFieldCode = i.GenerateFieldRegisterCode(fields, excludeFields); string registerValueTypeCode = i.GenerateValueTypeRegisterCode(realClsName); string registerMiscCode = i.GenerateMiscRegisterCode(realClsName, true, true); string commonCode = i.GenerateCommonCode(realClsName); ConstructorInfo[] ctors = i.GetConstructors(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); string ctorRegisterCode = i.GenerateConstructorRegisterCode(ctors, excludeMethods); string methodWraperCode = i.GenerateMethodWraperCode(methods, realClsName, excludeMethods); string fieldWraperCode = i.GenerateFieldWraperCode(fields, realClsName, excludeFields); string cloneWraperCode = i.GenerateCloneWraperCode(fields, realClsName); string ctorWraperCode = i.GenerateConstructorWraperCode(ctors, realClsName, excludeMethods); sw.WriteLine(registerMethodCode); sw.WriteLine(registerFieldCode); sw.WriteLine(registerValueTypeCode); sw.WriteLine(registerMiscCode); sw.WriteLine(ctorRegisterCode); sw.WriteLine(" }"); sw.WriteLine(); sw.WriteLine(commonCode); sw.WriteLine(methodWraperCode); sw.WriteLine(fieldWraperCode); sw.WriteLine(cloneWraperCode); sw.WriteLine(ctorWraperCode); sw.WriteLine(" }"); sw.WriteLine("}"); sw.Flush(); } } using (System.IO.StreamWriter sw = new System.IO.StreamWriter(outputPath + "/CLRBindings.cs", false, Encoding.UTF8)) { sw.WriteLine(@"using System; using System.Collections.Generic; using System.Reflection; namespace CSHotFix.Runtime.Generated { class CLRBindings { /// <summary> /// Initialize the CLR binding, please invoke this AFTER CLR Redirection registration /// </summary> public static void Initialize(CSHotFix.Runtime.Enviorment.AppDomain app) {"); foreach (var i in clsNames) { sw.Write(" "); sw.Write(i); sw.WriteLine(".Register(app);"); } sw.WriteLine(@" } } }"); } }