public static void OnBegin() { GeneratorHelp.ClearTypeInfo(); //读取JSBCodeGenSetting下所有CsExportedMethodAttribute属性 var eportedMethodAtrs = typeof(JSGenerator).Assembly.GetCustomAttributes(typeof(CsExportedMethodAttribute), false); CsExportedMethodDic = new Dictionary <Type, Dictionary <string, CsExportedMethodAttribute> >(); foreach (var obj in eportedMethodAtrs) { var methodAttribute = obj as CsExportedMethodAttribute; if (!CsExportedMethodDic.ContainsKey(methodAttribute.TargetType)) { CsExportedMethodDic[methodAttribute.TargetType] = new Dictionary <string, CsExportedMethodAttribute>(); } CsExportedMethodDic[methodAttribute.TargetType].Add(methodAttribute.TargetMethodName, methodAttribute); } _streamWriter = OpenFile(JSPathSettings.csExportJsFile); _streamWriter.Write(@" if (typeof(JsTypes) == ""undefined"") var JsTypes = []; //this.Enum = {}; "); }
public static List <string> GenerateClass() { /*if (type.IsInterface) * { * Debug.Log("Interface: " + type.ToString() + " ignored."); * return; * }*/ List <string> memberNames = new List <string>(); GeneratorHelp.ATypeInfo ti; int slot = GeneratorHelp.AddTypeInfo(type, out ti); var sbHeader = BuildHeader(type); var sbCons = sbHeader.Append(BuildConstructors(type, ti.constructors, slot, ti.howmanyConstructors, memberNames)); var sbFields = BuildFields(type, ti.fields, slot, memberNames); var sbProperties = BuildProperties(type, ti.properties, slot, memberNames); var sbMethods = BuildMethods(type, ti.methods, slot, memberNames); //sbMethods.Append(BuildTail()); var sbClass = BuildClass(type, sbFields, sbProperties, sbMethods, sbCons); HandleStringFormat(sbClass); // string fileName = JSBindingSettings.jsGeneratedDir + "/" + // JSNameMgr.GetTypeFileName(JSGenerator.type) // + JSBindingSettings.jsExtension; // var writer2 = OpenFile(fileName, false); // writer2.Write(sbClass.ToString()); // writer2.Close(); W.Write(sbClass.ToString()); return(memberNames); }
public static void GenerateClass(Type type, out List <string> memberNames) { memberNames = new List <string>(); GeneratorHelp.ATypeInfo ti; int slot = GeneratorHelp.AddTypeInfo(type, out ti); string jsDefName = GetJsTypeDefinition(type); var sbClass = new StringBuilder(); var sbDefinition = new StringBuilder(); var sbStaticDefinition = new StringBuilder(); BuildConstructors(type, ti.constructors, slot, sbDefinition, memberNames); BuildProperties(type, ti.properties, slot, sbDefinition, sbStaticDefinition, memberNames); BuildMethods(type, ti.methods, slot, sbDefinition, sbStaticDefinition, memberNames); var sbAllDefinition = new StringBuilder(); if (sbStaticDefinition.Length > 0) { sbAllDefinition.AppendFormat(@" staticDefinition: [[{0} ]],", sbStaticDefinition); } if (sbDefinition.Length > 0) { sbAllDefinition.AppendFormat(@" definition: [[{0} ]],", sbDefinition); } sbClass.AppendFormat(@" // {0} var {1} = [[ assemblyName: '{2}', fullname: '{3}', Kind: '{4}',{5}{6}{7} ]]; jsb_ReplaceOrPushJsType({1}); ", type.FullName, jsDefName, type.Assembly.FullName, JSNameMgr.GetJSTypeFullName(type), GetJsTypeKind(type), GetJsTypeInheritInfo(type), BuildFields(type, ti.fields, slot, memberNames), sbAllDefinition); HandleStringFormat(sbClass); _streamWriter.Write(sbClass.ToString()); }
//static string enumFile = JSBindingSettings.jsGeneratedDir + "/enum" + JSBindingSettings.jsExtension; //static string tempFile = JSBindingSettings.jsDir + "/temp"+JSBindingSettings.jsExtension; public static void OnBegin() { GeneratorHelp.ClearTypeInfo(); // if (Directory.Exists(JSBindingSettings.jsGeneratedDir)) // { // // delete all last generated files // string[] files = Directory.GetFiles(JSBindingSettings.jsGeneratedDir); // for (int i = 0; i < files.Length; i++) // { // File.Delete(files[i]); // } // } // else // { // // create directory // Directory.CreateDirectory(JSBindingSettings.jsGeneratedDir); // } // clear generated enum files W = OpenFile(JSBindingSettings.jsGenFiles, false); }
static StringBuilder BuildRegisterFunction(ClassCallbackNames ccbn, GeneratorHelp.ATypeInfo ti) { string fmt = @" public static void __Register() [[ JSMgr.CallbackInfo ci = new JSMgr.CallbackInfo(); ci.type = typeof({0}); ci.fields = new JSMgr.CSCallbackField[] [[ {1} ]]; ci.properties = new JSMgr.CSCallbackProperty[] [[ {2} ]]; ci.constructors = new JSMgr.MethodCallBackInfo[] [[ {3} ]]; ci.methods = new JSMgr.MethodCallBackInfo[] [[ {4} ]]; JSMgr.allCallbackInfo.Add(ci); ]] "; StringBuilder sb = new StringBuilder(); StringBuilder sbField = new StringBuilder(); StringBuilder sbProperty = new StringBuilder(); StringBuilder sbCons = new StringBuilder(); StringBuilder sbMethod = new StringBuilder(); for (int i = 0; i < ccbn.fields.Count; i++) sbField.AppendFormat(" {0},\n", ccbn.fields[i]); for (int i = 0; i < ccbn.properties.Count; i++) sbProperty.AppendFormat(" {0},\n", ccbn.properties[i]); for (int i = 0; i < ccbn.constructors.Count; i++) { if (ccbn.constructors.Count == 1 && ti.constructors.Length == 0) // no constructors add a default so ... sbCons.AppendFormat(" new JSMgr.MethodCallBackInfo({0}, '{1}'),\n", ccbn.constructors[i], type.Name); else sbCons.AppendFormat(" new JSMgr.MethodCallBackInfo({0}, '{1}'),\n", ccbn.constructors[i], ti.constructors[i] == null ? ".ctor" : ti.constructors[i].Name); } for (int i = 0; i < ccbn.methods.Count; i++) { // if method is not overloaded // don's save the cs param array sbMethod.AppendFormat(" new JSMgr.MethodCallBackInfo({0}, '{1}'),\n", ccbn.methods[i], ti.methods[i].Name); } sb.AppendFormat(fmt, JSNameMgr.GetTypeFullName(ccbn.type), sbField, sbProperty, sbCons, sbMethod); return sb; }
// can handle all methods public static StringBuilder BuildMethods(Type type, MethodInfo[] methods, int slot, List <string> lstNames) { string fmt = @" /* {6} */ _jstype.definition.{1} = function({2}) [[ {9} return CS.Call({7}, {3}, {4}, false, {8}{5}); ]]"; string fmtStatic = @" /* static {6} {8} */ _jstype.staticDefinition.{1} = function({2}) [[ {9} return CS.Call({7}, {3}, {4}, true{5}); ]]"; //bool bIsSystemObject = (type == typeof(System.Object)); StringBuilder sb = new StringBuilder(); for (int i = 0; i < methods.Length; i++) { MethodInfo method = methods[i]; bool bOverloaded = ((i > 0 && method.Name == methods[i - 1].Name) || (i < methods.Length - 1 && method.Name == methods[i + 1].Name)); if (!bOverloaded) { if (GeneratorHelp.MethodIsOverloaded(type, method.Name)) { bOverloaded = true; //Debug.Log("$$$ " + type.Name + "." + method.Name + (method.IsStatic ? " true" : " false")); } } StringBuilder sbFormalParam = new StringBuilder(); StringBuilder sbActualParam = new StringBuilder(); ParameterInfo[] paramS = method.GetParameters(); StringBuilder sbInitT = new StringBuilder(); int TCount = 0; // add T to formal param if (method.IsGenericMethodDefinition) { TCount = method.GetGenericArguments().Length; for (int j = 0; j < TCount; j++) { sbFormalParam.AppendFormat("t{0}", j); if (j < TCount - 1 || paramS.Length > 0) { sbFormalParam.Append(", "); } sbInitT.AppendFormat(" var native_t{0} = t{0}.getNativeType();\n", j); sbActualParam.AppendFormat(", native_t{0}", j); } } int L = paramS.Length; for (int j = 0; j < L; j++) { sbFormalParam.AppendFormat("a{0}/*{1}*/{2}", j, paramS[j].ParameterType.Name, (j == L - 1 ? "" : ", ")); ParameterInfo par = paramS[j]; if (par.ParameterType.IsArray && par.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0) { sbActualParam.AppendFormat(", jsb_formatParamsArray({0}, a{0}, arguments)", j); } else { sbActualParam.AppendFormat(", a{0}", j); } } //int TCount = method.GetGenericArguments().Length; string methodName = method.Name; // if (methodName == "ToString") { methodName = "toString"; } string mName = SharpKitMethodName(methodName, paramS, bOverloaded, TCount); lstNames.Add((method.IsStatic ? "Static_" : "") + mName); if (!method.IsStatic) { sb.AppendFormat(fmt, className, mName, // [1] method name sbFormalParam.ToString(), // [2] formal param slot, // [3] slot i, // [4] index sbActualParam, // [5] actual param method.ReturnType.Name, // [6] return type name (int)JSVCall.Oper.METHOD, // [7] OP "this", // [8] this sbInitT //[9] generic types init ); } else { sb.AppendFormat(fmtStatic, className, mName, sbFormalParam.ToString(), slot, i, sbActualParam, method.ReturnType.Name, (int)JSVCall.Oper.METHOD, "", sbInitT); } } return(sb); }
public static void BuildMethods(Type type, MethodInfo[] methods, int slot, StringBuilder sbDefinition, StringBuilder sbStaticDefinition, List <string> memberNames) { for (int index = 0; index < methods.Length; index++) { var method = methods[index]; string methodName = method.Name; if (methodName == "ToString") { methodName = "toString"; } bool isStatic = method.IsStatic; bool overloaded = (index > 0 && method.Name == methods[index - 1].Name) || (index < methods.Length - 1 && method.Name == methods[index + 1].Name); if (!overloaded) { if (GeneratorHelp.MethodIsOverloaded(type, method)) { overloaded = true; //Debug.Log("$$$ " + type.Name + "." + method.Name + (method.IsStatic ? " true" : " false")); } } var sbFormalParam = new StringBuilder(); var sbActualParam = new StringBuilder(); var paramS = method.GetParameters(); var sbInitGenericParam = new StringBuilder(); // add T to formal param int genericArgsCount = 0; //包含泛型参数个数 if (method.IsGenericMethodDefinition) { genericArgsCount = method.GetGenericArguments().Length; for (int j = 0; j < genericArgsCount; j++) { sbFormalParam.AppendFormat("t{0}", j); if (j < genericArgsCount - 1 || paramS.Length > 0) { sbFormalParam.Append(", "); } sbInitGenericParam.AppendFormat("\n var native_t{0} = t{0}.getNativeType();", j); sbActualParam.AppendFormat(", native_t{0}", j); } } string jsMethodName = GetOverloadedMethodSuffix(methodName, paramS, overloaded, genericArgsCount); memberNames.Add((isStatic ? "Static_" : "") + jsMethodName); //判断该方法是否有定义CsExportedMethodAttribute属性 CsExportedMethodAttribute csExportedAttr = null; if (method.IsDefined(typeof(CsExportedMethodAttribute), false)) { var attributes = method.GetCustomAttributes(typeof(CsExportedMethodAttribute), false); csExportedAttr = attributes[0] as CsExportedMethodAttribute; } if (CsExportedMethodDic != null && CsExportedMethodDic.ContainsKey(type)) { CsExportedMethodDic[type].TryGetValue(method.Name, out csExportedAttr); } if (csExportedAttr != null) { string jsCode = csExportedAttr.JsCode; if (isStatic) { sbStaticDefinition.Append(jsCode); } else { sbDefinition.Append(jsCode); } continue; } int paramLength = paramS.Length; for (int j = 0; j < paramLength; j++) { sbFormalParam.AppendFormat("a{0}/*{1}*/{2}", j, paramS[j].ParameterType.Name, j == paramLength - 1 ? "" : ", "); var par = paramS[j]; if (par.ParameterType.IsArray && par.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0) { sbActualParam.AppendFormat(", jsb_formatParamsArray({0}, a{0}, arguments)", j); } else if (par.ParameterType.IsArray && par.ParameterType.GetElementType() == typeof(Type)) { //如果是System.Type类型数组参数,通过转换获取其类型全名数组 sbActualParam.AppendFormat(", jsb_convertTypeParamsArray(a{0})", j); } else if (par.ParameterType == typeof(Type)) { //如果是System.Type类型参数需要传递其FullName回来 //在C#层通过JSDataExchangeMgr.GetTypeByName获取其类型对象 sbActualParam.AppendFormat(", a{0} != null ? a{0}.get_FullName() : null", j); } else if (par.ParameterType == typeof(Exception)) { sbActualParam.AppendFormat(", Error.getException(a{0})", j); } else { sbActualParam.AppendFormat(", a{0}", j); } } if (isStatic) { sbStaticDefinition.AppendFormat(@" {0}: function({1}) [[ {2} return CS.Call({3}, {4}, {5}, true{6}); //Ret: {7} ]],", jsMethodName, sbFormalParam, sbInitGenericParam, (int)JSVCall.Oper.METHOD, slot, index, sbActualParam, method.ReturnType.Name); } else { sbDefinition.AppendFormat(@" {0}: function({1}) [[ {2} return CS.Call({3}, {4}, {5}, false, this{6}); //Ret: {7} ]],", jsMethodName, sbFormalParam, sbInitGenericParam, (int)JSVCall.Oper.METHOD, slot, index, sbActualParam, method.ReturnType.Name); } } }
static void GenInterfaceOrStructOrClass(Type type, TypeStatus ts, Func <Type, TypeStatus> getParent, Action <Type> onNewType) { TextFile tfFile = null; if (type.DeclaringType != null) { ts.IsInnerType = true; TypeStatus tsParent = getParent(type.DeclaringType); if (tsParent == null || tsParent.status == TypeStatus.Status.Wait) { if (tsParent == null) { onNewType(type.DeclaringType); } return; } if (tsParent.status == TypeStatus.Status.Ignored) { ts.status = TypeStatus.Status.Ignored; return; } tfFile = tsParent.tf.FindByTag("epos"); } if (tfFile == null) { tfFile = new TextFile(); } ts.tf = tfFile; ts.status = TypeStatus.Status.Exported; GeneratorHelp.ATypeInfo ti = GeneratorHelp.CreateTypeInfo(type); StringBuilder sb = new StringBuilder(); TextFile tfNs = tfFile; //string dir = Dir; // // ignore Experimental @eugenejiang // if (type.Namespace != null && type.Namespace.IndexOf("UnityEngine.Experimental.") >= 0) { // return; // } if (type.DeclaringType == null && !string.IsNullOrEmpty(type.Namespace)) { tfNs = tfFile.Add("namespace {0}", type.Namespace).BraceIn(); tfNs.BraceOut(); } GenAttributeForClassIfNeeded(type, tfNs); // multiple attributes // tfNs.Add("[Bridge.External]"); TextFile tfClass = null; sb.Remove(0, sb.Length); { // force public if (type.IsPublic || type.IsNestedPublic || type.IsNested || type.IsNestedFamily) { sb.Append("public "); } // if (type.IsNestedFamily) { // sb.Append("protected "); // } // if (type.FullName.IndexOf("DropdownItem") >= 0) { // Debug.Assert(false); // } if (type.IsClass) { if (type.IsAbstract && type.IsSealed) { sb.Append("static "); } //else if (type.IsAbstract) // sb.Append("abstract "); //else if (type.IsSealed) // sb.Append("sealed "); //if (type.is) } if (type.IsInterface) { sb.Append("interface "); } else if (type.IsValueType) { sb.Append("struct "); } else { sb.Append("class "); } string className = type.CsFullName(CsNameOption.CompilableWithT); int dot = className.LastIndexOf("."); if (dot >= 0) { className = className.Substring(dot + 1); } sb.Append(className); Type vBaseType = type.ValidBaseType(); Type[] interfaces = type.GetDeclaringInterfaces(); if (vBaseType != null || interfaces.Length > 0) { sb.Append(" : "); args a = new args(); if (vBaseType != null) { a.Add(typefn(vBaseType, type.Namespace, CsNameOption.CompilableWithT)); onNewType(vBaseType); } foreach (var i in interfaces) { a.Add(typefn(i, type.Namespace, CsNameOption.CompilableWithT)); onNewType(i); } sb.Append(a.ToString()); } tfClass = tfNs.Add(sb.ToString()).BraceIn(); tfClass.BraceOut(); } tfClass.AddTag("epos"); if (handleEvents(tfClass, type, onNewType)) { tfClass.AddLine(); } for (int i = 0; i < ti.Fields.Count; i++) { MemberInfoEx infoEx = ti.Fields[i]; FieldInfo field = infoEx.member as FieldInfo; var publicOrProtected = "public"; if (field.IsFamily) { // publicOrProtected = "protected"; } if (field.IsLiteral && !field.IsInitOnly) { { var attributes = field.GetCustomAttributes(); foreach (var attr in attributes) { tfClass.Add("[{0}]", attr.GetType().Name); onNewType(attr.GetType()); } } if ("string" == typefn(field.FieldType, type.Namespace)) { tfClass.Add(publicOrProtected + " const {0} {1} = \"{2}\";", typefn(field.FieldType, type.Namespace), field.Name, field.GetValue(null)); } else if ("float" == typefn(field.FieldType, type.Namespace)) { var fv = (float)field.GetValue(null); string defaultvalue; if (float.IsNaN(fv)) { defaultvalue = "float.NaN"; } else if (float.IsPositiveInfinity(fv)) { defaultvalue = "float.PositiveInfinity"; } else if (float.IsNegativeInfinity(fv)) { defaultvalue = "float.NegativeInfinity"; } else { defaultvalue = fv + "f"; } tfClass.Add(publicOrProtected + " const {0} {1} = {2};", typefn(field.FieldType, type.Namespace), field.Name, defaultvalue); } else { tfClass.Add(publicOrProtected + " const {0} {1} = {2};", typefn(field.FieldType, type.Namespace), field.Name, field.GetValue(null)); } } else { tfClass.Add(publicOrProtected + " {0}{1} {2};", (field.IsStatic ? "static " : ""), typefn(field.FieldType, type.Namespace), field.Name); } onNewType(field.FieldType); } if (ti.Fields.Count > 0) { tfClass.AddLine(); } // Constructors for (int i = 0; i < ti.Cons.Count; i++) { MemberInfoEx infoEx = ti.Cons[i]; ConstructorInfo con = infoEx.member as ConstructorInfo; if (type.IsValueType) { // 结构体不需要无参数构造函数 if (con == null || con.GetParameters().Length == 0) { continue; } } string ctorName = type.Name; if (type.IsGenericTypeDefinition) { int flag = ctorName.LastIndexOf('`'); if (flag >= 0) { ctorName = ctorName.Substring(0, flag); } } var constructorBuilder = new StringBuilder(); var paras = con == null ? "" : Ps2String(type, con.GetParameters()); constructorBuilder.Append($"public {ctorName}({paras})"); var baseType = type.ValidBaseType(); if (baseType != null && !HasDefaultConstructor(baseType)) { constructorBuilder.Append($" : base({BaseConstructorParameters(baseType)})"); } constructorBuilder.Append(" { throw new Exception(\"not impl\"); }"); tfClass.Add(constructorBuilder.ToString()); if (con != null) { foreach (var p in con.GetParameters()) { onNewType(p.ParameterType); } } } if (ti.Cons.Count > 0) { tfClass.AddLine(); } handlePros(tfClass, type, ti, onNewType); if (ti.Pros.Count > 0) { tfClass.AddLine(); } handleMethods(tfClass, type, ti, onNewType); if (!type.IsInterface) { handleInterfaceProblems(tfClass, type, onNewType); } }
static void handleInterfaceProblems(TextFile tfClass, Type cType, Action <Type> OnNewType) { Type[] interfaces = cType.GetValidInterfaces(); Action <Type, MethodInfo> actionMethod = (iType, method) => { StringBuilder sbDef = new StringBuilder(); // sbDef.Append("extern "); if (!(method.IsSpecialName && method.Name == "op_Implicit")) { sbDef.Append(typefn(method.ReturnType, cType.Namespace, CsNameOption.CompilableWithT) + " "); } OnNewType(method.ReturnType); sbDef.Append(iType.CsFullName(CsNameOption.CompilableWithT) + "."); // 这句是重点 sbDef.Append(MethodNameString(cType, method)); if (method.IsGenericMethodDefinition) { Type[] argus = method.GetGenericArguments(); args t_args = new args(); foreach (var a in argus) { t_args.Add(a.Name); } sbDef.Append(t_args.Format(args.ArgsFormat.GenericT)); } sbDef.Append("("); ParameterInfo[] ps = method.GetParameters(); { sbDef.Append(Ps2String(cType, ps)); sbDef.Append(") { throw new Exception(\"Exception\"); }"); foreach (var p in ps) { OnNewType(p.ParameterType); } } tfClass.Add(sbDef.ToString()); }; Action <Type, PropertyInfo> actionPro = (iType, pro) => { OnNewType(pro.PropertyType); ParameterInfo[] ps = pro.GetIndexParameters(); args iargs = new args(); bool isIndexer = (ps.Length > 0); if (isIndexer) { for (int j = 0; j < ps.Length; j++) { iargs.AddFormat("{0} {1}", typefn(ps[j].ParameterType, cType.Namespace), ps[j].Name); OnNewType(ps[j].ParameterType); } } MethodInfo getm = pro.GetGetMethod(true); MethodInfo setm = pro.GetSetMethod(true); bool canGet = getm != null && getm.IsPublic; bool canSet = setm != null && setm.IsPublic; string getset = ""; { if (canGet) { getset += "get { throw new Exception(\"not impl\"); }"; } if (canSet) { getset += " set { throw new Exception(\"not impl\"); }"; } } string vo = string.Empty; if (isIndexer) { tfClass.Add("{4}{0} {1}{2} {{ {3} }}", typefn(pro.PropertyType, cType.Namespace), iType.CsFullName(CsNameOption.CompilableWithT) + ".this", // 这句是重点 iargs.Format(args.ArgsFormat.Indexer), getset, vo); } else { tfClass.Add("{3}{0} {1} {{ {2} }}", typefn(pro.PropertyType, cType.Namespace), iType.CsFullName(CsNameOption.CompilableWithT) + "." + // 这句是重点 pro.Name, getset, vo); } }; foreach (Type iType in interfaces) { GeneratorHelp.ATypeInfo ti = GeneratorHelp.CreateTypeInfo(iType); for (int i = 0; i < ti.Methods.Count; i++) { MemberInfoEx infoEx = ti.Methods[i]; MethodInfo method = infoEx.member as MethodInfo; actionMethod(iType, method); } for (int i = 0; i < ti.Pros.Count; i++) { MemberInfoEx infoEx = ti.Pros[i]; PropertyInfo pro = infoEx.member as PropertyInfo; actionPro(iType, pro); } // 特殊处理,BridgeProj工程 if (iType == typeof(ICollection)) { tfClass.Add("bool System.Collections.ICollection.IsReadOnly { get; }"); } } }
public static void GenWraps(Type[] arrClasses, ISet <string> blackList, Func <Type, bool> filter) { GeneratorHelp.ClearTypeInfo(); Dictionary <Type, TypeStatus> dict = new Dictionary <Type, TypeStatus>(); Action <Type> onNewType = null; onNewType = (nt) => { while (true) { if (nt.IsByRef || nt.IsArray) { nt = nt.GetElementType(); continue; } if (nt.IsGenericType && !nt.IsGenericTypeDefinition) { foreach (var ga in nt.GetGenericArguments()) { onNewType(ga); } nt = nt.GetGenericTypeDefinition(); continue; } if (nt.IsGenericParameter) { return; } break; } if (!blackList.Contains(nt.FullName) && filter(nt) && !dict.ContainsKey(nt) && (nt.Namespace == null || !nt.FullName.StartsWith("System."))) { if (nt.DeclaringType != null) { if (!blackList.Contains(nt.DeclaringType.FullName)) { dict.Add(nt, new TypeStatus()); } } else { dict.Add(nt, new TypeStatus()); } } }; Func <Type, TypeStatus> getParent = (type) => { if (dict.ContainsKey(type)) { return(dict[type]); } return(null); }; foreach (var type in arrClasses) { onNewType(type); } while (true) { Type[] keys = new Type[dict.Count]; dict.Keys.CopyTo(keys, 0); foreach (Type type in keys) { TypeStatus ts = dict[type]; if (ts.status != TypeStatus.Status.Wait) { continue; } if (ShouldIgnoreType(type)) { ts.status = TypeStatus.Status.Ignored; continue; } if (type.IsEnum) { GenEnum(type, ts, getParent, onNewType); } else if (typeof(Delegate).IsAssignableFrom(type)) { GenDelegate(type, ts, getParent, onNewType); } else { GenInterfaceOrStructOrClass(type, ts, getParent, onNewType); } } bool bContinue = false; foreach (var kv in dict) { if (kv.Value.status == TypeStatus.Status.Wait) { bContinue = true; break; } } if (!bContinue) { break; } } TextFile tfAll = new TextFile(); tfAll.Add("#if UNITY_WAGAME"); tfAll.Add("using Bridge;"); tfAll.Add("using System;"); foreach (var kv in dict) { if (kv.Value.status == TypeStatus.Status.Exported && !kv.Value.IsInnerType) { tfAll.Add(kv.Value.tf.Ch); tfAll.AddLine(); } } tfAll.Add("#endif"); File.WriteAllText(JSBindingSettings.CswFilePath, tfAll.Format(-1)); }