Browse Source

Merge pull request #408 from golddranks/fix_namespaces_3

Fix namespaces 3
pull/413/head
João Matos 11 years ago
parent
commit
d7616213cd
  1. 17
      build/Tests.lua
  2. 14
      src/Generator/Driver.cs
  3. 45
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  4. 3
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  5. 39
      src/Generator/Passes/RenameRootNamespaces.cs
  6. 2
      tests/NamespacesBase/NamespacesBase.cs
  7. 23
      tests/NamespacesBase/NamespacesBase.h
  8. 56
      tests/NamespacesDerived/NamespacesDerived.cpp
  9. 2
      tests/NamespacesDerived/NamespacesDerived.cs
  10. 49
      tests/NamespacesDerived/NamespacesDerived.h
  11. 6
      tests/NamespacesDerived/premake4.lua

17
build/Tests.lua

@ -38,7 +38,7 @@ function SetupManagedTestProject()
SetupManagedProject() SetupManagedProject()
end end
function SetupTestGeneratorProject(name) function SetupTestGeneratorProject(name, depends)
project(name .. ".Gen") project(name .. ".Gen")
SetupManagedTestProject() SetupManagedTestProject()
kind "ConsoleApp" kind "ConsoleApp"
@ -47,14 +47,19 @@ function SetupTestGeneratorProject(name)
dependson { name .. ".Native" } dependson { name .. ".Native" }
links linktable = {
{
"System.Core", "System.Core",
"CppSharp.AST", "CppSharp.AST",
"CppSharp.Generator", "CppSharp.Generator",
"CppSharp.Generator.Tests" "CppSharp.Generator.Tests",
} }
if depends ~= nil then
table.insert(linktable, depends .. ".Gen")
end
links(linktable)
SetupParser() SetupParser()
end end
@ -84,7 +89,7 @@ function SetupTestNativeProject(name, depends)
files { "**.h", "**.cpp" } files { "**.h", "**.cpp" }
if depends ~= nil then if depends ~= nil then
links { depends } links { depends .. ".Native" }
end end
end end
@ -117,7 +122,7 @@ function SetupTestProjectsCSharp(name, depends)
linktable = { "CppSharp.Runtime" } linktable = { "CppSharp.Runtime" }
if depends ~= nil then if depends ~= nil then
table.insert(linktable, depends) table.insert(linktable, depends .. ".CSharp")
end end
links(linktable) links(linktable)

14
src/Generator/Driver.cs

@ -32,6 +32,18 @@ namespace CppSharp
public ASTContext ASTContext { get; private set; } public ASTContext ASTContext { get; private set; }
public SymbolContext Symbols { get; private set; } public SymbolContext Symbols { get; private set; }
public struct TranslationUnitRenameInfo
{
public string translationUnit;
public string rootNamespaceName;
}
public static Dictionary<string, TranslationUnitRenameInfo> RootNamespaceRenames { get; private set; }
static Driver()
{
Driver.RootNamespaceRenames = new Dictionary<string, TranslationUnitRenameInfo>();
}
public Driver(DriverOptions options, IDiagnosticConsumer diagnostics) public Driver(DriverOptions options, IDiagnosticConsumer diagnostics)
{ {
Options = options; Options = options;
@ -279,6 +291,8 @@ namespace CppSharp
if (Options.GeneratePropertiesAdvanced) if (Options.GeneratePropertiesAdvanced)
TranslationUnitPasses.AddPass(new GetterSetterToPropertyAdvancedPass()); TranslationUnitPasses.AddPass(new GetterSetterToPropertyAdvancedPass());
TranslationUnitPasses.AddPass(new RenameRootNamespacesPass());
} }
public void ProcessCode() public void ProcessCode()

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

