|
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