From 921189c3de9536309b2183432cc21a252c136c75 Mon Sep 17 00:00:00 2001 From: Kurt Alfred Kluever Date: Thu, 9 Jan 2025 13:27:04 -0800 Subject: [PATCH] Retain `camelCasing` when translating from a field name to a method name in `UnnecessaryLambda`. PiperOrigin-RevId: 713776818 --- .../bugpatterns/UnnecessaryLambda.java | 22 +++++++++++++------ .../bugpatterns/UnnecessaryLambdaTest.java | 7 +++--- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryLambda.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryLambda.java index dba027bd357..cf797e6b9dc 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryLambda.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryLambda.java @@ -18,6 +18,8 @@ import static com.google.common.base.CaseFormat.LOWER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE; +import static com.google.common.base.CharMatcher.inRange; +import static com.google.common.base.CharMatcher.is; import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; import static com.google.errorprone.fixes.SuggestedFixes.prettyType; @@ -32,6 +34,7 @@ import static com.sun.tools.javac.util.Position.NOPOS; import static java.util.stream.Collectors.joining; +import com.google.common.base.CharMatcher; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Streams; import com.google.errorprone.BugPattern; @@ -126,6 +129,8 @@ public Void visitMethodInvocation(MethodInvocationTree node, Void unused) { return describeMatch(tree, fix.build()); } + private static final CharMatcher UPPER_CASE = inRange('A', 'Z').or(is('_')).or(inRange('0', '9')); + @Override public Description matchVariable(VariableTree tree, VisitorState state) { if (tree.getInitializer() == null) { @@ -152,15 +157,18 @@ public Description matchVariable(VariableTree tree, VisitorState state) { return NO_MATCH; } SuggestedFix.Builder fix = SuggestedFix.builder(); - String name = - isStatic(sym) - ? UPPER_UNDERSCORE.converterTo(LOWER_CAMEL).convert(tree.getName().toString()) - : tree.getName().toString(); + String varName = tree.getName().toString(); + // NOTE: if https://github.com/google/guava/issues/2212 gets resolved, we could use it here. + String methodName = + (isStatic(sym) && UPPER_CASE.matchesAllOf(varName)) + ? UPPER_UNDERSCORE.converterTo(LOWER_CAMEL).convert(varName) + : varName; + new TreePathScanner() { @Override public Void visitMemberSelect(MemberSelectTree node, Void unused) { if (Objects.equals(getSymbol(node), sym)) { - replaceUseWithMethodReference(fix, node, name, state.withPath(getCurrentPath())); + replaceUseWithMethodReference(fix, node, methodName, state.withPath(getCurrentPath())); } return super.visitMemberSelect(node, null); } @@ -168,13 +176,13 @@ public Void visitMemberSelect(MemberSelectTree node, Void unused) { @Override public Void visitIdentifier(IdentifierTree node, Void unused) { if (Objects.equals(getSymbol(node), sym)) { - replaceUseWithMethodReference(fix, node, name, state.withPath(getCurrentPath())); + replaceUseWithMethodReference(fix, node, methodName, state.withPath(getCurrentPath())); } return super.visitIdentifier(node, null); } }.scan(state.getPath().getCompilationUnit(), null); SuggestedFixes.removeModifiers(tree, state, Modifier.FINAL).ifPresent(fix::merge); - lambdaToMethod(state, lambda, fix, name, type); + lambdaToMethod(state, lambda, fix, methodName, type); return describeMatch(tree, fix.build()); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryLambdaTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryLambdaTest.java index 9a44ad57802..059034754e9 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryLambdaTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryLambdaTest.java @@ -277,20 +277,19 @@ void g() { } } """) - // TODO: b/388821905 - we should retain the camelCasing of the variable name .addOutputLines( "Test.java", """ import java.util.function.Function; class Test { - private static String notuppercased(String x) { + private static String notUpperCased(String x) { return "hello " + x; } void g() { - Function l = Test::notuppercased; - System.err.println(notuppercased("world")); + Function l = Test::notUpperCased; + System.err.println(notUpperCased("world")); } } """)