Skip to content

Commit 1de7484

Browse files
Merge pull request #673 from rolfbjarne/objc-decl-typeparamlist
Fix ObjC[Category|Interface]Decl.TypeParamList.
2 parents d0e44c8 + d099da0 commit 1de7484

File tree

8 files changed

+124
-3
lines changed

8 files changed

+124
-3
lines changed

sources/ClangSharp.Interop/Extensions/CXCursor.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,8 @@ public readonly CXCursor DefaultArg
12571257

12581258
public readonly int NumTemplateParameterLists => clangsharp.Cursor_getNumTemplateParameterLists(this);
12591259

1260+
public readonly int NumTypeParams => clangsharp.Cursor_getNumTypeParams(this);
1261+
12601262
public readonly int NumVBases => clangsharp.Cursor_getNumVBases(this);
12611263

12621264
public readonly CXObjCDeclQualifierKind ObjCDeclQualifiers => (CXObjCDeclQualifierKind)clang.Cursor_getObjCDeclQualifiers(this);
@@ -1911,6 +1913,8 @@ public readonly int GetPlatformAvailability(out bool alwaysDeprecated, out CXStr
19111913

19121914
public readonly long GetTemplateArgumentValue(uint i) => clang.Cursor_getTemplateArgumentValue(this, i);
19131915

1916+
public readonly CXCursor GetTypeParam(uint index) => clangsharp.Cursor_getTypeParam(this, index);
1917+
19141918
public readonly CXCursor GetVBase(uint index) => clangsharp.Cursor_getVBase(this, index);
19151919

19161920
public override readonly string ToString() => Spelling.ToString();

sources/ClangSharp.Interop/clangsharp/clangsharp.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,9 @@ public static partial class @clangsharp
738738
[DllImport("libClangSharp", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clangsharp_Cursor_getNumTemplateParameterLists", ExactSpelling = true)]
739739
public static extern int Cursor_getNumTemplateParameterLists(CXCursor C);
740740

741+
[DllImport("libClangSharp", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clangsharp_Cursor_getNumTypeParams", ExactSpelling = true)]
742+
public static extern int Cursor_getNumTypeParams(CXCursor C);
743+
741744
[DllImport("libClangSharp", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clangsharp_Cursor_getNumVBases", ExactSpelling = true)]
742745
public static extern int Cursor_getNumVBases(CXCursor C);
743746

@@ -869,6 +872,9 @@ public static partial class @clangsharp
869872
[DllImport("libClangSharp", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clangsharp_Cursor_getTypeOperand", ExactSpelling = true)]
870873
public static extern CXType Cursor_getTypeOperand(CXCursor C);
871874

875+
[DllImport("libClangSharp", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clangsharp_Cursor_getTypeParam", ExactSpelling = true)]
876+
public static extern CXCursor Cursor_getTypeParam(CXCursor C, [NativeTypeName("unsigned int")] uint i);
877+
872878
[DllImport("libClangSharp", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clangsharp_Cursor_getUnaryExprOrTypeTraitKind", ExactSpelling = true)]
873879
public static extern CX_UnaryExprOrTypeTrait Cursor_getUnaryExprOrTypeTraitKind(CXCursor C);
874880

sources/ClangSharp/Cursors/Decls/ObjCCategoryDecl.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ internal ObjCCategoryDecl(CXCursor handle) : base(handle, CXCursor_ObjCCategoryD
2626
_nextClassCategory = new ValueLazy<ObjCCategoryDecl>(() => TranslationUnit.GetOrCreate<ObjCCategoryDecl>(Handle.GetSubDecl(2)));
2727
_nextClassCategoryRaw = new ValueLazy<ObjCCategoryDecl>(() => TranslationUnit.GetOrCreate<ObjCCategoryDecl>(Handle.GetSubDecl(3)));
2828
_protocols = LazyList.Create<ObjCProtocolDecl>(Handle.NumProtocols, (i) => TranslationUnit.GetOrCreate<ObjCProtocolDecl>(Handle.GetProtocol(unchecked((uint)i))));
29-
_typeParamList = LazyList.Create<ObjCTypeParamDecl>(Handle.NumArguments, (i) => TranslationUnit.GetOrCreate<ObjCTypeParamDecl>(Handle.GetArgument(unchecked((uint)i))));
29+
_typeParamList = LazyList.Create<ObjCTypeParamDecl>(Handle.NumTypeParams, (i) => TranslationUnit.GetOrCreate<ObjCTypeParamDecl>(Handle.GetTypeParam(unchecked((uint)i))));
3030
}
3131

3232
public ObjCInterfaceDecl ClassInterface => _classInterface.Value;

sources/ClangSharp/Cursors/Decls/ObjCInterfaceDecl.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ internal ObjCInterfaceDecl(CXCursor handle) : base(handle, CXCursor_ObjCInterfac
4747
_superClass = new ValueLazy<ObjCInterfaceDecl>(() => TranslationUnit.GetOrCreate<ObjCInterfaceDecl>(Handle.GetSubDecl(2)));
4848
_superClassType = new ValueLazy<ObjCObjectType>(() => TranslationUnit.GetOrCreate<ObjCObjectType>(Handle.TypeOperand));
4949
_typeForDecl = new ValueLazy<Type>(() => TranslationUnit.GetOrCreate<Type>(Handle.ThisType));
50-
_typeParamList = LazyList.Create<ObjCTypeParamDecl>(Handle.NumArguments, (i) => TranslationUnit.GetOrCreate<ObjCTypeParamDecl>(Handle.GetArgument(unchecked((uint)i))));
50+
_typeParamList = LazyList.Create<ObjCTypeParamDecl>(Handle.NumTypeParams, (i) => TranslationUnit.GetOrCreate<ObjCTypeParamDecl>(Handle.GetTypeParam(unchecked((uint)i))));
5151
_visibleCategories = new ValueLazy<List<ObjCCategoryDecl>>(() => [.. CategoryList.Where((category) => category.IsUnconditionallyVisible)]);
5252
_visibleExtensions = new ValueLazy<List<ObjCCategoryDecl>>(() => [.. CategoryList.Where((category) => category.IsClassExtension && category.IsUnconditionallyVisible)]);
5353
}

sources/ClangSharp/Cursors/Decls/ObjCTypeParamDecl.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace ClangSharp;
88

99
public sealed class ObjCTypeParamDecl : TypedefNameDecl
1010
{
11-
internal ObjCTypeParamDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_ObjCTypeParam)
11+
internal ObjCTypeParamDecl(CXCursor handle) : base(handle, CXCursor_TemplateTypeParameter, CX_DeclKind_ObjCTypeParam)
1212
{
1313
}
1414

sources/libClangSharp/ClangSharp.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3635,6 +3635,29 @@ int clangsharp_Cursor_getNumTemplateParameterLists(CXCursor C) {
36353635
return -1;
36363636
}
36373637

3638+
int clangsharp_Cursor_getNumTypeParams(CXCursor C)
3639+
{
3640+
if (isDeclOrTU(C.kind)) {
3641+
const Decl* D = getCursorDecl(C);
3642+
3643+
if (const ObjCCategoryDecl* OCCD = dyn_cast<ObjCCategoryDecl>(D)) {
3644+
ObjCTypeParamList* typeParamList = OCCD->getTypeParamList();
3645+
if (typeParamList)
3646+
return typeParamList->size();
3647+
return 0;
3648+
}
3649+
3650+
if (const ObjCInterfaceDecl* OCID = dyn_cast<ObjCInterfaceDecl>(D)) {
3651+
ObjCTypeParamList* typeParamList = OCID->getTypeParamList();
3652+
if (typeParamList)
3653+
return typeParamList->size();
3654+
return 0;
3655+
}
3656+
}
3657+
3658+
return 0;
3659+
}
3660+
36383661
int clangsharp_Cursor_getNumVBases(CXCursor C) {
36393662
if (isDeclOrTU(C.kind)) {
36403663
const Decl* D = getCursorDecl(C);
@@ -4763,6 +4786,42 @@ CXType clangsharp_Cursor_getTypeOperand(CXCursor C) {
47634786
return MakeCXType(QualType(), getCursorTU(C));
47644787
}
47654788

4789+
CXCursor clangsharp_Cursor_getTypeParam(CXCursor C, unsigned i) {
4790+
if (isDeclOrTU(C.kind)) {
4791+
const Decl* D = getCursorDecl(C);
4792+
4793+
if (const ObjCCategoryDecl* OCCD = dyn_cast<ObjCCategoryDecl>(D)) {
4794+
ObjCTypeParamList* typeParamList = OCCD->getTypeParamList();
4795+
4796+
unsigned int n = 0;
4797+
if (i < typeParamList->size()) {
4798+
for (auto d : *typeParamList) {
4799+
if (n == i) {
4800+
return MakeCXCursor(d, getCursorTU(C));
4801+
}
4802+
n++;
4803+
}
4804+
}
4805+
}
4806+
4807+
if (const ObjCInterfaceDecl* OCID = dyn_cast<ObjCInterfaceDecl>(D)) {
4808+
ObjCTypeParamList* typeParamList = OCID->getTypeParamList();
4809+
4810+
unsigned int n = 0;
4811+
if (i < typeParamList->size()) {
4812+
for (auto d : *typeParamList) {
4813+
if (n == i) {
4814+
return MakeCXCursor(d, getCursorTU(C));
4815+
}
4816+
n++;
4817+
}
4818+
}
4819+
}
4820+
}
4821+
4822+
return clang_getNullCursor();
4823+
}
4824+
47664825
CX_UnaryExprOrTypeTrait clangsharp_Cursor_getUnaryExprOrTypeTraitKind(CXCursor C) {
47674826
if (isStmtOrExpr(C.kind)) {
47684827
const Stmt* S = getCursorStmt(C);

sources/libClangSharp/ClangSharp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,8 @@ CLANGSHARP_LINKAGE int clangsharp_Cursor_getNumTemplateParameters(CXCursor C, un
651651

652652
CLANGSHARP_LINKAGE int clangsharp_Cursor_getNumTemplateParameterLists(CXCursor C);
653653

654+
CLANGSHARP_LINKAGE int clangsharp_Cursor_getNumTypeParams(CXCursor C);
655+
654656
CLANGSHARP_LINKAGE int clangsharp_Cursor_getNumVBases(CXCursor C);
655657

656658
CLANGSHARP_LINKAGE CXCursor clangsharp_Cursor_getOpaqueValue(CXCursor C);
@@ -737,6 +739,8 @@ CLANGSHARP_LINKAGE CXCursor clangsharp_Cursor_getTypedefNameForAnonDecl(CXCursor
737739

738740
CLANGSHARP_LINKAGE CXType clangsharp_Cursor_getTypeOperand(CXCursor C);
739741

742+
CLANGSHARP_LINKAGE CXCursor clangsharp_Cursor_getTypeParam(CXCursor C, unsigned i);
743+
740744
CLANGSHARP_LINKAGE CX_UnaryExprOrTypeTrait clangsharp_Cursor_getUnaryExprOrTypeTraitKind(CXCursor C);
741745

742746
CLANGSHARP_LINKAGE CXCursor clangsharp_Cursor_getUnderlyingDecl(CXCursor C);

tests/ClangSharp.UnitTests/ObjectiveCTest.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public sealed class ObjectiveCTest : TranslationUnitTest
1313
[Test]
1414
public void Method_Selector()
1515
{
16+
AssertNeedNewClangSharp();
17+
1618
var inputContents = $@"
1719
@interface MyClass
1820
@property int P1;
@@ -48,6 +50,8 @@ @interface MyClass
4850
[Test]
4951
public void Category_TypeParamList()
5052
{
53+
AssertNeedNewClangSharp();
54+
5155
var inputContents = $@"
5256
@interface MyClass
5357
@end
@@ -94,6 +98,8 @@ @protocol P2
9498
[Test]
9599
public void Method_IsPropertyAccessor()
96100
{
101+
AssertNeedNewClangSharp();
102+
97103
var inputContents = $@"
98104
@interface MyClass
99105
@property int P1;
@@ -126,9 +132,49 @@ @interface MyClass
126132
Assert.That(methodStaticMethod.IsPropertyAccessor, Is.False, "methodStaticMethod.IsPropertyAccessor");
127133
}
128134

135+
[Test]
136+
public void TypeParams()
137+
{
138+
AssertNeedNewClangSharp();
139+
140+
var inputContents = $$"""
141+
@interface NSObject
142+
@end
143+
144+
@interface MyClass<A, B> : NSObject
145+
@end
146+
147+
@interface MyClass<T, Y> (MyCategory)
148+
@end
149+
150+
""";
151+
using var translationUnit = CreateTranslationUnit(inputContents, "objective-c++");
152+
153+
var classes = translationUnit.TranslationUnitDecl.Decls.OfType<ObjCInterfaceDecl>().ToList();
154+
155+
var myClass = classes.SingleOrDefault(v => v.Name == "MyClass")!;
156+
Assert.That(myClass, Is.Not.Null, "MyClass");
157+
Assert.That(myClass.TypeParamList, Is.Not.Null, "myClass TypeParamList");
158+
var myClassTypeParams = myClass.TypeParamList.ToList();
159+
Assert.That(myClassTypeParams.Count, Is.EqualTo(2), "myClassTypeParams.Count");
160+
Assert.That(myClassTypeParams[0].Name, Is.EqualTo("A"), "myClassTypeParams[0].Name");
161+
Assert.That(myClassTypeParams[1].Name, Is.EqualTo("B"), "myClassTypeParams[1].Name");
162+
163+
var categories = translationUnit.TranslationUnitDecl.Decls.OfType<ObjCCategoryDecl>().ToList();
164+
var myCategory = categories.SingleOrDefault(v => v.Name == "MyCategory")!;
165+
Assert.That(myCategory, Is.Not.Null, "MyCategory");
166+
Assert.That(myCategory.TypeParamList, Is.Not.Null, "myCategory TypeParamList");
167+
var myCategoryTypeParams = myCategory.TypeParamList.ToList();
168+
Assert.That(myCategoryTypeParams.Count, Is.EqualTo(2), "myCategoryTypeParams.Count");
169+
Assert.That(myCategoryTypeParams[0].Name, Is.EqualTo("T"), "myCategoryTypeParams[0].Name");
170+
Assert.That(myCategoryTypeParams[1].Name, Is.EqualTo("Y"), "myCategoryTypeParams[1].Name");
171+
}
172+
129173
[Test]
130174
public void PointerTypes()
131175
{
176+
AssertNeedNewClangSharp();
177+
132178
var inputContents = """
133179
@interface MyClass
134180
-(void)instanceMethod:(MyClass **)ptrToPtrToMyClass;
@@ -158,6 +204,8 @@ @interface MyClass
158204
[Test]
159205
public void BlockTypes()
160206
{
207+
AssertNeedNewClangSharp();
208+
161209
var inputContents = $$"""
162210
@interface MyClass
163211
-(MyClass *(^)(id))instanceMethod1;

0 commit comments

Comments
 (0)