|
3 | 3 |
|
4 | 4 | namespace CppSharp.Passes |
5 | 5 | { |
6 | | - /// <summary> |
7 | | - /// Moves a function to a class, if any, named after the function's header. |
8 | | - /// </summary> |
9 | 6 | public class MoveFunctionToClassPass : TranslationUnitPass |
10 | 7 | { |
| 8 | + public MoveFunctionToClassPass() |
| 9 | + { |
| 10 | + VisitOptions.VisitClassBases = VisitOptions.VisitClassFields = |
| 11 | + VisitOptions.VisitClassMethods = VisitOptions.VisitClassProperties = |
| 12 | + VisitOptions.VisitClassTemplateSpecializations = VisitOptions.VisitEventParameters = |
| 13 | + VisitOptions.VisitFunctionParameters = VisitOptions.VisitFunctionReturnType = |
| 14 | + VisitOptions.VisitNamespaceEnums = VisitOptions.VisitNamespaceEvents = |
| 15 | + VisitOptions.VisitNamespaceTemplates = VisitOptions.VisitNamespaceTypedefs = |
| 16 | + VisitOptions.VisitNamespaceVariables = VisitOptions.VisitPropertyAccessors = |
| 17 | + VisitOptions.VisitTemplateArguments = false; |
| 18 | + } |
| 19 | + |
11 | 20 | public override bool VisitFunctionDecl(Function function) |
12 | 21 | { |
13 | | - if (!VisitDeclaration(function)) |
| 22 | + if (!function.IsGenerated) |
14 | 23 | return false; |
15 | 24 |
|
16 | | - if (!function.IsGenerated || function.Namespace is Class) |
| 25 | + Class @class = FindClassToMoveFunctionTo(function); |
| 26 | + |
| 27 | + if (@class == null || |
| 28 | + @class.TranslationUnit.Module != function.TranslationUnit.Module) |
17 | 29 | return false; |
18 | 30 |
|
19 | | - var @class = FindClassToMoveFunctionTo(function.Namespace); |
20 | | - if (@class != null && @class.TranslationUnit.Module == function.TranslationUnit.Module) |
| 31 | + // Create a new fake method so it acts as a static method. |
| 32 | + var method = new Method(function) |
| 33 | + { |
| 34 | + Namespace = @class, |
| 35 | + OperatorKind = function.OperatorKind, |
| 36 | + OriginalFunction = null, |
| 37 | + IsStatic = true |
| 38 | + }; |
| 39 | + if (method.IsOperator) |
21 | 40 | { |
22 | | - MoveFunction(function, @class); |
23 | | - Diagnostics.Debug("Function moved to class: {0}::{1}", @class.Name, function.Name); |
| 41 | + method.IsNonMemberOperator = true; |
| 42 | + method.Kind = CXXMethodKind.Operator; |
24 | 43 | } |
25 | 44 |
|
26 | | - if (function.IsOperator) |
27 | | - function.ExplicitlyIgnore(); |
| 45 | + function.ExplicitlyIgnore(); |
| 46 | + |
| 47 | + @class.Methods.Add(method); |
| 48 | + |
| 49 | + Diagnostics.Debug($"Function {function.Name} moved to class {@class.Name}"); |
28 | 50 |
|
29 | 51 | return true; |
30 | 52 | } |
31 | 53 |
|
32 | | - private Class FindClassToMoveFunctionTo(INamedDecl @namespace) |
| 54 | + private Class FindClassToMoveFunctionTo(Function function) |
33 | 55 | { |
34 | | - var unit = @namespace as TranslationUnit; |
35 | | - if (unit == null) |
| 56 | + Class @class = null; |
| 57 | + if (function.IsOperator) |
36 | 58 | { |
37 | | - return ASTContext.FindClass( |
38 | | - @namespace.Name, ignoreCase: true).FirstOrDefault(); |
| 59 | + foreach (var param in function.Parameters) |
| 60 | + { |
| 61 | + if (FunctionToInstanceMethodPass.GetClassParameter(param, out @class)) |
| 62 | + break; |
| 63 | + } |
| 64 | + if (@class == null) |
| 65 | + function.ExplicitlyIgnore(); |
39 | 66 | } |
40 | | - return ASTContext.FindCompleteClass( |
41 | | - unit.FileNameWithoutExtension.ToLowerInvariant(), true); |
42 | | - } |
43 | | - |
44 | | - private static void MoveFunction(Function function, Class @class) |
45 | | - { |
46 | | - var method = new Method(function) |
| 67 | + else |
47 | 68 | { |
48 | | - Namespace = @class, |
49 | | - IsStatic = true |
50 | | - }; |
51 | | - |
52 | | - function.ExplicitlyIgnore(); |
53 | | - |
54 | | - if (method.OperatorKind != CXXOperatorKind.None) |
55 | | - { |
56 | | - var param = function.Parameters[0]; |
57 | | - Class type; |
58 | | - if (!FunctionToInstanceMethodPass.GetClassParameter(param, out type)) |
59 | | - return; |
60 | | - method.Kind = CXXMethodKind.Operator; |
61 | | - method.IsNonMemberOperator = true; |
62 | | - method.OriginalFunction = null; |
| 69 | + var unit = function.Namespace as TranslationUnit; |
| 70 | + @class = unit == null |
| 71 | + ? ASTContext.FindClass( |
| 72 | + function.Namespace.Name, ignoreCase: true).FirstOrDefault() |
| 73 | + : ASTContext.FindCompleteClass( |
| 74 | + unit.FileNameWithoutExtension.ToLowerInvariant(), true); |
63 | 75 | } |
64 | 76 |
|
65 | | - @class.Methods.Add(method); |
| 77 | + return @class; |
66 | 78 | } |
67 | 79 | } |
68 | 80 | } |
0 commit comments