Skip to content

fix: match JDT LS on same-arity overloads, type arguments and varargs - #2

Merged
1lck merged 1 commit into
mainfrom
fix/jdtls-comparison
Nov 12, 2026
Merged

1lck merged 1 commit into
mainfrom
fix/jdtls-comparison

Conversation

@1lck

@1lck 1lck commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

背景

在 Nacos(2886 个 Java 文件)上同时问 JDT LS 和本插件同一批位置(3 组种子 × 1500 个),比较跳转目标。修复前唯一的两处跳错都是参数个数相同的重载,另有几类 JDT LS 能跳而本插件跳不了的写法。

改动

  • 同参数个数的重载按实参类型挑(internal/codenav/overloads.go):索引给每个方法/构造器记下参数的简单类型名(每个成员一个驻留字符串,同签名共享)。调用处有多个候选时,按实参里看得出的类型打分:字面量(字符串、字符、数字后缀、布尔、null)、字符串拼接、强转、X.class、new 表达式、局部变量和字段声明的类型、解析器能跟下去的表达式类型。规则和 Java 一样:不需要展开可变参数就能匹配的候选优先于可变参数候选;分数相同取第一个(与原来行为一致)。
    • 例:new AccessException("user not found!") 原来跳到 AccessException(int),现在跳到 AccessException(String);initClassMethod(Set.of(...)) 跳到 Set 版本;Preconditions.checkArgument(x, "msg") 跳到两参数版本而不是可变参数版本。
  • 显式类型实参调用(internal/codenav/qualified.go):RestResult.<T>builder() 的 builder 和其后的调用链能跳。
  • 限定名注解:@ExtractorManager.Extractor(...) 的 Extractor 跳到嵌套注解类型。
  • 可变参数参数:String... keys、Type... typeArguments 原来在声明和使用处都跳不了(findLocal 没认出 ...)。
  • resolve.go/parse.go 的改动(Viff 上游文件)都记在 internal/codenav/UPSTREAM.md:Viff 还没发布 codenav,上游发布后连同新文件一起提回去。
  • README 新增“和 JDT LS 对比跳转目标”一节,功能和限制说明同步更新;docs/releases/v0.0.1.md 同步。

验证

  • 新增 internal/codenav/jdtls_cases_test.go(修复前失败 12+5 条,修复后通过);go test -race ./... 通过。
  • 和 JDT LS 对比(修复后):
结果 种子 2 种子 7 种子 11
项目内同一处 1099 1071 1086
JDK 同一个类 326 337 327
都没有结果 8 14 17
只有 JDT LS:依赖库 59 72 64
只有 JDT LS:项目内/JDK 8 3 5
只有本插件 0 2 0
都跳了但不一样 0 1 1

剩下的“不一样”都不是跳错:org.xml.sax.Attributes 在 JDK 里(JDT LS 归为依赖库);Properties.putAll 是 JDK 9 起的重写(模块按 JDK 8 编译)。

  • 命中率与性能(A/B 同条件,ruoyi-vue-pro 6355 文件):命中率不变,p50 约 65 µs,RSS 旧 69.0–70.5 MiB / 新 66.4–72.5 MiB,在噪声内。Nacos 命中率 93.9%/94.9% → 94.0%/95.0%。

🤖 Generated with Claude Code

Comparing definition targets with JDT LS on Nacos (3 x 1500 positions)
found two wrong jumps, both overloads with the same parameter count
(new AccessException("...") went to AccessException(int)), and a few
positions JDT LS resolves that this index missed.

- Overloads with the same arity are scored against what the arguments
  are known to be: literals, casts, new expressions, declared types of
  locals and fields, and the expression types the resolver follows.
  As in Java, a fixed-arity candidate beats one needing varargs.
- Explicit type arguments (RestResult.<T>builder()) no longer hide the
  qualifier.
- Qualified annotations (@Outer.Inner(...)) resolve to the nested type.
- Varargs parameters (String... keys) are found as locals.

Parameter types are stored as one interned string per member; an A/B
run on ruoyi-vue-pro shows no memory or latency change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@1lck
1lck merged commit 7537b2c into main Nov 12, 2026
3 checks passed
@1lck
1lck deleted the fix/jdtls-comparison branch November 12, 2026 13:11
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