Skip to content

tree-sitter

tree-sitter

bash
compilation_unit          #代码文件
    using_directive       #using语句 -> using CodeGenApi.Swagger;
        using             #-> using
        qualified_name    #-> CodeGenApi.Swagger
            identifier
            .
            identifier
        ;                 #-> ;
    file_scoped_namespace_declaration  #namespace CodeGenApi.Controllers;
        namespace
        qualified_name
        ;
    
    comment               #///或者//注释
    class_declaration     #整个class代码,不包含summary注释
        attribute_list    #注解或者特性 [ApiController]
            [
            attribute     #-> ApiController
            ]
        attribute_list    #-> [Route(\"api/gen/table-template-histories\")]
            [
            attribute     #-> Route(\"api/gen/table-template-histories\")
                identifier              #-> Route
                attribute_argument_list #-> (\"api/gen/table-template-histories\")
                    (
                    attribute_argument  #-> \"api/gen/table-template-histories\"
                        string_literal
                        \"
                        string_literal_content #-> api/gen/table-template-histories
                        \"
                    )
            ]
        attribute_list    #-> [SwaggerTag(\"代码生成模版历史\"), SwaggerGroupInfo(\"Gen\")]
            [
            attribute     #-> SwaggerTag(\"代码生成模版历史\")
                identifier              #-> SwaggerTag
                attribute_argument_list #-> (\"代码生成模版历史\")
                    (
                    attribute_argument  #-> \"代码生成模版历史\"
                        string_literal
                        \"
                        string_literal_content #-> 代码生成模版历史
                        \"
                    )
                ,
                identifier              #-> SwaggerGroupInfo
                attribute_argument_list #-> (\"Gen\")
                    (
                    attribute_argument  #-> \"Gen\"
                        string_literal
                        \"
                        string_literal_content #-> Gen
                        \"
                    )
            ]
            modifier    #->public
            class       #-> class
            identifier  #-> GenTemplateHistoryController
            parameter_list
                (
                parameter      #-> GenTemplateHistoryService service
                    identifier #-> GenTemplateHistoryService
                    identifier #-> service
                )
            base_list
                :
                identifier
            declaration_list
bash
declaration_list
    {
    comment
    method_declaration
        attribute_list
        modifier        #-> public
        modifier        #-> async
        generic_name    #-> Task<ResultModelWithCount<GenTemplateHistoryVo>>
        identifier
        parameter_list
        block
            {
            comment
            local_declaration_statement #-> var result = await service.PageAsync(param);
            return_statement            #-> 
                return
                identifier
                ;
            }
    }
bash
using_directive
file_scoped_namespace_declaration

comment              #summary内容
                     #---- 定义在 class_declaration
attribute_list       #注解区域
modifier class identifier parameter_list base_list
declaration_list

Tree‑sitter 只负责把源码解析成 CST(具体语法树),它本身不直接生成调用图、没有 “跨函数语义分析” 能力Tree-sitte...。调用图是在 Tree‑sitter 之上,自己做一遍「语法树遍历 + 名字解析 + 跨文件汇总」才得到的。

Tree‑sitter 到底能干啥、不能干啥

  • ✅ 能干:把文本 → 结构化 CST 树,告诉你这是函数定义、那是函数调用、这是标识符、那是参数列表。
  • ❌ 不能干:
    • 不知道这个调用指向「哪个具体函数」(同名函数、跨文件、类方法、动态调用都分不清)
    • 不做跨文件、跨模块分析
    • 不维护全局函数表、不做名字绑定

局限(必须说清楚)

  • 动态调用抓不准:eval、字符串拼接函数名、反射、动态 import → tree‑sitter 看不出来
  • 跨语言难:JS 调 Rust、Python 调 C,解析器各一套,要自己做跨语言符号映射
  • 语义歧义:同名、重载、泛型、多态 → 静态分析只能猜,难 100% 精准

一句话:它只告诉你「长什么样」,不告诉你「是谁、指向谁」

因为代码里的调用分 4 种,直接用名字匹配 90% 会错

1. func()               → 全局/局部函数
2. obj.method()          → 实例方法
3. Class.method()        → 静态方法
4. self.method()         → 自身类方法

Tree-sitter 能告诉你调用的结构,但不会告诉你这个名字到底指向谁

你必须自己做「符号绑定」

真实符号 = 前缀 + 名字

全局函数        → 名字
实例方法        → 类名.名字
静态方法        → 类名.名字
自身方法(self)  → 当前类名.名字

只要你能算出前缀,就能 100% 精准匹配。

调用是 func() → 全局 / 当前类函数

查找顺序(必须按这个来,才准确)

  1. 先找当前类里有没有这个名字的方法
  2. 再找全局函数
  3. 最后找外部导入函数

上次更新时间:

最近更新