@ -105,6 +105,43 @@ namespace CppSharp.Generators.CSharp
#region Identifiers #region Identifiers
// Takes a declaration (type, class etc.) that is referenced from a context, and the context.
// If the referenced name needs a qualification in the context, add it. Otherwise, return just the name.
public string QualifiedIdentifierIfNeeded(Declaration context, Declaration reference)
{
var refNames = new Stack<string>();
var ctxNames = new Stack<string>();
var refCtx = reference;
while (refCtx != null)
{
if (!string.IsNullOrWhiteSpace(refCtx.Name))
refNames.Push(refCtx.Name);
refCtx = refCtx.Namespace;
}
var ctxCtx = context;
while (ctxCtx != null)
{
if (!string.IsNullOrWhiteSpace(ctxCtx.Name))
ctxNames.Push(ctxCtx.Name);
ctxCtx = ctxCtx.Namespace;
}
if (context.GenerationKind == GenerationKind.Generate && Options.GenerateLibraryNamespace)
ctxNames.Push(Options.OutputNamespace);
if (reference.GenerationKind == GenerationKind.Generate && Options.GenerateLibraryNamespace)
refNames.Push(Options.OutputNamespace);
while (refNames.Count > 1 && ctxNames.Count > 1 &&refNames.Peek() == ctxNames.Peek())
{
refNames.Pop();
ctxNames.Pop();
}
return string.Join(".", refNames);
}
public string QualifiedIdentifier(Declaration decl) public string QualifiedIdentifier(Declaration decl)
{ {
var names = new List<string> { decl.Name }; var names = new List<string> { decl.Name };
@ -633,7 +670,7 @@ namespace CppSharp.Generators.CSharp
bases.AddRange( bases.AddRange(
from @base in @class.Bases from @base in @class.Bases
where @base.IsClass where @base.IsClass
select QualifiedIdentifier(@base.Class)); select QualifiedIdentifierIfNeeded(@class, @base.Class));
} }
if (@class.IsGenerated) if (@class.IsGenerated)
@ -1781,7 +1818,7 @@ namespace CppSharp.Generators.CSharp
var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType; var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType;
if (hasBaseClass) if (hasBaseClass)
WriteLineIndent(": base(({0}.Internal*) native{1})", WriteLineIndent(": base(({0}.Internal*) native{1})",
@class.BaseClass.Name, @class.IsAbstractImpl ? ", true" : string.Empty); QualifiedIdentifierIfNeeded(@class, @class.BaseClass), @class.IsAbstractImpl ? ", true" : string.Empty);
WriteStartBraceIndent(); WriteStartBraceIndent();
@ -1828,7 +1865,7 @@ namespace CppSharp.Generators.CSharp
// Allocate memory for a new native object and call the ctor. // Allocate memory for a new native object and call the ctor.
WriteLine("var ret = Marshal.AllocHGlobal({0});", @class.Layout.Size); WriteLine("var ret = Marshal.AllocHGlobal({0});", @class.Layout.Size);
WriteLine("{0}.Internal.{1}(ret, new global::System.IntPtr(&native));", WriteLine("{0}.Internal.{1}(ret, new global::System.IntPtr(&native));",
QualifiedIdentifier(@class), GetFunctionNativeIdentifier(copyCtorMethod)); QualifiedIdentifierIfNeeded(@class, @class), GetFunctionNativeIdentifier(copyCtorMethod));
WriteLine("return ({0}.Internal*) ret;", className); WriteLine("return ({0}.Internal*) ret;", className);
} }
else else
@ -2243,7 +2280,7 @@ namespace CppSharp.Generators.CSharp
if (construct == null) if (construct == null)
{ {
WriteLine("var {0} = new {1}.Internal();", GeneratedIdentifier("ret"), WriteLine("var {0} = new {1}.Internal();", GeneratedIdentifier("ret"),
QualifiedIdentifier(retClass.OriginalClass ?? retClass)); QualifiedIdentifierIfNeeded(function, retClass.OriginalClass ?? retClass));
} }
else else
{ {

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

@ -551,9 +551,6 @@ namespace CppSharp.Generators.CSharp
var ctx = decl.Namespace; var ctx = decl.Namespace;
while (ctx != null) while (ctx != null)
{ {
if (ctx is TranslationUnit)
break;
if (!string.IsNullOrWhiteSpace(ctx.Name)) if (!string.IsNullOrWhiteSpace(ctx.Name))
names.Add(ctx.Name); names.Add(ctx.Name);

39
src/Generator/Passes/RenameRootNamespaces.cs

@ -0,0 +1,39 @@
using CppSharp.AST;
using System;
using System.Collections.Generic;
namespace CppSharp.Passes
{
// This pass visits all the translation units and checks if they originate from library being processed or
// from some other library that is being depended upon. It will rename the root namespaces of all the "foreign"
// libraries so that there wouldn't be clashes and so that the code generation phase would be able to generate
// names with fully qualified namespace prefixes.
public class RenameRootNamespacesPass : TranslationUnitPass
{
public override bool VisitTranslationUnit(TranslationUnit unit)
{
if (!base.VisitTranslationUnit(unit))
return false;
var fileName = unit.TranslationUnit.FileName;
if (Driver.RootNamespaceRenames.ContainsKey(fileName))
{
var rootNamespace = Driver.RootNamespaceRenames[fileName].rootNamespaceName;
if (this.Driver.Options.OutputNamespace != rootNamespace)
unit.Name = rootNamespace;
}
else if (unit.GenerationKind == GenerationKind.Generate)
{
Driver.RootNamespaceRenames.Add(fileName, new Driver.TranslationUnitRenameInfo
{
translationUnit = fileName,
rootNamespaceName = Driver.Options.OutputNamespace,
});
}
return true;
}
}
}

2
tests/NamespacesBase/NamespacesBase.cs

@ -32,7 +32,5 @@ namespace CppSharp.Tests
{ {
ConsoleDriver.Run(new NamespacesBaseTests(GeneratorKind.CSharp)); ConsoleDriver.Run(new NamespacesBaseTests(GeneratorKind.CSharp));
} }
} }
} }

