Browse Source

Added support for directly wrapping entire sets of interdependent libraries.

It's realised by using modules. Users now have to define one module for each library they want wrapped while setting the driver up.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/646/head
Dimitar Dobrev 10 years ago
parent
commit
b41dc261ed
  1. 2
      examples/SDL/SDL.cs
  2. 9
      src/AST/Declaration.cs
  3. 51
      src/AST/Expression.cs
  4. 7
      src/AST/Module.cs
  5. 8
      src/AST/SymbolContext.cs
  6. 9
      src/AST/TranslationUnit.cs
  7. 4
      src/CppParser/Bindings/ParserGen.cs
  8. 12
      src/CppParser/Bootstrap/Bootstrap.cs
  9. 4
      src/Generator.Tests/ASTTestFixture.cs
  10. 2
      src/Generator.Tests/GeneratorTest.cs
  11. 4
      src/Generator.Tests/ReadNativeDependenciesTest.cs
  12. 93
      src/Generator/Driver.cs
  13. 74
      src/Generator/Generator.cs
  14. 3
      src/Generator/Generators/CLI/CLIHeadersTemplate.cs
  15. 2
      src/Generator/Generators/CLI/CLIMarshal.cs
  16. 5
      src/Generator/Generators/CLI/CLITextTemplate.cs
  17. 2
      src/Generator/Generators/CLI/CLITypePrinter.cs
  18. 1
      src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs
  19. 30
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  20. 2
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  21. 49
      src/Generator/Options.cs
  22. 16
      src/Generator/Passes/CleanUnitPass.cs
  23. 50
      src/Generator/Passes/DelegatesPass.cs
  24. 6
      src/Generator/Passes/FixDefaultParamValuesOfOverridesPass.cs
  25. 17
      src/Generator/Passes/GenerateInlinesCodePass.cs
  26. 21
      src/Generator/Passes/GenerateTemplatesCodePass.cs
  27. 5
      src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs
  28. 7
      src/Generator/Passes/HandleDefaultParamValuesPass.cs
  29. 2
      src/Generator/Passes/MoveFunctionToClassPass.cs
  30. 9
      src/Generator/Passes/MoveOperatorToClassPass.cs
  31. 10
      src/Generator/Passes/RenameRootNamespaces.cs
  32. 3
      src/Generator/Types/Types.cs
  33. 11
      tests/NamespacesDerived/NamespacesDerived.cs

2
examples/SDL/SDL.cs

@ -13,7 +13,7 @@ namespace CppSharp
options.LibraryName = "SDL"; options.LibraryName = "SDL";
options.Headers.Add("SDL.h"); options.Headers.Add("SDL.h");
var sdlPath = Path.Combine(GetExamplesDirectory("SDL"), "SDL-2.0/include"); var sdlPath = Path.Combine(GetExamplesDirectory("SDL"), "SDL-2.0/include");
options.Module.IncludeDirs.Add(sdlPath); options.addIncludeDirs(sdlPath);
options.OutputDir = "SDL"; options.OutputDir = "SDL";
} }

9
src/AST/Declaration.cs

@ -41,11 +41,7 @@ namespace CppSharp.AST
/// <summary> /// <summary>
/// Declaration is generated to be used internally. /// Declaration is generated to be used internally.
/// </summary> /// </summary>
Internal, Internal
/// <summary>
/// Declaration was already generated in a linked assembly.
/// </summary>
Link,
} }
/// <summary> /// <summary>
@ -252,8 +248,7 @@ namespace CppSharp.AST
{ {
var k = GenerationKind; var k = GenerationKind;
return k == GenerationKind.Generate return k == GenerationKind.Generate
|| k == GenerationKind.Internal || k == GenerationKind.Internal;
|| k == GenerationKind.Link;
} }
} }

51
src/AST/Expression.cs

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace CppSharp.AST namespace CppSharp.AST
{ {
@ -7,6 +9,8 @@ namespace CppSharp.AST
public string DebugText; public string DebugText;
public abstract TV Visit<TV>(IExpressionVisitor<TV> visitor); public abstract TV Visit<TV>(IExpressionVisitor<TV> visitor);
public abstract Expression Clone();
} }
public class BuiltinTypeExpression : Expression public class BuiltinTypeExpression : Expression
@ -39,6 +43,19 @@ namespace CppSharp.AST
{ {
return visitor.VisitExpression(this); return visitor.VisitExpression(this);
} }
public override Expression Clone()
{
return new BuiltinTypeExpression
{
Value = this.Value,
Type = this.Type,
DebugText = this.DebugText,
Class = this.Class,
Declaration = this.Declaration,
String = this.String
};
}
} }
public class BinaryOperator : Expression public class BinaryOperator : Expression
@ -59,6 +76,16 @@ namespace CppSharp.AST
{ {
return visitor.VisitExpression(this); return visitor.VisitExpression(this);
} }
public override Expression Clone()
{
return new BinaryOperator(LHS.Clone(), RHS.Clone(), OpcodeStr)
{
DebugText = this.DebugText,
Declaration = this.Declaration,
String = this.String
};
}
} }
public class CallExpr : Expression public class CallExpr : Expression
@ -75,6 +102,18 @@ namespace CppSharp.AST
{ {
return visitor.VisitExpression(this); return visitor.VisitExpression(this);
} }
public override Expression Clone()
{
var clone = new CallExpr
{
DebugText = this.DebugText,
Declaration = this.Declaration,
String = this.String
};
clone.Arguments.AddRange(Arguments.Select(a => a.Clone()));
return clone;
}
} }
public class CXXConstructExpr : Expression public class CXXConstructExpr : Expression
@ -91,6 +130,18 @@ namespace CppSharp.AST
{ {
return visitor.VisitExpression(this); return visitor.VisitExpression(this);
} }
public override Expression Clone()
{
var clone = new CXXConstructExpr
{
DebugText = this.DebugText,
Declaration = this.Declaration,
String = this.String
};
clone.Arguments.AddRange(Arguments.Select(a => a.Clone()));
return clone;
}
} }
public interface IExpressionVisitor<out T> public interface IExpressionVisitor<out T>

