static void CheckMethodGenInfos(Dictionary <string, TsTypeGenInfo> tsGenTypeInfos, TsTypeGenInfo info) { if (info.IsCheckOk || info.BaseType == null) { return; } var baseInfo = info.BaseType; var baseName = (!string.IsNullOrEmpty(baseInfo.Namespace) ? (baseInfo.Namespace + ".") : "") + baseInfo.Name; if (tsGenTypeInfos.TryGetValue(baseName, out baseInfo) && info.Methods != null && baseInfo.Methods != null) { CheckMethodGenInfos(tsGenTypeInfos, baseInfo); var methods1 = SelectMethodGenInfos(tsGenTypeInfos, baseInfo, true); var methods2 = SelectMethodGenInfos(tsGenTypeInfos, info, false); var select = new List <TsMethodGenInfo>(info.Methods); foreach (var pair in methods1) { var name = pair.Key; if (!methods2.ContainsKey(name)) { continue; } var ms1 = pair.Value; var ms2 = methods2[name]; if (ms2.Count == 0) { continue; } var diffms = new List <TsMethodGenInfo>(); foreach (var m1 in ms1) { var diff = true; foreach (var m2 in ms2) { if (m1.Equals(m2)) { diff = false; break; } } if (diff) { diffms.Add(m1); } } if (ms2.Count + diffms.Count != ms1.Count) { select.AddRange(diffms); } } info.Methods = select.ToArray(); } info.IsCheckOk = true; }
public static TsTypeGenInfo ToTsTypeGenInfo(Type type, HashSet <Type> genTypeSet) { var result = new TsTypeGenInfo() { Name = type.Name.Replace('`', '$'), Methods = genTypeSet.Contains(type) ? (type.IsAbstract ? new MethodBase[] { } : type.GetConstructors(Flags).Where(m => !isFiltered(m)).Cast <MethodBase>()) .Concat(type.GetMethods(Flags) .Where(m => !isFiltered(m) && !IsGetterOrSetter(m) && !m.IsGenericMethodDefinition) .Cast <MethodBase>()) .Select(m => ToTsMethodGenInfo(m)).ToArray() : new TsMethodGenInfo[] { }, Properties = genTypeSet.Contains(type) ? type.GetFields(Flags).Where(m => !isFiltered(m)) .Select(f => new TsPropertyGenInfo() { Name = f.Name, TypeName = GetTsTypeName(f.FieldType), IsStatic = f.IsStatic }) .Concat( type.GetProperties(Flags).Where(m => !isFiltered(m)) .Select(p => new TsPropertyGenInfo() { Name = p.Name, TypeName = GetTsTypeName(p.PropertyType), IsStatic = IsStatic(p) })) .ToArray() : new TsPropertyGenInfo[] { }, IsGenericTypeDefinition = type.IsGenericTypeDefinition, IsDelegate = (IsDelegate(type) && type != typeof(Delegate)), IsInterface = type.IsInterface, Namespace = type.Namespace, }; if (result.IsGenericTypeDefinition) { result.GenericParameters = type.GetGenericArguments().Select(t => t.ToString()).ToArray(); } if (result.IsDelegate) { if (type == typeof(Delegate) || type == typeof(System.MulticastDelegate)) { result.DelegateDef = "(...args:any[]) => any"; } else { var m = type.GetMethod("Invoke"); var tsFuncDef = "(" + string.Join(", ", m.GetParameters().Select(p => p.Name + ": " + GetTsTypeName(p.ParameterType)).ToArray()) + ") => " + GetTsTypeName(m.ReturnType); result.DelegateDef = tsFuncDef; } } if (type.IsNested) { List <string> p = new List <string>(); Type temp = type; while (temp.IsNested) { p.Add(temp.DeclaringType.Name.Replace('`', '$')); temp = temp.DeclaringType; } p.Reverse(); if (type.Namespace != null) { result.Namespace = type.Namespace + '.' + string.Join(".", p.ToArray()); } else { result.Namespace = string.Join(".", p.ToArray()); } } if (!type.IsEnum && type.BaseType != null && type != typeof(object) && !result.IsDelegate && !result.IsInterface) { result.BaseType = new TsTypeGenInfo() { Name = type.BaseType.IsGenericType ? GetTsTypeName(type.BaseType): type.BaseType.Name.Replace('`', '$'), Namespace = type.BaseType.Namespace }; if (type.BaseType.IsGenericType && type.BaseType.Namespace != null) { result.BaseType.Name = result.BaseType.Name.Substring(type.BaseType.Namespace.Length + 1); } } if (type.IsEnum) { result.IsEnum = true; var KeyValues = type.GetFields(BindingFlags.Static | BindingFlags.Public) .Where(f => f.Name != "value__") .Select(f => f.Name + " = " + Convert.ToInt32(f.GetValue(null))).ToArray(); result.EnumKeyValues = string.Join(", ", KeyValues); } return(result); }
static TsMethodGenInfo[] GetMethodGenInfos(Dictionary <string, TsTypeGenInfo> tsGenTypeInfos, TsTypeGenInfo info, bool getBaseMethods) { var result = new List <TsMethodGenInfo>(); if (info.Methods != null) { result.AddRange(info.Methods); } if (info.ExtensionMethods != null) { foreach (var m in info.ExtensionMethods) { result.Add(new TsMethodGenInfo() { Name = m.Name, Document = m.Document, ParameterInfos = m.ParameterInfos, IsConstructor = m.IsConstructor, IsStatic = false, }); } } if (getBaseMethods && info.BaseType != null) { var baseInfo = info.BaseType; var baseName = (!string.IsNullOrEmpty(baseInfo.Namespace) ? (baseInfo.Namespace + ".") : "") + baseInfo.Name; if (tsGenTypeInfos.TryGetValue(baseName, out baseInfo)) { foreach (var m in GetMethodGenInfos(tsGenTypeInfos, baseInfo, true)) { if (!result.Contains(m)) { result.Add(m); } } } } return(result.ToArray()); }
static Dictionary <string, List <TsMethodGenInfo> > SelectMethodGenInfos(Dictionary <string, TsTypeGenInfo> tsGenTypeInfos, TsTypeGenInfo info, bool getBaseMethods) { var result = new Dictionary <string, List <TsMethodGenInfo> >(); foreach (var m in GetMethodGenInfos(tsGenTypeInfos, info, getBaseMethods)) { if (!result.ContainsKey(m.Name)) { result.Add(m.Name, new List <TsMethodGenInfo>()); } result[m.Name].Add(m); } return(result); }
/// <summary> /// resolve implemented/override and overload method /// </summary> private static void CheckGenInfos(Dictionary <string, TsTypeGenInfo> tsGenTypeInfos, TsTypeGenInfo info) { if (info.IsCheckOk || info.BaseType == null && info.interfaces == null /* || info.IsInterface */) { info.IsCheckOk = true; return; } info.IsCheckOk = true; TsTypeGenInfo targetInfo; //find baseType methods Dictionary <string, List <TsMethodGenInfo> > baseMethods = null; TsPropertyGenInfo[] baseProperties = null; if (info.BaseType != null && tsGenTypeInfos.TryGetValue(info.BaseType.FullName, out targetInfo)) { CheckGenInfos(tsGenTypeInfos, targetInfo); baseMethods = MethodGenInfosToDict(TsMethodGenInfo.FromTsGenTypeInfos(tsGenTypeInfos, targetInfo, true)); baseProperties = TsPropertyGenInfo.FromTsTypeGenInfo(tsGenTypeInfos, targetInfo, true); } //find interfaces TsMethodGenInfo[] ifaceMethods = null; TsPropertyGenInfo[] ifaceProperties = null; if (info.interfaces != null) { List <TsMethodGenInfo> methods = new List <TsMethodGenInfo>(); List <TsPropertyGenInfo> properties = new List <TsPropertyGenInfo>(); foreach (var iface in info.interfaces) { if (!tsGenTypeInfos.TryGetValue(iface.FullName, out targetInfo)) { continue; } methods.AddRange(TsMethodGenInfo.FromTsGenTypeInfos(tsGenTypeInfos, targetInfo, true)); properties.AddRange(TsPropertyGenInfo.FromTsTypeGenInfo(tsGenTypeInfos, targetInfo, true)); } ifaceMethods = methods.ToArray(); ifaceProperties = properties.ToArray(); } if (baseMethods == null && ifaceMethods == null) { return; } Dictionary <string, List <TsMethodGenInfo> > ownMethods = MethodGenInfosToDict(TsMethodGenInfo.FromTsGenTypeInfos(tsGenTypeInfos, info, false)); TsPropertyGenInfo[] ownProperties = TsPropertyGenInfo.FromTsTypeGenInfo(tsGenTypeInfos, info, false); //implemented method if (ifaceMethods != null) { List <TsMethodGenInfo> infos; var implMethods = ifaceMethods.Where( method => !(( ownMethods.TryGetValue(method.Name, out infos) && infos.FirstOrDefault(m => method.Equals(m)) != null ) || ( baseMethods != null && baseMethods.TryGetValue(method.Name, out infos) && infos.FirstOrDefault(m => method.Equals(m)) != null )) ); var implProperties = ifaceProperties.Where( prop => !(( ownProperties.FirstOrDefault(p => prop.Name.Equals(p.Name)) != null ) || ( baseProperties != null && baseProperties.FirstOrDefault(p => prop.Name.Equals(p.Name)) != null )) ); info.Methods = info.Methods.Concat(implMethods).ToArray(); info.Properties = info.Properties.Concat(implProperties).ToArray(); ownMethods = MethodGenInfosToDict(info.Methods); } //override/overload method if (baseMethods != null) { var selectMethods = new List <TsMethodGenInfo>(info.Methods); foreach (var pair in baseMethods) { var methodName = pair.Key; List <TsMethodGenInfo> oMethods; if (!ownMethods.TryGetValue(methodName, out oMethods) || oMethods.Count == 0) { continue; } List <TsMethodGenInfo> bMethods = pair.Value.Distinct().ToList(); var diffMethods = new List <TsMethodGenInfo>(); foreach (var bMethod in bMethods) { if (oMethods.FirstOrDefault(m => bMethod.Equals(m)) == null) { diffMethods.Add(bMethod); } } if (oMethods.Count + diffMethods.Count != bMethods.Count) { selectMethods.AddRange(diffMethods); } } info.Methods = selectMethods.ToArray(); } info.Methods = info.Methods.Distinct(new TsMethodGenInfoComparer()).ToArray(); }
public static TypingGenInfo FromTypes(IEnumerable <Type> types) { HashSet <Type> genTypeSet = new HashSet <Type>(); HashSet <Type> workTypes = new HashSet <Type>(); HashSet <Type> refTypes = new HashSet <Type>(); foreach (var type in types) { AddRefType(workTypes, refTypes, type); var defType = type.IsGenericType ? type.GetGenericTypeDefinition() : type; if (!genTypeSet.Contains(defType)) { genTypeSet.Add(defType); } foreach (var field in type.GetFields(Utils.Flags)) { AddRefType(workTypes, refTypes, field.FieldType); } foreach (var method in type.GetMethods(Utils.Flags)) { AddRefType(workTypes, refTypes, method.ReturnType); foreach (var pinfo in method.GetParameters()) { AddRefType(workTypes, refTypes, pinfo.ParameterType); } } foreach (var constructor in type.GetConstructors()) { foreach (var pinfo in constructor.GetParameters()) { AddRefType(workTypes, refTypes, pinfo.ParameterType); } } } if (!genTypeSet.Contains(typeof(Array)) && !refTypes.Contains(typeof(Array))) { AddRefType(workTypes, refTypes, typeof(Array)); } var tsTypeGenInfos = new Dictionary <string, TsTypeGenInfo>(); foreach (var t in refTypes.Distinct()) { var info = TsTypeGenInfo.FromType(t, genTypeSet); tsTypeGenInfos.Add(info.FullName, info); } foreach (var info in tsTypeGenInfos) { CheckGenInfos(tsTypeGenInfos, info.Value); } return(new TypingGenInfo() { NamespaceInfos = tsTypeGenInfos.Values.GroupBy(t => t.Namespace) .Select(g => new TsNamespaceGenInfo() { Name = g.Key, Types = g.ToArray() }).ToArray(), #if CSHARP_7_3_OR_NEWER TaskDef = refTypes.Contains(typeof(System.Threading.Tasks.Task <>)) ? "type $Task<T> = System.Threading.Tasks.Task$1<T>" : "interface $Task<T> {}", #else TaskDef = "interface $Task<T> {}", #endif }); }
public static TsTypeGenInfo FromType(Type type, HashSet <Type> genTypeSet) { var result = new TsTypeGenInfo() { Name = type.Name.Replace('`', '$'), Document = DocResolver.GetTsDocument(type), Methods = genTypeSet.Contains(type) ? TsMethodGenInfo.FromType(type, genTypeSet) : new TsMethodGenInfo[] { }, Properties = genTypeSet.Contains(type) ? type.GetFields(Utils.Flags) .Where(m => !Utils.IsNotSupportedMember(m, true)) .Where(m => Utils.getBindingMode(m) != BindingMode.DontBinding) .Select(f => new TsPropertyGenInfo() { Name = f.Name, Document = DocResolver.GetTsDocument(f), TypeName = Utils.GetTsTypeName(f.FieldType), IsStatic = f.IsStatic }) .Concat( type.GetProperties(Utils.Flags).Where(m => m.Name != "Item") .Where(m => !Utils.IsNotSupportedMember(m, true)) .Where(m => Utils.getBindingMode(m) != BindingMode.DontBinding) .Select(p => new TsPropertyGenInfo() { Name = p.Name, Document = DocResolver.GetTsDocument(p), TypeName = Utils.GetTsTypeName(p.PropertyType), IsStatic = Utils.IsStatic(p), HasGetter = p.GetGetMethod() != null && p.GetGetMethod().IsPublic, HasSetter = p.GetSetMethod() != null && p.GetSetMethod().IsPublic }) ) .ToArray() : new TsPropertyGenInfo[] { }, IsGenericTypeDefinition = type.IsGenericTypeDefinition, IsDelegate = (Utils.IsDelegate(type) && type != typeof(Delegate)), IsInterface = type.IsInterface, Namespace = type.Namespace, ExtensionMethods = Utils.GetExtensionMethods(type, genTypeSet).Select(m => TsMethodGenInfo.FromMethodBase(m, type.IsGenericTypeDefinition, true)).ToArray() }; if (result.IsGenericTypeDefinition) { result.GenericParameters = type.GetGenericArguments().Select(t => t.ToString()).ToArray(); } if (result.IsDelegate) { if (type == typeof(Delegate) || type == typeof(System.MulticastDelegate)) { result.DelegateDef = "(...args:any[]) => any"; } else { var m = type.GetMethod("Invoke"); var tsFuncDef = "(" + string.Join(", ", m.GetParameters().Select(p => p.Name + ": " + Utils.GetTsTypeName(p.ParameterType)).ToArray()) + ") => " + Utils.GetTsTypeName(m.ReturnType); result.DelegateDef = tsFuncDef; } } Type[] interfaces = type.GetInterfaces(); if (interfaces != null && interfaces.Length > 0) { List <TsTypeGenInfo> genInfoList = new List <TsTypeGenInfo>(); for (int i = 0; i < interfaces.Length; i++) { var interfaceTypeGenInfo = new TsTypeGenInfo() { Name = interfaces[i].IsGenericType ? Utils.GetTsTypeName(interfaces[i]) : interfaces[i].Name.Replace('`', '$'), Document = DocResolver.GetTsDocument(interfaces[i]), Namespace = interfaces[i].Namespace }; if (interfaces[i].IsNested) { List <string> p = new List <string>(); Type temp = interfaces[i]; while (temp.IsNested) { p.Add(temp.DeclaringType.Name.Replace('`', '$')); temp = temp.DeclaringType; } p.Reverse(); if (interfaces[i].Namespace != null) { interfaceTypeGenInfo.Namespace = interfaces[i].Namespace + '.' + string.Join(".", p.ToArray()); } else { interfaceTypeGenInfo.Namespace = string.Join(".", p.ToArray()); } } if (interfaces[i].IsGenericType && interfaces[i].Namespace != null) { interfaceTypeGenInfo.Name = interfaceTypeGenInfo.Name.Substring(interfaceTypeGenInfo.Namespace.Length + 1); } genInfoList.Add(interfaceTypeGenInfo); } result.interfaces = genInfoList.ToArray(); } if (type.IsNested) { List <string> p = new List <string>(); Type temp = type; while (temp.IsNested) { p.Add(temp.DeclaringType.Name.Replace('`', '$')); temp = temp.DeclaringType; } p.Reverse(); if (type.Namespace != null) { result.Namespace = type.Namespace + '.' + string.Join(".", p.ToArray()); } else { result.Namespace = string.Join(".", p.ToArray()); } } if (!type.IsEnum && type.BaseType != null && type != typeof(object) && !result.IsDelegate && !result.IsInterface) { result.BaseType = new TsTypeGenInfo() { Name = type.BaseType.IsGenericType ? Utils.GetTsTypeName(type.BaseType) : type.BaseType.Name.Replace('`', '$'), Document = DocResolver.GetTsDocument(type.BaseType), Namespace = type.BaseType.Namespace }; if (type.BaseType.IsNested) { List <string> p = new List <string>(); Type temp = type.BaseType; while (temp.IsNested) { p.Add(temp.DeclaringType.Name.Replace('`', '$')); temp = temp.DeclaringType; } p.Reverse(); if (type.BaseType.Namespace != null) { result.BaseType.Namespace = type.BaseType.Namespace + '.' + string.Join(".", p.ToArray()); } else { result.BaseType.Namespace = string.Join(".", p.ToArray()); } } if (type.BaseType.IsGenericType && type.BaseType.Namespace != null) { result.BaseType.Name = result.BaseType.Name.Substring(result.BaseType.Namespace.Length + 1); } } if (type.IsEnum) { result.IsEnum = true; var KeyValues = type.GetFields(BindingFlags.Static | BindingFlags.Public) .Where(f => f.Name != "value__") .Select(f => f.Name + " = " + Convert.ChangeType(f.GetValue(null), Enum.GetUnderlyingType(type))).ToArray(); result.EnumKeyValues = string.Join(", ", KeyValues); } return(result); }
public static TsPropertyGenInfo[] FromTsTypeGenInfo(Dictionary <string, TsTypeGenInfo> tsGenTypeInfos, TsTypeGenInfo info, bool getBaseMethods) { var result = new List <TsPropertyGenInfo>(); if (info.Properties != null) { result.AddRange(info.Properties); } if (getBaseMethods) { TsTypeGenInfo taregtInfo; if (info.BaseType != null && tsGenTypeInfos.TryGetValue(info.BaseType.FullName, out taregtInfo)) { result.AddRange(TsPropertyGenInfo.FromTsTypeGenInfo(tsGenTypeInfos, taregtInfo, true)); } if (info.IsInterface && info.interfaces != null) { foreach (var iface in info.interfaces) { if (tsGenTypeInfos.TryGetValue(iface.FullName, out taregtInfo)) { result.AddRange(TsPropertyGenInfo.FromTsTypeGenInfo(tsGenTypeInfos, taregtInfo, true)); } } } } return(result.Distinct().ToArray()); }
public static TsMethodGenInfo[] FromTsGenTypeInfos(Dictionary <string, TsTypeGenInfo> tsGenTypeInfos, TsTypeGenInfo info, bool getBaseMethods) { var result = new List <TsMethodGenInfo>(); if (info.Methods != null) { result.AddRange(info.Methods); } if (info.ExtensionMethods != null) { result.AddRange(info.ExtensionMethods.Select(m => new TsMethodGenInfo() { Name = m.Name, Document = m.Document, ParameterInfos = m.ParameterInfos, IsConstructor = m.IsConstructor, IsStatic = false, })); } if (getBaseMethods) { TsTypeGenInfo taregtInfo; if (info.BaseType != null && tsGenTypeInfos.TryGetValue(info.BaseType.FullName, out taregtInfo)) { result.AddRange(TsMethodGenInfo.FromTsGenTypeInfos(tsGenTypeInfos, taregtInfo, true)); } if (info.IsInterface && info.interfaces != null) { foreach (var iface in info.interfaces) { if (tsGenTypeInfos.TryGetValue(iface.FullName, out taregtInfo)) { result.AddRange(TsMethodGenInfo.FromTsGenTypeInfos(tsGenTypeInfos, taregtInfo, true)); } } } } return(result.Distinct(new TsMethodGenInfoComparer()).ToArray()); }