コード例 #1
0
ファイル: JSGenerator.cs プロジェクト: midgithub/FishBattle
    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 = {};
");
    }
コード例 #2
0
    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);
    }
コード例 #3
0
ファイル: JSGenerator.cs プロジェクト: midgithub/FishBattle
    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());
    }
コード例 #4
0
    //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);
    }
コード例 #5
0
ファイル: CSGenerator.cs プロジェクト: shuidong/qjsbunitynew
    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;
    }
コード例 #6
0
    // 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);
    }
コード例 #7
0
ファイル: JSGenerator.cs プロジェクト: midgithub/FishBattle
    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);
            }
        }
    }
コード例 #8
0
        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);
            }
        }
コード例 #9
0
        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; }");
                }
            }
        }
コード例 #10
0
        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));
        }