コード例 #1
0
        // 参数typeM是一个method的声明中使用到的类型,比如返回值,参数
        // ShouldIgnoreTypeInM判断这个typeM是否是Bridge中已经有定义了
        // 如果有,表示这个类型在逻辑代码中应当是纯Js的类型,其对象不应该传递到C#中
        // 那么这个method就应该对Js不可见
        static bool ShouldIgnoreTypeInM(Type classType, MethodInfo method, Type typeM)
        {
            Type t = typeM;

            while (t.IsArray)
            {
                t = t.GetElementType();
            }
            if (t.IsByRef)
            {
                t = t.GetElementType();
            }
            if (t.IsGenericType)
            {
                t = t.GetGenericTypeDefinition();
            }
            while (t.DeclaringType != null)
            {
                t = t.DeclaringType;
            }

            if (t == typeof(void) ||
                t.IsPrimitive ||
                t == typeof(string) ||
                t.IsEnum ||
                t == typeof(System.Object) ||
                // 这2个暂且不算吧
                t == typeof(IEnumerable) || t == typeof(IEnumerator) || t == typeof(IEnumerator <>) || t == typeof(IEnumerable <>) ||
                typeof(Delegate).IsAssignableFrom(t))
            {
                return(false);
            }

            if (classType == typeof(MonoBehaviour) && (method.Name == "StartCoroutine" || method.Name == "StopCoroutine"))
            {
                return(false);
            }
            if (classType == typeof(GameObject) && method.Name == "AddComponent")
            {
                return(false);
            }

            HashSet <string> bridgeTypes = JSBindingSettings.LoadBridgeDefinedTypes(false);

            if (bridgeTypes.Contains(t.FullName))
            {
                return(true);
            }
            return(false);
        }
