Tools and libraries to glue C/C++ APIs to high-level languages
 
 
 
 
 

88 lines
3.0 KiB

using System.Linq;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators;
namespace CppSharp.Passes
{
/// <summary>
/// This pass will try to hoist functions into classes so they
/// work just like instance methods.
/// </summary>
public class FunctionToInstanceMethodPass : TranslationUnitPass
{
public override bool VisitMethodDecl(Method method)
{
return true;
}
public override bool VisitFunctionDecl(Function function)
{
if (!function.IsGenerated)
return false;
// Check if this function can be converted.
if (function.Parameters.Count == 0)
return false;
var classParam = function.Parameters[0];
Class @class;
if (!GetClassParameter(classParam, out @class))
return false;
// If we reach here, it means the first parameter is of class type.
// This means we can change the function to be an instance method.
// Clean up the name of the function now that it will be an instance method.
if (!function.Name.StartsWith(@class.Name, System.StringComparison.Ordinal))
return false;
function.Name = function.Name.Substring(@class.Name.Length);
function.ExplicitlyIgnore();
// Create a new fake method so it acts as an instance method.
var method = new Method
{
Namespace = @class,
OriginalNamespace = function.Namespace,
Name = function.Name,
OriginalName = function.OriginalName,
Mangled = function.Mangled,
Access = AccessSpecifier.Public,
Kind = CXXMethodKind.Normal,
ReturnType = function.ReturnType,
CallingConvention = function.CallingConvention,
IsVariadic = function.IsVariadic,
IsInline = function.IsInline,
Conversion = MethodConversionKind.FunctionToInstanceMethod,
FunctionType = function.FunctionType
};
method.Parameters.AddRange(function.Parameters.Select(
p => new Parameter(p) { Namespace = method }));
if (Options.GeneratorKind == GeneratorKind.CSharp)
method.Parameters.RemoveAt(0);
@class.Methods.Add(method);
Diagnostics.Debug("Function converted to instance method: {0}::{1}", @class.Name,
function.Name);
return true;
}
public static bool GetClassParameter(Parameter classParam, out Class @class)
{
TagType tag;
if (classParam.Type.IsPointerTo(out tag))
{
@class = tag.Declaration as Class;
return true;
}
return classParam.Type.TryGetClass(out @class);
}
}
}