新增: AST代码智能语言扩展 Go/Java/Python(tree-sitter 表驱动)

Phase1 范围 3 grammar/4 类 → 6 grammar/9 类。grammar_for/DEFINITION_KINDS/Cargo.toml 加表项(零架构改动,grammar crate 0.23 ABI 兼容 0.25 主 crate),补 3 处 py 相关测试断言(py 加支持后原无 grammar 样例失效),测试 306 passed。
This commit is contained in:
2026-06-25 02:13:46 +08:00
parent d7e0d7ac55
commit fc705443bd
3 changed files with 42 additions and 9 deletions

View File

@@ -66,6 +66,10 @@ tree-sitter = "0.25"
tree-sitter-rust = "0.24.2"
tree-sitter-typescript = "0.23.2"
tree-sitter-javascript = "0.25.0"
# Phase1 扩展:Go / Java / Python(静态编译,表驱动加表项,零架构改动)
tree-sitter-go = "0.23"
tree-sitter-java = "0.23"
tree-sitter-python = "0.23"
# 阶段3a/3b 统一审批模型开关(path_auth 审批链扎实重构 plan 阶段3)。
# 3a 后端合并(单 HashMap + kind 字段)为编译期结构性变更,本 flag 用于文档标记 +

View File

@@ -39,16 +39,29 @@ const DEFINITION_KINDS: &[&str] = &[
"interface_declaration",
"enum_declaration",
"method_definition",
// Go
"method_declaration", // Go method(receiver func)
"type_declaration", // Go type Xxx struct/interface/func
// Java
"constructor_declaration", // Java constructor
"annotation_type_declaration", // @interface
"record_declaration", // Java record(Java 16+)
// Python(tree-sitter-python 用 _definition 后缀)
"function_definition",
"class_definition",
];
/// 文件后缀 → tree-sitter grammar 集中 lookup(静态编译,不动态加载 / 不抽 trait)。
///
/// 设计(grammar 策略 2026-06-24 定稿,详见插件机制设计文档):
/// **3 个 grammar 覆盖 4 类文件**,架构成本最低。
/// **6 个 grammar 覆盖 9 类文件**,架构成本最低。
/// - `.rs` → tree-sitter-rust
/// - `.ts` → tree-sitter-typescript(language_typescript)
/// - `.tsx` → tree-sitter-typescript(language_tsx)
/// - `.js` / `.jsx` → tree-sitter-javascript
/// - `.go` → tree-sitter-go
/// - `.java` → tree-sitter-java
/// - `.py` → tree-sitter-python
/// - `.vue` → 返回 None 标记"需切 script 段"(Vue 借 TS,逻辑在 script,read_symbol 内 extract_vue_script 切段喂 ts)
///
/// 未来加语言 = 此处加一行 + 可能补 DEFINITION_KINDS(表驱动,~几行),不返工调用方。
@@ -59,19 +72,22 @@ pub fn grammar_for(ext: &str) -> Option<Language> {
"ts" => Some(Language::from(tree_sitter_typescript::LANGUAGE_TYPESCRIPT)),
"tsx" => Some(Language::from(tree_sitter_typescript::LANGUAGE_TSX)),
"js" | "jsx" => Some(Language::from(tree_sitter_javascript::LANGUAGE)),
"go" => Some(Language::from(tree_sitter_go::LANGUAGE)),
"java" => Some(Language::from(tree_sitter_java::LANGUAGE)),
"py" => Some(Language::from(tree_sitter_python::LANGUAGE)),
// Vue 借 TS:返 None 标记需切 script 段(read_symbol 内 extract_vue_script + 喂 ts)
"vue" => None,
_ => None,
}
}
/// 判断 ext 是否为 Phase1 支持语言(含 Vue 借 TS)。
/// 判断 ext 是否为支持语言(含 Vue 借 TS)。
///
/// 预留:当前 handler 直接调 read_symbol(内部已兜底 ext 判断),本函数供测试 + 未来
/// handler 层提前判 ext 省一次 fs read(不支持直接返兜底不读文件)。测试消费,非真死代码。
#[allow(dead_code)]
pub fn is_supported_ext(ext: &str) -> bool {
matches!(ext, "rs" | "ts" | "tsx" | "js" | "jsx" | "vue")
matches!(ext, "rs" | "ts" | "tsx" | "js" | "jsx" | "vue" | "go" | "java" | "py")
}
/// 提取 Vue SFC 的 `<script>` 段内容(借 TS 解析)。
@@ -140,7 +156,7 @@ pub fn read_symbol(
Some(g) => g,
None => {
return fallback(symbol, path, file_hash, "no_grammar",
&format!("不支持 {} 文件符号解析(Phase1 支持 .rs/.ts/.tsx/.js/.jsx/.vue)", ext));
&format!("不支持 {} 文件符号解析(支持 .rs/.ts/.tsx/.js/.jsx/.vue/.go/.java/.py)", ext));
}
};
@@ -387,18 +403,26 @@ struct Config {
assert!(grammar_for("tsx").is_some());
assert!(grammar_for("js").is_some());
assert!(grammar_for("jsx").is_some());
// Phase1 扩展:Go / Java / Python(静态编译,表驱动加表项)
assert!(grammar_for("go").is_some());
assert!(grammar_for("java").is_some());
assert!(grammar_for("py").is_some());
// Vue 借 TS:grammar 本身返 None(切段后用 ts)
assert!(grammar_for("vue").is_none());
// 不支持语言
assert!(grammar_for("py").is_none());
assert!(grammar_for("").is_none());
}
#[test]
fn test_is_supported_ext() {
assert!(is_supported_ext("rs"));
assert!(is_supported_ext("go"));
assert!(is_supported_ext("java"));
assert!(is_supported_ext("py"));
assert!(is_supported_ext("vue"));
assert!(!is_supported_ext("py"));
// 不支持语言
assert!(!is_supported_ext("rb"));
assert!(!is_supported_ext("md"));
}
#[test]
@@ -455,8 +479,10 @@ struct Config {
#[test]
fn test_read_symbol_no_grammar_fallback() {
let src = "def hello():\n print('hi')\n";
let r = read_symbol(src, "h", "test.py", "hello", false, None, None);
// Ruby 无 grammar(.rb 未集成 tree-sitter-ruby),走兜底。
// 注:原用 .py 做"无 grammar"样例,Phase1 扩展加 Python 支持后失效。
let src = "def hello\n puts 'hi'\nend\n";
let r = read_symbol(src, "h", "test.rb", "hello", false, None, None);
assert_eq!(r["fallback"], true);
assert_eq!(r["reason"], "no_grammar");
assert!(r["suggestion"].as_str().unwrap().contains("不支持"));