From f33ca7db8018e9a827cbce71a51cfd2616bfdda4 Mon Sep 17 00:00:00 2001 From: Joao Matos Date: Sat, 20 Feb 2021 20:41:33 +0000 Subject: [PATCH] Add new pass to convert C++ FastDelegate types into CppSharp delegates. --- src/Generator/Driver.cs | 1 + .../Passes/FastDelegateToDelegatesPass.cs | 75 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 src/Generator/Passes/FastDelegateToDelegatesPass.cs diff --git a/src/Generator/Driver.cs b/src/Generator/Driver.cs index 85822f49..9940c4c9 100644 --- a/src/Generator/Driver.cs +++ b/src/Generator/Driver.cs @@ -254,6 +254,7 @@ namespace CppSharp TranslationUnitPasses.AddPass(new FlattenAnonymousTypesToFields()); TranslationUnitPasses.AddPass(new CleanInvalidDeclNamesPass()); + TranslationUnitPasses.AddPass(new FastDelegateToDelegatesPass()); TranslationUnitPasses.AddPass(new FieldToPropertyPass()); TranslationUnitPasses.AddPass(new CheckIgnoredDeclsPass()); TranslationUnitPasses.AddPass(new CheckFlagEnumsPass()); diff --git a/src/Generator/Passes/FastDelegateToDelegatesPass.cs b/src/Generator/Passes/FastDelegateToDelegatesPass.cs new file mode 100644 index 00000000..1ed83421 --- /dev/null +++ b/src/Generator/Passes/FastDelegateToDelegatesPass.cs @@ -0,0 +1,75 @@ +using System; +using System.Linq; +using CppSharp.AST; +using CppSharp.AST.Extensions; +using CppSharp.Passes; +using Type = CppSharp.AST.Type; + +namespace CppSharp +{ + public class FastDelegateToDelegatesPass : TranslationUnitPass + { + static bool IsFastDelegate(Type type) + { + if (!type.TryGetClass(out var @class)) + return false; + + return @class.Name == "FastDelegate"; + } + + public override bool VisitTranslationUnit(TranslationUnit unit) + { + if (unit.FileNameWithoutExtension == "FastDelegates" && + unit.Namespaces.Any(n => n.Name == "fastdelegate")) + { + unit.GenerationKind = GenerationKind.None; + return true; + } + + return base.VisitTranslationUnit(unit); + } + + public override bool VisitFieldDecl(Field field) + { + if (!IsFastDelegate(field.Type)) + return false; + + var templateSpecType = field.Type as TemplateSpecializationType; + if (templateSpecType == null) + throw new Exception("Expected a template specialization type as delegate type"); + + var functionType = templateSpecType.Arguments.First().Type.Type as FunctionType; + if (functionType == null) + throw new Exception("Expected a function type as inner delegate type"); + + var @class = field.Namespace as Class; + var @event = new Event + { + Name = field.Name, + Namespace = @class, + QualifiedType = new QualifiedType(functionType), + GenerationKind = GenerationKind.Generate + }; + + int paramIndex = 0; + foreach (var param in functionType.Parameters) + { + var newParam = new Parameter(param) + { + GenerationKind = GenerationKind.Generate, + }; + + if (string.IsNullOrEmpty(newParam.Name)) + newParam.Name = $"arg{paramIndex}"; + + @event.Parameters.Add(newParam); + paramIndex++; + } + + @class.Declarations.Add(@event); + field.GenerationKind = GenerationKind.None; + + return base.VisitFieldDecl(field); + } + } +} \ No newline at end of file