/// <summary> /// Generate C function. /// </summary> public CFunction(MethodInfo function, Type cls, IReadOnlyList <string> genericTypes = null) { Declaration = ""; Definition = ""; if (function.GetCustomAttribute <CMethodCoverAttribute>() != null || function.DeclaringType.IsAbstract) { return; } if (function.GetCustomAttribute <CMethodCoverAttribute>() != null) { return; } var pars = function.GetParameters().Select(parameter => $"{CType.Deserialize(parameter.ParameterType)} {parameter.Name}").ToList(); if (function.IsGenericMethod && genericTypes != null) { var generics = function.GetGenericArguments(); for (var i = 0; i < generics.Length; i++) { var generic = generics[i]; for (var index = 0; index < function.GetParameters().Length; index++) { var parameter = function.GetParameters()[index]; if (parameter.ParameterType.Name == generic.Name) { pars[index] = $"{genericTypes[i]} {parameter.Name}"; } } } } var parts = function.ReturnType.Name.Split('.'); /* * DEC */ Declaration = $"extern {CType.Deserialize(parts[parts.Length - 1])} " + $"{cls.Name + function.Name}" + $"{Visualizer.Additional(function, cls)} ("; foreach (var par in pars) { Declaration += $"{par}"; if (pars[pars.Count - 1] != par) { Declaration += ", "; } } if (!function.IsStatic) { if (pars.Count > 0) { Declaration += ", "; } Declaration += $"struct {function.DeclaringType?.Name}*me"; } Declaration += ");\n\n"; /* * DEF */ if (function.DeclaringType != null) { Definition = $"{CType.Deserialize(parts[parts.Length - 1])} " + $"{cls.Name + function.Name}" + $"{Visualizer.Additional(function, cls)} ("; foreach (var par in pars) { Definition += $"{par}"; if (pars[pars.Count - 1] != par) { Definition += ", "; } } if (!function.IsStatic) { if (pars.Count > 0) { Definition += ", "; } Definition += $"struct {function.DeclaringType?.Name}*me"; } Definition += ")\n{\n"; } Visualizer.FirstPass = false; foreach (var line in Visualizer.BuildBody(function)) { Definition += line; } Definition += "}\n\n"; }
/// <summary> /// Generate C class/struct. /// </summary> /// <param name="type">Class type</param> public CClass(Type type) { Structure = ""; if (type.IsAbstract) { return; } if (type.Name.Contains("<") || type.Name.Contains("`")) { Console.WriteLine($"Unsupported and/or generic type {type.Name}"); return; } Structure += $"typedef struct {type.Name}\n" + "{\n"; var methods = type.GetMethods().ToList(); methods.AddRange(type.GetMethods(BindingFlags.NonPublic)); var methodList = (from method in type.GetMethods() where type.BaseType != null from info in type.BaseType?.GetMethods() where method.GetBaseDefinition() == info select method).ToList(); /* * Collect methods */ foreach (var method in type.GetMethods()) { if (method.GetCustomAttribute <CMethodCoverAttribute>() != null) { return; } if (type.BaseType != null) { var none = true; foreach (var info in type.BaseType.GetMethods()) { if (method.GetBaseDefinition() == info) { none = false; } } if (none) { methodList.Add(method); } } else { methodList.Add(method); } } foreach (var method in methodList) { if (method.IsStatic) { continue; } try { var parts = method.ReturnType.Name.Split('.'); Structure += $"\t{CType.Deserialize(parts[parts.Length - 1])} (*{method.Name}{Visualizer.Additional(method, type)})("; foreach (var parameter in method.GetParameters()) { Structure += $"{CType.Deserialize(parameter.ParameterType)} {parameter.Name}"; } if (!method.IsStatic) { if (method.GetParameters().Length > 0) { Structure += ", "; } Structure += $"struct {type.Name}*me"; } Structure += ");\n\n"; } catch { Console.WriteLine("Failed"); } } var fields = type.GetFields().ToList(); fields.AddRange(type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)); foreach (var field in fields) { if (field.IsStatic) { continue; } try { var newName = field.Name.Where(t => t != '<' && t != '>') .Aggregate("", (current, t) => current + t); Structure += $"\t{CType.Deserialize(field.FieldType.Name)} {newName};\n"; } catch { Console.WriteLine("Failed"); } } Structure += "}" + $" {type.Name};\n\n"; }
/// <summary> /// Generate C constructor. /// </summary> /// <param name="function">Method</param> /// <param name="cls">Class</param> public CConstructor(MethodBase function, Type cls) { Declaration = ""; Definition = ""; var pars = function.GetParameters().Select(parameter => $"{CType.Deserialize(parameter.ParameterType)} {parameter.Name}").ToList(); if (function.DeclaringType == null) { return; } Definition += $"struct {function.DeclaringType.Name}* new{function.DeclaringType.Name}{Visualizer.Additional(function, cls)} ("; foreach (var par in pars) { Definition += $"{par}"; if (pars[pars.Count - 1] != par) { Definition += ", "; } } Definition += ")\n{\n\t" + $"{function.DeclaringType.Name}* me = " + $"malloc(sizeof({function.DeclaringType.Name}));"; if (function.DeclaringType != null) { foreach (var method in function.DeclaringType.GetMethods()) { if (method.IsConstructor || method.IsStatic) { continue; } Definition += $"\n\tme->{method.Name}{Visualizer.Additional(method, cls)} = &{function.DeclaringType.Name + method.Name}{Visualizer.Additional(method, cls)};"; } Definition += "\n"; Visualizer.FirstPass = false; foreach (var line in Visualizer.BuildBody(function)) { Definition += line; } } Definition += "\n\treturn me;"; Definition += "\n}\n\n"; Declaration += $"struct {function.DeclaringType.Name}* new{function.DeclaringType.Name}{Visualizer.Additional(function, cls)} ("; foreach (var par in pars) { Declaration += $"{par}"; if (pars[pars.Count - 1] != par) { Declaration += ", "; } } Declaration += ");\n\n"; }