Получить информацию о классе из ObjCPropertyDecl

У меня возникли проблемы с извлечением информации о классе из типа clang ObjCPropertyDecl.

Пример файла Objective-C:

#import <Foundation/Foundation.h>

@interface Test: NSObject

@property (nonatomic, strong, nullable) NSObject *test;
@property (nonatomic, strong, nullable) NSArray<NSObject *> *test1;

@end

@implementation Test

@end

Сброс ast дает мне это:

...
|-ObjCInterfaceDecl 0x104bbf8e0 <test.m:7:1, line:12:2> line:7:12 Test
| |-super ObjCInterface 0x103962618 'NSObject'
| |-ObjCImplementation 0x104bbff40 'Test'
| |-ObjCPropertyDecl 0x104bbfa20 <line:9:1, col:51> col:51 test 'NSObject * _Nullable':'NSObject *' readwrite nonatomic strong
| |-ObjCPropertyDecl 0x104bbfbe0 <line:10:1, col:62> col:62 test1 'NSArray<NSObject *> * _Nullable':'NSArray<NSObject *> *' readwrite nonatomic strong
| |-ObjCMethodDecl 0x104bbfc50 <line:9:51> col:51 implicit - test 'NSObject * _Nullable':'NSObject *'
| |-ObjCMethodDecl 0x104bbfcd8 <col:51> col:51 implicit - setTest: 'void'
| | `-ParmVarDecl 0x104bbfd60 <col:51> col:51 test 'NSObject * _Nullable':'NSObject *'
| |-ObjCMethodDecl 0x104bbfdc8 <line:10:62> col:62 implicit - test1 'NSArray<NSObject *> * _Nullable':'NSArray<NSObject *> *'
| `-ObjCMethodDecl 0x104bbfe50 <col:62> col:62 implicit - setTest1: 'void'
|   `-ParmVarDecl 0x104bbfed8 <col:62> col:62 test1 'NSArray<NSObject *> * _Nullable':'NSArray<NSObject *> *'
...

Раньше у меня было правило OCLint, которое полагалось на проверку типа, чтобы увидеть, является ли он NSArray, поэтому я использовал ASTVisitor и этот код:

string propertyType = node->getType().getAsString();
// compare to "NSArray *"

Обратите внимание, что и ключевое слово nullable, и универсальные шаблоны в приведенном выше примере кода изменяют уточненный тип (см. дамп AST).

Мой вопрос: есть ли способ получить только тип класса Objective-C из ObjCPropertyDecl, например. NSArray * или NSString * без лишнего сахара?

Я пробовал getSplitDesugaredType();, и это хорошо работает для удаления обнуляемых частей, но не удаляет дженерики.

Редактировать:

В настоящее время я думаю, что я мог бы получить Type из SplitQualType, затем преобразовать в ObjCObjectPointerType и получить ObjCObjectType, и это может иметь нужную мне информацию, но я попытаюсь реализовать это завтра.


person danielbeard    schedule 20.05.2016    source источник


Ответы (1)


Хорошо, после долгих поисков я нашел приемлемое решение:

std::string propertyType(clang::ObjCPropertyDecl *d) {
  QualType T = d->getType();
  if (auto TypePtr = T.getTypePtr()) {
     if (TypePtr->isObjCObjectPointerType()) {
        if (auto InterfaceType = TypePtr->getAsObjCInterfacePointerType()) {
            return InterfaceType->getObjectType()->getBaseType().getAsString();
        }
    }
  }
  return "";
}

Примеры:

@property (nonatomic, strong, nullable) NSObject *test; Возвращает: NSObject

@property (nonatomic, strong, nullable) NSArray<NSObject *> *test1; Возвращает: NSArray

Примечание. Это вернет только значения для типов указателей объектов, свойства для скалярных значений, таких как NSInteger и т. д., вернут пустую строку.

person danielbeard    schedule 23.05.2016