Support external Eclipse formatter profile via -Asimplebuilder.formatterProfile (#278) - #30
devin-ai-integration[bot] wants to merge 3 commits into
Conversation
…formatterProfile (java-helpers#278) Co-Authored-By: Andreas Igel <andreas.igel@computacenter.com>
Co-Authored-By: Andreas Igel <andreas.igel@computacenter.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
| **Maven**: | ||
| ```xml | ||
| <compilerArgs> | ||
| <arg>-Asimplebuilder.formatterProfile=${project.basedir}/config/eclipse-formatter.xml</arg> |
There was a problem hiding this comment.
Is ${project.basedir} really supported here? I would have expected, that a path (relative or absolute) would be needed here and the processor would not interpret an environment variable
There was a problem hiding this comment.
You're right that the processor does no placeholder substitution — it uses the string as given (file path first, then classpath resource). ${project.basedir} works in the example only because Maven interpolates it inside pom.xml before javac is started, so the processor receives an absolute path. Clarified that in the docs in 2e1b3a8 (and that relative paths resolve against javac's working directory).
| new RoasterCodeGenerator(processingEnv, logger, context.getPerformanceTracker()); | ||
| new RoasterCodeGenerator( | ||
| processingEnv, logger, context.getPerformanceTracker(), context.getFormatterProfile()); |
There was a problem hiding this comment.
Instead of adding a new parameter here, does context contain the processingEnv or code versa? So just giving one of both into constructor?
There was a problem hiding this comment.
Good point — ProcessingContext already holds the ProcessingEnvironment, logger, performance tracker and now the formatter profile. Done in 2e1b3a8: RoasterCodeGenerator has a single constructor RoasterCodeGenerator(ProcessingContext); added getProcessingEnvironment()/getLogger() to the context and updated the resilience test accordingly.
| private RoasterSourceFormatter getFormatter(FormattingMode mode) { | ||
| return formatterCache.computeIfAbsent(mode, m -> new RoasterSourceFormatter(logger, m)); | ||
| return formatterCache.computeIfAbsent( | ||
| mode, m -> new RoasterSourceFormatter(logger, m, formatterProfile)); |
There was a problem hiding this comment.
Please put the creation of a formatting profile into separate line or onto a helper function
There was a problem hiding this comment.
Done in 2e1b3a8: getFormatter now uses computeIfAbsent(mode, this::createFormatter) with a dedicated createFormatter(FormattingMode) helper.
| .getResourceAsStream(formatterProfileResource)) { | ||
| boolean fallbackToBundled = | ||
| !DEFAULT_FORMATTER_PROFILE_RESOURCE.equals(formatterProfileResource); | ||
| Optional<Properties> configured = loadProfile(formatterProfileResource, fallbackToBundled); |
There was a problem hiding this comment.
Having selector booleans in function calls is an antipattern right?
There was a problem hiding this comment.
Agreed. Done in 2e1b3a8: the boolean is gone — loadFormatterProperties now branches once on whether a custom profile is configured and delegates to loadConfiguredProfile(location) (warns "…falling back to the bundled profile") / loadBundledProfile() (warns "…not found on the processor classpath"), both built on a shared readProfile(location).
Co-Authored-By: Andreas Igel <andreas.igel@computacenter.com>
|
moved to java-helpers#284 |
Summary
Resolves java-helpers#278: the JDT formatter profile used for generated builders can now be replaced per project instead of being hard-wired to the bundled
eclipse-java-format.xml.New project-wide compiler option (no annotation override, as scoped in the issue):
Resolution in
RoasterSourceFormatter.loadFormatterProperties():Both are built on a shared
readProfile(location); the path is used as given (no placeholder substitution —${project.basedir}in the Maven example is interpolated by Maven before javac runs).Plumbing:
CompilerArgumentsEnum.FORMATTER_PROFILE→ProcessingContext.getFormatterProfile()(trimmed,null= default) →RoasterCodeGenerator(ProcessingContext)(now the single constructor; the context gainedgetProcessingEnvironment()/getLogger()) →RoasterSourceFormatter(logger, mode, formatterProfile)(3-arg ctor now public, blank → default).Behavior change to note: a missing custom profile previously (via the package-private test ctor) degraded to lightweight formatting; now it falls back to the bundled profile with a warning, so JDT formatting stays on. Two
RoasterSourceFormatterTestcases asserting the old lightweight degradation were replaced byconstructor_missingProfile_fallsBackToBundledProfile; the "profile unavailable → lightweight" path now only triggers when the bundled resource itself is absent.Tests: filesystem profile (tab-indent variant of the bundled XML, asserts tabs in output vs spaces for default), explicit classpath name, missing path, blank value, malformed XML,
CompilerArgumentsReaderread, and an end-to-end compilation with-Asimplebuilder.formatterProfile=<tempfile>inConfigurationProcessingTest. Documented underformattingModeindocs/CONFIGURATION.md.Full processor suite: 423 tests green; example module regenerates byte-identically.
Link to Devin session: https://app.devin.ai/sessions/d691231fba0842a4b842b275ca4b35ed
Open in Devin Desktop: https://app.devin.ai/desktop/session/d691231fba0842a4b842b275ca4b35ed?variant=devin
Requested by: @AndreasIgel