From 599dc6f818d9b896c070adb000ab6380738ca1af Mon Sep 17 00:00:00 2001 From: Chris Van de Velde Date: Mon, 16 Jun 2025 12:08:06 +1000 Subject: [PATCH 1/3] Create variable names that are CheckStyle compat --- .../PatternMatchingInstanceof.java | 14 ++++++-- .../PatternMatchingInstanceofTest.java | 32 +++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceof.java b/core/src/main/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceof.java index aae89f12d4b..9a711a00679 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceof.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceof.java @@ -53,6 +53,8 @@ import com.sun.source.util.TreePathScanner; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.TypeTag; + +import java.nio.charset.StandardCharsets; import java.util.HashSet; import java.util.stream.Stream; import javax.inject.Inject; @@ -162,11 +164,17 @@ public Description matchInstanceOf(InstanceOfTree instanceOfTree, VisitorState s private static String generateVariableName(Type targetType, VisitorState state) { Type unboxed = state.getTypes().unboxedType(targetType); String simpleName = targetType.tsym.getSimpleName().toString(); - String lowerFirstLetter = toLowerCase(String.valueOf(simpleName.charAt(0))); - String camelCased = lowerFirstLetter + simpleName.substring(1); + char[] chars = simpleName.toCharArray(); + chars[0] = Character.toLowerCase(chars[0]); + for (int i = 1; i < chars.length + 1; i++) { + if (Character.isUpperCase(chars[i]) && Character.isUpperCase(chars[i + 1])) { + chars[i] = Character.toLowerCase(chars[i]); + } + } + String camelCased = new String(chars); if (SourceVersion.isKeyword(camelCased) || (unboxed != null && unboxed.getTag() != TypeTag.NONE)) { - return lowerFirstLetter; + return Character.toString(Character.toLowerCase(simpleName.charAt(0))); } return camelCased; } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceofTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceofTest.java index c03cec68cfc..7125d73e258 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceofTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceofTest.java @@ -500,6 +500,38 @@ void test(Object o) { .doTest(); } + @Test + public void checkStyleCompliantName() { + helper + .addInputLines( + "Class.java", + """ + import java.sql.SQLException; + + class Class { + void test(SQLException e) { + if (e instanceof SQLException) { + test((Class) e); + } + } + } + """) + .addOutputLines( + "Class.java", + """ + import java.sql.SQLException; + + class Class { + void test(SQLException o) { + if (e instanceof SQLException sqlException) { + test(sqlException); + } + } + } + """) + .doTest(); + } + @Test public void recordPatternMatching() { assume().that(Runtime.version().feature()).isAtLeast(21); From ffa07b8e7323c5f955069c9ed7b71510a90676bb Mon Sep 17 00:00:00 2001 From: Chris Van de Velde Date: Mon, 16 Jun 2025 12:55:34 +1000 Subject: [PATCH 2/3] Handle InterruptedIOException better --- .../bugpatterns/PatternMatchingInstanceof.java | 7 +++++-- .../bugpatterns/PatternMatchingInstanceofTest.java | 14 +++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceof.java b/core/src/main/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceof.java index 9a711a00679..e6cf34f890f 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceof.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceof.java @@ -165,11 +165,14 @@ private static String generateVariableName(Type targetType, VisitorState state) Type unboxed = state.getTypes().unboxedType(targetType); String simpleName = targetType.tsym.getSimpleName().toString(); char[] chars = simpleName.toCharArray(); + boolean priotCharWasUpper = Character.isUpperCase(chars[0]);; chars[0] = Character.toLowerCase(chars[0]); - for (int i = 1; i < chars.length + 1; i++) { - if (Character.isUpperCase(chars[i]) && Character.isUpperCase(chars[i + 1])) { + for (int i = 1; i < chars.length - 1; i++) { + boolean currentCharIsUpper = Character.isUpperCase(chars[i]); + if (currentCharIsUpper && priotCharWasUpper && Character.isUpperCase(chars[i + 1])) { chars[i] = Character.toLowerCase(chars[i]); } + priotCharWasUpper = currentCharIsUpper; } String camelCased = new String(chars); if (SourceVersion.isKeyword(camelCased) diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceofTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceofTest.java index 7125d73e258..0e9aa12e8cf 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceofTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceofTest.java @@ -507,11 +507,17 @@ public void checkStyleCompliantName() { "Class.java", """ import java.sql.SQLException; + import java.io.InterruptedIOException; class Class { void test(SQLException e) { if (e instanceof SQLException) { - test((Class) e); + test((SQLException) e); + } + } + void test(InterruptedIOException e) { + if (e instanceof InterruptedIOException) { + test((InterruptedIOException) e); } } } @@ -520,6 +526,7 @@ void test(SQLException e) { "Class.java", """ import java.sql.SQLException; + import java.io.InterruptedIOException; class Class { void test(SQLException o) { @@ -527,6 +534,11 @@ void test(SQLException o) { test(sqlException); } } + void test(InterruptedIOException e) { + if (e instanceof InterruptedIOException interruptedIoException) { + test(interruptedIoException); + } + } } """) .doTest(); From f36fe68e8c4853109448e73cd55bff1162cc4f81 Mon Sep 17 00:00:00 2001 From: Chris Van de Velde Date: Mon, 16 Jun 2025 13:13:47 +1000 Subject: [PATCH 3/3] More fixes; I wish I could build this locally! --- .../PatternMatchingInstanceof.java | 8 +++---- .../PatternMatchingInstanceofTest.java | 22 +++++++------------ 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceof.java b/core/src/main/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceof.java index e6cf34f890f..529199e5fa2 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceof.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceof.java @@ -16,7 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.base.Ascii.toLowerCase; import static com.google.common.collect.Streams.stream; import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; import static com.google.errorprone.fixes.SuggestedFix.mergeFixes; @@ -54,7 +53,6 @@ import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.TypeTag; -import java.nio.charset.StandardCharsets; import java.util.HashSet; import java.util.stream.Stream; import javax.inject.Inject; @@ -165,14 +163,14 @@ private static String generateVariableName(Type targetType, VisitorState state) Type unboxed = state.getTypes().unboxedType(targetType); String simpleName = targetType.tsym.getSimpleName().toString(); char[] chars = simpleName.toCharArray(); - boolean priotCharWasUpper = Character.isUpperCase(chars[0]);; + boolean priorCharWasUpper = Character.isUpperCase(chars[0]);; chars[0] = Character.toLowerCase(chars[0]); for (int i = 1; i < chars.length - 1; i++) { boolean currentCharIsUpper = Character.isUpperCase(chars[i]); - if (currentCharIsUpper && priotCharWasUpper && Character.isUpperCase(chars[i + 1])) { + if (currentCharIsUpper && priorCharWasUpper && Character.isUpperCase(chars[i + 1])) { chars[i] = Character.toLowerCase(chars[i]); } - priotCharWasUpper = currentCharIsUpper; + priorCharWasUpper = currentCharIsUpper; } String camelCased = new String(chars); if (SourceVersion.isKeyword(camelCased) diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceofTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceofTest.java index 0e9aa12e8cf..14f4f8a156a 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceofTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/PatternMatchingInstanceofTest.java @@ -506,18 +506,15 @@ public void checkStyleCompliantName() { .addInputLines( "Class.java", """ - import java.sql.SQLException; import java.io.InterruptedIOException; + import java.sql.SQLException; class Class { - void test(SQLException e) { - if (e instanceof SQLException) { - test((SQLException) e); - } - } - void test(InterruptedIOException e) { + void test(Object e) { if (e instanceof InterruptedIOException) { test((InterruptedIOException) e); + } else if (e instanceof SQLException) { + test((SQLException) e); } } } @@ -525,18 +522,15 @@ void test(InterruptedIOException e) { .addOutputLines( "Class.java", """ - import java.sql.SQLException; import java.io.InterruptedIOException; + import java.sql.SQLException; class Class { - void test(SQLException o) { - if (e instanceof SQLException sqlException) { - test(sqlException); - } - } - void test(InterruptedIOException e) { + void test(Object e) { if (e instanceof InterruptedIOException interruptedIoException) { test(interruptedIoException); + } else if (e instanceof SQLException sqlException) { + test(sqlException); } } }