有关此问题的完整讨论,请参见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上,记录的输出如下所示:
每个Clang cursor
的名称显示在左侧,而缩进的下方是每个游标的子级。您可以看到这些子项中的一个是返回值SBElementArray
。您还可以看到return_type.kind
值未定义。该脚本遍历cursor
的子级,直到找到非parameter
类型的子级为止。它知道这个孩子是返回值,将其取出,然后编写正确的Swift代码。
在macOS Mojave上,返回值不再是cursor
的子级,如日志输出所示:
因此,在这种情况下,脚本找不到任何返回值,并且现在函数编写不正确。
该如何解决?我已经花了几个小时阅读Clang文档,寻找更改日志等。我无法弄清楚(A)更改了什么,(B)获取函数/方法的返回值的新方法应该是什么。
我需要一个比我更了解Clang的人。谢谢。