7
src/Generator/Module.cs → src/AST/Module.cs

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace CppSharp namespace CppSharp.AST
{ {
public class Module public class Module
{ {
@ -12,6 +12,8 @@ namespace CppSharp
Libraries = new List<string>(); Libraries = new List<string>();
Defines = new List<string>(); Defines = new List<string>();
Undefines = new List<string>(); Undefines = new List<string>();
Units = new List<TranslationUnit>();
CodeFiles = new List<string>();
} }
public List<string> IncludeDirs { get; private set; } public List<string> IncludeDirs { get; private set; }
@ -22,6 +24,9 @@ namespace CppSharp
public List<string> Undefines { get; set; } public List<string> Undefines { get; set; }
public string OutputNamespace { get; set; } public string OutputNamespace { get; set; }
public List<TranslationUnit> Units { get; private set; }
public List<string> CodeFiles { get; private set; }
public string SharedLibraryName public string SharedLibraryName
{ {
get get

8
src/AST/SymbolContext.cs

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
namespace CppSharp.AST namespace CppSharp.AST
{ {
@ -79,8 +80,9 @@ namespace CppSharp.AST
{ {
foreach (var symbol in library.Symbols) foreach (var symbol in library.Symbols)
{ {
Symbols[symbol] = library; if (!Symbols.ContainsKey(symbol))
if (symbol.StartsWith("__")) Symbols[symbol] = library;
if (symbol.StartsWith("__", StringComparison.Ordinal))
{ {
string stripped = symbol.Substring(1); string stripped = symbol.Substring(1);
if (!Symbols.ContainsKey(stripped)) if (!Symbols.ContainsKey(stripped))

9
src/AST/TranslationUnit.cs

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
@ -24,6 +25,12 @@ namespace CppSharp.AST
/// Contains the macros present in the unit. /// Contains the macros present in the unit.
public List<MacroDefinition> Macros; public List<MacroDefinition> Macros;
public Module Module
{
get { return (Module) module.Target; }
set { module = new WeakReference(value); }
}
public bool IsSystemHeader { get; set; } public bool IsSystemHeader { get; set; }
public bool IsValid { get { return FilePath != "<invalid>"; } } public bool IsValid { get { return FilePath != "<invalid>"; } }
@ -75,5 +82,7 @@ namespace CppSharp.AST
(fileRelativePath = Path.Combine(FileRelativeDirectory, FileName)); (fileRelativePath = Path.Combine(FileRelativeDirectory, FileName));
} }
} }
private WeakReference module;
} }
} }

4
src/CppParser/Bindings/ParserGen.cs

@ -71,8 +71,8 @@ namespace CppSharp
SetupLinuxOptions(options); SetupLinuxOptions(options);
var basePath = Path.Combine(GetSourceDirectory("src"), "CppParser"); var basePath = Path.Combine(GetSourceDirectory("src"), "CppParser");
options.Module.IncludeDirs.Add(basePath); options.addIncludeDirs(basePath);
options.Module.LibraryDirs.Add("."); options.addLibraryDirs(".");
options.OutputDir = Path.Combine(GetSourceDirectory("src"), "CppParser", options.OutputDir = Path.Combine(GetSourceDirectory("src"), "CppParser",
"Bindings", Kind.ToString()); "Bindings", Kind.ToString());

12
src/CppParser/Bootstrap/Bootstrap.cs

@ -42,16 +42,16 @@ namespace CppSharp
options.MicrosoftMode = false; options.MicrosoftMode = false;
options.TargetTriple = "i686-apple-darwin12.4.0"; options.TargetTriple = "i686-apple-darwin12.4.0";
options.Module.Defines.Add("__STDC_LIMIT_MACROS"); options.addDefines ("__STDC_LIMIT_MACROS");
options.Module.Defines.Add("__STDC_CONSTANT_MACROS"); options.addDefines ("__STDC_CONSTANT_MACROS");
var llvmPath = Path.Combine (GetSourceDirectory ("deps"), "llvm"); var llvmPath = Path.Combine (GetSourceDirectory ("deps"), "llvm");
var clangPath = Path.Combine(llvmPath, "tools", "clang"); var clangPath = Path.Combine(llvmPath, "tools", "clang");
options.Module.IncludeDirs.Add(Path.Combine(llvmPath, "include")); options.addIncludeDirs(Path.Combine(llvmPath, "include"));
options.Module.IncludeDirs.Add(Path.Combine(llvmPath, "build", "include")); options.addIncludeDirs(Path.Combine(llvmPath, "build", "include"));
options.Module.IncludeDirs.Add(Path.Combine (llvmPath, "build", "tools", "clang", "include")); options.addIncludeDirs (Path.Combine (llvmPath, "build", "tools", "clang", "include"));
options.Module.IncludeDirs.Add(Path.Combine(clangPath, "include")); options.addIncludeDirs(Path.Combine(clangPath, "include"));
} }
public void SetupPasses(Driver driver) public void SetupPasses(Driver driver)

4
src/Generator.Tests/ASTTestFixture.cs

@ -15,13 +15,11 @@ namespace CppSharp.Generator.Tests
Options = new DriverOptions(); Options = new DriverOptions();
var testsPath = GeneratorTest.GetTestsDirectory("Native"); var testsPath = GeneratorTest.GetTestsDirectory("Native");
Options.Module.IncludeDirs.Add(testsPath); Options.addIncludeDirs(testsPath);
Options.Headers.AddRange(files); Options.Headers.AddRange(files);
Driver = new Driver(Options, new TextDiagnosticPrinter()); Driver = new Driver(Options, new TextDiagnosticPrinter());
foreach (var includeDir in Options.Module.IncludeDirs)
Options.addIncludeDirs(includeDir);
Driver.SetupIncludes(); Driver.SetupIncludes();
Driver.BuildParseOptions(); Driver.BuildParseOptions();
if (!Driver.ParseCode()) if (!Driver.ParseCode())

2
src/Generator.Tests/GeneratorTest.cs

@ -46,7 +46,7 @@ namespace CppSharp.Utils
options.TargetTriple = Environment.Is64BitProcess ? "x86_64-apple-darwin" : "i686-apple-darwin"; options.TargetTriple = Environment.Is64BitProcess ? "x86_64-apple-darwin" : "i686-apple-darwin";
var path = Path.GetFullPath(GetTestsDirectory(name)); var path = Path.GetFullPath(GetTestsDirectory(name));
options.Module.IncludeDirs.Add(path); options.addIncludeDirs(path);
// Remove this hardcoded path once we update our LLVM binary packages to bundle // Remove this hardcoded path once we update our LLVM binary packages to bundle
// the built-in Clang includes. // the built-in Clang includes.

4
src/Generator.Tests/ReadNativeDependenciesTest.cs

@ -38,11 +38,9 @@ namespace CppSharp.Generator.Tests
private static IList<string> GetDependencies(string library) private static IList<string> GetDependencies(string library)
{ {
var driverOptions = new DriverOptions(); var driverOptions = new DriverOptions();
driverOptions.Module.LibraryDirs.Add(GeneratorTest.GetTestsDirectory("Native")); driverOptions.addLibraryDirs(GeneratorTest.GetTestsDirectory("Native"));
driverOptions.Libraries.Add(library); driverOptions.Libraries.Add(library);
var driver = new Driver(driverOptions, new TextDiagnosticPrinter()); var driver = new Driver(driverOptions, new TextDiagnosticPrinter());
foreach (var libraryDir in driverOptions.Module.LibraryDirs)
driverOptions.addLibraryDirs(libraryDir);
Assert.IsTrue(driver.ParseLibraries()); Assert.IsTrue(driver.ParseLibraries());
var dependencies = driver.Symbols.Libraries[0].Dependencies; var dependencies = driver.Symbols.Libraries[0].Dependencies;
return dependencies; return dependencies;

93
src/Generator/Driver.cs

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
using CppSharp.AST; using CppSharp.AST;
using CppSharp.Generators; using CppSharp.Generators;
@ -15,6 +14,7 @@ using Microsoft.CSharp;
using CppSharp.Parser; using CppSharp.Parser;
using System.CodeDom; using System.CodeDom;
using System; using System;
using System.Reflection;
namespace CppSharp namespace CppSharp
{ {
@ -67,15 +67,18 @@ namespace CppSharp
static void ValidateOptions(DriverOptions options) static void ValidateOptions(DriverOptions options)
{ {
if (string.IsNullOrWhiteSpace(options.LibraryName)) foreach (var module in options.Modules)
throw new InvalidOptionException(); {
if (string.IsNullOrWhiteSpace(module.LibraryName))
throw new InvalidOptionException("One of your modules has no library name.");
if (string.IsNullOrWhiteSpace(module.OutputNamespace))
module.OutputNamespace = module.LibraryName;
}
if (options.NoGenIncludeDirs != null) if (options.NoGenIncludeDirs != null)
foreach (var incDir in options.NoGenIncludeDirs) foreach (var incDir in options.NoGenIncludeDirs)
options.addIncludeDirs(incDir); options.addIncludeDirs(incDir);
if (string.IsNullOrWhiteSpace(options.OutputNamespace))
options.OutputNamespace = options.LibraryName;
} }
public void Setup() public void Setup()
@ -194,6 +197,21 @@ namespace CppSharp
options.addLibraryDirs(lib); options.addLibraryDirs(lib);
} }
foreach (var module in Options.Modules.Where(m => m.Headers.Contains(file.Path)))
{
foreach (var include in module.IncludeDirs)
options.addIncludeDirs(include);
foreach (var define in module.Defines)
options.addDefines(define);
foreach (var undefine in module.Undefines)
options.addUndefines(undefine);
foreach (var library in module.Libraries)
options.addLibraryDirs(library);
}
return options; return options;
} }
@ -213,7 +231,7 @@ namespace CppSharp
public void BuildParseOptions() public void BuildParseOptions()
{ {
foreach (var header in Options.Headers) foreach (var header in Options.Modules.SelectMany(m => m.Headers))
{ {
var source = Project.AddFile(header); var source = Project.AddFile(header);
source.Options = BuildParseOptions(source); source.Options = BuildParseOptions(source);
@ -224,7 +242,7 @@ namespace CppSharp
public bool ParseLibraries() public bool ParseLibraries()
{ {
foreach (var library in Options.Libraries) foreach (var library in Options.Modules.SelectMany(m => m.Libraries))
{ {
if (this.Symbols.Libraries.Any(l => l.FileName == library)) if (this.Symbols.Libraries.Any(l => l.FileName == library))
continue; continue;
@ -248,7 +266,6 @@ namespace CppSharp
public void SetupPasses(ILibrary library) public void SetupPasses(ILibrary library)
{ {
TranslationUnitPasses.AddPass(new CleanUnitPass(Options));
TranslationUnitPasses.AddPass(new SortDeclarationsPass()); TranslationUnitPasses.AddPass(new SortDeclarationsPass());
TranslationUnitPasses.AddPass(new ResolveIncompleteDeclsPass()); TranslationUnitPasses.AddPass(new ResolveIncompleteDeclsPass());
TranslationUnitPasses.AddPass(new CheckIgnoredDeclsPass()); TranslationUnitPasses.AddPass(new CheckIgnoredDeclsPass());
@ -290,8 +307,8 @@ namespace CppSharp
TranslationUnitPasses.AddPass(new GenerateAbstractImplementationsPass()); TranslationUnitPasses.AddPass(new GenerateAbstractImplementationsPass());
if (Options.GenerateDefaultValuesForArguments) if (Options.GenerateDefaultValuesForArguments)
{ {
TranslationUnitPasses.AddPass(new HandleDefaultParamValuesPass());
TranslationUnitPasses.AddPass(new FixDefaultParamValuesOfOverridesPass()); TranslationUnitPasses.AddPass(new FixDefaultParamValuesOfOverridesPass());
TranslationUnitPasses.AddPass(new HandleDefaultParamValuesPass());
} }
} }
@ -331,7 +348,7 @@ namespace CppSharp
return Generator.Generate(); return Generator.Generate();
} }
public void SaveCode(List<GeneratorOutput> outputs) public void SaveCode(IEnumerable<GeneratorOutput> outputs)
{ {
var outputPath = Path.GetFullPath(Options.OutputDir); var outputPath = Path.GetFullPath(Options.OutputDir);
@ -352,32 +369,22 @@ namespace CppSharp
if (Options.GenerateName != null) if (Options.GenerateName != null)
fileBase = Options.GenerateName(output.TranslationUnit); fileBase = Options.GenerateName(output.TranslationUnit);
if (Options.IsCSharpGenerator && Options.CompileCode) foreach (var template in output.Templates)
{
compileUnits.AddRange(
output.Templates.Select(t => new CodeSnippetCompileUnit(t.Generate())));
compileUnits.AddRange(
Options.CodeFiles.Select(c => new CodeSnippetCompileUnit(File.ReadAllText(c))));
}
else
{ {
foreach (var template in output.Templates) var fileRelativePath = string.Format("{0}.{1}", fileBase, template.FileExtension);
{ Diagnostics.Message("Generated '{0}'", fileRelativePath);
var fileRelativePath = string.Format("{0}.{1}", fileBase, template.FileExtension);
Diagnostics.Message("Generated '{0}'", fileRelativePath); var file = Path.Combine(outputPath, fileRelativePath);
File.WriteAllText(file, template.Generate());
var file = Path.Combine(outputPath, fileRelativePath); output.TranslationUnit.Module.CodeFiles.Add(file);
File.WriteAllText(file, template.Generate());
Options.CodeFiles.Add(file);
}
} }
} }
} }
public void CompileCode() public void CompileCode(AST.Module module)
{ {
var assemblyFile = string.IsNullOrEmpty(Options.LibraryName) ? var assemblyFile = string.IsNullOrEmpty(module.LibraryName) ?
"out.dll" : Options.LibraryName + ".dll"; "out.dll" : module.LibraryName + ".dll";
var docFile = Path.ChangeExtension(Path.GetFileName(assemblyFile), ".xml"); var docFile = Path.ChangeExtension(Path.GetFileName(assemblyFile), ".xml");
@ -414,8 +421,8 @@ namespace CppSharp
using (var codeProvider = new CSharpCodeProvider( using (var codeProvider = new CSharpCodeProvider(
new Dictionary<string, string> { { "CompilerVersion", "v4.0" } })) new Dictionary<string, string> { { "CompilerVersion", "v4.0" } }))
{ {
compilerResults = codeProvider.CompileAssemblyFromDom( compilerResults = codeProvider.CompileAssemblyFromFile(
compilerParameters, compileUnits.ToArray()); compilerParameters, module.CodeFiles.ToArray());
} }
var errors = compilerResults.Errors.Cast<CompilerError>().Where(e => !e.IsWarning && var errors = compilerResults.Errors.Cast<CompilerError>().Where(e => !e.IsWarning &&
@ -429,7 +436,7 @@ namespace CppSharp
{ {
Diagnostics.Message("Compilation succeeded."); Diagnostics.Message("Compilation succeeded.");
var wrapper = Path.Combine(outputDir, assemblyFile); var wrapper = Path.Combine(outputDir, assemblyFile);
foreach (var library in Options.Libraries) foreach (var library in module.Libraries)
libraryMappings[library] = wrapper; libraryMappings[library] = wrapper;
} }
} }
@ -444,7 +451,6 @@ namespace CppSharp
GeneratorOutputPasses.AddPass(pass); GeneratorOutputPasses.AddPass(pass);
} }
private readonly List<CodeSnippetCompileUnit> compileUnits = new List<CodeSnippetCompileUnit>();
private bool hasParsingErrors; private bool hasParsingErrors;
} }
@ -459,18 +465,6 @@ namespace CppSharp
library.Setup(driver); library.Setup(driver);
foreach (var includeDir in options.Module.IncludeDirs)
options.addIncludeDirs(includeDir);
foreach (var libraryDir in options.Module.LibraryDirs)
options.addLibraryDirs(libraryDir);
foreach (var define in options.Module.Defines)
options.addDefines(define);
foreach (var undefine in options.Module.Undefines)
options.addUndefines(undefine);
driver.Setup(); driver.Setup();
if(driver.Options.Verbose) if(driver.Options.Verbose)
@ -498,6 +492,8 @@ namespace CppSharp
return; return;
} }
new CleanUnitPass(options).VisitLibrary(driver.ASTContext);
if (!options.Quiet) if (!options.Quiet)
Log.Message("Processing code..."); Log.Message("Processing code...");
@ -526,7 +522,8 @@ namespace CppSharp
{ {
driver.SaveCode(outputs); driver.SaveCode(outputs);
if (driver.Options.IsCSharpGenerator && driver.Options.CompileCode) if (driver.Options.IsCSharpGenerator && driver.Options.CompileCode)
driver.CompileCode(); foreach (var module in driver.Options.Modules)
driver.CompileCode(module);
} }
driver.Generator.Dispose(); driver.Generator.Dispose();

74
src/Generator/Generator.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using CppSharp.AST; using CppSharp.AST;
@ -35,6 +36,8 @@ namespace CppSharp.Generators
/// </summary> /// </summary>
public abstract class Generator : IDisposable public abstract class Generator : IDisposable
{ {
public static string CurrentOutputNamespace = string.Empty;
public Driver Driver { get; private set; } public Driver Driver { get; private set; }
protected Generator(Driver driver) protected Generator(Driver driver)
@ -69,50 +72,59 @@ namespace CppSharp.Generators
var outputs = new List<GeneratorOutput>(); var outputs = new List<GeneratorOutput>();
var units = Driver.ASTContext.TranslationUnits.Where( var units = Driver.ASTContext.TranslationUnits.Where(
u => u.IsGenerated && u.HasDeclarations && !u.IsSystemHeader && u.IsValid); u => u.IsGenerated && u.HasDeclarations && !u.IsSystemHeader && u.IsValid).ToList();
if (Driver.Options.IsCSharpGenerator && Driver.Options.GenerateSingleCSharpFile) if (Driver.Options.IsCSharpGenerator && Driver.Options.GenerateSingleCSharpFile)
GenerateSingleTemplate(units, outputs); GenerateSingleTemplate(outputs);
else else
foreach (var unit in units) GenerateTemplates(outputs, units);
GenerateTemplate(unit, outputs);
return outputs; return outputs;
} }
private void GenerateSingleTemplate(IEnumerable<TranslationUnit> units, ICollection<GeneratorOutput> outputs) private void GenerateTemplates(List<GeneratorOutput> outputs, List<TranslationUnit> units)
{ {
var output = new GeneratorOutput foreach (var unit in units)
{ {
TranslationUnit = new TranslationUnit var includeDir = Path.GetDirectoryName(unit.FilePath);
var templates = Generate(new[] { unit });
if (templates.Count == 0)
return;
CurrentOutputNamespace = unit.Module.OutputNamespace;
foreach (var template in templates)
{ {
FilePath = string.Format("{0}.cs", Driver.Options.OutputNamespace ?? Driver.Options.LibraryName) template.Process();
}, }
Templates = Generate(units)
};
output.Templates[0].Process();
outputs.Add(output);
OnUnitGenerated(output);
}
private void GenerateTemplate(TranslationUnit unit, ICollection<GeneratorOutput> outputs) var output = new GeneratorOutput
{ {
var templates = Generate(new[] { unit }); TranslationUnit = unit,
if (templates.Count == 0) Templates = templates
return; };
outputs.Add(output);
foreach (var template in templates) OnUnitGenerated(output);
{
template.Process();
} }
}
var output = new GeneratorOutput private void GenerateSingleTemplate(ICollection<GeneratorOutput> outputs)
{
foreach (var module in Driver.Options.Modules)
{ {
TranslationUnit = unit, CurrentOutputNamespace = module.OutputNamespace;
Templates = templates var output = new GeneratorOutput
}; {
outputs.Add(output); TranslationUnit = new TranslationUnit
{
OnUnitGenerated(output); FilePath = string.Format("{0}.cs", module.OutputNamespace ?? module.LibraryName),
Module = module
},
Templates = Generate(module.Units)
};
output.Templates[0].Process();
outputs.Add(output);
OnUnitGenerated(output);
}
} }
/// <summary> /// <summary>

3
src/Generator/Generators/CLI/CLIHeadersTemplate.cs

@ -99,6 +99,7 @@ namespace CppSharp.Generators.CLI
{ {
// Create a new tree of namespaces out of the type references found. // Create a new tree of namespaces out of the type references found.
var rootNamespace = new TranslationUnit(); var rootNamespace = new TranslationUnit();
rootNamespace.Module = TranslationUnit.Module;
var sortedRefs = typeReferences.ToList(); var sortedRefs = typeReferences.ToList();
sortedRefs.Sort((ref1, ref2) => sortedRefs.Sort((ref1, ref2) =>
@ -192,7 +193,7 @@ namespace CppSharp.Generators.CLI
{ {
PushBlock(CLIBlockKind.Namespace, @namespace); PushBlock(CLIBlockKind.Namespace, @namespace);
WriteLine("namespace {0}", isTopLevel WriteLine("namespace {0}", isTopLevel
? Options.OutputNamespace ? @namespace.TranslationUnit.Module.OutputNamespace
: @namespace.Name); : @namespace.Name);
WriteStartBraceIndent(); WriteStartBraceIndent();
} }

2
src/Generator/Generators/CLI/CLIMarshal.cs

@ -313,7 +313,7 @@ namespace CppSharp.Generators.CLI
public string QualifiedIdentifier(Declaration decl) public string QualifiedIdentifier(Declaration decl)
{ {
if (Context.Driver.Options.GenerateLibraryNamespace) if (Context.Driver.Options.GenerateLibraryNamespace)
return string.Format("{0}::{1}", Context.Driver.Options.OutputNamespace, return string.Format("{0}::{1}", decl.TranslationUnit.Module.OutputNamespace,
decl.QualifiedName); decl.QualifiedName);
return string.Format("{0}", decl.QualifiedName); return string.Format("{0}", decl.QualifiedName);
} }

5
src/Generator/Generators/CLI/CLITextTemplate.cs

@ -84,9 +84,10 @@ namespace CppSharp.Generators.CLI
if (Options.GenerateLibraryNamespace) if (Options.GenerateLibraryNamespace)
{ {
if (string.IsNullOrEmpty(decl.QualifiedName)) if (string.IsNullOrEmpty(decl.QualifiedName))
return string.Format("{0}", Options.OutputNamespace); return string.Format("{0}", decl.TranslationUnit.Module.OutputNamespace);
return string.Format("{0}::{1}", Options.OutputNamespace, decl.QualifiedName); return string.Format("{0}::{1}",
decl.TranslationUnit.Module.OutputNamespace, decl.QualifiedName);
} }
return decl.QualifiedName; return decl.QualifiedName;

2
src/Generator/Generators/CLI/CLITypePrinter.cs

@ -327,7 +327,7 @@ namespace CppSharp.Generators.CLI
string rootNamespace = null; string rootNamespace = null;
if (Options.GenerateLibraryNamespace) if (Options.GenerateLibraryNamespace)
names.Add(rootNamespace = Driver.Options.OutputNamespace); names.Add(rootNamespace = decl.TranslationUnit.Module.OutputNamespace);
if (!string.IsNullOrEmpty(decl.Namespace.QualifiedName)) if (!string.IsNullOrEmpty(decl.Namespace.QualifiedName))
{ {

1
src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs

@ -40,7 +40,6 @@ namespace CppSharp.Generators.CSharp
switch (callExpr.Declaration.GenerationKind) switch (callExpr.Declaration.GenerationKind)
{ {
case GenerationKind.Generate: case GenerationKind.Generate:
case GenerationKind.Link:
return new CSharpExpressionPrinterResult return new CSharpExpressionPrinterResult
{ {
Value = string.Format("{0}.{1}({2})", Value = string.Format("{0}.{1}({2})",

30
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -167,7 +167,7 @@ namespace CppSharp.Generators.CSharp
if (Options.GenerateLibraryNamespace) if (Options.GenerateLibraryNamespace)
{ {
PushBlock(CSharpBlockKind.Namespace); PushBlock(CSharpBlockKind.Namespace);
WriteLine("namespace {0}", Driver.Options.OutputNamespace); WriteLine("namespace {0}", TranslationUnit.Module.OutputNamespace);
WriteStartBraceIndent(); WriteStartBraceIndent();
} }
@ -829,9 +829,9 @@ namespace CppSharp.Generators.CSharp
#endregion #endregion
private Tuple<string, string> GetDeclarationLibrarySymbol(IMangledDecl decl) private Tuple<string, string> GetDeclarationLibrarySymbol(Variable decl)
{ {
var library = Options.SharedLibraryName; var library = decl.TranslationUnit.Module.SharedLibraryName;
if (!Options.CheckSymbols) if (!Options.CheckSymbols)
goto Out; goto Out;
@ -1555,8 +1555,9 @@ namespace CppSharp.Generators.CSharp
return; return;
} }
var typeFullName = TypePrinter.VisitClassDecl(@class); var typeFullName = TypePrinter.VisitClassDecl(@class);
if (!string.IsNullOrEmpty(Driver.Options.OutputNamespace)) if (!string.IsNullOrEmpty(@class.TranslationUnit.Module.OutputNamespace))
typeFullName = string.Format("{0}.{1}", Driver.Options.OutputNamespace, typeFullName); typeFullName = string.Format("{0}.{1}",
@class.TranslationUnit.Module.OutputNamespace, typeFullName);
WriteLine("SetupVTables(GetType().FullName == \"{0}\");", typeFullName); WriteLine("SetupVTables(GetType().FullName == \"{0}\");", typeFullName);
} }
} }
@ -1573,7 +1574,7 @@ namespace CppSharp.Generators.CSharp
for (int i = 0; i < method.Parameters.Count; i++) for (int i = 0; i < method.Parameters.Count; i++)
{ {
var param = method.Parameters[i]; var param = method.Parameters[i];
if (!param.IsGenerated && param.GenerationKind != GenerationKind.Link) if (!param.IsGenerated)
continue; continue;
if (param.Kind == ParameterKind.IndirectReturnType) if (param.Kind == ParameterKind.IndirectReturnType)
@ -1600,7 +1601,7 @@ namespace CppSharp.Generators.CSharp
if (hasReturn) if (hasReturn)
Write("var {0} = ", Helpers.ReturnIdentifier); Write("var {0} = ", Helpers.ReturnIdentifier);
if (method.IsGenerated || method.GenerationKind == GenerationKind.Link) if (method.IsGenerated)
{ {
WriteLine("{0}.{1}({2});", Helpers.TargetIdentifier, WriteLine("{0}.{1}({2});", Helpers.TargetIdentifier,
method.Name, string.Join(", ", marshals)); method.Name, string.Join(", ", marshals));
@ -1682,7 +1683,8 @@ namespace CppSharp.Generators.CSharp
var vTableMethodDelegateName = GetVTableMethodDelegateName(method); var vTableMethodDelegateName = GetVTableMethodDelegateName(method);
WriteLine("private static {0} {1}Instance;", GetDelegateName(Driver.Delegates[method]), WriteLine("private static {0} {1}Instance;",
GetDelegateName(method, @class.TranslationUnit.Module.OutputNamespace),
vTableMethodDelegateName); vTableMethodDelegateName);
NewLine(); NewLine();
@ -2483,13 +2485,15 @@ namespace CppSharp.Generators.CSharp
delegateId = Generator.GeneratedIdentifier(@delegate); delegateId = Generator.GeneratedIdentifier(@delegate);
WriteLine("var {0} = ({1}) Marshal.GetDelegateForFunctionPointer(new IntPtr({2}), typeof({1}));", WriteLine("var {0} = ({1}) Marshal.GetDelegateForFunctionPointer(new IntPtr({2}), typeof({1}));",
delegateId, GetDelegateName(Driver.Delegates[method]), Helpers.SlotIdentifier); delegateId, GetDelegateName(method, method.TranslationUnit.Module.OutputNamespace),
Helpers.SlotIdentifier);
} }
private string GetDelegateName(DelegatesPass.DelegateDefinition @delegate) private string GetDelegateName(Function function, string outputNamespace)
{ {
var @delegate = Driver.Delegates[function];
if (string.IsNullOrWhiteSpace(@delegate.Namespace) || if (string.IsNullOrWhiteSpace(@delegate.Namespace) ||
Driver.Options.OutputNamespace == @delegate.Namespace) outputNamespace == @delegate.Namespace)
{ {
return @delegate.Signature; return @delegate.Signature;
} }
@ -3086,7 +3090,7 @@ namespace CppSharp.Generators.CSharp
PushBlock(CSharpBlockKind.InternalsClassMethod); PushBlock(CSharpBlockKind.InternalsClassMethod);
WriteLine("[SuppressUnmanagedCodeSecurity]"); WriteLine("[SuppressUnmanagedCodeSecurity]");
string libName = Options.SharedLibraryName; string libName = function.TranslationUnit.Module.SharedLibraryName;
if (Options.CheckSymbols) if (Options.CheckSymbols)
{ {
@ -3102,7 +3106,7 @@ namespace CppSharp.Generators.CSharp
libName = libName.Substring(3); libName = libName.Substring(3);
} }
if (libName == null) if (libName == null)
libName = Options.SharedLibraryName; libName = function.TranslationUnit.Module.SharedLibraryName;
if (Options.GenerateInternalImports) if (Options.GenerateInternalImports)
libName = "__Internal"; libName = "__Internal";

2
src/Generator/Generators/CSharp/CSharpTypePrinter.cs

@ -631,7 +631,7 @@ namespace CppSharp.Generators.CSharp
} }
names.Reverse(); names.Reverse();
if (names[0] == driver.Options.OutputNamespace) if (names[0] == Generator.CurrentOutputNamespace)
names.RemoveAt(0); names.RemoveAt(0);
return string.Join(".", names); return string.Join(".", names);
} }

49
src/Generator/Options.cs

@ -27,7 +27,7 @@ namespace CppSharp
OutputDir = Directory.GetCurrentDirectory(); OutputDir = Directory.GetCurrentDirectory();
Module = new Module(); Modules = new List<Module>();
GeneratorKind = GeneratorKind.CSharp; GeneratorKind = GeneratorKind.CSharp;
GenerateLibraryNamespace = true; GenerateLibraryNamespace = true;
@ -39,8 +39,6 @@ namespace CppSharp
Encoding = Encoding.ASCII; Encoding = Encoding.ASCII;
CodeFiles = new List<string>();
StripLibPrefix = true; StripLibPrefix = true;
ExplicitlyPatchedVirtualFunctions = new List<string>(); ExplicitlyPatchedVirtualFunctions = new List<string>();
@ -59,24 +57,34 @@ namespace CppSharp
/// </summary> /// </summary>
public bool DryRun; public bool DryRun;
public List<Module> Modules { get; private set; }
public Module MainModule
{
get
{
if (Modules.Count == 0)
Modules.Add(new Module());
return Modules[0];
}
}
// Parser options // Parser options
public List<string> Headers { get { return Module.Headers; } } public List<string> Headers { get { return MainModule.Headers; } }
public bool IgnoreParseWarnings; public bool IgnoreParseWarnings;
public bool IgnoreParseErrors; public bool IgnoreParseErrors;
public Module Module { get; set; }
public bool IsItaniumLikeAbi { get { return Abi != CppAbi.Microsoft; } } public bool IsItaniumLikeAbi { get { return Abi != CppAbi.Microsoft; } }
public bool IsMicrosoftAbi { get { return Abi == CppAbi.Microsoft; } } public bool IsMicrosoftAbi { get { return Abi == CppAbi.Microsoft; } }
// Library options // Library options
public List<string> Libraries { get { return Module.Libraries; } } public List<string> Libraries { get { return MainModule.Libraries; } }
public bool CheckSymbols; public bool CheckSymbols;
public string SharedLibraryName public string SharedLibraryName
{ {
get { return Module.SharedLibraryName; } get { return MainModule.SharedLibraryName; }
set { Module.SharedLibraryName = value; } set { MainModule.SharedLibraryName = value; }
} }
// Generator options // Generator options
@ -84,16 +92,16 @@ namespace CppSharp
public string OutputNamespace public string OutputNamespace
{ {
get { return Module.OutputNamespace; } get { return MainModule.OutputNamespace; }
set { Module.OutputNamespace = value; } set { MainModule.OutputNamespace = value; }
} }
public string OutputDir; public string OutputDir;
public string LibraryName public string LibraryName
{ {
get { return Module.LibraryName; } get { return MainModule.LibraryName; }
set { Module.LibraryName = value; } set { MainModule.LibraryName = value; }
} }
public bool OutputInteropIncludes; public bool OutputInteropIncludes;
@ -129,7 +137,7 @@ namespace CppSharp
/// <summary> /// <summary>
/// If set to true the CLI generator will use ObjectOverridesPass to create /// If set to true the CLI generator will use ObjectOverridesPass to create
/// Equals, GetHashCode and (if the insertion operator << is overloaded) ToString /// Equals, GetHashCode and (if the insertion operator &lt;&lt; is overloaded) ToString
/// methods. /// methods.
/// </summary> /// </summary>
public bool GenerateObjectOverrides; public bool GenerateObjectOverrides;
@ -158,14 +166,14 @@ namespace CppSharp
public string InlinesLibraryName public string InlinesLibraryName
{ {
get { return Module.InlinesLibraryName; } get { return MainModule.InlinesLibraryName; }
set { Module.InlinesLibraryName = value; } set { MainModule.InlinesLibraryName = value; }
} }
public string TemplatesLibraryName public string TemplatesLibraryName
{ {
get { return Module.TemplatesLibraryName; } get { return MainModule.TemplatesLibraryName; }
set { Module.TemplatesLibraryName = value; } set { MainModule.TemplatesLibraryName = value; }
} }
public bool IsCSharpGenerator public bool IsCSharpGenerator
@ -178,7 +186,6 @@ namespace CppSharp
get { return GeneratorKind == GeneratorKind.CLI; } get { return GeneratorKind == GeneratorKind.CLI; }
} }
public List<string> CodeFiles { get; private set; }
public readonly List<string> DependentNameSpaces = new List<string>(); public readonly List<string> DependentNameSpaces = new List<string>();
public bool MarshalCharAsManagedChar { get; set; } public bool MarshalCharAsManagedChar { get; set; }
/// <summary> /// <summary>
@ -201,5 +208,9 @@ namespace CppSharp
public class InvalidOptionException : Exception public class InvalidOptionException : Exception
{ {
public InvalidOptionException(string message) :
base(message)
{
}
} }
} }

16
src/Generator/Passes/CleanUnitPass.cs

@ -1,3 +1,6 @@
using System;
using System.IO;
using System.Linq;
using CppSharp.AST; using CppSharp.AST;
namespace CppSharp.Passes namespace CppSharp.Passes
@ -13,9 +16,14 @@ namespace CppSharp.Passes
public override bool VisitTranslationUnit(TranslationUnit unit) public override bool VisitTranslationUnit(TranslationUnit unit)
{ {
if (IsExternalDeclaration(unit) && unit.IsGenerated) if (unit.IsValid && !unit.IsSystemHeader && unit.HasDeclarations)
unit.GenerationKind = GenerationKind.Link; {
var includeDir = Path.GetDirectoryName(unit.FilePath);
unit.Module = DriverOptions.Modules.FirstOrDefault(
m => m.IncludeDirs.Contains(includeDir)) ?? DriverOptions.MainModule;
unit.Module.Units.Add(unit);
}
// Try to get an include path that works from the original include // Try to get an include path that works from the original include
// directories paths. // directories paths.
if (unit.IsValid) if (unit.IsValid)
@ -64,7 +72,7 @@ namespace CppSharp.Passes
foreach (var path in DriverOptions.NoGenIncludeDirs) foreach (var path in DriverOptions.NoGenIncludeDirs)
{ {
if (translationUnit.FilePath.StartsWith(path)) if (translationUnit.FilePath.StartsWith(path, StringComparison.Ordinal))
return true; return true;
} }

50
src/Generator/Passes/DelegatesPass.cs

@ -3,8 +3,8 @@ using System.Linq;
using System.Text; using System.Text;
using CppSharp.AST; using CppSharp.AST;
using CppSharp.AST.Extensions; using CppSharp.AST.Extensions;
using CppSharp.Generators;
using CppSharp.Generators.CSharp; using CppSharp.Generators.CSharp;
using System;
namespace CppSharp.Passes namespace CppSharp.Passes
{ {
@ -37,8 +37,8 @@ namespace CppSharp.Passes
public override bool VisitLibrary(ASTContext context) public override bool VisitLibrary(ASTContext context)
{ {
foreach (var library in Driver.Options.Libraries.Where(l => !libsDelegates.ContainsKey(l))) foreach (var library in Driver.Options.Modules.SelectMany(m => m.Libraries))
libsDelegates.Add(library, new Dictionary<string, DelegateDefinition>()); libsDelegates[library] = new Dictionary<string, DelegateDefinition>();
var unit = context.TranslationUnits.LastOrDefault(u => u.IsValid && u.IsGenerated && var unit = context.TranslationUnits.LastOrDefault(u => u.IsValid && u.IsGenerated &&
!u.IsSystemHeader && u.HasDeclarations); !u.IsSystemHeader && u.HasDeclarations);
@ -46,12 +46,10 @@ namespace CppSharp.Passes
if (unit == null) if (unit == null)
return false; return false;
namespaceDelegates = new Namespace { Name = DelegatesNamespace, Namespace = unit };
var result = base.VisitLibrary(context); var result = base.VisitLibrary(context);
if (namespaceDelegates.Declarations.Count > 0) foreach (var module in Driver.Options.Modules.Where(m => namespacesDelegates.ContainsKey(m)))
unit.Declarations.Add(namespaceDelegates); module.Units.Last().Declarations.Add(namespacesDelegates[module]);
return result; return result;
} }
@ -94,6 +92,21 @@ namespace CppSharp.Passes
var @params = method.GatherInternalParams(Driver.Options.IsItaniumLikeAbi, true).ToList(); var @params = method.GatherInternalParams(Driver.Options.IsItaniumLikeAbi, true).ToList();
var delegateName = GenerateDelegateSignature(@params, method.ReturnType); var delegateName = GenerateDelegateSignature(@params, method.ReturnType);
Namespace namespaceDelegates;
if (namespacesDelegates.ContainsKey(method.TranslationUnit.Module))
{
namespaceDelegates = namespacesDelegates[method.TranslationUnit.Module];
}
else
{
namespaceDelegates = new Namespace
{
Name = DelegatesNamespace,
Namespace = method.TranslationUnit.Module.Units.Last()
};
namespacesDelegates.Add(method.TranslationUnit.Module, namespaceDelegates);
}
var @delegate = new TypedefDecl var @delegate = new TypedefDecl
{ {
Name = delegateName, Name = delegateName,
@ -110,17 +123,20 @@ namespace CppSharp.Passes
Namespace = namespaceDelegates Namespace = namespaceDelegates
}; };
Generator.CurrentOutputNamespace = method.TranslationUnit.Module.OutputNamespace;
var delegateString = @delegate.Visit(TypePrinter).Type; var delegateString = @delegate.Visit(TypePrinter).Type;
var existingDelegate = GetExistingDelegate(delegateString); var existingDelegate = GetExistingDelegate(
method.TranslationUnit.Module.Libraries, delegateString);
if (existingDelegate != null) if (existingDelegate != null)
{ {
Driver.Delegates.Add(method, existingDelegate); Driver.Delegates.Add(method, existingDelegate);
return true; return true;
} }
existingDelegate = new DelegateDefinition(Driver.Options.OutputNamespace, delegateString); existingDelegate = new DelegateDefinition(
method.TranslationUnit.Module.OutputNamespace, delegateString);
Driver.Delegates.Add(method, existingDelegate); Driver.Delegates.Add(method, existingDelegate);
foreach (var library in Driver.Options.Libraries) foreach (var library in method.TranslationUnit.Module.Libraries)
libsDelegates[library].Add(delegateString, existingDelegate); libsDelegates[library].Add(delegateString, existingDelegate);
namespaceDelegates.Declarations.Add(@delegate); namespaceDelegates.Declarations.Add(@delegate);
@ -128,16 +144,16 @@ namespace CppSharp.Passes
return true; return true;
} }
private DelegateDefinition GetExistingDelegate(string delegateString) private DelegateDefinition GetExistingDelegate(IList<string> libraries, string delegateString)
{ {
if (Driver.Options.Libraries.Count == 0) if (libraries.Count == 0)
return Driver.Delegates.Values.FirstOrDefault(t => t.Signature == delegateString); return Driver.Delegates.Values.FirstOrDefault(t => t.Signature == delegateString);
DelegateDefinition @delegate = null; DelegateDefinition @delegate = null;
if (Driver.Options.Libraries.Union( if (libraries.Union(
Driver.Symbols.Libraries.SelectMany(l => l.Dependencies)).Any( Driver.Symbols.Libraries.Where(l => libraries.Contains(l.FileName)).SelectMany(
l => libsDelegates.ContainsKey(l) && l => l.Dependencies)).Any(l => libsDelegates.ContainsKey(l) &&
libsDelegates[l].TryGetValue(delegateString, out @delegate))) libsDelegates[l].TryGetValue(delegateString, out @delegate)))
return @delegate; return @delegate;
return null; return null;
@ -183,7 +199,7 @@ namespace CppSharp.Passes
} }
} }
private Namespace namespaceDelegates; private Dictionary<Module, Namespace> namespacesDelegates = new Dictionary<Module, Namespace>();
private CSharpTypePrinter typePrinter; private CSharpTypePrinter typePrinter;
private static readonly Dictionary<string, Dictionary<string, DelegateDefinition>> libsDelegates = private static readonly Dictionary<string, Dictionary<string, DelegateDefinition>> libsDelegates =
new Dictionary<string, Dictionary<string, DelegateDefinition>>(); new Dictionary<string, Dictionary<string, DelegateDefinition>>();

6
src/Generator/Passes/FixDefaultParamValuesOfOverridesPass.cs

@ -11,7 +11,11 @@ namespace CppSharp.Passes
Method rootBaseMethod = ((Class) method.Namespace).GetBaseMethod(method); Method rootBaseMethod = ((Class) method.Namespace).GetBaseMethod(method);
for (int i = 0; i < method.Parameters.Count; i++) for (int i = 0; i < method.Parameters.Count; i++)
{ {
method.Parameters[i].DefaultArgument = rootBaseMethod.Parameters[i].DefaultArgument; if (rootBaseMethod.Parameters[i].DefaultArgument != null)
{
method.Parameters[i].DefaultArgument =
rootBaseMethod.Parameters[i].DefaultArgument.Clone();
}
} }
} }
return base.VisitMethodDecl(method); return base.VisitMethodDecl(method);

17
src/Generator/Passes/GenerateInlinesCodePass.cs

@ -14,13 +14,16 @@ namespace CppSharp.Passes
private void WriteInlinesIncludes() private void WriteInlinesIncludes()
{ {
var cppBuilder = new StringBuilder(); foreach (var module in Driver.Options.Modules)
foreach (var header in Driver.Options.Headers) {
cppBuilder.AppendFormat("#include <{0}>\n", header); var cppBuilder = new StringBuilder();
var cpp = string.Format("{0}.cpp", Driver.Options.InlinesLibraryName); foreach (var header in module.Headers)
Directory.CreateDirectory(Driver.Options.OutputDir); cppBuilder.AppendFormat("#include <{0}>\n", header);
var path = Path.Combine(Driver.Options.OutputDir, cpp); var cpp = string.Format("{0}.cpp", module.InlinesLibraryName);
File.WriteAllText(path, cppBuilder.ToString()); Directory.CreateDirectory(Driver.Options.OutputDir);
var path = Path.Combine(Driver.Options.OutputDir, cpp);
File.WriteAllText(path, cppBuilder.ToString());
}
} }
} }
} }

