Skip to content

Use Prince of Space 2.3.1 - #12444

Draft
bric3 wants to merge 1 commit into
masterfrom
bdu/use-prince-of-space
Draft

bric3 wants to merge 1 commit into
masterfrom
bdu/use-prince-of-space

Conversation

@bric3

@bric3 bric3 commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

What Does This Do

Switches all five Spotless Java configurations from google-java-format 1.36.1 to Prince of Space 2.3.1.
It keeps two-space indentation, a 100-character line width, Java 25 syntax and Prince's default closing-parenthesis placement, and updates the contributor and agent guides.
Spotless remains at 8.10.4 and TableTest formatter at 1.1.2; the native integration loads the explicitly pinned Prince version.

Representative Formatting Changes

Each diff compares google-java-format 1.36.1 on master 3ab1b20503 with Prince of Space 2.3.1 on 2931a8d7dc. Lambda and anonymous-class excerpts include their closing braces and parentheses.

Lambda Pipelines

PluginApplication.java

-        Extension.EXTENSIONS.stream()
-            .filter(ext -> ext.appliesTo(spec))
-            .forEach(
-                ext -> {
-                  try {
-                    ext.apply(configuration, result);
-                  } catch (final Throwable e) {
-                    result.addError(e, ErrorCode.EXTENSION_ERROR, ext.getClass());
-                  }
-                });
+        Extension.EXTENSIONS
+          .stream()
+          .filter(ext -> ext.appliesTo(spec))
+          .forEach(ext -> {
+            try {
+              ext.apply(configuration, result);
+            } catch (final Throwable e) {
+              result.addError(e, ErrorCode.EXTENSION_ERROR, ext.getClass());
+            }
+          });

Fluent Calls

AdviceGeneratorImpl.java

-      final List<Expression> helperTypes =
-          Arrays.stream(helpers)
-              .map(type -> new StringLiteralExpr(type.getClassName()))
-              .collect(Collectors.toList());
+      final List<Expression> helperTypes = Arrays
+        .stream(helpers)
+        .map(type -> new StringLiteralExpr(type.getClassName()))
+        .collect(Collectors.toList());

Nested Callbacks

CoreTracer.java

-    sharedCommunicationObjects.whenReady(
-        () ->
-            AgentTaskScheduler.get()
-                .execute(
-                    () -> {
-                      startMetricsAggregation(config, sco);
-                      maybeStartLogsExport(config);
-                    }));
+    sharedCommunicationObjects.whenReady(() -> AgentTaskScheduler.get().execute(() -> {
+      startMetricsAggregation(config, sco);
+      maybeStartLogsExport(config);
+    }));

Nested Lambda Pipelines

AssertBuilder.java

   protected Set<Class<?>> getSpi(ClassOrInterfaceDeclaration type) {
-    return type.getAnnotationByName("AutoService")
-        .<Set<Class<?>>>map(
-            annotation ->
-                annotation.asNormalAnnotationExpr().getPairs().stream()
-                    .filter(pair -> pair.getNameAsString().equals("value"))
-                    .flatMap(
-                        pair ->
-                            pair.getValue().asArrayInitializerExpr().getValues().stream()
-                                .map(
-                                    value ->
-                                        value
-                                            .asClassExpr()
-                                            .getType()
-                                            .resolve()
-                                            .asReferenceType()
-                                            .getTypeDeclaration()
-                                            .get()
-                                            .getQualifiedName()))
-                    .map(AssertBuilder::loadClass)
-                    .collect(Collectors.toSet()))
-        .orElse(Collections.emptySet());
+    return type
+      .getAnnotationByName("AutoService")
+      .<Set<Class<?>>>map(annotation -> annotation
+        .asNormalAnnotationExpr()
+        .getPairs()
+        .stream()
+        .filter(pair -> pair.getNameAsString().equals("value"))
+        .flatMap(pair -> pair
+          .getValue()
+          .asArrayInitializerExpr()
+          .getValues()
+          .stream()
+          .map(value -> value
+            .asClassExpr()
+            .getType()
+            .resolve()
+            .asReferenceType()
+            .getTypeDeclaration()
+            .get()
+            .getQualifiedName()))
+        .map(AssertBuilder::loadClass)
+        .collect(Collectors.toSet()))
+      .orElse(Collections.emptySet());
   }

Balanced Parameter Wrapping

PluginApplication.java

   private static void printReport(
-      final Configuration configuration, final List<CallSiteResult> result, final boolean failed) {
-    CallSiteReporter.getReporter(configuration)
-        .forEach(reporter -> reporter.report(result, failed));
+      final Configuration configuration,
+      final List<CallSiteResult> result,
+      final boolean failed
+  ) {
+    CallSiteReporter
+      .getReporter(configuration)
+      .forEach(reporter -> reporter.report(result, failed));
   }

The configuration uses two-space indentation, a 100-character line width, balanced wrapping and Prince's default closingParenOnNewLine(true).

Lambda in an HTTP Builder Chain

SharedCommunicationObjects.java

Before (google-java-format 1.36.1):

  private OkHttpClient injectTestAgentSessionHeaderInterceptor(String testSessionToken) {
    return agentHttpClient
        .newBuilder()
        .addInterceptor(
            chain ->
                chain.proceed(
                    chain
                        .request()
                        .newBuilder()
                        .header(X_DATADOG_TEST_SESSION_TOKEN, testSessionToken)
                        .build()))
        .build();
  }

After (Prince of Space 2.3.1):

  private OkHttpClient injectTestAgentSessionHeaderInterceptor(String testSessionToken) {
    return agentHttpClient
      .newBuilder()
      .addInterceptor(chain -> chain.proceed(chain
        .request()
        .newBuilder()
        .header(X_DATADOG_TEST_SESSION_TOKEN, testSessionToken)
        .build()
      ))
      .build();
  }

