Libclang Python绑定:获取ObjC方法返回值

时间:2018-10-04 06:29:34

标签: python objective-c swift clang libclang

背景

有关此问题的完整讨论,请参见https://github.com/tingraldi/SwiftScripting/issues/18

上面的链接有一个长长的Python脚本,该脚本将Objective-C File.h头文件转换为File.swift。为此,它使用libclang解析文件并将AST转换为Swift输出。

这是我们正在处理的头文件的缩写内容:

@interface FinderContainer : FinderItem

- (SBElementArray<FinderItem *> *) items;
- (SBElementArray<FinderContainer *> *) containers;

@end

问题

在具有Xcode 9.4.1和pip install clang==3.5的macOS 10.13.6上,脚本可以完美运行并生成正确的输出:

@objc public protocol FinderContainer: FinderItem {
    @objc optional func items() -> SBElementArray
    ...  // Truncated
}

但是,在安装了Xcode 10并且具有相同pip install clang==3.5的macOS Mojave上,缺少函数的返回值:

@objc public protocol FinderContainer: FinderItem {
    @objc optional func items()
    ...  // Truncated
}

注意:我已经测试了clang 3.5和最新版本:6.0.0.2。两者产生相同的结果。


出了什么问题

这部分python脚本使用了一个函数/方法声明,并将其转换为Swift:

def emit_function(self, cursor):

    # ----LOGGING ADDITIONS -------------------------------------------------
    print(cursor.spelling)
    parameter_children_names = [child for child in cursor.get_children()]
    for x in parameter_children_names: print('   child --> ' + x.spelling)
    print('   result_type: ' + str(cursor.result_type.kind))
    # -----------------------------------------------------------------------

    func_name = safe_name(cursor.spelling.split(':')[0], keywords=general_keywords)
    parameter_cursors = [child for child in cursor.get_children() if child.kind == CursorKind.PARM_DECL]
    parameters = ['{}: {}'.format(arg_name(child.spelling, position=parameter_cursors.index(child)), type_for_type(child.type, as_arg=True))
                  for child in parameter_cursors]
    return_type = [child.type for child in cursor.get_children() if child.kind != CursorKind.PARM_DECL]
    if return_type:
        return_string = ' -> {}'.format(type_for_type(return_type[0]))
    else:
        return_string = ''

    self.emit_line('    @objc optional func {}({}){}{}'.format(
        func_name, ", ".join(parameters), return_string, self.line_comment(cursor)))

在macOS 10.13上,记录的输出如下所示:

enter image description here

每个Clang cursor的名称显示在左侧,而缩进的下方是每个游标的子级。您可以看到这些子项中的一个是返回值SBElementArray。您还可以看到return_type.kind值未定义。该脚本遍历cursor的子级,直到找到非parameter类型的子级为止。它知道这个孩子是返回值,将其取出,然后编写正确的Swift代码。

在macOS Mojave上,返回值不再是cursor的子级,如日志输出所示:

enter image description here

因此,在这种情况下,脚本找不到任何返回值,并且现在函数编写不正确。


我的问题

该如何解决?我已经花了几个小时阅读Clang文档,寻找更改日志等。我无法弄清楚(A)更改了什么,(B)获取函数/方法的返回值的新方法应该是什么。

我需要一个比我更了解Clang的人。谢谢。

0 个答案:

没有答案