21
src/Generator/Passes/GenerateTemplatesCodePass.cs

@ -34,15 +34,18 @@ namespace CppSharp.Passes
private void WriteTemplateInstantiations() private void WriteTemplateInstantiations()
{ {
var cppBuilder = new StringBuilder(); foreach (var module in Driver.Options.Modules)
foreach (var header in Driver.Options.Headers) {
cppBuilder.AppendFormat("#include <{0}>\n", header); var cppBuilder = new StringBuilder();
foreach (var templateInstantiation in templateInstantiations) foreach (var header in module.Headers)
cppBuilder.AppendFormat("\ntemplate class {0};", templateInstantiation); cppBuilder.AppendFormat("#include <{0}>\n", header);
var cpp = string.Format("{0}.cpp", Driver.Options.TemplatesLibraryName); foreach (var templateInstantiation in templateInstantiations)
Directory.CreateDirectory(Driver.Options.OutputDir); cppBuilder.AppendFormat("\ntemplate class {0};", templateInstantiation);
var path = Path.Combine(Driver.Options.OutputDir, cpp); var cpp = string.Format("{0}.cpp", module.TemplatesLibraryName);
File.WriteAllText(path, cppBuilder.ToString()); Directory.CreateDirectory(Driver.Options.OutputDir);
var path = Path.Combine(Driver.Options.OutputDir, cpp);
File.WriteAllText(path, cppBuilder.ToString());
}
} }
private HashSet<string> templateInstantiations = new HashSet<string>(); private HashSet<string> templateInstantiations = new HashSet<string>();

