🌐 语言 / Language | 🇨🇳 中文 | 🇬🇧 English
code-detector 是一个以go语言编写,跨平台、多编程语言的函数扫描工具。它可以递归扫描指定项目目录,自动识别源文件中的函数/方法定义,记录其行号范围、函数体、调用依赖等信息,并将结果存入 SQLite 数据库以供后续分析。
探测所有代码中的函数 全局变量 自动注册进数据库
从函数角度审查项目的健壮性,函数的合理程度,是否重复造轮子 排除无关上下文干扰,对code agent具有良好支持辅助作用
当前版本:v1.5
| 语言 | 内部名称 | 文件扩展名 | 解析器 |
|---|---|---|---|
| Go | go |
.go |
tree-sitter AST |
| Python | python |
.py |
tree-sitter AST |
| Java | java |
.java |
tree-sitter AST |
| JavaScript | javascript |
.js, .jsx, .mjs |
tree-sitter AST |
| TypeScript / TSX | typescript |
.ts, .tsx |
tree-sitter AST |
| C# | csharp |
.cs |
tree-sitter AST |
| C++ | cpp |
.cpp, .cxx, .cc, .hpp |
tree-sitter AST |
| C | c |
.c, .h¹ |
tree-sitter AST |
| Rust | rust |
.rs |
tree-sitter AST |
| Ruby | ruby |
.rb |
tree-sitter AST |
| Swift | swift |
.swift |
tree-sitter AST |
| Kotlin | kotlin |
.kt, .kts |
tree-sitter AST |
| PHP | php |
.php |
tree-sitter AST |
| Lua | lua |
.lua |
tree-sitter AST |
| Scala | scala |
.scala |
tree-sitter AST |
| Shell / Bash / Zsh | bash |
.sh, .bash, .zsh |
tree-sitter AST |
| Elixir | elixir |
.ex, .exs |
tree-sitter AST |
| Terraform / HCL | hcl |
.tf, .tfvars, .hcl |
tree-sitter AST |
| Elm | elm |
.elm |
tree-sitter AST |
| Groovy | groovy |
.groovy, .gvy, .gy, .gsh |
tree-sitter AST |
| OCaml | ocaml |
.ml, .mli |
tree-sitter AST |
| ERB (Embedded Ruby) | erb |
.erb |
ERB 块解析器 |
| Vue | vue |
.vue |
Template DSL 解析器 |
| Handlebars / Mustache | handlebars |
.hbs, .handlebars, .mustache |
Template DSL 解析器 |
| Jinja2 | jinja2 |
.j2, .jinja, .jinja2 |
Template DSL 解析器 |
| Liquid | liquid |
.liquid |
Template DSL 解析器 |
| 自定义语言 | — | 通过 config.yaml 扩展 |
通用正则解析器 |
¹
.h文件自动消歧:根据文件内容自动识别为 C / C++ / Objective-C 并调用对应解析器。 config.yaml 中已预配模板(取消注释启用):Haskell, R, Objective-C, PowerShell, Perl, Dart, Zig。
code-detector [选项] <项目根目录>不指定 <项目根目录> 时,默认扫描程序所在目录。
扫描所有支持的语言:
code-detector -verbose ./myproject仅扫描特定语言(逗号分隔):
code-detector -lang go,java,python ./myproject指定语言名称列表:
code-detector -lang go,py,js,ts,rs -verbose ./src-lang 参数接受语言内部名称或文件扩展名,例如:go / py / java / js / ts / cs / cpp / rs / rb / kt / swift / php / lua / scala / sh / ex / tf / elm / groovy / sql / proto / css / html / yaml / toml / svelte / cue / ml / vue / hbs 等 35+ 种语言。
排除目录并指定并发数:
code-detector -skip-dirs .git,bin,obj,node_modules -workers 8 ./myproject构建调用图并输出统计:
code-detector -graph ./myproject增量扫描(仅重新解析变更的文件):
code-detector -incremental ./myproject💡 智能增量:如果数据库文件已存在(来自之前的扫描),程序会自动启用增量模式,无需手动指定
-incremental。首次扫描或 DB 不存在时则执行全量扫描。
一键扫描(跳过所有测试文件夹):
scan.bat项目根目录下提供了 scan.bat,双击即可执行带 -skip-dirs testdata,testdata_extreme,tests,test,__tests__,node_modules,mock,mocks 的扫描,自动跳过常见的测试/临时目录,适合日常快速扫描。
指定输出数据库路径:
code-detector -db ./output/my_scan.db -verbose ./myproject调试模式(查看解析器跳过详情):
code-detector -debug ./myproject
-debug模式会输出各语言解析器的内部调试信息(如括号匹配失败时跳过了哪个函数及其位置),便于排查解析器 bug。正常使用-verbose即可。
| 选项 | 说明 |
|---|---|
-lang <列表> |
要扫描的语言,逗号分隔(如 go,py,java)。不指定则扫描所有支持语言 |
-db <路径> |
SQLite 数据库输出路径(默认 scaned_db/scan_result.db) |
-config <路径> |
配置文件路径(默认 config.yaml) |
-max-size <N> |
单文件最大字节数(默认 1MB),超过此大小的文件将被跳过 |
-skip-dirs <列表> |
额外跳过的子目录名,逗号分隔(默认跳过 .git、node_modules 等) |
-workers <N> |
并发工作协程数(默认等于 CPU 逻辑核心数) |
-verbose |
输出详细日志,显示扫描进度、注册信息和解析器跳过记录 |
-debug |
等同于 -verbose,并输出各语言解析器的调试信息(如括号匹配失败时的跳过详情),用于报告解析器 bug |
-graph |
扫描完成后构建调用关系图并输出统计摘要 |
-incremental |
增量扫描模式:仅重新解析 mtime(修改时间)发生变化的文件 |
-format |
输出格式: text(默认)或 json |
-v |
显示版本号 |
直接在终端中运行可执行文件:
code-detector -lang go,python -verbose D:\projects\myapp滚动输出扫描日志,完成后自动退出。如果双击运行(非交互式终端),程序不会暂停等待按键。
.\code-detector.exe -lang go,js,ts -graph .\myproject指定完整路径:
& "D:\tools\code-detector.exe" -lang cpp,cs -workers 8 -verbose "D:\projects\myapp"扫描结果默认存储在 scaned_db/scan_result.db(SQLite 数据库),包含 6 张表,以下是完整的字段说明:
| DB 字段 | 中文说明 | 说明 |
|---|---|---|
id |
会话 ID | 自增主键 |
project_root |
项目根目录 | 被扫描的项目根路径 |
scan_time |
扫描时间 | 扫描开始时间 |
duration_ms |
扫描耗时(毫秒) | 扫描总耗时 |
file_count |
扫描文件数 | 扫描的文件总数 |
func_count |
函数总数 | 发现的函数/方法总数 |
var_count |
全局变量总数 | 发现的全局变量/常量总数 |
| DB 字段 | 中文说明 | 说明 |
|---|---|---|
id |
函数 ID | 自增主键 |
session_id |
所属会话 ID | 关联 scan_sessions.id |
name |
函数名 | 函数/方法名称 |
package_name |
包名/命名空间 | 所属包或命名空间(如 Go 的 package、Java 的 package、C# 的 namespace) |
language |
编程语言 | 语言内部名称(如 go、python、java) |
file_path |
文件路径 | 相对于项目根目录的路径 |
line_start |
起始行号 | 函数定义起始行 |
line_end |
结束行号 | 函数体结束行 |
body |
函数体源码 | 函数的完整源代码 |
hash |
内容哈希 | 函数内容 FNV-1a 32位哈希(十六进制,用于去重判断) |
call_count |
调用总次数 | 函数内部调用次数(含重复调用同一函数) |
nesting_depth |
嵌套深度 | 最大括号嵌套层级 |
parameters |
参数列表 | 函数参数定义字符串,如 (a int, b string) |
return_types |
返回类型 | 返回值类型,如 (int, error) |
receiver |
接收器 | 方法接收器,如 (s *Server) |
is_method |
是否为方法 | 1 为方法,0 为普通函数 |
visibility |
可见性 | public 或 private(基于首字母大小写) |
cyclomatic |
圈复杂度 | McCabe 圈复杂度(if/for/switch/case/&&/ |
parameter_count |
参数个数 | 函数参数数量 |
return_count |
return 语句数 | 函数体中 return 语句的数量 |
statement_count |
语句数 | 函数体中的语句总数 |
anonymous_funcs |
匿名函数数 | 函数内部包含的匿名函数/闭包数量 |
| DB 字段 | 中文说明 | 说明 |
|---|---|---|
id |
依赖 ID | 自增主键 |
caller_id |
调用方函数 ID | 调用者函数 ID,关联 functions.id |
callee_name |
被调用函数名 | 被调用的函数名称 |
| DB 字段 | 中文说明 | 说明 |
|---|---|---|
id |
变量 ID | 自增主键 |
session_id |
所属会话 ID | 关联 scan_sessions.id |
name |
变量名 | 变量/常量名称 |
var_type |
变量类型 | 数据类型(如 int、string、[]byte) |
language |
编程语言 | 语言内部名称 |
package_name |
包名/命名空间 | 所属包或命名空间 |
visibility |
可见性 | public 或 private |
file_path |
文件路径 | 相对于项目根目录的路径 |
line_num |
所在行号 | 变量定义的行号 |
is_const |
是否为常量 | 1 表示常量,0 表示变量 |
hash |
内容哈希 | FNV-1a 32位哈希(十六进制,用于去重) |
| DB 字段 | 中文说明 | 说明 |
|---|---|---|
file_path |
文件路径 | 主键,文件完整路径 |
mtime |
修改时间戳 | 文件最后修改时间的 Unix 时间戳 |
hash |
文件哈希 | 文件内容的 FNV-1a 哈希(用于变更检测) |
session_id |
所属会话 ID | 关联 scan_sessions.id |
content_hash |
内容哈希 | 文件内容的 FNV-1a 哈希(用于 AST 缓存) |
funcs_json |
函数缓存 | 缓存解析结果的 JSON(函数列表) |
globals_json |
全局变量缓存 | 缓存解析结果的 JSON(全局变量列表) |
updated_at |
更新时间戳 | 缓存写入的 Unix 时间戳 |
| DB 字段 | 中文说明 | 说明 |
|---|---|---|
id |
类型 ID | 自增主键 |
session_id |
所属会话 ID | 关联 scan_sessions.id |
name |
类型名 | 类型定义名称 |
kind |
类型种类 | 类型类别:struct / interface / alias / enum |
language |
编程语言 | 语言内部名称 |
package_name |
包名/命名空间 | 所属包或命名空间 |
file_path |
文件路径 | 相对于项目根目录的路径 |
line_start |
起始行号 | 类型定义起始行 |
line_end |
结束行号 | 类型定义结束行 |
body |
类型体源码 | 类型定义的完整源代码 |
fields |
字段描述 | 结构化字段描述(JSON 格式) |
kind |
类型种类 | 类型类别:struct / interface / alias / enum |
language |
编程语言 | 语言内部名称 |
package_name |
包名/命名空间 | 所属包或命名空间 |
file_path |
文件路径 | 相对于项目根目录的路径 |
line_start |
起始行号 | 类型定义起始行 |
line_end |
结束行号 | 类型定义结束行 |
body |
类型体源码 | 类型定义的完整源代码 |
fields |
字段描述 | 结构化字段描述(JSON 格式) |
无需重新扫描,直接读取已有 SQLite 数据库进行分析,支持对扫描结果的离线审计。
code-detector -query <模式> [-db <数据库路径>] [-format text|json]| 模式 | 说明 | 示例 |
|---|---|---|
summary |
显示数据库概要(会话数、函数/变量总数、语言分布等) | -query summary |
functions |
列出所有函数(不含函数体,按文件分组显示行号、调用次数) | -query functions |
func=NAME |
查看函数详情(支持逗号批量: func=A,B,C,含依赖、调用方、函数体预览) |
-query func=main |
vars |
列出所有全局变量 | -query vars |
deps |
调用统计:最热函数、死代码候选、调用分支最广的函数 | -query deps |
calls=NAME |
查看哪些函数调用了指定函数 | -query calls=Parse |
dead |
列出 call_count = 0 的潜在死代码 | -query dead |
missing |
列出被调用但找不到定义的函数名(自动过滤标准库,用于发现依赖缺失) | -query missing |
largest=N / top=N |
列出行数最多的 N 个函数(超大函数风险分析,largest 为推荐名) |
-query largest=10 |
deep=N |
列出嵌套深度 >= N 的函数(复杂度分析) | -query deep=3 |
tree=NAME |
🆕 递归提取指定函数及其所有传递依赖(含函数体) | -query tree=main |
complexity=N |
🆕 列出圈复杂度最高的 N 个函数 | -query complexity=5 |
params=N |
🆕 列出参数数量 >= N 的函数 | -query params=5 |
anon |
🆕 列出包含匿名函数/闭包的函数 | -query anon |
files |
🆕 文件级统计:函数数/圈复杂度/参数/return/可见性分布 | -query files |
types |
🆕 列出所有类型定义(struct/interface) | -query types |
module=NAME |
🆕 查看指定包/模块内的所有函数 | -query module=main |
api |
🆕 列出所有公开/导出函数及其复杂度 | -query api |
affected=NAME |
🆕 反向依赖追踪:修改某函数将影响哪些调用方 | -query affected=Parse |
changelog |
🆕 对比最近两次扫描的函数变更差异(新增/移除/行数变化) | -query changelog |
quality |
🆕 解析质量报告:复杂度/函数大小/语言分布/死代码统计 | -query quality |
smell |
🔬 代码异味检测:上帝函数/过长函数/高复杂度/参数过多/嵌套过深/死代码 6 维度 | -query smell |
graphviz=TITLE |
📊 输出 Graphviz DOT 格式调用图,按包名分组子图,颜色编码分类 | -query graphviz=myapp |
coverage |
📈 函数级测试覆盖分析:统计已覆盖/未覆盖函数数及比例,输出 Top 30 未覆盖函数 | -query coverage |
crosslang[=NAME] |
🌐 跨语言调用检测:列出调用方与被调用方分属不同语言的边;指定函数名则筛选 | -query crosslang / -query crosslang=Parse |
diff=s1,s2 |
🔄 指定会话差异对比:对比任意两次扫描会话的函数新增/移除/变更(含行号变化) | -query diff=1,2 |
complexity=NAME |
📐 深度复杂度报告:认知复杂度 / Halstead 容量/难度/工作量 / 可维护性指数 MI | -query complexity=Scan |
clone[=0.8] |
🔄 代码克隆检测:精确克隆(函数体完全一致)+ 近似克隆(MinHash 相似度≥阈值) | -query clone / -query clone=0.9 |
coupling |
🔗 耦合度分析:Ca(被调数)/Ce(调用数)/不稳定性I,含可视化条形图 | -query coupling |
circular |
🔁 循环依赖检测:DFS 查找调用图中的循环路径(长度≤10) | -query circular |
lcom |
🧩 方法内聚度 LCOM:按类型分组计算方法间字段共享度(0=完美内聚, 1=完全无内聚) | -query lcom |
smell-extended |
👃 扩展异味检测:新增霰弹式修改/依恋情结/消息链/中间人/数据团/过度通用 6 种 | -query smell-extended |
sec-scan |
🔒 函数级安全扫描:硬编码密钥/SQL注入/命令注入/危险函数/路径遍历 5 类 | -query sec-scan |
perf-scan |
⚡ 函数级性能扫描:N+1查询/循环内I-O/字符串拼接/大对象分配/类型转换 5 类 | -query perf-scan |
deep-analysis |
📊 深度综合分析报告:以上 7 项汇总一览(复杂度/克隆/耦合/内聚/异味/安全/性能) | -query deep-analysis |
批量查询示例 — 同时查看多个函数详情:
code-detector -query func=main,Scan,InitDBJSON 输出示例 — 所有 -query 模式均支持:
code-detector -query summary -format json
code-detector -query func=main -format json
code-detector -query top=5 -format json
code-detector -query tree=printBanner -format json启用 -graph 选项时,终端会输出调用关系统计摘要。
code-detector 从 v0.8 起支持 MCP(Model Context Protocol) 服务器模式,让 AI 客户端(如 Claude Desktop)可以直接与 code-detector 交互,实时查询项目函数数据。
code-detector -mcp [-db <数据库路径>]通过 stdio 传输 JSON-RPC 消息,兼容所有标准 MCP 客户端。
| 工具名 | 功能说明 | 对应 CLI 查询 |
|---|---|---|
get_summary |
数据库概要统计(会话/函数/变量/语言分布) | summary |
list_functions |
列出所有函数(可按语言筛选) | functions |
get_function |
查看指定函数详情(签名/复杂度/依赖) | func=NAME |
get_function_body |
获取函数体源码 | (新增) |
list_variables |
列出全局变量 | vars |
analyze_deps |
函数调用关系统计 | deps |
find_callers |
查看谁调用了指定函数 | calls=NAME |
find_dead_code |
死代码检测 | dead |
find_missing_deps |
缺失依赖检测 | missing |
find_missing_deps |
缺失依赖检测(自动过滤标准库) | missing |
top_functions |
按行数排序 TOP N | largest=N / top=N |
deep_nesting |
深层嵌套函数检测 | deep=N |
high_complexity |
高圈复杂度函数 TOP N | complexity=N |
many_params |
参数数量超标检测 | params=N |
find_anonymous |
含匿名函数的函数检测 | anon |
file_metrics |
文件级统计信息 | files |
list_types |
类型定义列表 | types |
get_func_tree |
递归提取函数及其所有传递依赖(含函数体) | tree=NAME |
get_module |
🆕 查看指定包/模块内所有函数 | module=NAME |
list_api |
🆕 列出所有公开/导出函数 | api |
get_affected |
🆕 反向依赖追踪:修改某函数会影响哪些调用方 | affected=NAME |
get_changelog |
🆕 对比最近两次扫描的函数变更差异 | changelog |
get_quality |
🆕 解析质量报告(复杂度/大小/语言分布) | quality |
| URI | 内容 | 格式 |
|---|---|---|
db://summary |
数据库概要 | JSON |
db://functions |
全量函数列表 | JSON |
db://variables |
全局变量列表 | JSON |
db://files |
文件级统计 | JSON |
db://types |
类型定义 | JSON |
db://sessions/latest |
最近扫描会话信息 | JSON |
db://quality |
🆕 解析质量报告(复杂度/函数大小/语言分布) | JSON |
db://api |
🆕 公开 API 函数列表 | JSON |
db://changelog/latest |
🆕 最近两次扫描的函数变更差异 | JSON |
在 Claude Desktop 的 claude_desktop_config.json 中添加:
{
"mcpServers": {
"code-detector": {
"command": "code-detector.exe",
"args": ["-mcp", "-db", "D:\\projects\\myapp\\scaned_db\\scan_result.db"]
}
}
}配置完成后,Claude Desktop 即可直接调用上述 23 个工具和 9 个资源来查询项目代码分析结果。
- 程序内置了系统关键目录保护,拒绝扫描 Windows 系统盘根目录、
C:\Windows、/etc、/proc等系统目录,避免磁盘卡死或数据损坏。 - 提供退出前的按键等待(仅在交互式终端中触发),方便双击运行时查看结果。
默认 config.yaml 为空(使用内置解析器),您可以按以下格式自定义语言解析规则:
languages:
- name: "my_lang"
extensions: [".mylang"]
function_regex: "func\\s+(?P<name>\\w+)\\s*\\("
single_comment: ["//"]
block_comment: [["/*", "*/"]]如果某个扩展名已被内置解析器占用,配置中的自定义规则不会覆盖内置解析器。内置支持以外的扩展名才会使用自定义正则解析。
build.batmake build构建产物为 code-detector.exe。
本项目基于 MIT 许可证 开源。
本项目使用了 tree-sitter — 强大的增量解析框架, 其核心及各语言语法解析器均基于 MIT 许可证发布。