diff --git a/src/Generator/Passes/FunctionToStaticMethodPass.cs b/src/Generator/Passes/FunctionToStaticMethodPass.cs new file mode 100644 index 00000000..c0f9ecbe --- /dev/null +++ b/src/Generator/Passes/FunctionToStaticMethodPass.cs @@ -0,0 +1,73 @@ +using System; +using System.Diagnostics; +using System.Text.RegularExpressions; + +namespace Cxxi.Passes +{ + /// + /// This pass will try to hoist functions into classes so they + /// work just like static methods. + /// + public class FunctionToStaticMethodPass : TranslationUnitPass + { + /// + /// Processes a function declaration. + /// + public override bool ProcessFunction(Function function) + { + if (function.Ignore) + return false; + + var types = SplitCamelCase(function.Name); + if (types.Length == 0) + return false; + + var @class = Library.FindCompleteClass(types[0]); + if (@class == null) + return false; + + // Clean up the name of the function now that it will be an instance method. + function.Name = function.Name.Substring(@class.Name.Length); + function.ExplicityIgnored = true; + + // Create a new fake method so it acts as an instance method. + var method = new Method() + { + Namespace = @class.Namespace, + Name = function.Name, + OriginalName = function.OriginalName, + Access = AccessSpecifier.Public, + Kind = CXXMethodKind.Normal, + ReturnType = function.ReturnType, + Parameters = function.Parameters, + CallingConvention = function.CallingConvention, + IsVariadic = function.IsVariadic, + IsInline = function.IsInline, + IsStatic = true, + Conversion = MethodConversionKind.FunctionToStaticMethod + }; + + @class.Methods.Add(method); + + Console.WriteLine("Static method: {0}::{1}", @class.Name, + function.Name); + + return true; + } + + public static string[] SplitCamelCase(string input) + { + var str = Regex.Replace(input, "([A-Z])", " $1", RegexOptions.Compiled); + return str.Trim().Split(); + } + } + + public static class FunctionToStaticMethodExtensions + { + public static void FunctionToStaticMethod(this PassBuilder builder) + { + var pass = new FunctionToStaticMethodPass(); + builder.AddPass(pass); + } + } +}