Anonymous Classes in Method Calls

PluginApplication.java

-      Files.walkFileTree(
-          configuration.classesFolder,
-          new SimpleFileVisitor<Path>() {
-            public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) {
-              if (Files.isRegularFile(file)
-                  && pattern.matcher(file.getFileName().toString()).matches()) {
-                builder.build(file.toFile()).ifPresent(result::add);
-              }
-              return FileVisitResult.CONTINUE;
-            }
-          });
+      Files.walkFileTree(configuration.classesFolder, new SimpleFileVisitor<Path>() {
+        public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) {
+          if (Files.isRegularFile(file)
+              && pattern.matcher(file.getFileName().toString()).matches()) {
+            builder.build(file.toFile()).ifPresent(result::add);
+          }
+          return FileVisitResult.CONTINUE;
+        }
+      });

Ternary Expressions

SharedCommunicationObjects.java

-    httpClientTimeout =
-        config.isCiVisibilityEnabled()
-            ? config.getCiVisibilityBackendApiTimeoutMillis()
-            : TimeUnit.SECONDS.toMillis(config.getAgentTimeout());
+    httpClientTimeout = config.isCiVisibilityEnabled()
+        ? config.getCiVisibilityBackendApiTimeoutMillis()
+        : TimeUnit.SECONDS.toMillis(config.getAgentTimeout());

Mandatory Braces

CoreTracer.java

-      if (this.inUse) return false;
+      if (this.inUse) {
+        return false;
+      }

Javadoc Normalisation

CoreTracer.java

-  /** Tracer start time in nanoseconds measured up to a millisecond accuracy */
+  /**
+   * Tracer start time in nanoseconds measured up to a millisecond accuracy
+   */

Import Separation

PluginApplication.java

 import static datadog.trace.plugin.csi.impl.CallSiteFactory.typeResolver;
-
 import datadog.trace.plugin.csi.AdviceGenerator.CallSiteResult;

Motivation

Refresh the formatter experiment with Prince of Space 2.3.1, including its surrogate, NUL escape and trailing-array-comment fixes.

Additional Notes

This is the configuration base of the two-PR draft experiment. The regenerated Java output is in #12445.
Both branches were rebuilt from freshly fetched master at 3ab1b2050365377e42f546710cfdc314639476b0.

Caution

The Prince of Space 2.3.1 / TableTest formatter 1.1.2 pipeline still requires 129 file exclusions:

  • 102 files: TableTest formatter 1.1.2 turns concatenated row strings into separate annotation array elements;
  • 27 files: other comments are duplicated, removed or reordered.

These files retain their exact content from master. The exclusions are listed in gradle/spotless.gradle.

Prince 2.3.1 preserves the surrogate char literals in both TraceGenerator fixtures and the escaped NUL in PatchUtil, so these three files are re-enabled. The exclusions decrease from 132 to 129.

ClientIpAddressResolver now formats its IPv4 range array without the added fence: its range comments appear once and in order. TagInterceptorTest keeps two narrow spotless:off / spotless:on fences for long TableTest arrays; their comments now identify the TableTest formatter as the component that corrupts concatenated rows.

Direct API checks reproduce the TableTest failure independently of Prince. The three targeted Prince reproductions pass with 2.3.1. Other comment duplication remains: Prince 2.3.1 prints the "All bits set" field comment in DD64bTraceId twice, without Spotless or the TableTest formatter.

The included sources pass the preservation audit and a forced second Java formatting pass. The audit checks parsed structure, identifiers, decoded literals and constant strings, TableTest data, comment content and order, and exact fenced regions. It permits added control-flow braces, conventional comment layout and import organisation. Inline comments can move to a preceding line.

The uncached repository-wide reformat used an 8 GB Gradle daemon heap after the 4 GB run exhausted its heap. Both final passes disable the build cache following a Spotless cached-output file-move failure.

A forced rerun of all Spotless formats stalled in :dd-smoke-tests:java9-modules:spotlessGroovyGradle and was stopped. The forced stability check therefore targets Java formatting tasks.

Focused core tests use a temporary external init script to omit an unrelated private container-image lookup; test caching is disabled for that run. Full-suite tests and performance benchmarks were not run.

The Palantir experiments are #12421 and #12422. The Google Java Format 2 experiments are #13144 and #13145.

Contributor Checklist

@bric3 bric3 added tag: no release notes Changes to exclude from release notes type: refactoring tag: experimental Experimental changes comp: tooling Build & Tooling tag: ai generated Largely based on code generated by an AI or LLM labels Sep 9, 2026
@dougqh

dougqh commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Nice. I'd very much like to have forEach read more like a conventional loop...
list.forEach(item -> { // process item here });

@bric3
bric3 added this pull request to stack #12446 September 9, 2026 16:29
@bric3
bric3 force-pushed the bdu/use-prince-of-space branch from 2c7ea9f to d929fef Compare November 1, 2026 15:36
@bric3 bric3 changed the title Use Prince of Space Use Prince of Space 2.3.0 Nov 1, 2026
@bric3
bric3 force-pushed the bdu/use-prince-of-space branch from d929fef to 374c313 Compare November 1, 2026 19:44
@bric3
bric3 force-pushed the bdu/use-prince-of-space branch from 374c313 to 933e5b6 Compare November 2, 2026 10:52
@bric3 bric3 changed the title Use Prince of Space 2.3.0 Use Prince of Space 2.3.1 Nov 2, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: tooling Build & Tooling tag: ai generated Largely based on code generated by an AI or LLM tag: experimental Experimental changes tag: no release notes Changes to exclude from release notes type: refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants