Skip to content

feat: 不依赖 JDT LS 的轻量 Java 跳转插件 0.0.1 - #1

Merged
1lck merged 1 commit into
mainfrom
feat/java-navigation-0.0.1
Nov 12, 2026
Merged

1lck merged 1 commit into
mainfrom
feat/java-navigation-0.0.1

Conversation

@1lck

@1lck 1lck commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

改动

新插件 Java Navigation 0.0.1:不依赖 JDT LS 的轻量 Java 跳转,按插件契约 v0 编写。插件自带一个用 Go 写的语言服务器(stdio LSP),不需要 JDK 运行时,也不导入 Maven/Gradle。

功能点

  • 跳转到定义:类型、方法、构造器、字段、枚举常量、局部变量、参数、类型参数、注解及其属性。解析时依据导入、同包、通配导入、嵌套、继承链和参数个数,支持调用链 a.b().c;Lombok 访问器跳到字段。
  • 跳进 JDK:项目里找不到的名字到本机 JDK 的 src.zip 里找。按需把那一个源码文件解压成只读副本,放在 ${stateDir} 里,在副本里还能继续跳。
  • 查找引用:只列出能跳回该声明的出现,package/import 不算引用;上限 5000 条。
  • 文档结构:按客户端能力返回树形或扁平的 documentSymbol。
  • 文档同步:支持增量 didChange,打开文件的未保存内容参与索引,关闭后改回读磁盘上的版本。
  • 索引新鲜度:第一次查询时建索引(Git 仓库里用 git ls-files,否则遍历目录,跳过构建输出目录)。距上次扫描超过 2 秒的查询会先按大小和修改时间增量重扫;收到 didChangeWatchedFiles 时也会重扫。
  • 协议细节:协商 UTF-8/UTF-16 位置编码;支持多个工作区文件夹(含增删)、$/cancelRequest、shutdown/exit;不支持的请求返回 MethodNotFound。Windows 上启动 git 不弹控制台窗口。

代码结构

  • internal/codenav/:Viff 的 Java 声明索引,原样拷贝,来源与同步规则见 UPSTREAM.md。Lithe 新增的只有 symbols.go(文档结构)。
  • internal/jdk/:JDK 定位改编自 Viff 的 platform/jdk.go;src.zip 读取改编自 app/jdk.go,新增 Extract/EntryOf/CacheDir。缓存目录名里带上 src.zip 的路径、大小和修改时间,换了 JDK 不会复用旧副本。
  • internal/workspace/:索引生命周期、增量扫描、打开文档覆盖、引用查找。
  • internal/lsp/:JSON-RPC 帧、位置编码转换、URI(含 Windows 盘符与 UNC 路径)、请求处理。
  • cmd/java-navigation/:入口,参数 --state-dir、--version、--no-jdk。

打包与发布

  • scripts/package.mjs:在任意机器上交叉编译(CGO_ENABLED=0、-trimpath),每个平台一个 zip:darwin-arm64、darwin-x64、windows-x64、windows-arm64。Windows 包里的 plugin.json 把启动路径改成 bin/java-navigation.exe。
  • plugin.json:requires 为 languageServers、languages,权限只有 languageServer.launch,启动方式为 packaged,参数 --state-dir ${stateDir},校验参数 --version。
  • CI:Linux 跑 gofmt、vet、-race 测试并打包,按 Lithe Store 规则校验;Windows 跑一次测试。release.yml 推送 tag 后发布,v0.0.1 作为预发布。
  • 许可:Apache-2.0;Viff 来源的代码按 MIT,见 THIRD_PARTY_NOTICES.md。

验证(本地,Apple M4)

  • go test -race ./... 全部通过,包括端到端 LSP 会话测试:初始化、增量编辑后跳转、引用、文档结构、退出。

  • 四个平台包都通过 Lithe Store 的 checkManifest 和 Core 的 plugin-manifest.schema.json。

  • 宿主联调:用桌面端固定的 Core(47c9859)走了一遍完整流程:plugins.declarative.validate 校验清单 → languageServerLaunchPlan 规划为 packaged 启动 → lsp.startServer 启动,会话进入 ready,声明的能力是 definition、references、documentSymbols。三种请求和跳进 JDK 都返回正确位置;${stateDir} 里只有解压出的副本,插件包文件的 SHA-256 前后一致。联调用的是临时测试文件,没有提交。

  • 真实项目(随机取 1500 个标识符,不含关键字和字符串):

    项目 能跳转 单次 p99 第一次跳转 常驻内存
    Nacos 94–95% ≈1 ms 0.12 s ≈75 MiB
    ruoyi-vue-pro ≈54% ≈0.6 ms 0.17 s ≈75–85 MiB

    ruoyi 跳不了的几乎都是依赖库的注解(Swagger @Schema、Lombok @Data、@NotNull、Spring 注解)。

还没验证 / 已知限制

  • 桌面端界面里的手工验收(从文件安装、Cmd+点击、References 面板、Structure),由维护者测试。
  • Windows 包只交叉编译过,Windows 上的测试交给 CI。
  • 不读依赖库;没有 lambda 参数和泛型替换的类型推断;以字面量开头的调用("".trim())推不出类型,这类规则要先在 Viff 修再同步过来。
  • 与 Java Support(JDT LS)同时启用时,宿主怎么分配请求还没有定义,README 里写了暂时不要同时启用。

🤖 Generated with Claude Code

- 语言服务器(Go):跳转到定义、查找引用、文档结构,stdio LSP,支持 UTF-8/UTF-16 位置编码与增量文档同步。
- 解析规则复用 Viff 的 codenav(MIT),原样拷贝,Lithe 新增的 symbols.go 单独成文件。
- 跳进本机 JDK 的 src.zip,按需解压成只读副本放在 ${stateDir}。
- 按平台交叉编译打包(darwin-arm64/x64、windows-x64/arm64),按插件契约 v0 声明 packaged 语言服务器。
- CI(Linux 全量 + Windows 测试、打包与 Store 规则校验)与发布工作流。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@1lck
1lck marked this pull request as ready for review November 12, 2026 11:50
@1lck
1lck merged commit 8e21678 into main Nov 12, 2026
3 checks passed
@1lck
1lck deleted the feat/java-navigation-0.0.1 branch November 12, 2026 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant