From 010cef12f8442c90eb454f3c9eea4fc90f21332f Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 24 Sep 2026 23:04:41 +0300 Subject: [PATCH] Treat a single upper case letter as a type name in a dotted chain A dotted name is broken after its type-name prefix, and the prefix is found from the case of each segment: "com.example.Foo.bar" is a package, a class and a member. A single upper case letter such as Android's R counted as an all-caps constant, so in "com.some.extremely.verbose.pkg.name.R.string.some_resource" no prefix was found and the name broke at every dot, one segment per line. This ports google/google-java-format#731 by Liam Miller-Cushon: a single upper case letter is UpperCamelCase, so the chain keeps "com.some.extremely.verbose.pkg.name.R.string" together and breaks before the last segment. The golden b26306390 and the two TypeNameClassifierTest assertions come from upstream, with the expected output in this project's style. The 15,747 files of the JDK 21 sources format exactly as before. --- .../java/com/palantir/javaformat/java/TypeNameClassifier.java | 3 ++- .../com/palantir/javaformat/java/TypeNameClassifierTest.java | 2 ++ .../com/palantir/javaformat/java/testdata/b26306390.input | 3 +++ .../com/palantir/javaformat/java/testdata/b26306390.output | 4 ++++ 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/b26306390.input create mode 100644 open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/b26306390.output diff --git a/open-java-format/src/main/java/com/palantir/javaformat/java/TypeNameClassifier.java b/open-java-format/src/main/java/com/palantir/javaformat/java/TypeNameClassifier.java index e151ac194..ccdd5e4b6 100644 --- a/open-java-format/src/main/java/com/palantir/javaformat/java/TypeNameClassifier.java +++ b/open-java-format/src/main/java/com/palantir/javaformat/java/TypeNameClassifier.java @@ -164,7 +164,8 @@ static JavaCaseFormat from(String name) { hasLowercase |= Character.isLowerCase(c); } if (firstUppercase) { - return hasLowercase ? UPPER_CAMEL : UPPERCASE; + // A single upper case letter is a type name: Android's R, and generic type parameters such as T. + return (hasLowercase || name.length() == 1) ? UPPER_CAMEL : UPPERCASE; } else { return hasUppercase ? LOWER_CAMEL : LOWERCASE; } diff --git a/open-java-format/src/test/java/com/palantir/javaformat/java/TypeNameClassifierTest.java b/open-java-format/src/test/java/com/palantir/javaformat/java/TypeNameClassifierTest.java index 4293f51db..907cbb972 100644 --- a/open-java-format/src/test/java/com/palantir/javaformat/java/TypeNameClassifierTest.java +++ b/open-java-format/src/test/java/com/palantir/javaformat/java/TypeNameClassifierTest.java @@ -41,6 +41,7 @@ public void caseFormat() throws Exception { assertThat(JavaCaseFormat.from("a_$")).isEqualTo(JavaCaseFormat.LOWERCASE); assertThat(JavaCaseFormat.from("_")).isEqualTo(JavaCaseFormat.LOWERCASE); assertThat(JavaCaseFormat.from("_A")).isEqualTo(JavaCaseFormat.UPPERCASE); + assertThat(JavaCaseFormat.from("A")).isEqualTo(JavaCaseFormat.UPPER_CAMEL); } private static Optional getPrefix(String qualifiedName) { @@ -60,6 +61,7 @@ public void typePrefixLength() { assertThat(getPrefix("ClassName.CONST")).hasValue(1); assertThat(getPrefix("ClassName.varName")).hasValue(1); assertThat(getPrefix("ClassName.Inner.varName")).hasValue(2); + assertThat(getPrefix("com.R.foo")).hasValue(2); } @Test diff --git a/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/b26306390.input b/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/b26306390.input new file mode 100644 index 000000000..da6c01b01 --- /dev/null +++ b/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/b26306390.input @@ -0,0 +1,3 @@ +class B26306390 { + int resourceId = com.some.extremely.verbose.pkg.name.R.string.some_extremely_long_resource_identifier_that_exceeds_the_column_limit; +} diff --git a/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/b26306390.output b/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/b26306390.output new file mode 100644 index 000000000..be9f7c82b --- /dev/null +++ b/open-java-format/src/test/resources/com/palantir/javaformat/java/testdata/b26306390.output @@ -0,0 +1,4 @@ +class B26306390 { + int resourceId = com.some.extremely.verbose.pkg.name.R.string + .some_extremely_long_resource_identifier_that_exceeds_the_column_limit; +}