Skip to content

Commit fcb35e5

Browse files
committed
Move non-scoped enums nested in classes to their parents
Signed-off-by: Dimitar Dobrev <[email protected]>
1 parent 9cad946 commit fcb35e5

File tree

7 files changed

+100
-19
lines changed

7 files changed

+100
-19
lines changed

src/AST/Declaration.cs

+5-3
Original file line numberDiff line numberDiff line change
@@ -201,13 +201,15 @@ public virtual string LogicalOriginalName
201201
public string GetQualifiedName(Func<Declaration, string> getName,
202202
Func<Declaration, DeclarationContext> getNamespace)
203203
{
204-
if (Namespace == null)
204+
DeclarationContext declarationContext = getNamespace(this);
205+
206+
if (declarationContext == null)
205207
return getName(this);
206208

207-
if (Namespace.IsRoot)
209+
if (declarationContext.IsRoot)
208210
return getName(this);
209211

210-
var namespaces = GatherNamespaces(getNamespace(this));
212+
var namespaces = GatherNamespaces(declarationContext);
211213

212214
var names = namespaces.Select(getName).ToList();
213215
names.Add(getName(this));

src/Generator/Driver.cs

+1
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ public void SetupPasses(ILibrary library)
235235
TranslationUnitPasses.AddPass(new FindSymbolsPass());
236236
TranslationUnitPasses.AddPass(new CheckMacroPass());
237237
TranslationUnitPasses.AddPass(new CheckStaticClass());
238+
TranslationUnitPasses.AddPass(new MoveNonScopedNestedEnumsToParentPass());
238239
TranslationUnitPasses.AddPass(new MoveOperatorToClassPass());
239240
TranslationUnitPasses.AddPass(new MoveFunctionToClassPass());
240241
TranslationUnitPasses.AddPass(new CheckAmbiguousFunctions());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using CppSharp.AST;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace CppSharp.Passes
6+
{
7+
/// <summary>
8+
/// This pass moves old-style (non-scoped) enumerations nested in classes
9+
/// to the parents of those classes.
10+
/// </summary>
11+
/// <remarks>
12+
/// Such enums are presumably written this way because C++ before 11
13+
/// could not scope enums and nesting was the only way to do so
14+
/// in order to prevent conflicts. But target languages don't have
15+
/// this limitation so we can generate a more sensible API.
16+
/// </remarks>
17+
public class MoveNonScopedNestedEnumsToParentPass : TranslationUnitPass
18+
{
19+
public override bool VisitASTContext(ASTContext context)
20+
{
21+
bool result = base.VisitASTContext(context);
22+
23+
foreach (var movableEnum in movableEnums)
24+
{
25+
DeclarationContext declarationContext = movableEnum.Namespace;
26+
declarationContext.Declarations.Remove(movableEnum);
27+
declarationContext.Namespace.Declarations.Add(movableEnum);
28+
movableEnum.Namespace = declarationContext.Namespace;
29+
}
30+
31+
return result;
32+
}
33+
34+
public override bool VisitEnumDecl(Enumeration @enum)
35+
{
36+
if (!base.VisitEnumDecl(@enum))
37+
return false;
38+
39+
if (string.IsNullOrEmpty(@enum.Name) ||
40+
!(@enum.Namespace is Class) ||
41+
@enum.Access != AccessSpecifier.Public ||
42+
@enum.IsScoped)
43+
return false;
44+
45+
if (@enum.Namespace.Namespace.Declarations.Union(movableEnums).Any(
46+
e => e.Name == @enum.Name))
47+
return false;
48+
49+
movableEnums.Add(@enum);
50+
51+
return true;
52+
}
53+
54+
private readonly List<Enumeration> movableEnums = new List<Enumeration>();
55+
}
56+
}

tests/CSharp/CSharp.Tests.cs

+9-9
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ public void TestUncompilableCode()
3838
new HasCtorWithMappedToEnum<TestFlag>(TestFlag.Flag1).Dispose();
3939
using (var testOverrideFromSecondaryBase = new TestOverrideFromSecondaryBase())
4040
{
41-
testOverrideFromSecondaryBase.function();
41+
testOverrideFromSecondaryBase.Function();
4242
var ok = false;
43-
testOverrideFromSecondaryBase.function(ref ok);
44-
var property = testOverrideFromSecondaryBase.property;
43+
testOverrideFromSecondaryBase.Function(ref ok);
44+
var property = testOverrideFromSecondaryBase.Property;
4545
testOverrideFromSecondaryBase.VirtualMember();
4646
}
4747
using (var foo = new Foo())
@@ -670,12 +670,12 @@ public void TestEnumProperty()
670670
{
671671
using (var proprietor = new Proprietor())
672672
{
673-
Assert.That(proprietor.Items, Is.EqualTo(Bar.Items.Item1));
674-
proprietor.Items = Bar.Items.Item2;
675-
Assert.That(proprietor.Items, Is.EqualTo(Bar.Items.Item2));
676-
Assert.That(proprietor.ItemsByValue, Is.EqualTo(Bar.Items.Item1));
677-
proprietor.ItemsByValue = Bar.Items.Item2;
678-
Assert.That(proprietor.ItemsByValue, Is.EqualTo(Bar.Items.Item2));
673+
Assert.That(proprietor.Items, Is.EqualTo(Items.Item1));
674+
proprietor.Items = Items.Item2;
675+
Assert.That(proprietor.Items, Is.EqualTo(Items.Item2));
676+
Assert.That(proprietor.ItemsByValue, Is.EqualTo(Items.Item1));
677+
proprietor.ItemsByValue = Items.Item2;
678+
Assert.That(proprietor.ItemsByValue, Is.EqualTo(Items.Item2));
679679
}
680680
}
681681

tests/Common/Common.Tests.cs

+9-6
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ public unsafe void TestCodeGeneration()
1919
Assert.That(changedAccessOfInheritedProperty.Property, Is.EqualTo(2));
2020
}
2121
Foo.NestedAbstract a;
22-
var renamedEmptyEnum = Foo.RenamedEmptyEnum.EmptyEnum1;
22+
var renamedEmptyEnum = RenamedEmptyEnum.EmptyEnum1;
2323
using (var foo = new Foo())
2424
{
2525
Bar bar = foo;
26-
Assert.IsTrue(Bar.Item.Item1 == bar);
26+
Assert.IsTrue(Item.Item1 == bar);
2727

2828
using (var hasOverloadsWithDifferentPointerKindsToSameType =
2929
new HasOverloadsWithDifferentPointerKindsToSameType())
@@ -101,7 +101,7 @@ public void TestHello()
101101

102102
var bar = new Bar { A = 4, B = 7 };
103103
Assert.That(hello.AddBar(bar), Is.EqualTo(11));
104-
Assert.That(bar.RetItem1(), Is.EqualTo(Bar.Item.Item1));
104+
Assert.That(bar.RetItem1(), Is.EqualTo(Item.Item1));
105105

106106
var retFoo = hello.RetFoo(7, 2.0f);
107107
Assert.That(retFoo.A, Is.EqualTo(7));
@@ -245,7 +245,7 @@ public void TestLeftShiftOperator()
245245
{
246246
var foo2 = new Foo2 { C = 2 };
247247
Foo2 result = foo2 << 3;
248-
foo2.TestKeywordParam(IntPtr.Zero, Bar.Item.Item1, 1);
248+
foo2.TestKeywordParam(IntPtr.Zero, Item.Item1, 1);
249249
Assert.That(result.C, Is.EqualTo(16));
250250
}
251251

@@ -501,8 +501,11 @@ public void TestProperties()
501501
prop.VirtualSetterReturnsBoolean = 45;
502502
Assert.That(prop.VirtualSetterReturnsBoolean, Is.EqualTo(45));
503503

504-
Assert.That(prop.nestedEnum(), Is.EqualTo(5));
505-
Assert.That(prop.nestedEnum(55), Is.EqualTo(55));
504+
Assert.That(prop.NestedEnum(), Is.EqualTo(5));
505+
Assert.That(prop.NestedEnum(55), Is.EqualTo(55));
506+
507+
Assert.That(prop.nestedScopedEnum(10), Is.EqualTo(10));
508+
Assert.That(prop.nestedScopedEnum(65), Is.EqualTo(65));
506509
}
507510
}
508511

tests/Common/Common.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,16 @@ int TestProperties::nestedEnum(int i)
596596
return i;
597597
}
598598

599+
int TestProperties::nestedScopedEnum()
600+
{
601+
return 10;
602+
}
603+
604+
int TestProperties::nestedScopedEnum(int i)
605+
{
606+
return i;
607+
}
608+
599609
HasOverridenSetter::HasOverridenSetter()
600610
{
601611
}

tests/Common/Common.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,13 @@ DLL_API int Function()
578578
struct DLL_API TestProperties
579579
{
580580
public:
581-
enum class NestedEnum
581+
enum NestedEnum
582+
{
583+
Value1,
584+
Value2
585+
};
586+
587+
enum class NestedScopedEnum
582588
{
583589
Value1,
584590
Value2
@@ -609,6 +615,9 @@ struct DLL_API TestProperties
609615

610616
int nestedEnum();
611617
int nestedEnum(int i);
618+
619+
int nestedScopedEnum();
620+
int nestedScopedEnum(int i);
612621
private:
613622
int FieldValue;
614623
double _refToPrimitiveInSetter;

0 commit comments

Comments
 (0)