@flisk/swift-ast (英语)
Swift AST通过WebAssem在JavaScript中解析,由SwiftSyntax + SwiftParser提供动力.
导言
这个软件包将 SwiftSyntax + SwiftParser 编译为 WASI 模块,并将一个简单的 JavaScript API 将 Swift 源解析成一个紧凑的 JSON AST. 此外,它还提供了轻量级分析器(由Ruby Prism的ergonomics所启发),用于:
- 提取声明(功能、方法、类、结构、enum、变量)
- 查找和检查函数/方法调用(带有被调用人链和基准标识符)
- 遵循词汇范围内的简单标识引用
- 表面天真类型提示(例如,
let x: Int(中文(简体) )
它设计用于程序分析管道 @flisk/analyze-tracking 也可以作为CLI 与 npx。 。 。 .
快速启动( CLI)
不安装运行 :
npx @flisk/swift-ast /path/to/file.swift
此打印解析的 AST JSON 到 studout .
安装
npm i @flisk/swift-ast
程序化 API
解析到 JSON AST
import { parseSwiftAst } from '@flisk/swift-ast';
const source = `
struct Foo {
let x: Int
func bar(_ y: Int) -> Int { x + y }
}
`;
const ast = await parseSwiftAst(source);
console.dir(ast, { depth: null });
AST 形状( 简化后):
{
"root": 0,
"nodes": [
{ "kind": "SourceFileSyntax", "range": { "start": {"offset":0}, "end": {"offset":123} } },
{ "kind": "StructDeclSyntax", "name": "Foo", "range": { /* ... */ } },
{ "kind": "FunctionDeclSyntax", "name": "bar", "range": { /* ... */ } }
],
"edges": [[0,1],[1,2]]
}
基于文件的解析也有方便:
import { parseSwiftFile } from '@flisk/swift-ast';
const astFromFile = await parseSwiftFile('path/to/file.swift');
AST 分析器
import { analyzeAst } from '@flisk/swift-ast';
const analysis = analyzeAst(ast, source);
// All declarations by name
console.log([...analysis.byName.keys()]);
// All calls to a function/method named "track"
const calls = analysis.findCallsByName('track');
for (const c of calls) {
console.log({
name: c.name,
receiver: c.receiver,
base: c.baseIdentifier,
chain: c.calleeChain,
args: analysis.getCallArgs(c.id)
});
}
// Resolve a simple name to its symbol (best-effort)
const symbol = analysis.resolveNameAt('bar', /*offset*/ 0);
console.log(symbol?.kind, symbol?.name);
分析器返回类型( 高级) :
type Analysis = {
symbols: Map<number, SymbolInfo>;
calls: CallInfo[];
refs: RefInfo[];
byName: Map<string, number[]>;
findCallsByName(name: string): CallInfo[];
resolveNameAt(name: string, offset: number): SymbolInfo | undefined;
}
注释:
- 仅由语法驱动(没有完整的类型检查器). 名称解析是词汇学和最优的.
- 展出帮助简化跟踪分析:被标记为args,字典提取,包含符号查找,const字符串集合,以及被调用者的文本/链条等公用事业.
CLI 使用情况
# Print AST JSON
npx @flisk/swift-ast /path/to/file.swift
# With a local install
swift-ast /path/to/file.swift > ast.json
食谱
- 列出所有类/结构名称
const decls = [...analysis.symbols.values()].filter(s => s.kind === 'class' || s.kind === 'struct');
console.log(decls.map(d => d.name));
- 查找特定 API 的所有调用符( 如分析)
const hits = analysis.findCallsByName('track');
for (const call of hits) {
// receiver could be an instance, a type, or omitted
console.log(`${call.receiver ? call.receiver + '.' : ''}${call.name} at ${call.range.start.line}:${call.range.start.column}`);
}
- 获取变量的天真类型信息
const vars = [...analysis.symbols.values()].filter(s => s.kind === 'variable');
for (const v of vars) {
console.log(v.name, '::', v.typeAnnotation ?? '(inferred)');
}
环境
- 18号节点(使用内置)
node:wasi) (中文(简体) ). - 运行时不需要本地Swift工具链; Wasm 二进制船与 npm 包.
发展(捐助者)
- 通过 Swift 安装 快点
- 安装 Swift 6.2 :
swiftly install 6.2 - 选择 Swift 6.2 :
swiftly use 6.2 - 为 WASI 安装 SDK :
swift sdk install https://download.swift.org/swift-6.2-release/wasm/swift-6.2-RELEASE/swift-6.2-RELEASE_wasm.artifactbundle.tar.gz --checksum fe4e8648309fce86ea522e9e0d1dc48e82df6ba6e5743dbf0c53db8429fb5224
- 运行
swift sdk list并确保SWIFT_SDK_ID设定为相应的 SDK. - 构建 WASM 二进制 :
npm run build - 运行测试 :
npm test
注:SwiftSyntax版本被绑定在用于构建WASM的Swift工具链上. 如果您在本地重建, 请确保匹配 swift-syntax 用于工具链的标签.