コード例 #2
0
        public static ATypeInfo CreateTypeInfo(Type type)
        {
            ATypeInfo ti = new ATypeInfo();
            {
                var fields = type.GetFields(JSMgr.BindingFlagsField);
                for (int i = 0; i < fields.Length; i++)
                {
                    ti.Fields.Add(new MemberInfoEx(ti.Fields, fields[i], fields[i].IsStatic));
                }

                var pros = type.GetProperties(JSMgr.BindingFlagsProperty);
                for (int i = 0; i < pros.Length; i++)
                {
                    ti.Pros.Add(new MemberInfoEx(ti.Pros, pros[i], pros[i].GetAccessors()[0].IsStatic));
                }

                ti.Pros.Sort(PropertyInfoComparison);

                var methods = type.GetMethods(JSMgr.BindingFlagsMethod);
                for (int i = 0; i < methods.Length; i++)
                {
                    ti.Methods.Add(new MemberInfoEx(ti.Methods, methods[i], methods[i].IsStatic));
                }

                // 函数排序
                ti.Methods.Sort(MethodBaseComparison);

                var cons = type.GetConstructors();
                if (JSBindingSettings.NeedGenDefaultConstructor(type))
                {
                    // null 表示默认构造函数
                    var l = new List <ConstructorInfo>();
                    l.Add(null);
                    l.AddRange(cons);
                    cons = l.ToArray();
                }
                for (int i = 0; i < cons.Length; i++)
                {
                    ti.Cons.Add(new MemberInfoEx(ti.Cons, cons[i], false));
                }

                ti.Cons.Sort(MethodBaseComparison);
            }

            bool isStaticClass   = (type.IsClass && type.IsAbstract && type.IsSealed);
            bool isAbstractClass = (type.IsClass && type.IsAbstract);

            Dictionary <string, int> proAccessors = new Dictionary <string, int>();

            for (int i = 0; i < ti.Cons.Count; i++)
            {
                MemberInfoEx    infoEx = ti.Cons[i];
                ConstructorInfo con    = infoEx.member as ConstructorInfo;
                if (con == null)
                {
                    continue;
                }

                if (isAbstractClass ||
                    //type == typeof(UnityEngine.MonoBehaviour) ||
                    IsMemberObsolete(con) ||
                    JSBindingSettings.IsDiscard(type, con)
                    )
                {
                    infoEx.Ignored = true;
                    continue;
                }

                ParameterInfo[] ps = con.GetParameters();
                for (var k = 0; k < ps.Length; k++)
                {
                    Type pt = ps[k].ParameterType;
                    if (TypeIsPtr(pt))
                    {
                        infoEx.Ignored = true;
                        continue;
                    }
                }
            }

            for (int i = 0; i < ti.Fields.Count; i++)
            {
                MemberInfoEx infoEx = ti.Fields[i];
                FieldInfo    field  = infoEx.member as FieldInfo;

                if (typeof(System.Delegate).IsAssignableFrom(field.FieldType.BaseType))
                {
                    //Debug.Log("[field]" + type.ToString() + "." + ti.fields[i].Name + "is delegate!");
                }

                if (field.FieldType.ContainsGenericParameters ||
                    IsMemberObsolete(field) ||
                    JSBindingSettings.IsDiscard(type, field)
                    )
                {
                    infoEx.Ignored = true;
                }
            }

            for (int i = 0; i < ti.Pros.Count; i++)
            {
                MemberInfoEx infoEx = ti.Pros[i];
                PropertyInfo pro    = infoEx.member as PropertyInfo;

                if (typeof(System.Delegate).IsAssignableFrom(pro.PropertyType.BaseType))
                {
                    // Debug.Log("[property]" + type.ToString() + "." + pro.Name + "is delegate!");
                }

                MethodInfo[] accessors = pro.GetAccessors();
                foreach (var v in accessors)
                {
                    if (!proAccessors.ContainsKey(v.Name))
                    {
                        proAccessors.Add(v.Name, 0);
                    }
                }

                // Skip Obsolete
                if (IsMemberObsolete(pro) ||
                    TypeIsPtr(pro.PropertyType) ||
                    JSBindingSettings.IsDiscard(type, pro)
                    )
                {
                    infoEx.Ignored = true;
                }
            }

            for (int i = 0; i < ti.Methods.Count; i++)
            {
                MemberInfoEx infoEx = ti.Methods[i];
                MethodInfo   method = infoEx.member as MethodInfo;

                // skip non-static method in static class
                if ((isStaticClass && !method.IsStatic) ||
                    (method.IsSpecialName && proAccessors.ContainsKey(method.Name))
                    )
                {
                    infoEx.Ignored = true;
                    continue;
                }

                if (method.IsSpecialName)
                {
                    if (method.Name == "op_Addition" ||
                        method.Name == "op_Subtraction" ||
                        method.Name == "op_UnaryNegation" ||
                        method.Name == "op_Multiply" ||
                        method.Name == "op_Division" ||
                        method.Name == "op_Equality" ||
                        method.Name == "op_Inequality" ||

                        method.Name == "op_LessThan" ||
                        method.Name == "op_LessThanOrEqual" ||
                        method.Name == "op_GreaterThan" ||
                        method.Name == "op_GreaterThanOrEqual" ||

                        method.Name == "op_Implicit")
                    {
                        if (!method.IsStatic)
                        {
                            Debug.Log("忽略非静态特殊名字函数 " + type.Name + "." + method.Name);
                            infoEx.Ignored = true;
                            continue;
                        }
                    }
                    else
                    {
                        Debug.Log("忽略特殊名字函数 " + type.Name + "." + method.Name);
                        infoEx.Ignored = true;
                        continue;
                    }
                }

                // Skip Obsolete
                if (IsMemberObsolete(method))
                {
                    infoEx.Ignored = true;
                    continue;
                }

                ParameterInfo[] ps;
                bool            bDiscard = false;

                // 忽略掉类型带 T 的静态方法
                // 因为 SharpKit 调用时没有提供 T
                if (method.IsGenericMethodDefinition && /* || method.IsGenericMethod*/
                    method.IsStatic)
                {
                    ps = method.GetParameters();
                    for (int k = 0; k < ps.Length; k++)
                    {
                        if (ps[k].ParameterType.ContainsGenericParameters)
                        {
                            var Ts = JSDataExchangeMgr.RecursivelyGetGenericParameters(ps[k].ParameterType);
                            foreach (var t in Ts)
                            {
                                if (t.DeclaringMethod == null)
                                {
                                    bDiscard = true;
                                    break;
                                }
                            }
                            if (bDiscard)
                            {
                                break;
                            }
                        }
                    }
                    if (bDiscard)
                    {
                        Debug.LogWarning("忽略静态函数 " + type.Name + "." + method.Name);
                        infoEx.Ignored = true;
                        continue;
                    }
                }

                if (ShouldIgnoreTypeInM(type, method, method.ReturnType))
                {
                    Debug.Log(type.Name + "." + method.Name + " 忽略,因为返回值类型是逻辑类型");
                    infoEx.Ignored = true;
                    continue;
                }

                if (TypeIsPtr(method.ReturnType))
                {
                    Debug.Log(type.Name + "." + method.Name + " 忽略,因为返回值类型是 IntPtr");
                    infoEx.Ignored = true;
                    continue;
                }

                // 是否有 unsafe 的参数?
                bDiscard = false;
                ps       = method.GetParameters();
                for (var k = 0; k < ps.Length; k++)
                {
                    Type pt = ps[k].ParameterType;
                    if (TypeIsPtr(pt))
                    {
                        bDiscard = true;
                        break;
                    }
                }
                if (bDiscard)
                {
                    Debug.Log(type.Name + "." + method.Name + " 忽略,因为他有 IsPointer = true 的参数");
                    infoEx.Ignored = true;
                    continue;
                }

                bDiscard = false;
                for (var k = 0; k < ps.Length; k++)
                {
                    Type pt = ps[k].ParameterType;
                    if (ShouldIgnoreTypeInM(type, method, pt))
                    {
                        bDiscard = true;
                        break;
                    }
                }
                if (bDiscard)
                {
                    Debug.Log(type.Name + "." + method.Name + " 忽略,因为他的参数有逻辑类型");
                    infoEx.Ignored = true;
                    continue;
                }

                if (JSBindingSettings.IsDiscard(type, method))
                {
                    infoEx.Ignored = true;
                    continue;
                }
            }

            // 移除 Ignored 的项
            foreach (List <MemberInfoEx> lst in
                     new List <MemberInfoEx>[] { ti.Cons, ti.Fields, ti.Pros, ti.Methods })
            {
                for (int i = lst.Count - 1; i >= 0; i--)
                {
                    if (lst[i].Ignored)
                    {
                        lst.RemoveAt(i);
                    }
                }
            }
            return(ti);
        }