5
src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs

@ -25,8 +25,7 @@ namespace CppSharp.Passes
{ {
this.log = log; this.log = log;
foreach (var method in @class.Methods.Where( foreach (var method in @class.Methods.Where(
m => !m.IsConstructor && !m.IsDestructor && !m.IsOperator && m => !m.IsConstructor && !m.IsDestructor && !m.IsOperator && m.IsGenerated))
(m.IsGenerated || m.GenerationKind == GenerationKind.Link)))
DistributeMethod(method); DistributeMethod(method);
} }
@ -37,7 +36,7 @@ namespace CppSharp.Passes
foreach (Method getter in foreach (Method getter in
from getter in getters from getter in getters
where (getter.IsGenerated || getter.GenerationKind == GenerationKind.Link) && where getter.IsGenerated &&
((Class) getter.Namespace).Methods.All(m => m == getter || !m.IsGenerated || m.Name != getter.Name) ((Class) getter.Namespace).Methods.All(m => m == getter || !m.IsGenerated || m.Name != getter.Name)
select getter) select getter)
{ {

7
src/Generator/Passes/HandleDefaultParamValuesPass.cs

@ -37,9 +37,10 @@ namespace CppSharp.Passes
public override bool VisitFunctionDecl(Function function) public override bool VisitFunctionDecl(Function function)
{ {
if (!base.VisitFunctionDecl(function)) if (!base.VisitFunctionDecl(function) || function.TranslationUnit.IsSystemHeader)
return false; return false;
Generator.CurrentOutputNamespace = function.TranslationUnit.Module.OutputNamespace;
var overloadIndices = new List<int>(function.Parameters.Count); var overloadIndices = new List<int>(function.Parameters.Count);
foreach (var parameter in function.Parameters.Where(p => p.DefaultArgument != null)) foreach (var parameter in function.Parameters.Where(p => p.DefaultArgument != null))
{ {
@ -199,14 +200,14 @@ namespace CppSharp.Passes
switch (builtin.Type) switch (builtin.Type)
{ {
case PrimitiveType.Float: case PrimitiveType.Float:
if (statement.String.EndsWith(".F")) if (statement.String.EndsWith(".F", System.StringComparison.Ordinal))
{ {
result = statement.String.Replace(".F", ".0F"); result = statement.String.Replace(".F", ".0F");
return true; return true;
} }
break; break;
case PrimitiveType.Double: case PrimitiveType.Double:
if (statement.String.EndsWith(".")) if (statement.String.EndsWith(".", System.StringComparison.Ordinal))
{ {
result = statement.String + '0'; result = statement.String + '0';
return true; return true;

2
src/Generator/Passes/MoveFunctionToClassPass.cs

@ -17,7 +17,7 @@ namespace CppSharp.Passes
return false; return false;
var @class = FindClassToMoveFunctionTo(function.Namespace); var @class = FindClassToMoveFunctionTo(function.Namespace);
if (@class != null) if (@class != null && @class.TranslationUnit.Module == function.TranslationUnit.Module)
{ {
MoveFunction(function, @class); MoveFunction(function, @class);
Log.Debug("Function moved to class: {0}::{1}", @class.Name, function.Name); Log.Debug("Function moved to class: {0}::{1}", @class.Name, function.Name);

9
src/Generator/Passes/MoveOperatorToClassPass.cs

@ -18,13 +18,12 @@ namespace CppSharp.Passes
Class @class = null; Class @class = null;
foreach (var param in function.Parameters) foreach (var param in function.Parameters)
{ {
FunctionToInstanceMethodPass.GetClassParameter( if (FunctionToInstanceMethodPass.GetClassParameter(param, out @class))
param, out @class); break;
if (@class != null) break;
} }
if (@class == null) if (@class == null ||
@class.TranslationUnit.Module != function.TranslationUnit.Module)
return false; return false;
// Create a new fake method so it acts as a static method. // Create a new fake method so it acts as a static method.

10
src/Generator/Passes/RenameRootNamespaces.cs

@ -11,21 +11,21 @@ namespace CppSharp.Passes
{ {
public override bool VisitTranslationUnit(TranslationUnit unit) public override bool VisitTranslationUnit(TranslationUnit unit)
{ {
if (!base.VisitTranslationUnit(unit)) if (!base.VisitTranslationUnit(unit) || !unit.IsValid ||
unit.IsSystemHeader || !unit.HasDeclarations)
return false; return false;
var fileName = unit.TranslationUnit.FileName; var fileName = unit.TranslationUnit.FileName;
if (rootNamespaceRenames.ContainsKey(fileName)) if (rootNamespaceRenames.ContainsKey(fileName))
{ {
var rootNamespace = rootNamespaceRenames[fileName]; var rootNamespace = rootNamespaceRenames[fileName];
if (this.Driver.Options.OutputNamespace != rootNamespace) unit.Name = rootNamespace;
unit.Name = rootNamespace;
} }
else if (unit.GenerationKind == GenerationKind.Generate) else if (unit.GenerationKind == GenerationKind.Generate)
{ {
if (Driver.Options.IsCSharpGenerator) if (Driver.Options.IsCSharpGenerator)
unit.Name = Driver.Options.OutputNamespace; unit.Name = unit.Module.OutputNamespace;
rootNamespaceRenames.Add(fileName, Driver.Options.OutputNamespace); rootNamespaceRenames.Add(fileName, unit.Module.OutputNamespace);
} }
return true; return true;
} }

3
src/Generator/Types/Types.cs

@ -32,7 +32,8 @@ namespace CppSharp
if (decl.CompleteDeclaration != null) if (decl.CompleteDeclaration != null)
return VisitDeclaration(decl.CompleteDeclaration); return VisitDeclaration(decl.CompleteDeclaration);
if (decl.GenerationKind == GenerationKind.None) if (!(decl is TypedefDecl) && (!decl.IsGenerated ||
(decl is Class && decl.TranslationUnit.IsSystemHeader)))
{ {
Ignore(); Ignore();
return false; return false;

11
tests/NamespacesDerived/NamespacesDerived.cs

@ -19,17 +19,6 @@ namespace CppSharp.Tests
driver.Options.GeneratePropertiesAdvanced = true; driver.Options.GeneratePropertiesAdvanced = true;
} }
public override void Preprocess(Driver driver, ASTContext ctx)
{
foreach (TranslationUnit unit in ctx.TranslationUnits)
{
if (unit.FileName != "NamespacesDerived.h")
{
unit.GenerationKind = GenerationKind.Link;
}
}
}
public override void Postprocess(Driver driver, ASTContext ctx) public override void Postprocess(Driver driver, ASTContext ctx)
{ {
new CaseRenamePass( new CaseRenamePass(

Loading…
Cancel
Save