Repository navigation
feat: navigate into the jars old projects keep in their tree - #6
Merged
Merged
Conversation
Tested on niche frameworks and old projects (JFinal, Nutz, Solon, Ant, Struts 1, JForum 2): every target lands on its declaration, but JForum 2, an Ant project with its jars committed to WEB-INF/lib and no pom, found none of its dependencies, and the second variable of a declaration of several (int i = 0, size = s.length()) was never found. - deps.TreeJars lists the jars a working tree keeps: the lib and M2_REPO entries of Eclipse .classpath files in their order (with sourcepath), then jars with a lib or libs directory up to three levels above them (WEB-INF/lib, lib/optional), probing the usual lib directories next to build.xml, .classpath and .project even when .gitignore leaves them out. Test resource jars, the Gradle wrapper and build output are not dependencies. A -sources.jar or -src.zip next to a jar is its source. - A source archive is used only when one of the jar's classes is at its place in it: a zip of a source tree would name every class wrongly, so the class jar's stubs are used instead. - Dependencies are now switched on by their own option rather than by a Maven repository being set, and a change to a .classpath file or to any tree jar rereads them. - findLocal gives the variables after the commas of a declaration the first one's type; names in the initializers' arguments are deeper in parentheses and stay unaffected. - nav-bench -under samples another source root (src/, src/main/org/). JForum 2 resolves 99.3% of 1,500 positions (was 95.9%); JFinal, Nutz and Ant gain 4-7 positions each; Nacos and ruoyi-vue-pro are unchanged, and an A/B run shows no change in latency or memory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
为什么
上一个 PR 只在 Nacos 和 ruoyi-vue-pro 这两个新的 Spring/Maven 项目上测过。这次补测了小众框架和老项目,各取 1500 个随机位置:JFinal、Nutz、Solon、Apache Ant、Struts 1、JForum 2。跳到的目标逐个核对过,全部落在对应名字的声明行上,没有跳错的。但发现两个问题:
WEB-INF/lib和lib/里,由 Eclipse 的.classpath列出。插件只读 Maven,所以Logger、HttpSession、FreeMarker 的类都跳不过去。for (int i = 0, size = key.length(); i < size; i++)里的size、int S2, S5;里的S5。改动
读工作区里的 jar(新文件
internal/deps/tree.go).classpath里kind="lib"条目的顺序读,kind="var"的M2_REPO/...条目解析到本地仓库,sourcepath当作源码;/Other/lib/x.jar这种指向别的 Eclipse 项目的路径,按同级目录找。lib或libs目录的 jar,WEB-INF/lib、lib/optional都算。测试资源里的 jar(比如 ant 的src/etc/testcases/.../*.jar)、gradle-wrapper.jar,以及target/build/out/bin里的 jar 都不算。build.xml、.classpath、.project所在目录下的lib、libs、WEB-INF/lib、WebContent/WEB-INF/lib、WebRoot/WEB-INF/lib、web/WEB-INF/lib、src/main/webapp/WEB-INF/lib,即使被.gitignore忽略也会读,因为 Ant/Ivy 常把 jar 下载到这些位置。.classpath的sourcepath,否则取同目录的-sources.jar、-src.jar、-sources.zip、-src.zip。${stateDir}/dependency-sources。源码包必须按包名放(
internal/deps/jars.go)lib-1.0/src/com/...这样整个源码树打成的 zip,会把每个类的全名都推错,结果反而跳不过去,所以这种情况改用 class 存根。Maven 的-sources.jar同样走这个检查。.java都没有的空源码包(grpc-netty-shaded、ojdbc8),和旧代码的处理方式一样。依赖开关(
workspace、lsp、main)Options.Dependencies作为依赖库跳转的开关。以前要配了 Maven 仓库路径才会打开依赖库跳转,所以只有 Maven 项目能跳;现在MavenRepo为空只是不读 Maven 依赖,工作区里的 jar 照样读。--no-dependencies两者都关掉。pom.xml、.classpath、任一个工作区 jar 或它的源码包变了,下一次扫描就会重新读取依赖(depInputs)。一条声明里的多个变量(
internal/codenav/resolve.go)findLocal记下当前这条声明的类型和所在的括号深度。逗号后面、在同一层括号里的变量名沿用这个类型,遇到;、离开这层括号或进入代码块时清掉。M x = make(s2, b), z;里的b仍然是字段,不会被当成局部变量;方法参数和for (X x : xs)也不受影响。其他
cmd/nav-bench新增-under参数,用来指定源码根目录(比如src/、src/main/org/),适配非标准布局的项目。docs/releases/v0.0.1.md和codenav/UPSTREAM.md。实测(Apple M4,各 1500 个随机位置,种子 2)
lib/optional里的 3 个 jar)测试
go test ./...和go test -race ./...全部通过,gofmt 和 vet 干净。TestTreeJarsOfAnAntAndEclipseProject:.classpath的顺序、sourcepath、M2_REPO、缺失的条目、WEB-INF/lib和旁边的-sources.jar、lib/optional、被 gitignore 的lib/ivy;测试 jar、wrapper、build/lib被排除。TestSourcesNotRootedAtThePackagesAreIgnored:源码树打的 zip 改用存根,按包名放的源码包照常使用。TestDefinitionIntoJarsTheTreeKeeps:没有 pom 的项目跳进WEB-INF/lib的 jar;之后往lib/加 jar,下一次扫描就能找到,并且打开的是源码包;WEB-INF前后哈希一致。TestEveryVariableOfADeclarationIsALocal:旧代码上 6 个用例失败 5 个。不在本 PR
build.xml里写在lib之外目录的 classpath(比如<pathelement location="ext/x.jar"/>),以及 Gradle 依赖(Gradle 项目的依赖库跳转 #4)。🤖 Generated with Claude Code