Browse Source

Move non-scoped enums nested in classes to their parents

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1187/head
Dimitar Dobrev 6 years ago
parent
commit
fcb35e5536
  1. 8
      src/AST/Declaration.cs
  2. 1
      src/Generator/Driver.cs
  3. 56
      src/Generator/Passes/MoveNonScopedNestedEnumsToParentPass.cs
  4. 18
      tests/CSharp/CSharp.Tests.cs
  5. 15
      tests/Common/Common.Tests.cs
  6. 10
      tests/Common/Common.cpp
  7. 11
      tests/Common/Common.h

8
src/AST/Declaration.cs

@ -201,13 +201,15 @@ namespace CppSharp.AST @@ -201,13 +201,15 @@ namespace CppSharp.AST
public string GetQualifiedName(Func<Declaration, string> getName,
Func<Declaration, DeclarationContext> getNamespace)
{
if (Namespace == null)
DeclarationContext declarationContext = getNamespace(this);
if (declarationContext == null)
return getName(this);
if (Namespace.IsRoot)
if (declarationContext.IsRoot)
return getName(this);
var namespaces = GatherNamespaces(getNamespace(this));
var namespaces = GatherNamespaces(declarationContext);
var names = namespaces.Select(getName).ToList();
names.Add(getName(this));

1
src/Generator/Driver.cs

@ -235,6 +235,7 @@ namespace CppSharp @@ -235,6 +235,7 @@ namespace CppSharp
TranslationUnitPasses.AddPass(new FindSymbolsPass());
TranslationUnitPasses.AddPass(new CheckMacroPass());
TranslationUnitPasses.AddPass(new CheckStaticClass());
TranslationUnitPasses.AddPass(new MoveNonScopedNestedEnumsToParentPass());
TranslationUnitPasses.AddPass(new MoveOperatorToClassPass());
TranslationUnitPasses.AddPass(new MoveFunctionToClassPass());
TranslationUnitPasses.AddPass(new CheckAmbiguousFunctions());

56
src/Generator/Passes/MoveNonScopedNestedEnumsToParentPass.cs

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
using CppSharp.AST;
using System.Collections.Generic;
using System.Linq;
namespace CppSharp.Passes
{
/// <summary>
/// This pass moves old-style (non-scoped) enumerations nested in classes
/// to the parents of those classes.
/// </summary>
/// <remarks>
/// Such enums are presumably written this way because C++ before 11
/// could not scope enums and nesting was the only way to do so
/// in order to prevent conflicts. But target languages don't have
/// this limitation so we can generate a more sensible API.
/// </remarks>
public class MoveNonScopedNestedEnumsToParentPass : TranslationUnitPass
{
public override bool VisitASTContext(ASTContext context)
{
bool result = base.VisitASTContext(context);
foreach (var movableEnum in movableEnums)
{
DeclarationContext declarationContext = movableEnum.Namespace;
declarationContext.Declarations.Remove(movableEnum);
declarationContext.Namespace.Declarations.Add(movableEnum);
movableEnum.Namespace = declarationContext.Namespace;
}
return result;
}
public override bool VisitEnumDecl(Enumeration @enum)
{
if (!base.VisitEnumDecl(@enum))
return false;
if (string.IsNullOrEmpty(@enum.Name) ||
!(@enum.Namespace is Class) ||
@enum.Access != AccessSpecifier.Public ||
@enum.IsScoped)
return false;
if (@enum.Namespace.Namespace.Declarations.Union(movableEnums).Any(
e => e.Name == @enum.Name))
return false;
movableEnums.Add(@enum);
return true;
}
private readonly List<Enumeration> movableEnums = new List<Enumeration>();
}
}

18
tests/CSharp/CSharp.Tests.cs

@ -38,10 +38,10 @@ public unsafe class CSharpTests : GeneratorTestFixture @@ -38,10 +38,10 @@ public unsafe class CSharpTests : GeneratorTestFixture
new HasCtorWithMappedToEnum<TestFlag>(TestFlag.Flag1).Dispose();
using (var testOverrideFromSecondaryBase = new TestOverrideFromSecondaryBase())
{
testOverrideFromSecondaryBase.function();
testOverrideFromSecondaryBase.Function();
var ok = false;
testOverrideFromSecondaryBase.function(ref ok);
var property = testOverrideFromSecondaryBase.property;
testOverrideFromSecondaryBase.Function(ref ok);
var property = testOverrideFromSecondaryBase.Property;
testOverrideFromSecondaryBase.VirtualMember();
}
using (var foo = new Foo())
@ -670,12 +670,12 @@ public unsafe class CSharpTests : GeneratorTestFixture @@ -670,12 +670,12 @@ public unsafe class CSharpTests : GeneratorTestFixture
{
using (var proprietor = new Proprietor())
{
Assert.That(proprietor.Items, Is.EqualTo(Bar.Items.Item1));
proprietor.Items = Bar.Items.Item2;
Assert.That(proprietor.Items, Is.EqualTo(Bar.Items.Item2));
Assert.That(proprietor.ItemsByValue, Is.EqualTo(Bar.Items.Item1));
proprietor.ItemsByValue = Bar.Items.Item2;
Assert.That(proprietor.ItemsByValue, Is.EqualTo(Bar.Items.Item2));
Assert.That(proprietor.Items, Is.EqualTo(Items.Item1));
proprietor.Items = Items.Item2;
Assert.That(proprietor.Items, Is.EqualTo(Items.Item2));
Assert.That(proprietor.ItemsByValue, Is.EqualTo(Items.Item1));
proprietor.ItemsByValue = Items.Item2;
Assert.That(proprietor.ItemsByValue, Is.EqualTo(Items.Item2));
}
}

15
tests/Common/Common.Tests.cs

@ -19,11 +19,11 @@ public class CommonTests : GeneratorTestFixture @@ -19,11 +19,11 @@ public class CommonTests : GeneratorTestFixture
Assert.That(changedAccessOfInheritedProperty.Property, Is.EqualTo(2));
}
Foo.NestedAbstract a;
var renamedEmptyEnum = Foo.RenamedEmptyEnum.EmptyEnum1;
var renamedEmptyEnum = RenamedEmptyEnum.EmptyEnum1;
using (var foo = new Foo())
{
Bar bar = foo;
Assert.IsTrue(Bar.Item.Item1 == bar);
Assert.IsTrue(Item.Item1 == bar);
using (var hasOverloadsWithDifferentPointerKindsToSameType =
new HasOverloadsWithDifferentPointerKindsToSameType())
@ -101,7 +101,7 @@ public class CommonTests : GeneratorTestFixture @@ -101,7 +101,7 @@ public class CommonTests : GeneratorTestFixture
var bar = new Bar { A = 4, B = 7 };
Assert.That(hello.AddBar(bar), Is.EqualTo(11));
Assert.That(bar.RetItem1(), Is.EqualTo(Bar.Item.Item1));
Assert.That(bar.RetItem1(), Is.EqualTo(Item.Item1));
var retFoo = hello.RetFoo(7, 2.0f);
Assert.That(retFoo.A, Is.EqualTo(7));
@ -245,7 +245,7 @@ public class CommonTests : GeneratorTestFixture @@ -245,7 +245,7 @@ public class CommonTests : GeneratorTestFixture
{
var foo2 = new Foo2 { C = 2 };
Foo2 result = foo2 << 3;
foo2.TestKeywordParam(IntPtr.Zero, Bar.Item.Item1, 1);
foo2.TestKeywordParam(IntPtr.Zero, Item.Item1, 1);
Assert.That(result.C, Is.EqualTo(16));
}
@ -501,8 +501,11 @@ public class CommonTests : GeneratorTestFixture @@ -501,8 +501,11 @@ public class CommonTests : GeneratorTestFixture
prop.VirtualSetterReturnsBoolean = 45;
Assert.That(prop.VirtualSetterReturnsBoolean, Is.EqualTo(45));
Assert.That(prop.nestedEnum(), Is.EqualTo(5));
Assert.That(prop.nestedEnum(55), Is.EqualTo(55));
Assert.That(prop.NestedEnum(), Is.EqualTo(5));
Assert.That(prop.NestedEnum(55), Is.EqualTo(55));
Assert.That(prop.nestedScopedEnum(10), Is.EqualTo(10));
Assert.That(prop.nestedScopedEnum(65), Is.EqualTo(65));
}
}

10
tests/Common/Common.cpp

@ -596,6 +596,16 @@ int TestProperties::nestedEnum(int i) @@ -596,6 +596,16 @@ int TestProperties::nestedEnum(int i)
return i;
}
int TestProperties::nestedScopedEnum()
{
return 10;
}
int TestProperties::nestedScopedEnum(int i)
{
return i;
}
HasOverridenSetter::HasOverridenSetter()
{
}

11
tests/Common/Common.h

@ -578,7 +578,13 @@ DLL_API int Function() @@ -578,7 +578,13 @@ DLL_API int Function()
struct DLL_API TestProperties
{
public:
enum class NestedEnum
enum NestedEnum
{
Value1,
Value2
};
enum class NestedScopedEnum
{
Value1,
Value2
@ -609,6 +615,9 @@ public: @@ -609,6 +615,9 @@ public:
int nestedEnum();
int nestedEnum(int i);
int nestedScopedEnum();
int nestedScopedEnum(int i);
private:
int FieldValue;
double _refToPrimitiveInSetter;

Loading…
Cancel
Save