pub trait SharedProcessor: Sized {
// Required methods
fn language() -> &'static str;
fn grammar() -> Language;
fn kinds() -> &'static [KindRule];
fn handle_special(
node: Node<'_>,
bytes: &[u8],
entities: &mut Vec<Entity>,
imports: &mut Vec<ImportStmt>,
);
fn fallback(source: &str) -> (Vec<Entity>, Vec<ImportStmt>);
// Provided methods
fn post_process(_source: &str, _entities: &mut Vec<Entity>) { ... }
fn extract(source: &str) -> (Vec<Entity>, Vec<ImportStmt>) { ... }
fn record_by_rule(
node: Node<'_>,
bytes: &[u8],
rule: &KindRule,
entities: &mut Vec<Entity>,
) { ... }
fn parse_file(source: &str, path: &Path) -> Result<FileInsight> { ... }
}Expand description
共享的 tree-sitter 解析骨架 — 7 语言 walk/fallback 公共部分去重
背景:原 7 个 parser 的 walk 头部(bytes/entities/imports 初始化、 Parser 构造、set_language 失败→fallback、parse 返回 None→fallback、cursor 初始化)、 walk 尾部(DFS 遍历)与 parse 方法体(FileInsight 组装)逐字重复约 20 行 × 7, 全部收敛到本 trait 的默认实现,每语言只保留差异点。
差异点分三类承载:
- grammar():tree-sitter 语法常量(原 LANGUAGE 一行差异)
- kinds():纯 kind→kind 映射分支数据化(含签名提取规则), 公共 walk 命中后走统一的 record_by_rule;命中规则与 handle_special 的分支互斥(等价于原 match 每个 kind 恰好一个分支)
- handle_special():无法数据化的分支钩子 — 动态 kind 判断 (Go type_spec、JS variable_declarator 箭头函数)、子节点遍历 (field_declaration)、导入语句文本解析(use_declaration / import_* / using_directive)
fallback() 保持每语言钩子:各语言正则降级差异极大(C# 是启发式代码、 导入解析规则各异),强行表化会引入比原代码更复杂的规则引擎,故不数据化; 统一的是触发契约 — set_language 失败或 parse 返回 None 时由 extract() 统一调用 fallback(),保证降级路径行为一致。
post_process():walk 结束后的文档注释关联钩子 (Rust 的 /// 注释、Python 的 docstring),其余语言无操作。
Required Methods§
Sourcefn handle_special(
node: Node<'_>,
bytes: &[u8],
entities: &mut Vec<Entity>,
imports: &mut Vec<ImportStmt>,
)
fn handle_special( node: Node<'_>, bytes: &[u8], entities: &mut Vec<Entity>, imports: &mut Vec<ImportStmt>, )
无法数据化的节点处理钩子(动态 kind / 子节点遍历 / 导入解析)
Provided Methods§
Sourcefn post_process(_source: &str, _entities: &mut Vec<Entity>)
fn post_process(_source: &str, _entities: &mut Vec<Entity>)
walk 完成后的文档关联钩子(默认无操作)
Sourcefn extract(source: &str) -> (Vec<Entity>, Vec<ImportStmt>)
fn extract(source: &str) -> (Vec<Entity>, Vec<ImportStmt>)
统一 walk 入口:构造 parser → tree-sitter 失败触发 fallback → DFS 遍历
骨架与原各语言 walk 逐字一致:命中 kinds() 表走 record_by_rule, 未命中走 handle_special(等价于原 match 分支的聚合)。
Sourcefn record_by_rule(
node: Node<'_>,
bytes: &[u8],
rule: &KindRule,
entities: &mut Vec<Entity>,
)
fn record_by_rule( node: Node<'_>, bytes: &[u8], rule: &KindRule, entities: &mut Vec<Entity>, )
按 kinds() 规则统一提取实体(与各语言原 match 分支输出一致)
Sourcefn parse_file(source: &str, path: &Path) -> Result<FileInsight>
fn parse_file(source: &str, path: &Path) -> Result<FileInsight>
统一 FileInsight 组装(empty 早退 + extract),语言侧 parse 一行调用
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".