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
public string GetQualifiedName(Func<Declaration, string> getName, public string GetQualifiedName(Func<Declaration, string> getName,
Func<Declaration, DeclarationContext> getNamespace) Func<Declaration, DeclarationContext> getNamespace)
{ {
if (Namespace == null) DeclarationContext declarationContext = getNamespace(this);
if (declarationContext == null)
return getName(this); return getName(this);
if (Namespace.IsRoot) if (declarationContext.IsRoot)
return getName(this); return getName(this);
var namespaces = GatherNamespaces(getNamespace(this)); var namespaces = GatherNamespaces(declarationContext);
var names = namespaces.Select(getName).ToList(); var names = namespaces.Select(getName).ToList();
names.Add(getName(this)); names.Add(getName(this));

1
src/Generator/Driver.cs

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

56
src/Generator/Passes/MoveNonScopedNestedEnumsToParentPass.cs

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

15
tests/Common/Common.Tests.cs

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

11
tests/Common/Common.h

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

Loading…
Cancel
Save