Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sources/ClangSharp.Interop/Extensions/CXCursor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,8 @@ public readonly CXCursor DefaultArg

public readonly bool IsThisDeclarationADefinition => clangsharp.Cursor_getIsThisDeclarationADefinition(this) != 0;

public readonly bool IsPropertyAccessor => clangsharp.Cursor_getIsPropertyAccessor(this) != 0;

public readonly bool IsThrownVariableInScope => clangsharp.Cursor_getIsThrownVariableInScope(this) != 0;

public readonly bool IsTranslationUnit => clang.isTranslationUnit(Kind) != 0;
Expand Down
4 changes: 4 additions & 0 deletions sources/ClangSharp.Interop/clangsharp/clangsharp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,10 @@ public static partial class @clangsharp
[return: NativeTypeName("unsigned int")]
public static extern uint Cursor_getIsThisDeclarationADefinition(CXCursor C);

[DllImport("libClangSharp", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clangsharp_Cursor_getIsPropertyAccessor", ExactSpelling = true)]
[return: NativeTypeName("unsigned int")]
public static extern uint Cursor_getIsPropertyAccessor(CXCursor C);

[DllImport("libClangSharp", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clangsharp_Cursor_getIsThrownVariableInScope", ExactSpelling = true)]
[return: NativeTypeName("unsigned int")]
public static extern uint Cursor_getIsThrownVariableInScope(CXCursor C);
Expand Down
2 changes: 2 additions & 0 deletions sources/ClangSharp/Cursors/Decls/ObjCMethodDecl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,6 @@ internal ObjCMethodDecl(CXCursor handle) : base(handle, handle.Kind, CX_DeclKind
public ImplicitParamDecl SelfDecl => _selfDecl.Value;

public Type SendResultType => _sendResultType.Value;

public bool IsPropertyAccessor => Handle.IsPropertyAccessor;
}
11 changes: 11 additions & 0 deletions sources/libClangSharp/ClangSharp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2716,6 +2716,17 @@ unsigned clangsharp_Cursor_getIsThisDeclarationADefinition(CXCursor C) {
return 0;
}

unsigned clangsharp_Cursor_getIsPropertyAccessor(CXCursor C) {
if (isDeclOrTU(C.kind)) {
const Decl* D = getCursorDecl(C);

if (const ObjCMethodDecl* OCMD = dyn_cast<ObjCMethodDecl>(D)) {
return OCMD->isPropertyAccessor();
}
}

return 0;
}
unsigned clangsharp_Cursor_getIsThrownVariableInScope(CXCursor C) {
if (isStmtOrExpr(C.kind)) {
const Stmt* S = getCursorStmt(C);
Expand Down
2 changes: 2 additions & 0 deletions sources/libClangSharp/ClangSharp.h
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,8 @@ CLANGSHARP_LINKAGE unsigned clangsharp_Cursor_getIsTemplated(CXCursor C);

CLANGSHARP_LINKAGE unsigned clangsharp_Cursor_getIsThisDeclarationADefinition(CXCursor C);

CLANGSHARP_LINKAGE unsigned clangsharp_Cursor_getIsPropertyAccessor(CXCursor C);

CLANGSHARP_LINKAGE unsigned clangsharp_Cursor_getIsThrownVariableInScope(CXCursor C);

CLANGSHARP_LINKAGE unsigned clangsharp_Cursor_getIsTransparent(CXCursor C);
Expand Down
52 changes: 51 additions & 1 deletion tests/ClangSharp.UnitTests/ObjectiveCTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information.

using System;
using System.Linq;
using ClangSharp.Interop;
using NUnit.Framework;
Expand All @@ -10,9 +11,10 @@ namespace ClangSharp.UnitTests;
public sealed class ObjectiveCTest : TranslationUnitTest
{
[Test]
[Ignore("TODO: this needs a new version of libClangSharp published.")]
public void Category_TypeParamList()
{
AssertNeedNewClangSharp();

var inputContents = $@"
@interface MyClass
@end
Expand All @@ -29,6 +31,43 @@ @interface MyClass (MyCategory)
}
}

[Test]
public void Method_IsPropertyAccessor()
{
AssertNeedNewClangSharp();

var inputContents = $@"
@interface MyClass
@property int P1;
-(void) instanceMethod;
+(void) staticMethod;
@end
";

using var translationUnit = CreateTranslationUnit(inputContents, "objective-c++");

var classes = translationUnit.TranslationUnitDecl.Decls.OfType<ObjCInterfaceDecl>().ToList();
Assert.That(classes.Count, Is.GreaterThanOrEqualTo(1), $"At least one class");
var myClass = classes.SingleOrDefault(v => v.Name == "MyClass")!;
Assert.That(myClass, Is.Not.Null, "MyClass");

var methodP1 = myClass.Methods.SingleOrDefault(v => v.Name == "P1")!;
Assert.That(methodP1, Is.Not.Null, "methodP1");
Assert.That(methodP1.IsPropertyAccessor, Is.True, "methodP1.IsPropertyAccessor");

var methodSetP1 = myClass.Methods.SingleOrDefault(v => v.Name == "setP1:")!;
Assert.That(methodSetP1, Is.Not.Null, "methodSetP1");
Assert.That(methodSetP1.IsPropertyAccessor, Is.True, "methodSetP1.IsPropertyAccessor");

var methodInstanceMethod = myClass.Methods.SingleOrDefault(v => v.Name == "instanceMethod")!;
Assert.That(methodInstanceMethod, Is.Not.Null, "methodInstanceMethod");
Assert.That(methodInstanceMethod.IsPropertyAccessor, Is.False, "methodInstanceMethod.IsPropertyAccessor");

var methodStaticMethod = myClass.Methods.SingleOrDefault(v => v.Name == "staticMethod")!;
Assert.That(methodStaticMethod, Is.Not.Null, "methodStaticMethod");
Assert.That(methodStaticMethod.IsPropertyAccessor, Is.False, "methodStaticMethod.IsPropertyAccessor");
}

[Test]
public void PointerTypes()
{
Expand Down Expand Up @@ -57,4 +96,15 @@ @interface MyClass
var pointee2Type = pointeeType.PointeeType;
Assert.That(pointee2Type.Kind, Is.EqualTo(CXTypeKind.CXType_ObjCInterface), "pointee2Type.Kind");
}

private static void AssertNeedNewClangSharp()
{
var forceRun = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("FORCE_RUN"));

if (forceRun)
{
return;
}
Assert.Ignore("TODO: this needs a new version of libClangSharp published.");
}
}