From e0d4e83ad54c998d508a0c0a720a14c7e58c0fa8 Mon Sep 17 00:00:00 2001 From: Patrick Koenig Date: Tue, 2 Aug 2022 14:51:47 -0700 Subject: [PATCH] Add DefaultLocale check --- .../baseline/errorprone/DefaultLocale.java | 63 ++++++++++++++++++ .../errorprone/DefaultLocaleTest.java | 66 +++++++++++++++++++ .../BaselineErrorProneExtension.java | 1 + 3 files changed, 130 insertions(+) create mode 100644 baseline-error-prone/src/main/java/com/palantir/baseline/errorprone/DefaultLocale.java create mode 100644 baseline-error-prone/src/test/java/com/palantir/baseline/errorprone/DefaultLocaleTest.java diff --git a/baseline-error-prone/src/main/java/com/palantir/baseline/errorprone/DefaultLocale.java b/baseline-error-prone/src/main/java/com/palantir/baseline/errorprone/DefaultLocale.java new file mode 100644 index 000000000..830a6480e --- /dev/null +++ b/baseline-error-prone/src/main/java/com/palantir/baseline/errorprone/DefaultLocale.java @@ -0,0 +1,63 @@ +/* + * (c) Copyright 2019 Palantir Technologies Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.palantir.baseline.errorprone; + +import com.google.auto.service.AutoService; +import com.google.errorprone.BugPattern; +import com.google.errorprone.BugPattern.SeverityLevel; +import com.google.errorprone.VisitorState; +import com.google.errorprone.bugpatterns.BugChecker; +import com.google.errorprone.fixes.SuggestedFix; +import com.google.errorprone.matchers.Description; +import com.google.errorprone.matchers.Matcher; +import com.google.errorprone.matchers.method.MethodMatchers; +import com.sun.source.tree.ExpressionTree; +import com.sun.source.tree.MethodInvocationTree; + +@AutoService(BugChecker.class) +@BugPattern( + link = "https://github.com/palantir/gradle-baseline#baseline-error-prone-checks", + linkType = BugPattern.LinkType.CUSTOM, + summary = "Implicit use of the platform default locale, which can result in differing behaviour between JVM" + + " executions.", + severity = SeverityLevel.WARNING) +public final class DefaultLocale extends BugChecker implements BugChecker.MethodInvocationTreeMatcher { + + private static final long serialVersionUID = 1L; + + private static final Matcher MATCHER = MethodMatchers.instanceMethod() + .onExactClass("java.lang.String") + .namedAnyOf("toLowerCase", "toUpperCase") + .withNoParameters(); + + @Override + public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) { + if (MATCHER.matches(tree, state)) { + return buildDescription(tree) + .addFix(SuggestedFix.builder() + .addImport("java.util.Locale") + .replace( + state.getEndPosition(tree.getMethodSelect()), + state.getEndPosition(tree), + "(Locale.ROOT)") + .build()) + .build(); + } + + return Description.NO_MATCH; + } +} diff --git a/baseline-error-prone/src/test/java/com/palantir/baseline/errorprone/DefaultLocaleTest.java b/baseline-error-prone/src/test/java/com/palantir/baseline/errorprone/DefaultLocaleTest.java new file mode 100644 index 000000000..9fc267211 --- /dev/null +++ b/baseline-error-prone/src/test/java/com/palantir/baseline/errorprone/DefaultLocaleTest.java @@ -0,0 +1,66 @@ +/* + * (c) Copyright 2020 Palantir Technologies Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.palantir.baseline.errorprone; + +import org.junit.jupiter.api.Test; + +class DefaultLocaleTest { + + @Test + void testFixToLowerCase() { + fix().addInputLines( + "Test.java", + "class Test {", + " String f(String s) {", + " return s.toLowerCase();", + " }", + "}") + .addOutputLines( + "Test.java", + "import java.util.Locale;", + "class Test {", + " String f(String s) {", + " return s.toLowerCase(Locale.ROOT);", + " }", + "}") + .doTest(); + } + + @Test + void testFixToUpperCase() { + fix().addInputLines( + "Test.java", + "class Test {", + " String f(String s) {", + " return s.toUpperCase();", + " }", + "}") + .addOutputLines( + "Test.java", + "import java.util.Locale;", + "class Test {", + " String f(String s) {", + " return s.toUpperCase(Locale.ROOT);", + " }", + "}") + .doTest(); + } + + private RefactoringValidator fix() { + return RefactoringValidator.of(DefaultLocale.class, getClass()); + } +} diff --git a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/extensions/BaselineErrorProneExtension.java b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/extensions/BaselineErrorProneExtension.java index 1e629da33..c14d48d27 100644 --- a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/extensions/BaselineErrorProneExtension.java +++ b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/extensions/BaselineErrorProneExtension.java @@ -38,6 +38,7 @@ public class BaselineErrorProneExtension { "CompileTimeConstantViolatesLiskovSubstitution", "ConsistentLoggerName", "ConsistentOverrides", + "DefaultLocale", "DeprecatedGuavaObjects", "ExecutorSubmitRunnableFutureIgnored", "ExtendsErrorOrThrowable",