// 参数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); }
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); }