Browse Source

Merge pull request #646 from ddobrev/master

Added support for directly wrapping entire sets of interdependent libraries
pull/656/head
João Matos 10 years ago
parent
commit
d4768e883a
  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