You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用tree-sitter-javascript提取函数名失败,求问题原因及替代方案

问题原因

tree-sitter 的 tree.walk() 方法不接受回调函数,它返回的是一个 TreeCursor 实例,需要你手动调用游标的移动方法(如 gotoFirstChild()、gotoNextSibling())来遍历语法树节点。你之前试图给 walk() 传回调的写法完全不符合 API 设计,所以回调逻辑根本不会被执行,最终得到空数组。

修复与替代实现方法

方法一:使用 TreeCursor 手动遍历

通过手动控制游标遍历整个语法树,筛选出函数声明和函数表达式的名称节点:

const Parser = require('tree-sitter');
const JavaScript = require('tree-sitter-javascript');

const parser = new Parser();
parser.setLanguage(JavaScript);

const code = `
function foo() {}
const bar = function() {};
`;

const tree = parser.parse(code);
const functionNames = [];

const cursor = tree.walk();
let hasNext = true;

while (hasNext) {
  const node = cursor.node;
  // 匹配函数声明和函数表达式节点
  if (node.type === 'function_declaration' || node.type === 'function_expression') {
    const nameNode = node.childForFieldName('name');
    if (nameNode) {
      functionNames.push(nameNode.text);
      console.log('找到函数名:', nameNode.text);
    }
  }

  // 深度优先遍历逻辑:先遍历子节点,没有子节点则移动到下一个兄弟,直到回到根节点
  if (cursor.gotoFirstChild()) {
    continue;
  }
  while (!cursor.gotoNextSibling()) {
    if (!cursor.gotoParent()) {
      hasNext = false;
      break;
    }
  }
}

console.log(functionNames); // 输出: ['foo', 'bar']

方法二:使用 Tree-sitter Query(推荐)

Tree-sitter 提供了查询语法,可以精准匹配目标节点,代码更简洁易维护,还能轻松扩展匹配箭头函数、类方法等:

const Parser = require('tree-sitter');
const JavaScript = require('tree-sitter-javascript');

const parser = new Parser();
parser.setLanguage(JavaScript);

const code = `
function foo() {}
const bar = function() {};
const baz = () => {};
`;

const tree = parser.parse(code);
const functionNames = [];

// 定义查询规则,匹配多种函数类型的名称节点
const query = parser.getLanguage().query(`
  (function_declaration (identifier) @func-name)
  (function_expression (identifier) @func-name)
  (arrow_function (identifier) @func-name)
`);

// 执行查询并提取结果
const matches = query.matches(tree.rootNode);
matches.forEach(match => {
  const funcNameNode = match.captures.find(c => c.name === 'func-name').node;
  functionNames.push(funcNameNode.text);
  console.log('找到函数名:', funcNameNode.text);
});

console.log(functionNames); // 输出: ['foo', 'bar', 'baz']

内容的提问来源于stack exchange,提问作者Aadesh Kulkarni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 07:22:57