23
tests/NamespacesBase/NamespacesBase.h

@ -1,5 +1,28 @@
#include "../Tests.h" #include "../Tests.h"
namespace OverlappingNamespace
{
enum ColorsEnum {
white,
black,
red,
blue,
green,
};
class InBaseLib
{
public:
InBaseLib()
{
};
};
}
class DLL_API Base class DLL_API Base
{ {
public: public:

56
tests/NamespacesDerived/NamespacesDerived.cpp

@ -1,6 +1,60 @@
#include "NamespacesDerived.h" #include "NamespacesDerived.h"
Derived::Derived() : Base(10), component(5) OverlappingNamespace::InDerivedLib::InDerivedLib() : parentNSComponent(), color(black)
{ {
} }
Derived::Derived() : Base(10), baseComponent(5), nestedNSComponent(), color(OverlappingNamespace::blue)
{
}
Base Derived::getBase()
{
return baseComponent;
}
void Derived::setBase(Base b)
{
baseComponent = b;
}
OverlappingNamespace::InBaseLib Derived::getNestedNSComponent()
{
return nestedNSComponent;
}
void Derived::setNestedNSComponent(OverlappingNamespace::InBaseLib c)
{
nestedNSComponent = c;
}
Base2::Base2()
{
}
Derived2::Derived2() : Base2()
{
}
Base2 Derived2::getBase()
{
return baseComponent;
}
void Derived2::setBase(Base2 b)
{
baseComponent = b;
}
OverlappingNamespace::InDerivedLib Derived2::getNestedNSComponent()
{
return nestedNSComponent;
}
void Derived2::setNestedNSComponent(OverlappingNamespace::InDerivedLib c)
{
nestedNSComponent = c;
}

2
tests/NamespacesDerived/NamespacesDerived.cs

@ -15,7 +15,6 @@ namespace CppSharp.Tests
public override void SetupPasses(Driver driver) public override void SetupPasses(Driver driver)
{ {
driver.Options.DependentNameSpaces.Add("NamespacesBase");
} }
public override void Preprocess(Driver driver, ASTContext ctx) public override void Preprocess(Driver driver, ASTContext ctx)
@ -39,6 +38,7 @@ namespace CppSharp.Tests
public static void Main(string[] args) public static void Main(string[] args)
{ {
ConsoleDriver.Run(new NamespacesBaseTests(GeneratorKind.CSharp));
ConsoleDriver.Run(new NamespacesDerivedTests(GeneratorKind.CSharp)); ConsoleDriver.Run(new NamespacesDerivedTests(GeneratorKind.CSharp));
} }

49
tests/NamespacesDerived/NamespacesDerived.h

@ -1,13 +1,60 @@
#include "../Tests.h" #include "../Tests.h"
#include "../NamespacesBase/NamespacesBase.h" #include "../NamespacesBase/NamespacesBase.h"
// Namespace clashes with NamespacesBase.OverlappingNamespace
// Test whether qualified names turn out right.
namespace OverlappingNamespace
{
class InDerivedLib
{
public:
InDerivedLib();
Base parentNSComponent;
ColorsEnum color;
};
}
// Using a type imported from a different library.
class DLL_API Derived : public Base class DLL_API Derived : public Base
{ {
public: public:
Derived(); Derived();
Base component; Base baseComponent;
Base getBase();
void setBase(Base);
OverlappingNamespace::InBaseLib nestedNSComponent;
OverlappingNamespace::InBaseLib getNestedNSComponent();
void setNestedNSComponent(OverlappingNamespace::InBaseLib);
OverlappingNamespace::ColorsEnum color;
private: private:
int d; int d;
}; };
// For reference: using a type derived in the same library
class Base2
{
public:
Base2();
};
class Derived2 : public Base2
{
public:
Derived2();
Base2 baseComponent;
Base2 getBase();
void setBase(Base2);
OverlappingNamespace::InDerivedLib nestedNSComponent;
OverlappingNamespace::InDerivedLib getNestedNSComponent();
void setNestedNSComponent(OverlappingNamespace::InDerivedLib);
};

6
tests/NamespacesDerived/premake4.lua

@ -1,4 +1,4 @@
group "Tests/Namespaces" group "Tests/Namespaces"
SetupTestGeneratorProject("NamespacesDerived") SetupTestGeneratorProject("NamespacesDerived", "NamespacesBase")
SetupTestNativeProject("NamespacesDerived", "NamespacesBase.Native") SetupTestNativeProject("NamespacesDerived", "NamespacesBase")
SetupTestProjectsCSharp("NamespacesDerived", "NamespacesBase.CSharp") SetupTestProjectsCSharp("NamespacesDerived", "NamespacesBase")
Loading…
Cancel
Save