Skip to content

Commit 9e9ca36

Browse files
committed
Fix Objective-C template parameters used by an inner typedef
1 parent 728e9d3 commit 9e9ca36

File tree

9 files changed

+240
-102
lines changed

9 files changed

+240
-102
lines changed

src/CppAst.Tests/TestObjectiveC.cs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace CppAst.Tests;
99
public class TestObjectiveC : InlineTestBase
1010
{
1111
[Test]
12-
public void TestFoundationIncludes()
12+
public void TestAppKitIncludes()
1313
{
1414
if (!OperatingSystem.IsMacOS())
1515
{
@@ -18,7 +18,7 @@ public void TestFoundationIncludes()
1818
}
1919

2020
ParseAssert("""
21-
#import <Foundation/Foundation.h>
21+
#import <AppKit/AppKit.h>
2222
""",
2323
compilation =>
2424
{
@@ -148,7 +148,6 @@ @interface MyInterface
148148
);
149149
}
150150

151-
152151
[Test]
153152
public void TestInterfaceWithMultipleGenericParameters()
154153
{
@@ -182,6 +181,40 @@ @interface BaseInterface
182181
);
183182
}
184183

184+
185+
[Test]
186+
public void TestInterfaceWithGenericsAndTypedef()
187+
{
188+
ParseAssert("""
189+
@interface BaseInterface
190+
@end
191+
192+
// Generics require a base class
193+
@interface MyInterface<T1> : BaseInterface
194+
typedef T1 HelloWorld;
195+
@end
196+
""",
197+
compilation =>
198+
{
199+
Assert.False(compilation.HasErrors);
200+
Assert.AreEqual(2, compilation.Classes.Count);
201+
var myInterface = compilation.Classes[1];
202+
Assert.AreEqual(CppClassKind.ObjCInterface, myInterface.ClassKind);
203+
Assert.AreEqual("MyInterface", myInterface.Name);
204+
Assert.AreEqual(1, myInterface.TemplateParameters.Count);
205+
Assert.IsTrue(myInterface.TemplateParameters[0] is CppTemplateParameterType templateParam1 && templateParam1.Name == "T1");
206+
207+
// By default, typedef declared within interfaces are global, but in that case, it is depending on a template parameter
208+
// So it is not part of the global namespace
209+
Assert.AreEqual(0, compilation.Typedefs.Count);
210+
Assert.AreEqual(1, myInterface.Typedefs.Count);
211+
var typedef = myInterface.Typedefs[0];
212+
Assert.AreEqual("HelloWorld", typedef.Name);
213+
Assert.IsTrue(typedef.ElementType is CppTemplateParameterType templateSpecialization && templateSpecialization.Name == "T1");
214+
}, GetDefaultObjCOptions()
215+
);
216+
}
217+
185218
[Test]
186219
public void TestBlockFunctionPointer()
187220
{
@@ -275,6 +308,7 @@ @interface InterfaceBase
275308

276309
var myInterfaceBase = compilation.Classes[0];
277310
Assert.AreEqual(CppClassKind.ObjCInterface, myInterfaceBase.ClassKind);
311+
Assert.AreEqual(0, myInterfaceBase.BaseTypes.Count);
278312
Assert.AreEqual("InterfaceBase", myInterfaceBase.Name);
279313

280314
var myInterface = compilation.Classes[1];

src/CppAst/CppClass.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public CppClass(string name) : base(CppTypeKind.StructOrClass)
2828
Enums = new CppContainerList<CppEnum>(this);
2929
Classes = new CppContainerList<CppClass>(this);
3030
Typedefs = new CppContainerList<CppTypedef>(this);
31-
TemplateParameters = new List<CppType>();
31+
TemplateParameters = new CppContainerList<CppType>(this);
3232
Attributes = new List<CppAttribute>();
3333
TokenAttributes = new List<CppAttribute>();
3434
ObjCImplementedProtocols = new List<CppClass>();
@@ -175,7 +175,7 @@ public override string FullName
175175
public List<CppClass> ObjCCategories { get; }
176176

177177
/// <inheritdoc />
178-
public List<CppType> TemplateParameters { get; }
178+
public CppContainerList<CppType> TemplateParameters { get; }
179179

180180
public List<CppTemplateArgument> TemplateSpecializedArguments { get; } = new List<CppTemplateArgument>();
181181

src/CppAst/CppFunction.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Alexandre Mutel. All rights reserved.
1+
// Copyright (c) Alexandre Mutel. All rights reserved.
22
// Licensed under the BSD-Clause 2 license.
33
// See license.txt file in the project root for full license information.
44

@@ -21,7 +21,7 @@ public CppFunction(string name)
2121
{
2222
Name = name;
2323
Parameters = new CppContainerList<CppParameter>(this);
24-
TemplateParameters = new List<CppType>();
24+
TemplateParameters = new CppContainerList<CppType>(this);
2525
Attributes = new List<CppAttribute>();
2626
TokenAttributes = new List<CppAttribute>();
2727
}
@@ -111,7 +111,7 @@ public int DefaultParamCount
111111
public bool IsFunctionTemplate => ((int)Flags & (int)CppFunctionFlags.FunctionTemplate) != 0;
112112

113113
/// <inheritdoc />
114-
public List<CppType> TemplateParameters { get; }
114+
public CppContainerList<CppType> TemplateParameters { get; }
115115

116116
/// <inheritdoc />
117117
public override string ToString()

0 commit comments

Comments
 (0)