修复: 变量声明误判为符号定义
let/var 声明一律算定义致几乎任何文件误报改用符号读取 收窄为初始化为函数或类表达式才算定义,三处消费点统一收口
This commit is contained in:
@@ -39,7 +39,7 @@ const DEFINITION_KINDS: &[&str] = &[
|
||||
"interface_declaration",
|
||||
"enum_declaration",
|
||||
"method_definition",
|
||||
// TS/JS const/let/var 声明(如 const fn = () => {})
|
||||
// TS/JS const/let/var 声明,仅当初始化为函数/类值才算定义(收窄判定见 is_definition_node)
|
||||
"variable_declarator",
|
||||
// Go
|
||||
"method_declaration", // Go method(receiver func)
|
||||
@@ -124,9 +124,45 @@ pub(crate) fn contains_definition(source: &str, ext: &str) -> bool {
|
||||
tree_has_definition(&tree.root_node())
|
||||
}
|
||||
|
||||
/// 递归遍历语法树,判断是否含任一 DEFINITION_KINDS 定义节点(contains_definition 的遍历内核)。
|
||||
/// JS/TS 函数/类值表达式 kind:variable_declarator 是否算定义据此判定
|
||||
const FUNCTION_VALUE_KINDS: &[&str] = &["arrow_function", "function", "generator_function", "class"];
|
||||
|
||||
/// 节点是否为可提取定义:kind 在表内,variable_declarator 需初始化为函数/类值。
|
||||
///
|
||||
/// variable_declarator 单看 kind 过宽:`let msg = "fn main() {}"` 这类普通声明也命中,
|
||||
/// contains_definition 会对几乎任何 JS/TS 文件误报提示。收窄为 `const fn = () => {}`
|
||||
/// 形态(初始化值是函数/类表达式)才算定义,contains_definition / read_symbol /
|
||||
/// outline 三处共用同一判定。
|
||||
fn is_definition_node(node: &Node<'_>) -> bool {
|
||||
if !DEFINITION_KINDS.contains(&node.kind()) {
|
||||
return false;
|
||||
}
|
||||
if node.kind() != "variable_declarator" {
|
||||
return true;
|
||||
}
|
||||
match node.child_by_field_name("value") {
|
||||
Some(v) => subtree_contains_kind(v, FUNCTION_VALUE_KINDS),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// 子树内是否含任一目标 kind 节点
|
||||
fn subtree_contains_kind(node: Node<'_>, kinds: &[&str]) -> bool {
|
||||
if kinds.contains(&node.kind()) {
|
||||
return true;
|
||||
}
|
||||
let mut cursor = node.walk();
|
||||
for child in node.children(&mut cursor) {
|
||||
if subtree_contains_kind(child, kinds) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// 递归遍历语法树,判断是否含任一定义节点(contains_definition 的遍历内核)。
|
||||
fn tree_has_definition(node: &Node<'_>) -> bool {
|
||||
if DEFINITION_KINDS.contains(&node.kind()) {
|
||||
if is_definition_node(node) {
|
||||
return true;
|
||||
}
|
||||
let mut cursor = node.walk();
|
||||
@@ -246,7 +282,7 @@ pub fn read_symbol(
|
||||
|
||||
/// 递归遍历找匹配 symbol 名的定义节点。
|
||||
///
|
||||
/// 命中条件:node.kind() 在 DEFINITION_KINDS 内 + name field 文本 == symbol + kind_hint(若传)匹配。
|
||||
/// 命中条件:node 为定义节点(is_definition_node)+ name field 文本 == symbol + kind_hint(若传)匹配。
|
||||
/// 首个命中即返(find_definition 调用方短路)。
|
||||
fn find_definition<'a>(
|
||||
node: &Node<'a>,
|
||||
@@ -258,7 +294,7 @@ fn find_definition<'a>(
|
||||
if found.is_some() {
|
||||
return;
|
||||
}
|
||||
if DEFINITION_KINDS.contains(&node.kind()) {
|
||||
if is_definition_node(node) {
|
||||
let kind_ok = kind_hint.map_or(true, |h| kind_matches(node.kind(), h));
|
||||
if kind_ok {
|
||||
if let Some(name_node) = node.child_by_field_name("name") {
|
||||
@@ -452,7 +488,7 @@ fn collect_top_level_symbols(
|
||||
line_offset: usize,
|
||||
out: &mut Vec<serde_json::Value>,
|
||||
) {
|
||||
if DEFINITION_KINDS.contains(&node.kind()) {
|
||||
if is_definition_node(&node) {
|
||||
let name = symbol_name(node, source);
|
||||
let kind = node.kind().to_string();
|
||||
let line = node.start_position().row + 1 + line_offset;
|
||||
|
||||
Reference in New Issue
Block a user