背景
有关此问题的完整讨论,请参阅https://github.com/tingraldi/SwiftScripting/issues/18。
上面的链接有一个很长的 Python 脚本,可以将 Objective-CFile.h头文件转换为File.swift. 为此,它使用 libclang 解析文件并将 AST 转换为 Swift 输出。
这是我们正在处理的头文件的缩写内容:
@interface FinderContainer : FinderItem
- (SBElementArray<FinderItem *> *) items;
- (SBElementArray<FinderContainer *> *) containers;
@end
问题
在带有 Xcode 9.4.1 和 的 macOS 10.13.6 上pip install clang==3.5,脚本运行完美并生成正确的输出:
@objc public protocol FinderContainer: FinderItem {
@objc optional func items() -> SBElementArray
... // Truncated
}
但是,在安装了 Xcode 10 且相同的 macOS Mojave 上,pip install clang==3.5缺少函数的返回值:
@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 上,记录的输出如下所示:
每个 Clang 的名称cursor出现在左侧,下面缩进的是每个光标的子级。您可以看到其中一个孩子是返回值SBElementArray。您还可以看到该return_type.kind值未定义。脚本遍历 的子级,cursor直到找到一个不属于该parameter类型的子级。它知道这个孩子是返回值,把它拉出来,然后写出正确的 Swift 代码。
在 macOS Mojave 上,返回值不再是 的子级,cursor如日志输出所示:
因此,在这种情况下,脚本找不到返回值,并且函数现在编写不正确。
我的问题
我该如何解决?我花了几个小时阅读 Clang 文档、查找更改日志等。我无法弄清楚 (A) 发生了什么变化以及 (B) 获取函数/方法返回值的新方法应该是什么。
我需要一个比我更了解 Clang 的人。谢谢你。

