square / javapoet

A Java API for generating .java source files.
Apache License 2.0
10.83k stars 1.38k forks source link

Ability to modify JavaFile.TypeSpec #965

Open fejesjoco opened 1 year ago

fejesjoco commented 1 year ago

I would like an API for modifying the TypeSpec inside a built JavaFile, or in a JavaFile.Builder, but this seems impossible.

The TypeSpec field in JavaFile and JavaFile.Builder is final. It can only be passed from user code in the JavaFile.builder method, and it stays forever, not even JavaFile.toBuilder allows modifying it. This is surprising because I think all fields in JavaPoet's builders are normally mutable. Btw, the packageName suffers from the same issue.

Workarounds are not pretty. I could start a new TypeSpec from scratch and copy stuff over. But the fileComment field is only readable from JavaFile, while staticImports is only readable from JavaFile.Builder, and indent is private in both. (And btw I just noticed that toBuilder doesn't copy staticImports.)

(For a comparison, KotlinPoet's FileSpec.toBuilder allows changing the package, and the members field in FileSpec.Builder can be rebuilt entirely.)

One use case is actually similar to what my colleague proposed in issue #924: to build a framework that adds a Generated annotation to all TypeSpec's after they're built. More generally I'd like a framework where TypeSpec and JavaFile can be built concurrently and glued together afterwards.

Idea 1: we could have JavaFile.toBuilder overloads that allow changing the TypeSpec (and also the packageName). This matches what KotlinPoet does, and also matches what e.g. ParameterSpec.toBuilder does, but it's not a common pattern in this codebase.

Idea 2: we could make the TypeSpec (and also the packageName) non-final in JavaFile.Builder. Similar pattern can be seen in e.g. MethodSpec that allows changing the name, but again this isn't a common pattern.

I'm happy to send a PR with a solution that you like.

liujianpc commented 1 year ago

     您好,本人已收到您的邮件!谢谢!      祝您工作顺利,生活愉快!