From 1473488289556509ee82bd79785201a92ed0a6e8 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Tue, 12 Nov 2013 19:34:23 +0200 Subject: [PATCH] Added a pass to move functions to an appropriate existing class if possible. Signed-off-by: Dimitar Dobrev --- src/AST/ASTContext.cs | 16 +++--- src/AST/Namespace.cs | 10 ++-- .../Passes/MoveFunctionToClassPass.cs | 49 +++++++++++++++++++ 3 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 src/Generator/Passes/MoveFunctionToClassPass.cs diff --git a/src/AST/ASTContext.cs b/src/AST/ASTContext.cs index 64d8ad14..656d6d1b 100644 --- a/src/AST/ASTContext.cs +++ b/src/AST/ASTContext.cs @@ -61,27 +61,31 @@ namespace CppSharp.AST } /// Finds an existing struct/class in the library modules. - public IEnumerable FindClass(string name, bool create = false) + public IEnumerable FindClass(string name, bool create = false, bool ignoreCase = false) { - return TranslationUnits.Select(module => module.FindClass(name)).Where(type => type != null); + return TranslationUnits.Select( + module => module.FindClass(name, ignoreCase)).Where(type => type != null); } /// Finds the complete declaration of a class. - public Class FindCompleteClass(string name) + public Class FindCompleteClass(string name, bool ignoreCase = false) { - return FindClass(name).FirstOrDefault(@class => !@class.IsIncomplete); + return FindClass(name, ignoreCase: ignoreCase).FirstOrDefault( + @class => !@class.IsIncomplete); } /// Finds an existing function in the library modules. public IEnumerable FindFunction(string name) { - return TranslationUnits.Select(module => module.FindFunction(name)).Where(type => type != null); + return TranslationUnits.Select(module => module.FindFunction(name)).Where( + type => type != null); } /// Finds an existing typedef in the library modules. public IEnumerable FindTypedef(string name) { - return TranslationUnits.Select(module => module.FindTypedef(name)).Where(type => type != null); + return TranslationUnits.Select(module => module.FindTypedef(name)).Where( + type => type != null); } /// Finds an existing declaration by name. diff --git a/src/AST/Namespace.cs b/src/AST/Namespace.cs index 64c77d1d..cf9d2037 100644 --- a/src/AST/Namespace.cs +++ b/src/AST/Namespace.cs @@ -168,16 +168,20 @@ namespace CppSharp.AST return @class; } - public Class FindClass(string name) + public Class FindClass(string name, bool ignoreCase = false) { if (string.IsNullOrEmpty(name)) return null; - var entries = name.Split(new string[] { "::" }, + var entries = name.Split(new[] { "::" }, StringSplitOptions.RemoveEmptyEntries).ToList(); if (entries.Count <= 1) { - var @class = Classes.Find(e => e.Name.Equals(name)); + Class @class; + if (ignoreCase) + @class = Classes.Find(e => e.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + else + @class = Classes.Find(e => e.Name.Equals(name)); return @class; } diff --git a/src/Generator/Passes/MoveFunctionToClassPass.cs b/src/Generator/Passes/MoveFunctionToClassPass.cs new file mode 100644 index 00000000..ead334a2 --- /dev/null +++ b/src/Generator/Passes/MoveFunctionToClassPass.cs @@ -0,0 +1,49 @@ +using System.Linq; +using CppSharp.AST; + +namespace CppSharp.Passes +{ + public class MoveFunctionToClassPass : TranslationUnitPass + { + public override bool VisitFunctionDecl(Function function) + { + if (!AlreadyVisited(function) && !function.Ignore && !(function.Namespace is Class) + // HACK: there are bugs with operators generated by Q_DECLARE_OPERATORS_FOR_FLAGS, an incorrect argument type, to say the least + && !function.IsOperator) + { + TranslationUnit unit = function.Namespace as TranslationUnit; + Class @class; + if (unit != null) + { + @class = Driver.ASTContext.FindCompleteClass( + unit.FileNameWithoutExtension.ToLowerInvariant(), true); + if (@class != null) + { + MoveFunction(function, @class); + return base.VisitFunctionDecl(function); + } + } + @class = Driver.ASTContext.FindClass( + function.Namespace.Name, ignoreCase: true).FirstOrDefault(); + if (@class != null) + { + MoveFunction(function, @class); + } + } + return base.VisitFunctionDecl(function); + } + + private static void MoveFunction(Function function, Class @class) + { + var method = new Method(function) + { + Namespace = @class, + IsStatic = true + }; + + function.ExplicityIgnored = true; + + @class.Methods.Add(method); + } + } +}