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

14
src/Generator/Driver.cs

@ -32,6 +32,18 @@ namespace CppSharp @@ -32,6 +32,18 @@ namespace CppSharp
public ASTContext ASTContext { 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)
{
Options = options;
@ -279,6 +291,8 @@ namespace CppSharp @@ -279,6 +291,8 @@ namespace CppSharp
if (Options.GeneratePropertiesAdvanced)
TranslationUnitPasses.AddPass(new GetterSetterToPropertyAdvancedPass());
TranslationUnitPasses.AddPass(new RenameRootNamespacesPass());
}
public void ProcessCode()

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

@ -105,6 +105,43 @@ namespace CppSharp.Generators.CSharp @@ -105,6 +105,43 @@ namespace CppSharp.Generators.CSharp
#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)
{
var names = new List<string> { decl.Name };
@ -633,7 +670,7 @@ namespace CppSharp.Generators.CSharp @@ -633,7 +670,7 @@ namespace CppSharp.Generators.CSharp
bases.AddRange(
from @base in @class.Bases
where @base.IsClass
select QualifiedIdentifier(@base.Class));
select QualifiedIdentifierIfNeeded(@class, @base.Class));
}
if (@class.IsGenerated)
@ -1781,7 +1818,7 @@ namespace CppSharp.Generators.CSharp @@ -1781,7 +1818,7 @@ namespace CppSharp.Generators.CSharp
var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType;
if (hasBaseClass)
WriteLineIndent(": base(({0}.Internal*) native{1})",
@class.BaseClass.Name, @class.IsAbstractImpl ? ", true" : string.Empty);
QualifiedIdentifierIfNeeded(@class, @class.BaseClass), @class.IsAbstractImpl ? ", true" : string.Empty);
WriteStartBraceIndent();
@ -1828,7 +1865,7 @@ namespace CppSharp.Generators.CSharp @@ -1828,7 +1865,7 @@ namespace CppSharp.Generators.CSharp
// Allocate memory for a new native object and call the ctor.
WriteLine("var ret = Marshal.AllocHGlobal({0});", @class.Layout.Size);
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);
}
else
@ -2243,7 +2280,7 @@ namespace CppSharp.Generators.CSharp @@ -2243,7 +2280,7 @@ namespace CppSharp.Generators.CSharp
if (construct == null)
{
WriteLine("var {0} = new {1}.Internal();", GeneratedIdentifier("ret"),
QualifiedIdentifier(retClass.OriginalClass ?? retClass));
QualifiedIdentifierIfNeeded(function, retClass.OriginalClass ?? retClass));
}
else
{

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

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

39
src/Generator/Passes/RenameRootNamespaces.cs

@ -0,0 +1,39 @@ @@ -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 @@ -32,7 +32,5 @@ namespace CppSharp.Tests
{
ConsoleDriver.Run(new NamespacesBaseTests(GeneratorKind.CSharp));
}
}
}

23
tests/NamespacesBase/NamespacesBase.h

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

56
tests/NamespacesDerived/NamespacesDerived.cpp

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

49
tests/NamespacesDerived/NamespacesDerived.h

@ -1,13 +1,60 @@ @@ -1,13 +1,60 @@
#include "../Tests.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
{
public:
Derived();
Base component;
Base baseComponent;
Base getBase();
void setBase(Base);
OverlappingNamespace::InBaseLib nestedNSComponent;
OverlappingNamespace::InBaseLib getNestedNSComponent();
void setNestedNSComponent(OverlappingNamespace::InBaseLib);
OverlappingNamespace::ColorsEnum color;
private:
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 @@ @@ -1,4 +1,4 @@
group "Tests/Namespaces"
SetupTestGeneratorProject("NamespacesDerived")
SetupTestNativeProject("NamespacesDerived", "NamespacesBase.Native")
SetupTestProjectsCSharp("NamespacesDerived", "NamespacesBase.CSharp")
SetupTestGeneratorProject("NamespacesDerived", "NamespacesBase")
SetupTestNativeProject("NamespacesDerived", "NamespacesBase")
SetupTestProjectsCSharp("NamespacesDerived", "NamespacesBase")
Loading…
Cancel
Save