diff --git a/examples/SDL/SDL.cs b/examples/SDL/SDL.cs index 9b9f85d5..ccd8d090 100644 --- a/examples/SDL/SDL.cs +++ b/examples/SDL/SDL.cs @@ -14,13 +14,13 @@ namespace CppSharp options.OutputDir = "SDL"; } - public void SetupPasses(Driver driver, PassBuilder passes) + public void SetupPasses(Driver driver) { - passes.RemovePrefix("SDL_"); - passes.RemovePrefix("SCANCODE_"); - passes.RemovePrefix("SDLK_"); - passes.RemovePrefix("KMOD_"); - passes.RemovePrefix("LOG_CATEGORY_"); + driver.TranslationUnitPasses.RemovePrefix("SDL_"); + driver.TranslationUnitPasses.RemovePrefix("SCANCODE_"); + driver.TranslationUnitPasses.RemovePrefix("SDLK_"); + driver.TranslationUnitPasses.RemovePrefix("KMOD_"); + driver.TranslationUnitPasses.RemovePrefix("LOG_CATEGORY_"); } public void Preprocess(Driver driver, Library lib) diff --git a/src/Generator.Tests/Passes/TestPasses.cs b/src/Generator.Tests/Passes/TestPasses.cs index 50b75664..4bb1bc9e 100644 --- a/src/Generator.Tests/Passes/TestPasses.cs +++ b/src/Generator.Tests/Passes/TestPasses.cs @@ -7,7 +7,7 @@ namespace Generator.Tests.Passes [TestFixture] public class TestPasses : HeaderTestFixture { - private PassBuilder passBuilder; + private PassBuilder passBuilder; [TestFixtureSetUp] public void Init() @@ -18,7 +18,7 @@ namespace Generator.Tests.Passes public void Setup() { ParseLibrary("Passes.h"); - passBuilder = new PassBuilder(Driver); + passBuilder = new PassBuilder(Driver); } [Test] @@ -30,8 +30,9 @@ namespace Generator.Tests.Passes var @enum2 = Library.Enum("FlagEnum2"); Assert.IsFalse(@enum2.IsFlags); - passBuilder.CheckFlagEnums(); - passBuilder.RunPasses(); + passBuilder.AddPass(new CheckFlagEnumsPass()); + foreach (var pass in passBuilder.Passes) + pass.VisitLibrary(Library); Assert.IsTrue(@enum.IsFlags); Assert.IsFalse(@enum2.IsFlags); @@ -44,8 +45,9 @@ namespace Generator.Tests.Passes Assert.IsNull(c.Method("Start")); - passBuilder.FunctionToInstanceMethod(); - passBuilder.RunPasses(); + passBuilder.AddPass( new FunctionToInstanceMethodPass()); + foreach (var pass in passBuilder.Passes) + pass.VisitLibrary(Library); Assert.IsNotNull(c.Method("Start")); } @@ -58,8 +60,9 @@ namespace Generator.Tests.Passes Assert.IsFalse(Library.Function("FooStart").ExplicityIgnored); Assert.IsNull(c.Method("Start")); - passBuilder.FunctionToStaticMethod(); - passBuilder.RunPasses(); + passBuilder.AddPass(new FunctionToStaticMethodPass()); + foreach (var pass in passBuilder.Passes) + pass.VisitLibrary(Library); Assert.IsTrue(Library.Function("FooStart").ExplicityIgnored); Assert.IsNotNull(c.Method("Start")); @@ -74,7 +77,8 @@ namespace Generator.Tests.Passes var field = c.Field("lowerCaseField"); passBuilder.RenameDeclsUpperCase(RenameTargets.Any); - passBuilder.RunPasses(); + foreach (var pass in passBuilder.Passes) + pass.VisitLibrary(Library); Assert.That(method.Name, Is.EqualTo("LowerCaseMethod")); Assert.That(field.Name, Is.EqualTo("LowerCaseField")); @@ -89,8 +93,9 @@ namespace Generator.Tests.Passes Assert.IsNotNull(@enum); passBuilder.RemovePrefix("TEST_ENUM_ITEM_NAME_", RenameTargets.EnumItem); - passBuilder.CleanInvalidDeclNames(); - passBuilder.RunPasses(); + passBuilder.AddPass(new CleanInvalidDeclNamesPass()); + foreach (var pass in passBuilder.Passes) + pass.VisitLibrary(Library); Assert.That(@enum.Items[0].Name, Is.EqualTo("_0")); } diff --git a/src/Generator/Driver.cs b/src/Generator/Driver.cs index b1bcbe84..8576d7ca 100644 --- a/src/Generator/Driver.cs +++ b/src/Generator/Driver.cs @@ -30,7 +30,8 @@ namespace CppSharp public IDiagnosticConsumer Diagnostics { get; private set; } public Parser Parser { get; private set; } public TypeMapDatabase TypeDatabase { get; private set; } - public PassBuilder Passes { get; private set; } + public PassBuilder TranslationUnitPasses { get; private set; } + public PassBuilder GeneratorOutputPasses { get; private set; } public Generator Generator { get; private set; } public Library Library { get; private set; } @@ -44,7 +45,8 @@ namespace CppSharp Parser.OnHeaderParsed += OnFileParsed; Parser.OnLibraryParsed += OnFileParsed; TypeDatabase = new TypeMapDatabase(); - Passes = new PassBuilder(this); + TranslationUnitPasses = new PassBuilder(this); + GeneratorOutputPasses = new PassBuilder(this); } static void ValidateOptions(DriverOptions options) @@ -120,27 +122,28 @@ namespace CppSharp return true; } - public void AddPrePasses() - { - Passes.CleanUnit(Options); - Passes.SortDeclarations(); - Passes.ResolveIncompleteDecls(); - Passes.CheckIgnoredDecls(); - } + public void SetupPasses(ILibrary library) + { + TranslationUnitPasses.AddPass(new CleanUnitPass(Options)); + TranslationUnitPasses.AddPass(new SortDeclarationsPass()); + TranslationUnitPasses.AddPass(new ResolveIncompleteDeclsPass()); + TranslationUnitPasses.AddPass(new CheckIgnoredDeclsPass()); - public void AddPostPasses() - { - Passes.CleanInvalidDeclNames(); - Passes.CheckIgnoredDecls(); - Passes.CheckFlagEnums(); - Passes.CheckDuplicateNames(); - Generator.SetupPasses(Passes); + library.SetupPasses(this); + + TranslationUnitPasses.AddPass(new CleanInvalidDeclNamesPass()); + TranslationUnitPasses.AddPass(new CheckIgnoredDeclsPass()); + TranslationUnitPasses.AddPass(new CheckFlagEnumsPass()); + TranslationUnitPasses.AddPass(new CheckDuplicatedNamesPass()); } public void ProcessCode() { - foreach (var pass in Passes.Passes) + foreach (var pass in TranslationUnitPasses.Passes) + { + pass.Driver = this; pass.VisitLibrary(Library); + } Generator.Process(); } @@ -174,6 +177,16 @@ namespace CppSharp } } } + + public void AddTranslationUnitPass(TranslationUnitPass pass) + { + TranslationUnitPasses.AddPass(pass); + } + + public void AddGeneratorOutputPass(GeneratorOutputPass pass) + { + GeneratorOutputPasses.AddPass(pass); + } } public class DriverOptions @@ -273,15 +286,23 @@ namespace CppSharp Console.WriteLine("Processing code..."); library.Preprocess(driver, driver.Library); - driver.AddPrePasses(); - library.SetupPasses(driver, driver.Passes); - driver.AddPostPasses(); + driver.SetupPasses(library); driver.ProcessCode(); library.Postprocess(driver.Library); Console.WriteLine("Generating code..."); var outputs = driver.GenerateCode(); + + foreach (var output in outputs) + { + foreach (var pass in driver.GeneratorOutputPasses.Passes) + { + pass.Driver = driver; + pass.VisitGeneratorOutput(output); + } + } + driver.WriteCode(outputs); } } diff --git a/src/Generator/Generators/CLI/CLIGenerator.cs b/src/Generator/Generators/CLI/CLIGenerator.cs index 2f79c4aa..23d91c68 100644 --- a/src/Generator/Generators/CLI/CLIGenerator.cs +++ b/src/Generator/Generators/CLI/CLIGenerator.cs @@ -30,7 +30,7 @@ namespace CppSharp.Generators.CLI return outputs; } - public override bool SetupPasses(PassBuilder builder) + public override bool SetupPasses() { return true; } diff --git a/src/Generator/Generators/CSharp/CSharpGenerator.cs b/src/Generator/Generators/CSharp/CSharpGenerator.cs index 30d75eea..34a3cd7e 100644 --- a/src/Generator/Generators/CSharp/CSharpGenerator.cs +++ b/src/Generator/Generators/CSharp/CSharpGenerator.cs @@ -26,10 +26,10 @@ namespace CppSharp.Generators.CSharp return outputs; } - public override bool SetupPasses(PassBuilder builder) + public override bool SetupPasses() { - builder.CheckAbiParameters(Driver.Options); - builder.CheckOperatorOverloads(); + Driver.AddTranslationUnitPass(new CheckAbiParameters(Driver.Options)); + Driver.AddTranslationUnitPass(new CheckOperatorsOverloadsPass()); return true; } diff --git a/src/Generator/Generators/Generator.cs b/src/Generator/Generators/Generator.cs index 7c86c1bf..87a05003 100644 --- a/src/Generator/Generators/Generator.cs +++ b/src/Generator/Generators/Generator.cs @@ -49,7 +49,7 @@ namespace CppSharp.Generators /// /// Setup any generator-specific passes here. /// - public abstract bool SetupPasses(PassBuilder builder); + public abstract bool SetupPasses(); /// /// Setup any generator-specific processing here. diff --git a/src/Generator/Library.cs b/src/Generator/Library.cs index b64e02ac..4b0ff9b5 100644 --- a/src/Generator/Library.cs +++ b/src/Generator/Library.cs @@ -31,8 +31,7 @@ namespace CppSharp /// Setup your passes here. /// /// - /// - void SetupPasses(Driver driver, PassBuilder passes); + void SetupPasses(Driver driver); } public static class LibraryHelpers diff --git a/src/Generator/Passes/CheckAbiParameters.cs b/src/Generator/Passes/CheckAbiParameters.cs index 1133605d..3db69393 100644 --- a/src/Generator/Passes/CheckAbiParameters.cs +++ b/src/Generator/Passes/CheckAbiParameters.cs @@ -49,14 +49,4 @@ namespace CppSharp.Passes return needsMSHiddenPtr || options.IsItaniumAbi; } } - - public static class CheckAbiParametersExtensions - { - public static void CheckAbiParameters(this PassBuilder builder, - DriverOptions options) - { - var pass = new CheckAbiParameters(options); - builder.AddPass(pass); - } - } } diff --git a/src/Generator/Passes/CheckDuplicatedNamesPass.cs b/src/Generator/Passes/CheckDuplicatedNamesPass.cs index 1f9b2b95..22597bc4 100644 --- a/src/Generator/Passes/CheckDuplicatedNamesPass.cs +++ b/src/Generator/Passes/CheckDuplicatedNamesPass.cs @@ -137,13 +137,4 @@ namespace CppSharp.Passes Driver.Diagnostics.EmitWarning("Duplicate name {0}, renamed to {1}", fullName, decl.Name); } } - - public static class CheckDuplicateNamesExtensions - { - public static void CheckDuplicateNames(this PassBuilder builder) - { - var pass = new CheckDuplicatedNamesPass(); - builder.AddPass(pass); - } - } } diff --git a/src/Generator/Passes/CheckFlagEnumsPass.cs b/src/Generator/Passes/CheckFlagEnumsPass.cs index 3bb09989..be9d7fd4 100644 --- a/src/Generator/Passes/CheckFlagEnumsPass.cs +++ b/src/Generator/Passes/CheckFlagEnumsPass.cs @@ -3,7 +3,7 @@ using CppSharp.AST; namespace CppSharp.Passes { - class CheckFlagEnumsPass : TranslationUnitPass + public class CheckFlagEnumsPass : TranslationUnitPass { static bool IsFlagEnum(Enumeration @enum) { @@ -43,13 +43,4 @@ namespace CppSharp.Passes return base.VisitEnumDecl(@enum); } } - - public static class CheckFlagEnumsExtensions - { - public static void CheckFlagEnums(this PassBuilder builder) - { - var pass = new CheckFlagEnumsPass(); - builder.AddPass(pass); - } - } } diff --git a/src/Generator/Passes/CheckIgnoredDecls.cs b/src/Generator/Passes/CheckIgnoredDecls.cs index 11598ab6..8577857f 100644 --- a/src/Generator/Passes/CheckIgnoredDecls.cs +++ b/src/Generator/Passes/CheckIgnoredDecls.cs @@ -285,13 +285,4 @@ namespace CppSharp.Passes #endregion } - - public static class CheckIgnoredDeclsPassExtensions - { - public static void CheckIgnoredDecls(this PassBuilder builder) - { - var pass = new CheckIgnoredDeclsPass(); - builder.AddPass(pass); - } - } } diff --git a/src/Generator/Passes/CheckOperatorsOverloads.cs b/src/Generator/Passes/CheckOperatorsOverloads.cs index 7c6006b6..f7218326 100644 --- a/src/Generator/Passes/CheckOperatorsOverloads.cs +++ b/src/Generator/Passes/CheckOperatorsOverloads.cs @@ -198,13 +198,4 @@ namespace CppSharp.Passes } } } - - public static class CheckOperatorsOverloadsExtensions - { - public static void CheckOperatorOverloads(this PassBuilder builder) - { - var pass = new CheckOperatorsOverloadsPass(); - builder.AddPass(pass); - } - } } diff --git a/src/Generator/Passes/CleanInvalidDeclNamesPass.cs b/src/Generator/Passes/CleanInvalidDeclNamesPass.cs index 490913b6..d69f42ea 100644 --- a/src/Generator/Passes/CleanInvalidDeclNamesPass.cs +++ b/src/Generator/Passes/CleanInvalidDeclNamesPass.cs @@ -93,14 +93,5 @@ namespace CppSharp.Passes return base.VisitEnumItem(item); } } - - public static class CleanInvalidDeclNamesExtensions - { - public static void CleanInvalidDeclNames(this PassBuilder builder) - { - var pass = new CleanInvalidDeclNamesPass(); - builder.AddPass(pass); - } - } } diff --git a/src/Generator/Passes/CleanUnitPass.cs b/src/Generator/Passes/CleanUnitPass.cs index f0421faa..62240f3e 100644 --- a/src/Generator/Passes/CleanUnitPass.cs +++ b/src/Generator/Passes/CleanUnitPass.cs @@ -5,7 +5,6 @@ namespace CppSharp.Passes public class CleanUnitPass : TranslationUnitPass { public DriverOptions DriverOptions; - public PassBuilder Passes; public CleanUnitPass(DriverOptions options) { @@ -43,13 +42,4 @@ namespace CppSharp.Passes return includePath.Replace('\\', '/'); } } - - public static class CleanUnitPassExtensions - { - public static void CleanUnit(this PassBuilder builder, DriverOptions options) - { - var pass = new CleanUnitPass(options); - builder.AddPass(pass); - } - } } \ No newline at end of file diff --git a/src/Generator/Passes/FunctionToInstanceMethodPass.cs b/src/Generator/Passes/FunctionToInstanceMethodPass.cs index e169947d..6a0871b4 100644 --- a/src/Generator/Passes/FunctionToInstanceMethodPass.cs +++ b/src/Generator/Passes/FunctionToInstanceMethodPass.cs @@ -85,13 +85,4 @@ namespace CppSharp.Passes return false; } } - - public static class FunctionToInstanceMethodExtensions - { - public static void FunctionToInstanceMethod(this PassBuilder builder) - { - var pass = new FunctionToInstanceMethodPass(); - builder.AddPass(pass); - } - } } diff --git a/src/Generator/Passes/FunctionToStaticMethodPass.cs b/src/Generator/Passes/FunctionToStaticMethodPass.cs index f7bc833b..e53e81b8 100644 --- a/src/Generator/Passes/FunctionToStaticMethodPass.cs +++ b/src/Generator/Passes/FunctionToStaticMethodPass.cs @@ -57,13 +57,4 @@ namespace CppSharp.Passes return true; } } - - public static class FunctionToStaticMethodExtensions - { - public static void FunctionToStaticMethod(this PassBuilder builder) - { - var pass = new FunctionToStaticMethodPass(); - builder.AddPass(pass); - } - } } diff --git a/src/Generator/Passes/ObjectOverridesPass.cs b/src/Generator/Passes/ObjectOverridesPass.cs index bf3e5f71..15a284af 100644 --- a/src/Generator/Passes/ObjectOverridesPass.cs +++ b/src/Generator/Passes/ObjectOverridesPass.cs @@ -19,16 +19,21 @@ namespace CppSharp if (!method.IsSynthetized) continue; + var @class = (Class) method.Namespace; + switch (method.Name) { case "GetHashCode": block.Write("return (int)NativePtr;"); break; case "Equals": - + var cliTypePrinter = new CLITypePrinter(Driver); + var classCliType = @class.Visit(cliTypePrinter); block.WriteLine("if (!object) return false;"); - block.Write("return Instance == safe_cast({0})->Instance;", - method.Parameters[0].Name); + block.WriteLine("auto obj = dynamic_cast<{0}>({1});", + classCliType, method.Parameters[0].Name); + block.WriteLine("if (!obj) return false;"); + block.Write("return Instance == obj->Instance;"); break; } } diff --git a/src/Generator/Passes/Pass.cs b/src/Generator/Passes/Pass.cs index c4f4dd4b..a102dcf5 100644 --- a/src/Generator/Passes/Pass.cs +++ b/src/Generator/Passes/Pass.cs @@ -1,5 +1,6 @@  using CppSharp.AST; +using CppSharp.Generators; namespace CppSharp.Passes { @@ -14,6 +15,7 @@ namespace CppSharp.Passes public virtual bool VisitLibrary(Library library) { + Library = library; foreach (var unit in library.TranslationUnits) VisitTranslationUnit(unit); @@ -44,4 +46,17 @@ namespace CppSharp.Passes return decl.ExcludeFromPasses.Contains(type); } } + + /// + /// Used to modify generated output. + /// + public abstract class GeneratorOutputPass + { + public Driver Driver { get; set; } + + public virtual void VisitGeneratorOutput(GeneratorOutput output) + { + + } + } } diff --git a/src/Generator/Passes/PassBuilder.cs b/src/Generator/Passes/PassBuilder.cs index 1f446f4b..9b136e20 100644 --- a/src/Generator/Passes/PassBuilder.cs +++ b/src/Generator/Passes/PassBuilder.cs @@ -8,36 +8,25 @@ namespace CppSharp /// This class is used to build passes that will be run against the AST /// that comes from C++. /// - public class PassBuilder + public class PassBuilder { - public List Passes { get; private set; } + public List Passes { get; private set; } public Driver Driver { get; private set; } public PassBuilder(Driver driver) { - Passes = new List(); + Passes = new List(); Driver = driver; } /// /// Adds a new pass to the builder. /// - public void AddPass(TranslationUnitPass pass) + public void AddPass(T pass) { - pass.Driver = Driver; - pass.Library = Driver.Library; Passes.Add(pass); } - /// - /// Runs the passes in the builder. - /// - public void RunPasses() - { - foreach (var pass in Passes) - pass.VisitLibrary(Driver.Library); - } - /// /// Finds a previously-added pass of the given type. /// diff --git a/src/Generator/Passes/RenamePass.cs b/src/Generator/Passes/RenamePass.cs index ab553830..70953f0e 100644 --- a/src/Generator/Passes/RenamePass.cs +++ b/src/Generator/Passes/RenamePass.cs @@ -242,33 +242,33 @@ namespace CppSharp.Passes public static class RenamePassExtensions { - public static void RenameWithPattern(this PassBuilder builder, + public static void RenameWithPattern(this PassBuilder builder, string pattern, string replacement, RenameTargets targets) { builder.AddPass(new RegexRenamePass(pattern, replacement, targets)); } - public static void RemovePrefix(this PassBuilder builder, string prefix, + public static void RemovePrefix(this PassBuilder builder, string prefix, RenameTargets targets = RenameTargets.Any) { builder.AddPass(new RegexRenamePass("^" + prefix, string.Empty, targets)); } - public static void RenameDeclsCase(this PassBuilder builder, + public static void RenameDeclsCase(this PassBuilder builder, RenameTargets targets, RenameCasePattern pattern) { builder.AddPass(new CaseRenamePass(targets, pattern)); } - public static void RenameDeclsUpperCase(this PassBuilder builder, + public static void RenameDeclsUpperCase(this PassBuilder builder, RenameTargets targets) { builder.AddPass(new CaseRenamePass(targets, RenameCasePattern.UpperCamelCase)); } - public static void RenameDeclsLowerCase(this PassBuilder builder, + public static void RenameDeclsLowerCase(this PassBuilder builder, RenameTargets targets) { builder.AddPass(new CaseRenamePass(targets, diff --git a/src/Generator/Passes/ResolveIncompleteDeclsPass.cs b/src/Generator/Passes/ResolveIncompleteDeclsPass.cs index f3b73c56..6486a122 100644 --- a/src/Generator/Passes/ResolveIncompleteDeclsPass.cs +++ b/src/Generator/Passes/ResolveIncompleteDeclsPass.cs @@ -31,13 +31,4 @@ namespace CppSharp.Passes return base.VisitClassDecl(@class); } } - - public static class ResolveIncompleteDeclsExtensions - { - public static void ResolveIncompleteDecls(this PassBuilder builder) - { - var pass = new ResolveIncompleteDeclsPass(); - builder.AddPass(pass); - } - } } diff --git a/src/Generator/Passes/SortDeclarationsPass.cs b/src/Generator/Passes/SortDeclarationsPass.cs index 2b30e1ce..172b8831 100644 --- a/src/Generator/Passes/SortDeclarationsPass.cs +++ b/src/Generator/Passes/SortDeclarationsPass.cs @@ -25,13 +25,4 @@ namespace CppSharp.Passes return true; } } - - public static class SortDeclarationsExtensions - { - public static void SortDeclarations(this PassBuilder builder) - { - var pass = new SortDeclarationsPass(); - builder.AddPass(pass); - } - } } diff --git a/src/Generator/Types/CppTypePrinter.cs b/src/Generator/Types/CppTypePrinter.cs index 15a9aed9..22345d8b 100644 --- a/src/Generator/Types/CppTypePrinter.cs +++ b/src/Generator/Types/CppTypePrinter.cs @@ -212,7 +212,7 @@ namespace CppSharp.Types public string VisitParameterDecl(Parameter parameter) { - throw new NotImplementedException(); + return VisitParameter(parameter, hasName: false); } public string VisitTypedefDecl(TypedefDecl typedef) diff --git a/src/Generator/Utils/TestsUtils.cs b/src/Generator/Utils/TestsUtils.cs index 10bf26cd..23a139ba 100644 --- a/src/Generator/Utils/TestsUtils.cs +++ b/src/Generator/Utils/TestsUtils.cs @@ -42,7 +42,7 @@ namespace CppSharp.Utils { } - public virtual void SetupPasses(Driver driver, PassBuilder passes) + public virtual void SetupPasses(Driver driver) { } }