From 9ab5858c0664bd97d86c48248aefd9847b6980c4 Mon Sep 17 00:00:00 2001 From: ghm Date: Mon, 28 Oct 2024 07:37:51 -0700 Subject: [PATCH 01/38] Document our exciting Matches/NotMatches discoveries on @Placeholder. PiperOrigin-RevId: 690605162 --- .../google/errorprone/refaster/annotation/Placeholder.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/com/google/errorprone/refaster/annotation/Placeholder.java b/core/src/main/java/com/google/errorprone/refaster/annotation/Placeholder.java index 76baaca0039..4350b552842 100644 --- a/core/src/main/java/com/google/errorprone/refaster/annotation/Placeholder.java +++ b/core/src/main/java/com/google/errorprone/refaster/annotation/Placeholder.java @@ -79,6 +79,10 @@ * must contain references to all arguments that are passed to them -- except * those corresponding to parameters annotated with {@link MayOptionallyUse}. * + *

Note that {@link Matches} and {@link NotMatches} can be applied to placeholder methods, but, + * and this is a serious health warning, those predicates will only be matched if + * the placeholder method is used as an expression, not a statement. + * * @author lowasser@google.com (Louis Wasserman) */ @Target(ElementType.METHOD) From d67bc156b737d13ac693d73a403a11a97804423f Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 28 Oct 2024 08:16:13 -0700 Subject: [PATCH 02/38] Prepare for the removal of `TypeTag.UNKNOWN` The constant was removed as part of https://bugs.openjdk.org/browse/JDK-8339296 This is a minimal fix to avoid breaking for upcoming javac versions. I suspect this logic isn't actually necessary, we aren't supposed to process ASTs with errors and there have been a variety of improvements in how that's handled since this was added. PiperOrigin-RevId: 690616927 --- .../main/java/com/google/errorprone/util/ASTHelpers.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java b/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java index 2c52c2a3140..1491b4dbd81 100644 --- a/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java +++ b/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java @@ -1299,15 +1299,17 @@ public static boolean isVoidType(Type type, VisitorState state) { } private static final ImmutableSet SUBTYPE_UNDEFINED = - Sets.immutableEnumSet( - TypeTag.METHOD, TypeTag.PACKAGE, TypeTag.UNKNOWN, TypeTag.ERROR, TypeTag.FORALL); + Sets.immutableEnumSet(TypeTag.METHOD, TypeTag.PACKAGE, TypeTag.ERROR, TypeTag.FORALL); /** Returns true if {@code erasure(s) <: erasure(t)}. */ public static boolean isSubtype(Type s, Type t, VisitorState state) { if (s == null || t == null) { return false; } - if (SUBTYPE_UNDEFINED.contains(s.getTag()) || SUBTYPE_UNDEFINED.contains(t.getTag())) { + if (SUBTYPE_UNDEFINED.contains(s.getTag())) { + return false; + } + if (t == state.getSymtab().unknownType) { return false; } Types types = state.getTypes(); From e71db1f369a9367f6f2db34c4fbd006b6d6238fd Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 28 Oct 2024 16:23:59 -0700 Subject: [PATCH 03/38] Check that `--should-stop=ifError=FLOW` is set when EP is set up using the `-Xplugin` integration See https://github.com/google/error-prone/issues/4595#issuecomment-2424140062 PiperOrigin-RevId: 690786174 --- .../BaseErrorProneJavaCompiler.java | 16 +++-- .../ErrorProneCompilerIntegrationTest.java | 2 +- .../errorprone/ErrorProneJavacPluginTest.java | 60 +++++++++++++++++-- .../google/errorprone/VisitorStateTest.java | 3 +- .../bugpatterns/UnicodeInCodeTest.java | 3 +- 5 files changed, 72 insertions(+), 12 deletions(-) diff --git a/check_api/src/main/java/com/google/errorprone/BaseErrorProneJavaCompiler.java b/check_api/src/main/java/com/google/errorprone/BaseErrorProneJavaCompiler.java index 0d81955c2fe..9515aa0ebca 100644 --- a/check_api/src/main/java/com/google/errorprone/BaseErrorProneJavaCompiler.java +++ b/check_api/src/main/java/com/google/errorprone/BaseErrorProneJavaCompiler.java @@ -84,6 +84,7 @@ static void addTaskListener( JavacTask javacTask, ScannerSupplier scannerSupplier, ErrorProneOptions errorProneOptions) { Context context = ((BasicJavacTask) javacTask).getContext(); checkCompilePolicy(Options.instance(context).get("compilePolicy")); + checkShouldStopIfErrorPolicy(Options.instance(context).get("should-stop.ifError")); setupMessageBundle(context); RefactoringCollection[] refactoringCollection = {null}; javacTask.addTaskListener( @@ -196,13 +197,19 @@ private static ImmutableList setCompilePolicyToByFile(ImmutableListbuilder().addAll(args).add("-XDcompilePolicy=simple").build(); } - private static void checkShouldStopIfErrorPolicy(String arg) { - String value = arg.substring(arg.lastIndexOf('=') + 1); + private static void checkShouldStopIfErrorPolicy(String value) { + if (value == null) { + throw new InvalidCommandLineOptionException( + "The default --should-stop=ifError policy (INIT) is not supported by Error Prone," + + " pass --should-stop=ifError=FLOW instead"); + } CompileState state = CompileState.valueOf(value); if (CompileState.FLOW.isAfter(state)) { throw new InvalidCommandLineOptionException( String.format( - "%s is not supported by Error Prone, pass --should-stop=ifError=FLOW instead", arg)); + "--should-stop=ifError=%s is not supported by Error Prone, pass" + + " --should-stop=ifError=FLOW instead", + value)); } } @@ -210,7 +217,8 @@ private static ImmutableList setShouldStopIfErrorPolicyToFlow( ImmutableList args) { for (String arg : args) { if (arg.startsWith("--should-stop=ifError") || arg.startsWith("-XDshould-stop.ifError")) { - checkShouldStopIfErrorPolicy(arg); + String value = arg.substring(arg.lastIndexOf('=') + 1); + checkShouldStopIfErrorPolicy(value); return args; // don't do anything if a valid policy is already set } } diff --git a/core/src/test/java/com/google/errorprone/ErrorProneCompilerIntegrationTest.java b/core/src/test/java/com/google/errorprone/ErrorProneCompilerIntegrationTest.java index 0574fb186cd..560f8e403d5 100644 --- a/core/src/test/java/com/google/errorprone/ErrorProneCompilerIntegrationTest.java +++ b/core/src/test/java/com/google/errorprone/ErrorProneCompilerIntegrationTest.java @@ -758,6 +758,6 @@ public void stopPolicy_init_xD() { InvalidCommandLineOptionException.class, () -> compiler.compile(new String[] {"-XDshould-stop.ifError=INIT"}, ImmutableList.of())); - assertThat(e).hasMessageThat().contains("-XDshould-stop.ifError=INIT is not supported"); + assertThat(e).hasMessageThat().contains("--should-stop=ifError=INIT is not supported"); } } diff --git a/core/src/test/java/com/google/errorprone/ErrorProneJavacPluginTest.java b/core/src/test/java/com/google/errorprone/ErrorProneJavacPluginTest.java index b50eef04927..a86f04c13b3 100644 --- a/core/src/test/java/com/google/errorprone/ErrorProneJavacPluginTest.java +++ b/core/src/test/java/com/google/errorprone/ErrorProneJavacPluginTest.java @@ -100,7 +100,8 @@ public void hello() throws IOException { null, fileManager, diagnosticCollector, - ImmutableList.of("-Xplugin:ErrorProne", "-XDcompilePolicy=byfile"), + ImmutableList.of( + "-Xplugin:ErrorProne", "-XDcompilePolicy=byfile", "--should-stop=ifError=FLOW"), ImmutableList.of(), fileManager.getJavaFileObjects(source)); assertThat(task.call()).isFalse(); @@ -144,7 +145,8 @@ public void applyFixes() throws IOException { ImmutableList.of( "-Xplugin:ErrorProne" + " -XepPatchChecks:MissingOverride -XepPatchLocation:IN_PLACE", - "-XDcompilePolicy=byfile"), + "-XDcompilePolicy=byfile", + "--should-stop=ifError=FLOW"), ImmutableList.of(), fileManager.getJavaFileObjects(fileA, fileB)); assertWithMessage(Joiner.on('\n').join(diagnosticCollector.getDiagnostics())) @@ -203,7 +205,8 @@ public void applyToPatchFile() throws IOException { "-Xplugin:ErrorProne" + " -XepPatchChecks:MissingOverride -XepPatchLocation:" + patchDir, - "-XDcompilePolicy=byfile"), + "-XDcompilePolicy=byfile", + "--should-stop=ifError=FLOW"), ImmutableList.of(), fileManager.getJavaFileObjects(fileA, fileB)); assertWithMessage(Joiner.on('\n').join(diagnosticCollector.getDiagnostics())) @@ -254,7 +257,8 @@ public void explicitBadPolicyGiven() throws IOException { new PrintWriter(sw, true), fileManager, diagnosticCollector, - ImmutableList.of("-XDcompilePolicy=bytodo", "-Xplugin:ErrorProne"), + ImmutableList.of( + "-XDcompilePolicy=bytodo", "--should-stop=ifError=FLOW", "-Xplugin:ErrorProne"), ImmutableList.of(), fileManager.getJavaFileObjects(source)); RuntimeException expected = assertThrows(RuntimeException.class, () -> task.call()); @@ -375,7 +379,8 @@ public void compilesWithFix() throws IOException { diagnosticCollector, ImmutableList.of( "-Xplugin:ErrorProne -XepDisableAllChecks -Xep:TestCompilesWithFix:ERROR", - "-XDcompilePolicy=byfile"), + "-XDcompilePolicy=byfile", + "--should-stop=ifError=FLOW"), ImmutableList.of(), fileManager.getJavaFileObjects(source)); assertThat(task.call()).isFalse(); @@ -385,4 +390,49 @@ public void compilesWithFix() throws IOException { .collect(onlyElement()); assertThat(diagnostic.getMessage(ENGLISH)).contains("[TestCompilesWithFix]"); } + + @Test + public void noShouldStopIfErrorPolicy() throws IOException { + FileSystem fileSystem = Jimfs.newFileSystem(Configuration.unix()); + Path source = fileSystem.getPath("Test.java"); + Files.writeString(source, "class Test {}"); + JavacFileManager fileManager = new JavacFileManager(new Context(), false, UTF_8); + DiagnosticCollector diagnosticCollector = new DiagnosticCollector<>(); + StringWriter sw = new StringWriter(); + JavacTask task = + JavacTool.create() + .getTask( + new PrintWriter(sw, true), + fileManager, + diagnosticCollector, + ImmutableList.of("-Xplugin:ErrorProne", "-XDcompilePolicy=byfile"), + ImmutableList.of(), + fileManager.getJavaFileObjects(source)); + RuntimeException expected = assertThrows(RuntimeException.class, task::call); + assertThat(expected) + .hasMessageThat() + .contains("The default --should-stop=ifError policy (INIT) is not supported"); + } + + @Test + public void shouldStopIfErrorPolicyInit() throws IOException { + FileSystem fileSystem = Jimfs.newFileSystem(Configuration.unix()); + Path source = fileSystem.getPath("Test.java"); + Files.writeString(source, "class Test {}"); + JavacFileManager fileManager = new JavacFileManager(new Context(), false, UTF_8); + DiagnosticCollector diagnosticCollector = new DiagnosticCollector<>(); + StringWriter sw = new StringWriter(); + JavacTask task = + JavacTool.create() + .getTask( + new PrintWriter(sw, true), + fileManager, + diagnosticCollector, + ImmutableList.of( + "-Xplugin:ErrorProne", "-XDcompilePolicy=byfile", "--should-stop=ifError=INIT"), + ImmutableList.of(), + fileManager.getJavaFileObjects(source)); + RuntimeException expected = assertThrows(RuntimeException.class, task::call); + assertThat(expected).hasMessageThat().contains("--should-stop=ifError=INIT is not supported"); + } } diff --git a/core/src/test/java/com/google/errorprone/VisitorStateTest.java b/core/src/test/java/com/google/errorprone/VisitorStateTest.java index b0cde5a0ca8..d90b912fb96 100644 --- a/core/src/test/java/com/google/errorprone/VisitorStateTest.java +++ b/core/src/test/java/com/google/errorprone/VisitorStateTest.java @@ -180,7 +180,8 @@ public void memoizeCannotAccessTreePath() throws IOException { ImmutableList.of( "-Xplugin:ErrorProne -XepDisableAllChecks" + " -Xep:CheckThatTriesToMemoizeBasedOnTreePath:ERROR", - "-XDcompilePolicy=byfile"), + "-XDcompilePolicy=byfile", + "--should-stop=ifError=FLOW"), ImmutableList.of(), fileManager.getJavaFileObjects(source)); assertThat(task.call()).isFalse(); diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UnicodeInCodeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UnicodeInCodeTest.java index 9d3a31ec78b..aa080d70f37 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UnicodeInCodeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UnicodeInCodeTest.java @@ -162,7 +162,8 @@ public void asciiSub() { null, fileManager, diagnosticCollector, - ImmutableList.of("-Xplugin:ErrorProne", "-XDcompilePolicy=simple"), + ImmutableList.of( + "-Xplugin:ErrorProne", "-XDcompilePolicy=simple", "--should-stop=ifError=FLOW"), ImmutableList.of(), ImmutableList.of( new SimpleJavaFileObject( From aead1e833c8f8564f52a0059b899016281c87247 Mon Sep 17 00:00:00 2001 From: Error Prone Team Date: Tue, 29 Oct 2024 05:34:42 -0700 Subject: [PATCH 04/38] Ban extending @AutoValue.Builder and @AutoBuilder classes This addresses the internal AndroidLint checker, and the external-but-disabled-internally errorprone. This was TGP'ed. There were only 3 offending cases. I suppressed 2 and refactored 1. I reworded "an @AutoValue/@AutoOneOf class" to a broader "AutoValue-like classes", but I'm open to better ideas. PiperOrigin-RevId: 690981208 --- .../bugpatterns/ExtendsAutoValue.java | 62 ++++++++-- .../bugpatterns/ExtendsAutoValueTest.java | 114 +++++++++++++++++- 2 files changed, 157 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ExtendsAutoValue.java b/core/src/main/java/com/google/errorprone/bugpatterns/ExtendsAutoValue.java index dca28df5d7c..7cd45ba6341 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ExtendsAutoValue.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ExtendsAutoValue.java @@ -16,20 +16,27 @@ package com.google.errorprone.bugpatterns; +import static com.google.errorprone.util.ASTHelpers.annotationsAmong; +import static com.google.errorprone.util.ASTHelpers.getSymbol; + import com.google.common.collect.ImmutableSet; import com.google.errorprone.BugPattern; import com.google.errorprone.BugPattern.SeverityLevel; +import com.google.errorprone.ErrorProneFlags; import com.google.errorprone.VisitorState; import com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher; import com.google.errorprone.matchers.Description; import com.google.errorprone.suppliers.Supplier; import com.google.errorprone.util.ASTHelpers; import com.sun.source.tree.ClassTree; +import com.sun.source.tree.Tree; import com.sun.tools.javac.util.Name; +import java.util.stream.Stream; +import javax.inject.Inject; /** Makes sure that you are not extending a class that has @AutoValue as an annotation. */ @BugPattern( - summary = "Do not extend an @AutoValue/@AutoOneOf class in non-generated code.", + summary = "Do not extend an @AutoValue-like classes in non-generated code.", severity = SeverityLevel.ERROR) public final class ExtendsAutoValue extends BugChecker implements ClassTreeMatcher { @@ -37,26 +44,55 @@ public final class ExtendsAutoValue extends BugChecker implements ClassTreeMatch VisitorState.memoize( s -> ImmutableSet.of( + s.getName("com.google.auto.value.AutoOneOf"), + s.getName("com.google.auto.value.AutoValue"))); + + private static final Supplier> AUTOS_AND_BUILDERS = + VisitorState.memoize( + s -> + ImmutableSet.of( + s.getName("com.google.auto.value.AutoBuilder"), + s.getName("com.google.auto.value.AutoOneOf"), s.getName("com.google.auto.value.AutoValue"), - s.getName("com.google.auto.value.AutoOneOf"))); + s.getName("com.google.auto.value.AutoValue$Builder"))); + + private final boolean testBuilders; + private final Supplier> autos; + + @Inject + ExtendsAutoValue(ErrorProneFlags flags) { + this.testBuilders = flags.getBoolean("ExtendsAutoValue:builders").orElse(true); + this.autos = testBuilders ? AUTOS_AND_BUILDERS : AUTOS; + } @Override public Description matchClass(ClassTree tree, VisitorState state) { - if (tree.getExtendsClause() == null) { - // Doesn't extend anything, can't possibly be a violation. + if (tree.getExtendsClause() == null + && (!testBuilders || tree.getImplementsClause().isEmpty())) { return Description.NO_MATCH; } - if (!ASTHelpers.annotationsAmong( - ASTHelpers.getSymbol(tree.getExtendsClause()), AUTOS.get(state), state) - .isEmpty()) { - // Violation: one of its superclasses extends AutoValue. - if (!isInGeneratedCode(state)) { - return buildDescription(tree).build(); - } - } + Stream parents = + Stream.concat( + Stream.ofNullable(tree.getExtendsClause()), + testBuilders ? tree.getImplementsClause().stream() : Stream.empty()); - return Description.NO_MATCH; + return parents + .map(parent -> annotationsAmong(getSymbol(parent), autos.get(state), state)) + .filter(annotations -> !annotations.isEmpty()) + .findFirst() + .filter(unused -> !isInGeneratedCode(state)) + .map( + annotations -> { + String name = annotations.iterator().next().toString(); + name = name.substring(name.lastIndexOf('.') + 1); // Strip package + name = name.replace('$', '.'); // AutoValue$Builder -> AutoValue.Builder + return buildDescription(tree) + .setMessage( + String.format("Do not extend an @%s class in non-generated code.", name)) + .build(); + }) + .orElse(Description.NO_MATCH); } private static boolean isInGeneratedCode(VisitorState state) { diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ExtendsAutoValueTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ExtendsAutoValueTest.java index 5167ccb2a9c..b78536b2b9b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ExtendsAutoValueTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ExtendsAutoValueTest.java @@ -98,12 +98,114 @@ public void extendsAutoValue_bad() { @AutoValue class AutoClass {} - // BUG: Diagnostic contains: ExtendsAutoValue + // BUG: Diagnostic contains: Do not extend an @AutoValue class in non-generated code. public class TestClass extends AutoClass {} """) .doTest(); } + @Test + public void extendsAutoValue_builder_bad() { + helper + .addSourceLines( + "TestBuilder.java", + """ +import com.google.auto.value.AutoValue; + +@AutoValue +class AutoClass { + @AutoValue.Builder + abstract static class Builder { + abstract AutoClass build(); + } +} + +// BUG: Diagnostic contains: Do not extend an @AutoValue.Builder class in non-generated code. +public class TestBuilder extends AutoClass.Builder { + AutoClass build() { + throw new RuntimeException(); + } +} +""") + .doTest(); + } + + @Test + public void implementsAutoValue_builder_bad() { + helper + .addSourceLines( + "TestBuilder.java", + """ +import com.google.auto.value.AutoValue; + +@AutoValue +class AutoClass { + @AutoValue.Builder + interface Builder { + AutoClass build(); + } +} + +// BUG: Diagnostic contains: Do not extend an @AutoValue.Builder class in non-generated code. +public class TestBuilder implements AutoClass.Builder { + public AutoClass build() { + throw new RuntimeException(); + } +} +""") + .doTest(); + } + + @Test + public void extendsAutoBuilder_bad() { + helper + .addSourceLines( + "TestBuilder.java", + """ + import com.google.auto.value.AutoBuilder; + + class MyClass { + @AutoBuilder + abstract static class Builder { + abstract MyClass build(); + } + } + + // BUG: Diagnostic contains: Do not extend an @AutoBuilder class in non-generated code. + public class TestBuilder extends MyClass.Builder { + MyClass build() { + throw new RuntimeException(); + } + } + """) + .doTest(); + } + + @Test + public void implementsAutoBuilder_bad() { + helper + .addSourceLines( + "TestBuilder.java", + """ + import com.google.auto.value.AutoBuilder; + + class MyClass { + @AutoBuilder + interface Builder { + MyClass build(); + } + } + + // BUG: Diagnostic contains: Do not extend an @AutoBuilder class in non-generated code. + public class TestBuilder implements MyClass.Builder { + public MyClass build() { + throw new RuntimeException(); + } + } + """) + .doTest(); + } + @Test public void extendsAutoOneOf_bad() { helper @@ -117,7 +219,7 @@ class AutoClass { enum Kind {} } - // BUG: Diagnostic contains: ExtendsAutoValue + // BUG: Diagnostic contains: Do not extend an @AutoOneOf class in non-generated code. public class TestClass extends AutoClass {} """) .doTest(); @@ -132,7 +234,7 @@ public void extendsAutoValue_badNoImport() { @com.google.auto.value.AutoValue class AutoClass {} - // BUG: Diagnostic contains: ExtendsAutoValue + // BUG: Diagnostic contains: Do not extend an @AutoValue class in non-generated code. public class TestClass extends AutoClass {} """) .doTest(); @@ -150,7 +252,7 @@ public class OuterClass { @AutoValue abstract static class AutoClass {} - // BUG: Diagnostic contains: ExtendsAutoValue + // BUG: Diagnostic contains: Do not extend an @AutoValue class in non-generated code. class TestClass extends AutoClass {} } """) @@ -170,7 +272,7 @@ class OuterClass { static class AutoClass {} } - // BUG: Diagnostic contains: ExtendsAutoValue + // BUG: Diagnostic contains: Do not extend an @AutoValue class in non-generated code. public class TestClass extends OuterClass.AutoClass {} """) .doTest(); @@ -205,7 +307,7 @@ public void extendsAutoValue_innerClassExtends() { class AutoClass {} public class TestClass { - // BUG: Diagnostic contains: ExtendsAutoValue + // BUG: Diagnostic contains: Do not extend an @AutoValue class in non-generated code. public class Extends extends AutoClass {} } """) From 9adca4c0698127c4588dabfe9e56f0db6e031ff9 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 29 Oct 2024 11:03:58 -0700 Subject: [PATCH 05/38] Discourage conditional expressions and if statements where both branches are the same PiperOrigin-RevId: 691086580 --- .../bugpatterns/DuplicateBranches.java | 100 ++++++++ .../scanner/BuiltInCheckerSuppliers.java | 2 + .../bugpatterns/DuplicateBranchesTest.java | 218 ++++++++++++++++++ docs/bugpattern/DuplicateBranches.md | 32 +++ 4 files changed, 352 insertions(+) create mode 100644 core/src/main/java/com/google/errorprone/bugpatterns/DuplicateBranches.java create mode 100644 core/src/test/java/com/google/errorprone/bugpatterns/DuplicateBranchesTest.java create mode 100644 docs/bugpattern/DuplicateBranches.md diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/DuplicateBranches.java b/core/src/main/java/com/google/errorprone/bugpatterns/DuplicateBranches.java new file mode 100644 index 00000000000..3936c3fc9ad --- /dev/null +++ b/core/src/main/java/com/google/errorprone/bugpatterns/DuplicateBranches.java @@ -0,0 +1,100 @@ +/* + * Copyright 2024 The Error Prone Authors. + * + * 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.google.errorprone.bugpatterns; + +import static com.google.common.collect.Iterables.getLast; +import static com.google.errorprone.BugPattern.SeverityLevel.ERROR; +import static com.google.errorprone.matchers.Description.NO_MATCH; +import static com.google.errorprone.util.ASTHelpers.getStartPosition; +import static java.util.stream.Collectors.joining; + +import com.google.errorprone.BugPattern; +import com.google.errorprone.VisitorState; +import com.google.errorprone.bugpatterns.BugChecker.ConditionalExpressionTreeMatcher; +import com.google.errorprone.bugpatterns.BugChecker.IfTreeMatcher; +import com.google.errorprone.fixes.SuggestedFix; +import com.google.errorprone.matchers.Description; +import com.google.errorprone.util.ErrorProneTokens; +import com.sun.source.tree.BlockTree; +import com.sun.source.tree.ConditionalExpressionTree; +import com.sun.source.tree.IfTree; +import com.sun.source.tree.Tree; +import com.sun.source.tree.Tree.Kind; + +/** A {@link BugChecker}; see the associated {@link BugPattern} annotation for details. */ +@BugPattern(summary = "Both branches contain identical code", severity = ERROR) +public class DuplicateBranches extends BugChecker + implements IfTreeMatcher, ConditionalExpressionTreeMatcher { + @Override + public Description matchConditionalExpression( + ConditionalExpressionTree tree, VisitorState state) { + return match(tree, tree.getTrueExpression(), tree.getFalseExpression(), state); + } + + @Override + public Description matchIf(IfTree tree, VisitorState state) { + if (tree.getElseStatement() == null) { + return NO_MATCH; + } + return match(tree, tree.getThenStatement(), tree.getElseStatement(), state); + } + + // The comparison relies on Tree#toString, which isn't free for very long trees. Only check + // relatively short trees. + private static final int MAX_LENGTH_TO_COMPARE = 750; + + @SuppressWarnings("TreeToString") + private Description match(Tree tree, Tree thenTree, Tree elseTree, VisitorState state) { + if (state.getSourceForNode(thenTree).length() > MAX_LENGTH_TO_COMPARE + || state.getSourceForNode(elseTree).length() > MAX_LENGTH_TO_COMPARE) { + return NO_MATCH; + } + // This could do something similar to com.sun.tools.javac.comp.TreeDiffer. That doesn't + // do exactly what we want here, which is to compare the syntax including of identifiers and + // not their underlying symbols, and it would require a lot of case work to implement for all + // AST nodes. + if (!thenTree.toString().equals(elseTree.toString())) { + return NO_MATCH; + } + int start = getStartPosition(elseTree); + int end = state.getEndPosition(elseTree); + boolean needsBraces = false; + if (elseTree instanceof BlockTree) { + needsBraces = !state.getPath().getParentPath().getLeaf().getKind().equals(Kind.BLOCK); + var statements = ((BlockTree) elseTree).getStatements(); + start = getStartPosition(statements.get(0)); + end = state.getEndPosition(getLast(statements)); + } + String comments = + ErrorProneTokens.getTokens( + state.getSourceCode().subSequence(getStartPosition(tree), start).toString(), + getStartPosition(tree), + state.context) + .stream() + .flatMap(errorProneToken -> errorProneToken.comments().stream()) + .map(c -> c.getText()) + .collect(joining("\n")); + if (!comments.isEmpty()) { + comments += "\n"; + } + String replacement = comments + state.getSourceCode().subSequence(start, end); + if (needsBraces) { + replacement = "{\n" + replacement + "}"; + } + return describeMatch(tree, SuggestedFix.replace(tree, replacement)); + } +} diff --git a/core/src/main/java/com/google/errorprone/scanner/BuiltInCheckerSuppliers.java b/core/src/main/java/com/google/errorprone/scanner/BuiltInCheckerSuppliers.java index f9b7bed5964..49c549b9d59 100644 --- a/core/src/main/java/com/google/errorprone/scanner/BuiltInCheckerSuppliers.java +++ b/core/src/main/java/com/google/errorprone/scanner/BuiltInCheckerSuppliers.java @@ -121,6 +121,7 @@ import com.google.errorprone.bugpatterns.DoNotMockAutoValue; import com.google.errorprone.bugpatterns.DoNotMockChecker; import com.google.errorprone.bugpatterns.DoubleBraceInitialization; +import com.google.errorprone.bugpatterns.DuplicateBranches; import com.google.errorprone.bugpatterns.DuplicateDateFormatField; import com.google.errorprone.bugpatterns.DuplicateMapKeys; import com.google.errorprone.bugpatterns.EmptyCatch; @@ -706,6 +707,7 @@ public static ScannerSupplier warningChecks() { DoNotCallChecker.class, DoNotMockChecker.class, DoubleBraceInitialization.class, + DuplicateBranches.class, DuplicateMapKeys.class, DurationFrom.class, DurationGetTemporalUnit.class, diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/DuplicateBranchesTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/DuplicateBranchesTest.java new file mode 100644 index 00000000000..bf9c8eb87bb --- /dev/null +++ b/core/src/test/java/com/google/errorprone/bugpatterns/DuplicateBranchesTest.java @@ -0,0 +1,218 @@ +/* + * Copyright 2024 The Error Prone Authors. + * + * 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.google.errorprone.bugpatterns; + +import com.google.errorprone.BugCheckerRefactoringTestHelper; +import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode; +import com.google.errorprone.CompilationTestHelper; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class DuplicateBranchesTest { + + private final CompilationTestHelper compilationHelper = + CompilationTestHelper.newInstance(DuplicateBranches.class, getClass()); + + @Test + public void positive() { + compilationHelper + .addSourceLines( + "Test.java", + """ + class Test { + String f(boolean a, String b, String c) { + // BUG: Diagnostic contains: + return a ? b : b; + } + + String g(boolean a, String b, String c) { + // BUG: Diagnostic contains: + if (a) { + return b; + } else { + return b; + } + } + } + """) + .doTest(); + } + + @Test + public void negative() { + compilationHelper + .addSourceLines( + "Test.java", + """ + class Test { + String f(boolean a, String b, String c) { + return a ? b : c; + } + + String g(boolean a, String b, String c) { + if (a) { + return b; + } else { + return c; + } + } + + String h(boolean a, String b, String c) { + if (a) { + return b; + } + return ""; + } + } + """) + .doTest(); + } + + @Test + public void statementRefactoring() { + BugCheckerRefactoringTestHelper.newInstance(DuplicateBranches.class, getClass()) + .addInputLines( + "Test.java", + """ + class Test { + String g(boolean a, String b, String c) { + if (a) { + return b; + } else { + return b; + } + } + } + """) + .addOutputLines( + "Test.java", + """ + class Test { + String g(boolean a, String b, String c) { + return b; + } + } + """) + .doTest(TestMode.TEXT_MATCH); + } + + @Test + public void statementRefactoringChain() { + BugCheckerRefactoringTestHelper.newInstance(DuplicateBranches.class, getClass()) + .addInputLines( + "Test.java", + """ + class Test { + String g(boolean a, String b, String c) { + if (a) { + return c; + } else if (a) { + return b; + } else { + return b; + } + } + } + """) + .addOutputLines( + "Test.java", + """ + class Test { + String g(boolean a, String b, String c) { + if (a) { + return c; + } else { + return b; + } + } + } + """) + .doTest(TestMode.TEXT_MATCH); + } + + @Test + public void commentRefactoring() { + BugCheckerRefactoringTestHelper.newInstance(DuplicateBranches.class, getClass()) + .addInputLines( + "Test.java", + """ + class Test { + String g(boolean a, String b, String c) { + if (a) { + // foo + return b; + } else { + // bar + return b; + } + } + } + """) + .addOutputLines( + "Test.java", + """ + class Test { + String g(boolean a, String b, String c) { + // foo + // bar + return b; + } + } + """) + .doTest(TestMode.TEXT_MATCH); + } + + @Test + public void commentRefactoringIfElse() { + BugCheckerRefactoringTestHelper.newInstance(DuplicateBranches.class, getClass()) + .addInputLines( + "Test.java", + """ + class Test { + boolean g(boolean a, boolean b) { + if (a) { + return true; + } else if (a) { + // foo + return b; + } else { + // bar + return b; + } + } + } + """) + .addOutputLines( + "Test.java", + """ + class Test { + boolean g(boolean a, boolean b) { + if (a) { + return true; + } else { + // foo + // bar + return b; + } + } + } + """) + .doTest(TestMode.TEXT_MATCH); + } +} diff --git a/docs/bugpattern/DuplicateBranches.md b/docs/bugpattern/DuplicateBranches.md new file mode 100644 index 00000000000..19ace08b1ae --- /dev/null +++ b/docs/bugpattern/DuplicateBranches.md @@ -0,0 +1,32 @@ +Branching constructs (`if` statements, `conditional` expressions) should contain +difference code in the two branches. Repeating identical code in both branches +is usually a bug. + +For example: + +```java +condition ? same : same +``` + +```java +if (condition) { + same(); +} else { + same(); +} +``` + +this usually indicates a typo where one of the branches was supposed to contain +different logic: + +```java +condition ? something : somethingElse +``` + +```java +if (condition) { + doSomething(); +} else { + doSomethingElse(); +} +``` From 0fabb97c55301af8c6badc66f2340f6061fcc044 Mon Sep 17 00:00:00 2001 From: ghm Date: Wed, 30 Oct 2024 05:02:47 -0700 Subject: [PATCH 06/38] Discourage Yoda _inequalities_ as well as _equals_ checks. But special-case to allow stuff like `2 <= a && a <= 10`. PiperOrigin-RevId: 691375654 --- .../errorprone/bugpatterns/YodaCondition.java | 115 +++++++++++++++--- .../bugpatterns/YodaConditionTest.java | 35 ++++++ 2 files changed, 133 insertions(+), 17 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/YodaCondition.java b/core/src/main/java/com/google/errorprone/bugpatterns/YodaCondition.java index f246fb6f706..ce66fa31acc 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/YodaCondition.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/YodaCondition.java @@ -40,15 +40,18 @@ import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.Tree; +import com.sun.source.util.TreePath; import com.sun.tools.javac.code.Symbol.VarSymbol; import java.util.Objects; import java.util.regex.Pattern; +import org.jspecify.annotations.Nullable; /** See the summary. */ @BugPattern( summary = - "The non-constant portion of an equals check generally comes first. Prefer" - + " e.equals(CONSTANT) if e is non-null or Objects.equals(e, CONSTANT) if e may be", + "The non-constant portion of a comparison generally comes first. For equality, prefer" + + " e.equals(CONSTANT) if e is non-null or Objects.equals(e, CONSTANT) if e may be" + + " null. For standard operators, prefer e > CONSTANT.", severity = WARNING) public final class YodaCondition extends BugChecker implements BinaryTreeMatcher, MethodInvocationTreeMatcher { @@ -57,6 +60,10 @@ public Description matchBinary(BinaryTree tree, VisitorState state) { switch (tree.getKind()) { case EQUAL_TO: case NOT_EQUAL_TO: + case LESS_THAN: + case GREATER_THAN: + case LESS_THAN_EQUAL: + case GREATER_THAN_EQUAL: return fix( tree, tree.getLeftOperand(), @@ -95,25 +102,99 @@ private Description fix( ExpressionTree rhs, boolean provideNullSafeFix, VisitorState state) { - if (yodaCondition(lhs, rhs)) { - var description = buildDescription(lhs); - if (provideNullSafeFix - && !getNullnessValue(rhs, state, NullnessAnalysis.instance(state.context)) - .equals(Nullness.NONNULL)) { - var fix = SuggestedFix.builder().setShortDescription("null-safe fix"); - description.addFix( - fix.replace( + if (!yodaCondition(lhs, rhs)) { + return NO_MATCH; + } + if (isInequality(tree) && hasAdjacentComparison(state)) { + return NO_MATCH; + } + + var description = buildDescription(lhs); + if (provideNullSafeFix + && !getNullnessValue(rhs, state, NullnessAnalysis.instance(state.context)) + .equals(Nullness.NONNULL)) { + var fix = SuggestedFix.builder().setShortDescription("null-safe fix"); + description.addFix( + fix.replace( + tree, + format( + "%s.equals(%s, %s)", + qualifyType(state, fix, Objects.class.getName()), + state.getSourceForNode(rhs), + state.getSourceForNode(lhs))) + .build()); + } + return description + .addFix( + isInequality(tree) + ? SuggestedFix.replace( tree, format( - "%s.equals(%s, %s)", - qualifyType(state, fix, Objects.class.getName()), - state.getSourceForNode(rhs), - state.getSourceForNode(lhs))) - .build()); + "%s %s %s", + state.getSourceForNode(rhs), inverse(tree), state.getSourceForNode(lhs))) + : SuggestedFix.swap(lhs, rhs)) + .build(); + } + + @SuppressWarnings("TreeToString") // Can't think of a better approach. + private static boolean hasAdjacentComparison(VisitorState state) { + BinaryTree tree = (BinaryTree) state.getPath().getLeaf(); + + ConstantKind l = seemsConstant(tree.getLeftOperand()); + ConstantKind r = seemsConstant(tree.getRightOperand()); + boolean putativeVariableOnRight = l.constness > r.constness; + if (putativeVariableOnRight) { + ExpressionTree right = expressionToRight(state); + return right != null && right.toString().equals(tree.getRightOperand().toString()); + } + return false; + } + + private static @Nullable ExpressionTree expressionToRight(VisitorState state) { + TreePath path = state.getPath(); + while (true) { + Tree tree = path.getLeaf(); + TreePath parentPath = path.getParentPath(); + Tree parent = parentPath.getLeaf(); + if (!(parent instanceof BinaryTree)) { + break; + } + BinaryTree binaryTree = (BinaryTree) parent; + if (binaryTree.getLeftOperand() == tree) { + Tree right = binaryTree.getRightOperand(); + return isInequality(right) ? ((BinaryTree) right).getLeftOperand() : null; + } else { + path = path.getParentPath(); } - return description.addFix(SuggestedFix.swap(lhs, rhs)).build(); } - return NO_MATCH; + return null; + } + + private static boolean isInequality(Tree tree) { + switch (tree.getKind()) { + case LESS_THAN: + case GREATER_THAN: + case LESS_THAN_EQUAL: + case GREATER_THAN_EQUAL: + return true; + default: + return false; + } + } + + private static String inverse(Tree tree) { + switch (tree.getKind()) { + case LESS_THAN: + return ">"; + case GREATER_THAN: + return "<"; + case LESS_THAN_EQUAL: + return ">="; + case GREATER_THAN_EQUAL: + return "<="; + default: + throw new AssertionError(); + } } private static boolean yodaCondition(ExpressionTree lhs, ExpressionTree rhs) { diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/YodaConditionTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/YodaConditionTest.java index 5bf993dda0c..4544887ab5e 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/YodaConditionTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/YodaConditionTest.java @@ -63,6 +63,41 @@ boolean notYoda(int a) { .doTest(); } + @Test + public void comparison() { + testHelper + .addSourceLines( + "Test.java", + """ + class Test { + boolean yoda(int a) { + // BUG: Diagnostic contains: a < 4 + return 4 > a; + } + } + """) + .doTest(); + } + + @Test + public void comparison_noFindingWithAdjacentComparison() { + testHelper + .addSourceLines( + "Test.java", + """ + class Test { + boolean test(int a) { + return 4 < a && a < 7 && true && false; + } + + boolean test2(int a) { + return true && false && 4 < a && a < 7; + } + } + """) + .doTest(); + } + @Test public void boxedBoolean() { refactoring From e597cbf4551bc724d6432432bd37199afa866128 Mon Sep 17 00:00:00 2001 From: lgemeinhardt Date: Wed, 30 Oct 2024 07:50:42 -0700 Subject: [PATCH 07/38] Bundle google-java-format in the with-dependencies JAR Add google-java-format in with-dependencies JAR, broken after https://github.com/google/error-prone/commit/5f71110374e63f3c35b661f538295fa15b5c1db2 Similar to #1398, #1259 and #1238 Fixes #4633 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/error-prone/pull/4633 from lgemeinhardt:shade-google-java-format d468c7b04f264c1e1cc5171031e96fa4eed34c7d PiperOrigin-RevId: 691416915 --- core/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/core/pom.xml b/core/pom.xml index 40dac702e26..b425e327b32 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -437,6 +437,7 @@ com.google.code.findbugs:jsr305 com.google.protobuf:protobuf-java javax.inject:javax.inject + com.google.googlejavaformat:google-java-format From 81e3cfa0113f2c9d19ae8cfd4f2d33b52cffa7bd Mon Sep 17 00:00:00 2001 From: Stephan Schroevers Date: Wed, 30 Oct 2024 08:18:02 -0700 Subject: [PATCH 08/38] Introduce `IdentifierName:AllowInitialismsInTypeName` flag While default `IdentifierName` behavior is unchanged, this flag allows users to slightly relax the type name validation performed by this check. Fixes #4646 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/error-prone/pull/4646 from PicnicSupermarket:sschroevers/allow-initialisms-in-type-names 82abeaf229a11e1f6211c3fac170c811359e8210 PiperOrigin-RevId: 691425146 --- .../errorprone/bugpatterns/IdentifierName.java | 18 ++++++++++++++---- .../bugpatterns/IdentifierNameTest.java | 11 +++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/IdentifierName.java b/core/src/main/java/com/google/errorprone/bugpatterns/IdentifierName.java index a34c5f1ef3b..9cd1344d113 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/IdentifierName.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/IdentifierName.java @@ -41,6 +41,7 @@ import com.google.common.base.Splitter; import com.google.common.collect.ImmutableSet; import com.google.errorprone.BugPattern; +import com.google.errorprone.ErrorProneFlags; import com.google.errorprone.VisitorState; import com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher; @@ -60,6 +61,7 @@ import com.sun.tools.javac.util.Name; import java.util.regex.Pattern; import java.util.stream.Stream; +import javax.inject.Inject; import javax.lang.model.element.ElementKind; import javax.lang.model.element.Modifier; @@ -98,17 +100,25 @@ public final class IdentifierName extends BugChecker ", with acronyms treated as words" + " (https://google.github.io/styleguide/javaguide.html#s5.3-camel-case)"; + private final boolean allowInitialismsInTypeName; + + @Inject + IdentifierName(ErrorProneFlags flags) { + this.allowInitialismsInTypeName = + flags.getBoolean("IdentifierName:AllowInitialismsInTypeName").orElse(false); + } + @Override public Description matchClass(ClassTree tree, VisitorState state) { ClassSymbol symbol = getSymbol(tree); String name = tree.getSimpleName().toString(); - if (name.isEmpty() || isConformantUpperCamelName(name)) { + if (name.isEmpty() || isConformantTypeName(name)) { // The name can be empty for enum member declarations, which are desugared early to class // declarations. return NO_MATCH; } String renamed = suggestedClassRename(name); - String suggested = fixInitialisms(renamed); + String suggested = allowInitialismsInTypeName ? renamed : fixInitialisms(renamed); boolean fixable = !suggested.equals(name) && canBeRemoved(symbol); String diagnostic = "Classes should be named in UpperCamelCase" @@ -281,10 +291,10 @@ private static boolean isConformantLowerCamelName(String name) { && !PROBABLE_INITIALISM.matcher(name).find(); } - private static boolean isConformantUpperCamelName(String name) { + private boolean isConformantTypeName(String name) { return !name.contains("_") && isUpperCase(name.charAt(0)) - && !PROBABLE_INITIALISM.matcher(name).find(); + && (allowInitialismsInTypeName || !PROBABLE_INITIALISM.matcher(name).find()); } private static boolean isStaticVariable(Symbol symbol) { diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/IdentifierNameTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/IdentifierNameTest.java index 31d3f0ec22a..a748abf723b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/IdentifierNameTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/IdentifierNameTest.java @@ -601,6 +601,17 @@ public void className_badInitialism() { .doTest(); } + @Test + public void className_badInitialism_allowed() { + helper + .setArgs("-XepOpt:IdentifierName:AllowInitialismsInTypeName=true") + .addSourceLines( + "Test.java", // + "class RPCServiceTester {", + "}") + .doTest(); + } + @Test public void className_lowerCamelCase() { helper From 866c49b276862a2b1cdf4eff1c641c476a0177f1 Mon Sep 17 00:00:00 2001 From: ghm Date: Wed, 30 Oct 2024 09:39:28 -0700 Subject: [PATCH 09/38] Misc. tidying in argumentselectiondefects. PiperOrigin-RevId: 691450829 --- .../ArgumentSelectionDefectChecker.java | 48 +++----- .../AssertEqualsArgumentOrderChecker.java | 2 +- .../AutoValueConstructorOrderChecker.java | 5 +- .../argumentselectiondefects/Costs.java | 2 +- .../CreatesDuplicateCallHeuristic.java | 2 +- .../EnclosedByReverseHeuristic.java | 25 ++-- .../LowInformationNameHeuristic.java | 12 +- .../argumentselectiondefects/Matchers.java | 115 ++++++++---------- .../NameInCommentHeuristic.java | 2 +- .../PenaltyThresholdHeuristic.java | 2 +- 10 files changed, 97 insertions(+), 118 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectChecker.java index f535361a056..ba4e79ef3c4 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectChecker.java @@ -31,7 +31,6 @@ import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.NewClassTree; import com.sun.tools.javac.code.Symbol.MethodSymbol; -import java.util.function.Function; /** * Checks the lexical distance between method parameter names and the argument names at call sites. @@ -62,7 +61,7 @@ public class ArgumentSelectionDefectChecker extends BugChecker public ArgumentSelectionDefectChecker() { this( ArgumentChangeFinder.builder() - .setDistanceFunction(buildDefaultDistanceFunction()) + .setDistanceFunction(ArgumentSelectionDefectChecker::defaultDistanceFunction) .addHeuristic(new LowInformationNameHeuristic()) .addHeuristic(new PenaltyThresholdHeuristic()) .addHeuristic(new EnclosedByReverseHeuristic()) @@ -94,7 +93,7 @@ public Description matchNewClass(NewClassTree tree, VisitorState state) { MethodSymbol symbol = ASTHelpers.getSymbol(tree); // Don't return a match if the AutoValueConstructorOrderChecker would match it too - if (Matchers.AUTOVALUE_CONSTRUCTOR.matches(tree, state)) { + if (Matchers.isAutoValueConstructor(tree)) { return Description.NO_MATCH; } @@ -128,30 +127,23 @@ private Description visitNewClassOrMethodInvocation(InvocationInfo invocationInf * normalised NeedlemanWunschEditDistance. Otherwise, one of the names is unknown and so we return * 0 distance between it and its original parameter and infinite distance between all others. */ - private static Function buildDefaultDistanceFunction() { - return new Function() { - @Override - public Double apply(ParameterPair pair) { - if (pair.formal().isNullLiteral() || pair.actual().isNullLiteral()) { - return 0.0; - } - - if (!pair.formal().isUnknownName() && !pair.actual().isUnknownName()) { - String normalizedSource = - NamingConventions.convertToLowerUnderscore(pair.formal().name()); - String normalizedTarget = - NamingConventions.convertToLowerUnderscore(pair.actual().name()); - return NeedlemanWunschEditDistance.getNormalizedEditDistance( - /* source= */ normalizedSource, - /* target= */ normalizedTarget, - /* caseSensitive= */ false, - /* changeCost= */ 8, - /* openGapCost= */ 8, - /* continueGapCost= */ 1); - } - - return pair.formal().index() == pair.actual().index() ? 0.0 : Double.POSITIVE_INFINITY; - } - }; + private static double defaultDistanceFunction(ParameterPair pair) { + if (pair.formal().isNullLiteral() || pair.actual().isNullLiteral()) { + return 0.0; + } + + if (!pair.formal().isUnknownName() && !pair.actual().isUnknownName()) { + String normalizedSource = NamingConventions.convertToLowerUnderscore(pair.formal().name()); + String normalizedTarget = NamingConventions.convertToLowerUnderscore(pair.actual().name()); + return NeedlemanWunschEditDistance.getNormalizedEditDistance( + /* source= */ normalizedSource, + /* target= */ normalizedTarget, + /* caseSensitive= */ false, + /* changeCost= */ 8, + /* openGapCost= */ 8, + /* continueGapCost= */ 1); + } + + return pair.formal().index() == pair.actual().index() ? 0.0 : Double.POSITIVE_INFINITY; } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/AssertEqualsArgumentOrderChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/AssertEqualsArgumentOrderChecker.java index d9c019b32f6..8ae69f60684 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/AssertEqualsArgumentOrderChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/AssertEqualsArgumentOrderChecker.java @@ -43,7 +43,7 @@ * @author andrewrice@google.com (Andrew Rice) */ @BugPattern(summary = "Arguments are swapped in assertEquals-like call", severity = WARNING) -public class AssertEqualsArgumentOrderChecker extends BugChecker +public final class AssertEqualsArgumentOrderChecker extends BugChecker implements MethodInvocationTreeMatcher { private final ArgumentChangeFinder argumentchangeFinder = diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/AutoValueConstructorOrderChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/AutoValueConstructorOrderChecker.java index f9e48537584..72d53b3a8d6 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/AutoValueConstructorOrderChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/AutoValueConstructorOrderChecker.java @@ -41,7 +41,8 @@ * @author andrewrice@google.com (Andrew Rice) */ @BugPattern(summary = "Arguments to AutoValue constructor are in the wrong order", severity = ERROR) -public class AutoValueConstructorOrderChecker extends BugChecker implements NewClassTreeMatcher { +public final class AutoValueConstructorOrderChecker extends BugChecker + implements NewClassTreeMatcher { private final ArgumentChangeFinder argumentChangeFinder = ArgumentChangeFinder.builder() @@ -52,7 +53,7 @@ public class AutoValueConstructorOrderChecker extends BugChecker implements NewC @Override public Description matchNewClass(NewClassTree tree, VisitorState state) { - if (!Matchers.AUTOVALUE_CONSTRUCTOR.matches(tree, state)) { + if (!Matchers.isAutoValueConstructor(tree)) { return Description.NO_MATCH; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Costs.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Costs.java index 1ecfc39204d..e7f2d24e937 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Costs.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Costs.java @@ -30,7 +30,7 @@ * * @author andrewrice@google.com (Andrew Rice) */ -class Costs { +final class Costs { /** Formal parameters for the method being called. */ private final ImmutableList formals; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/CreatesDuplicateCallHeuristic.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/CreatesDuplicateCallHeuristic.java index 409c3dc5544..759f5c29f7f 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/CreatesDuplicateCallHeuristic.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/CreatesDuplicateCallHeuristic.java @@ -35,7 +35,7 @@ * * @author andrewrice@google.com (Andrew Rice) */ -class CreatesDuplicateCallHeuristic implements Heuristic { +final class CreatesDuplicateCallHeuristic implements Heuristic { /** * Returns true if there are no other calls to this method which already have an actual parameter diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/EnclosedByReverseHeuristic.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/EnclosedByReverseHeuristic.java index 29d37637af1..99fb4f73909 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/EnclosedByReverseHeuristic.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/EnclosedByReverseHeuristic.java @@ -16,9 +16,12 @@ package com.google.errorprone.bugpatterns.argumentselectiondefects; +import static com.google.common.collect.Streams.stream; +import static com.google.errorprone.names.NamingConventions.splitToLowercaseTerms; +import static java.util.Collections.disjoint; + import com.google.common.collect.ImmutableSet; import com.google.errorprone.VisitorState; -import com.google.errorprone.names.NamingConventions; import com.sun.source.tree.ClassTree; import com.sun.source.tree.MethodTree; import com.sun.source.tree.Tree; @@ -32,7 +35,7 @@ * * @author andrewrice@google.com (Andrew Rice) */ -class EnclosedByReverseHeuristic implements Heuristic { +final class EnclosedByReverseHeuristic implements Heuristic { private static final ImmutableSet DEFAULT_REVERSE_WORDS_TERMS = ImmutableSet.of( @@ -75,18 +78,12 @@ public boolean isAcceptableChange( return findReverseWordsMatchInParentNodes(state) == null; } - protected @Nullable String findReverseWordsMatchInParentNodes(VisitorState state) { - for (Tree tree : state.getPath()) { - Optional name = getName(tree); - if (name.isPresent()) { - for (String term : NamingConventions.splitToLowercaseTerms(name.get())) { - if (reverseWordsTerms.contains(term)) { - return term; - } - } - } - } - return null; + private @Nullable String findReverseWordsMatchInParentNodes(VisitorState state) { + return stream(state.getPath()) + .flatMap(t -> getName(t).stream()) + .filter(n -> !disjoint(splitToLowercaseTerms(n), reverseWordsTerms)) + .findFirst() + .orElse(null); } private static Optional getName(Tree tree) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/LowInformationNameHeuristic.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/LowInformationNameHeuristic.java index e0ba0c8f6cf..715f9d9e4ec 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/LowInformationNameHeuristic.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/LowInformationNameHeuristic.java @@ -29,7 +29,7 @@ * * @author andrewrice@google.com (Andrew Rice) */ -class LowInformationNameHeuristic implements Heuristic { +final class LowInformationNameHeuristic implements Heuristic { private static final ImmutableSet DEFAULT_FORMAL_PARAMETER_EXCLUSION_REGEXS = ImmutableSet.of( @@ -60,11 +60,9 @@ public boolean isAcceptableChange( * parameter name. */ protected @Nullable String findMatch(Parameter parameter) { - for (String regex : overloadedNamesRegexs) { - if (parameter.name().matches(regex)) { - return regex; - } - } - return null; + return overloadedNamesRegexs.stream() + .filter(r -> parameter.name().matches(r)) + .findFirst() + .orElse(null); } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Matchers.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Matchers.java index bc472cd84ff..0e99ee04545 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Matchers.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Matchers.java @@ -24,6 +24,8 @@ import static com.google.errorprone.matchers.Matchers.isSubtypeOf; import static com.google.errorprone.matchers.Matchers.not; import static com.google.errorprone.matchers.Matchers.staticMethod; +import static com.google.errorprone.util.ASTHelpers.getSymbol; +import static com.google.errorprone.util.ASTHelpers.hasDirectAnnotationWithSimpleName; import com.google.errorprone.VisitorState; import com.google.errorprone.matchers.ChildMultiMatcher.MatchType; @@ -49,71 +51,60 @@ final class Matchers { /** Matches if the tree is a constructor for an AutoValue class. */ - static final Matcher AUTOVALUE_CONSTRUCTOR = - new Matcher() { - @Override - public boolean matches(NewClassTree tree, VisitorState state) { - MethodSymbol sym = ASTHelpers.getSymbol(tree); - - ClassSymbol owner = (ClassSymbol) sym.owner; - if (owner == null) { - return false; - } - - Type superType = owner.getSuperclass(); - if (superType == null) { - return false; - } - - Symbol superSymbol = superType.tsym; - if (superSymbol == null) { - return false; - } - - if (!ASTHelpers.hasDirectAnnotationWithSimpleName(superSymbol, "AutoValue")) { - return false; - } - - return true; - } - }; - - // if any of the arguments are instances of throwable then abort - people like to use - // 'expected' as the name of the exception they are expecting - private static final Matcher ARGUMENT_EXTENDS_TRHOWABLE = + static boolean isAutoValueConstructor(NewClassTree tree) { + MethodSymbol sym = getSymbol(tree); + + ClassSymbol owner = (ClassSymbol) sym.owner; + if (owner == null) { + return false; + } + + Type superType = owner.getSuperclass(); + if (superType == null) { + return false; + } + + Symbol superSymbol = superType.tsym; + if (superSymbol == null) { + return false; + } + + if (!hasDirectAnnotationWithSimpleName(superSymbol, "AutoValue")) { + return false; + } + + return true; + } + + /** + * If any of the arguments are instances of throwable then abort - people like to use 'expected' + * as the name of the exception they are expecting. + */ + private static final Matcher ARGUMENT_EXTENDS_THROWABLE = hasArguments(MatchType.AT_LEAST_ONE, isSubtypeOf(Throwable.class)); - // if the method is a refaster-before template then it might be explicitly matching bad behaviour + /** + * If the method is a refaster-before template then it might be explicitly matching bad behaviour. + */ private static final Matcher METHOD_ANNOTATED_WITH_BEFORETEMPLATE = enclosingMethod(hasAnnotation("com.google.errorprone.refaster.annotation.BeforeTemplate")); - private static final Matcher TWO_PARAMETER_ASSERT = - new Matcher() { - @Override - public boolean matches(MethodInvocationTree tree, VisitorState state) { - List parameters = ASTHelpers.getSymbol(tree).getParameters(); - if (parameters.size() != 2) { - return false; - } - return ASTHelpers.isSameType( - parameters.get(0).asType(), parameters.get(1).asType(), state); - } - }; - - private static final Matcher THREE_PARAMETER_ASSERT = - new Matcher() { - @Override - public boolean matches(MethodInvocationTree tree, VisitorState state) { - List parameters = ASTHelpers.getSymbol(tree).getParameters(); - if (parameters.size() != 3) { - return false; - } - return ASTHelpers.isSameType( - parameters.get(0).asType(), state.getSymtab().stringType, state) - && ASTHelpers.isSameType( - parameters.get(1).asType(), parameters.get(2).asType(), state); - } - }; + private static boolean isTwoParameterAssert(MethodInvocationTree tree, VisitorState state) { + List parameters = getSymbol(tree).getParameters(); + if (parameters.size() != 2) { + return false; + } + return ASTHelpers.isSameType(parameters.get(0).asType(), parameters.get(1).asType(), state); + } + + private static boolean isThreeParameterAssert(MethodInvocationTree tree, VisitorState state) { + List parameters = getSymbol(tree).getParameters(); + if (parameters.size() != 3) { + return false; + } + return ASTHelpers.isSameType(parameters.get(0).asType(), state.getSymtab().stringType, state) + && ASTHelpers.isSameType(parameters.get(1).asType(), parameters.get(2).asType(), state); + } /** Matches if the tree corresponds to an assertEquals-style method */ static final Matcher ASSERT_METHOD = @@ -128,8 +119,8 @@ public boolean matches(MethodInvocationTree tree, VisitorState state) { information which would cause the tests to fail.*/ "ErrorProneTest") .withNameMatching(Pattern.compile("assert.*")), - anyOf(TWO_PARAMETER_ASSERT, THREE_PARAMETER_ASSERT), - not(ARGUMENT_EXTENDS_TRHOWABLE), + anyOf(Matchers::isTwoParameterAssert, Matchers::isThreeParameterAssert), + not(ARGUMENT_EXTENDS_THROWABLE), not(METHOD_ANNOTATED_WITH_BEFORETEMPLATE)); private Matchers() {} diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NameInCommentHeuristic.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NameInCommentHeuristic.java index 1490f6b65d8..20cd8764afa 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NameInCommentHeuristic.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NameInCommentHeuristic.java @@ -33,7 +33,7 @@ * * @author andrewrice@google.com (Andrew Rice) */ -class NameInCommentHeuristic implements Heuristic { +final class NameInCommentHeuristic implements Heuristic { /** * Return true if there are no comments on the original actual parameter of a change which match diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/PenaltyThresholdHeuristic.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/PenaltyThresholdHeuristic.java index 95ead686c7f..029cd27942d 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/PenaltyThresholdHeuristic.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/PenaltyThresholdHeuristic.java @@ -28,7 +28,7 @@ * * @author andrewrice@google.com (Andrew Rice) */ -class PenaltyThresholdHeuristic implements Heuristic { +final class PenaltyThresholdHeuristic implements Heuristic { private final double threshold; From f0c3c1eb1b576ee9bc44f1f21c9379e7a02dd745 Mon Sep 17 00:00:00 2001 From: ghm Date: Wed, 30 Oct 2024 09:53:23 -0700 Subject: [PATCH 10/38] Add a test confirming that ArgumentSelectionDefectChecker works on record construction, but _not_ record deconstruction. PiperOrigin-RevId: 691455946 --- .../ArgumentSelectionDefectCheckerTest.java | 60 +++++++++++++++++-- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectCheckerTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectCheckerTest.java index d505aa55c8e..6a650688d5c 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectCheckerTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectCheckerTest.java @@ -15,6 +15,8 @@ */ package com.google.errorprone.bugpatterns.argumentselectiondefects; +import static com.google.common.truth.TruthJUnit.assume; + import com.google.common.collect.ImmutableSet; import com.google.errorprone.BugPattern; import com.google.errorprone.BugPattern.SeverityLevel; @@ -38,6 +40,10 @@ @RunWith(JUnit4.class) public class ArgumentSelectionDefectCheckerTest { + private final CompilationTestHelper testHelper = + CompilationTestHelper.newInstance( + ArgumentSelectionDefectWithStringEquality.class, getClass()); + /** * A {@link BugChecker} which runs the ArgumentSelectionDefectChecker checker using string * equality for edit distance @@ -56,7 +62,7 @@ public ArgumentSelectionDefectWithStringEquality() { @Test public void argumentSelectionDefectChecker_findsSwap_withSwappedMatchingPair() { - CompilationTestHelper.newInstance(ArgumentSelectionDefectWithStringEquality.class, getClass()) + testHelper .addSourceLines( "Test.java", """ @@ -75,7 +81,7 @@ void test(Object first, Object second) { @Test public void argumentSelectionDefectChecker_findsSwap_withSwappedMatchingPairWithMethod() { - CompilationTestHelper.newInstance(ArgumentSelectionDefectWithStringEquality.class, getClass()) + testHelper .addSourceLines( "Test.java", """ @@ -96,7 +102,7 @@ void test(Object first) { @Test public void argumentSelectionDefectChecker_findsSwap_withOneNullArgument() { - CompilationTestHelper.newInstance(ArgumentSelectionDefectWithStringEquality.class, getClass()) + testHelper .addSourceLines( "Test.java", """ @@ -115,7 +121,7 @@ void test(Object second) { @Test public void argumentSelectionDefectChecker_rejectsSwap_withNoAssignableAlternatives() { - CompilationTestHelper.newInstance(ArgumentSelectionDefectWithStringEquality.class, getClass()) + testHelper .addSourceLines( "Test.java", """ @@ -132,7 +138,7 @@ void test(Integer first, String second) { @Test public void argumentSelectionDefectChecker_commentsOnlyOnSwappedPair_withThreeArguments() { - CompilationTestHelper.newInstance(ArgumentSelectionDefectWithStringEquality.class, getClass()) + testHelper .addSourceLines( "Test.java", """ @@ -360,7 +366,7 @@ public void parameterNamesAvailable_returnsTree_onMethodNotInCompilationUnit() { @Test public void description() { - CompilationTestHelper.newInstance(ArgumentSelectionDefectWithStringEquality.class, getClass()) + testHelper .addSourceLines( "Test.java", """ @@ -374,6 +380,48 @@ void test(Object first, Object second) { target(second, first); } } +""") + .doTest(); + } + + @Test + public void records() { + assume().that(Runtime.version().feature()).isAtLeast(16); + + testHelper + .addSourceLines( + "Test.java", + """ +class Test { + Foo test(String first, String second) { + // BUG: Diagnostic contains: may have been swapped + return new Foo(second, first); + } +} + +record Foo(String first, String second) {} +""") + .doTest(); + } + + @Test + public void recordDeconstruction() { + assume().that(Runtime.version().feature()).isAtLeast(21); + + testHelper + .addSourceLines( + "Test.java", + """ +class Test { + void test(Foo foo) { + switch (foo) { + // TODO(user): We should report a finding here! + case Foo(String second, String first) -> {} + } + } +} + +record Foo(String first, String second) {} """) .doTest(); } From d173d855200e409c6e79791a610a521d6fe104ce Mon Sep 17 00:00:00 2001 From: ghm Date: Thu, 31 Oct 2024 15:48:17 -0700 Subject: [PATCH 11/38] Add a note to FloggerArgumentToString that Flogger handles arrays and such nicely. PiperOrigin-RevId: 691960142 --- .../bugpatterns/flogger/FloggerArgumentToString.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerArgumentToString.java b/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerArgumentToString.java index 62c00eb1b46..4389a3888ac 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerArgumentToString.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerArgumentToString.java @@ -56,7 +56,8 @@ @BugPattern( summary = "Use Flogger's printf-style formatting instead of explicitly converting arguments to" - + " strings", + + " strings. Note that Flogger does more than just call toString; for instance, it" + + " formats arrays sensibly.", severity = WARNING) public class FloggerArgumentToString extends BugChecker implements MethodInvocationTreeMatcher { From b02e05b29a69880007b72fba2d1f93d10f1584bd Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 4 Nov 2024 09:42:23 -0800 Subject: [PATCH 12/38] DuplicateBranches: don't crash on empty blocks PiperOrigin-RevId: 692998546 --- .../bugpatterns/DuplicateBranches.java | 8 ++++-- .../bugpatterns/DuplicateBranchesTest.java | 25 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/DuplicateBranches.java b/core/src/main/java/com/google/errorprone/bugpatterns/DuplicateBranches.java index 3936c3fc9ad..297c57de3df 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/DuplicateBranches.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/DuplicateBranches.java @@ -76,8 +76,12 @@ private Description match(Tree tree, Tree thenTree, Tree elseTree, VisitorState if (elseTree instanceof BlockTree) { needsBraces = !state.getPath().getParentPath().getLeaf().getKind().equals(Kind.BLOCK); var statements = ((BlockTree) elseTree).getStatements(); - start = getStartPosition(statements.get(0)); - end = state.getEndPosition(getLast(statements)); + if (statements.isEmpty()) { + start = end; + } else { + start = getStartPosition(statements.get(0)); + end = state.getEndPosition(getLast(statements)); + } } String comments = ErrorProneTokens.getTokens( diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/DuplicateBranchesTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/DuplicateBranchesTest.java index bf9c8eb87bb..c8b0c42c124 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/DuplicateBranchesTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/DuplicateBranchesTest.java @@ -215,4 +215,29 @@ boolean g(boolean a, boolean b) { """) .doTest(TestMode.TEXT_MATCH); } + + @Test + public void negativeEmpty() { + BugCheckerRefactoringTestHelper.newInstance(DuplicateBranches.class, getClass()) + .addInputLines( + "Test.java", + """ + class Test { + void f(boolean a) { + if (a) { + } else { + } + } + } + """) + .addOutputLines( + "Test.java", + """ + class Test { + void f(boolean a) { + } + } + """) + .doTest(); + } } From 320f454e499a61aae7ef6462f952d10ea53aedde Mon Sep 17 00:00:00 2001 From: ghm Date: Tue, 5 Nov 2024 08:08:25 -0800 Subject: [PATCH 13/38] Remove some boxing via Optional in `getResultType`. Not a big deal, but this is an extra allocation and a bit obfuscated. (I almost want a Klippy for this pattern; I've seen it in readability reviews too...) PiperOrigin-RevId: 693353388 --- .../src/main/java/com/google/errorprone/util/ASTHelpers.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java b/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java index 1491b4dbd81..0b762e849bb 100644 --- a/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java +++ b/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java @@ -535,7 +535,7 @@ public static Type getReturnType(ExpressionTree expressionTree) { */ public static @Nullable Type getResultType(ExpressionTree expressionTree) { Type type = ASTHelpers.getType(expressionTree); - return type == null ? null : Optional.ofNullable(type.getReturnType()).orElse(type); + return type == null ? null : (type.getReturnType() == null ? type : type.getReturnType()); } /** From 04308eaa5367c538fe7399578782551c7736a816 Mon Sep 17 00:00:00 2001 From: Error Prone Team Date: Wed, 6 Nov 2024 12:00:36 -0800 Subject: [PATCH 14/38] Add SuppressBanSerializableForAndroid annotation Serialization on Android has a different threat model and requires different solution. Add this new annotation so that it's easier for ISE Hardening to tell these apart from problems in backend code. PiperOrigin-RevId: 693813292 --- .../testdata/BanSerializableReadNegativeCases.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/testdata/BanSerializableReadNegativeCases.java b/core/src/test/java/com/google/errorprone/bugpatterns/testdata/BanSerializableReadNegativeCases.java index aab8505604f..901132d1b8c 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/testdata/BanSerializableReadNegativeCases.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/testdata/BanSerializableReadNegativeCases.java @@ -114,6 +114,19 @@ public static final void directCall3() throws IOException, ClassNotFoundExceptio self.readObject(deserializer); } + // code is for Android + @SuppressWarnings("BanSerializableRead") + public static final void directCall4() throws IOException, ClassNotFoundException { + PipedInputStream in = new PipedInputStream(); + PipedOutputStream out = new PipedOutputStream(in); + + ObjectOutputStream serializer = new ObjectOutputStream(out); + ObjectInputStream deserializer = new ObjectInputStream(in); + + BanSerializableReadPositiveCases self = new BanSerializableReadPositiveCases(); + self.readObject(deserializer); + } + // calls to readObject should themselves be excluded in a readObject method void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { BanSerializableReadNegativeCases c = new BanSerializableReadNegativeCases(); From 6f6a638465454c70ce482937ef7faa163be9e21a Mon Sep 17 00:00:00 2001 From: ghm Date: Fri, 8 Nov 2024 06:17:32 -0800 Subject: [PATCH 15/38] Fix typos in MissingFail.md PiperOrigin-RevId: 694473171 --- docs/bugpattern/MissingFail.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/bugpattern/MissingFail.md b/docs/bugpattern/MissingFail.md index 83a3179ab28..67384adca06 100644 --- a/docs/bugpattern/MissingFail.md +++ b/docs/bugpattern/MissingFail.md @@ -1,4 +1,4 @@ -When testing for exceptions in junit, it is easy to forget the call to `fail()`: +When testing for exceptions in JUnit, it is easy to forget the call to `fail()`: ```java try { @@ -16,7 +16,7 @@ import static org.junit.Assert.fail; try { someOperationThatShouldThrow(); - fail() + fail(); } catch (SomeException expected) { assertThat(expected).hasMessage("Operation failed"); } @@ -81,5 +81,5 @@ characteristics are present: * A field assignment in the catch block. * A call to `assertTrue/False(boolean variable or field)` in the catch block. -* The last statement in the `try` block is an `assert*()` (that is not a noop: - `assertFalse(false)`, `assertTrue(true))` or `Mockito.verify()` call. +* The last statement in the `try` block is an `assert*()` (that is not a + noop): `assertFalse(false)`, `assertTrue(true))` or `Mockito.verify()` call. From 5cd43309737729e6070d85d784ff117301eed674 Mon Sep 17 00:00:00 2001 From: Kurt Alfred Kluever Date: Tue, 12 Nov 2024 13:49:03 -0800 Subject: [PATCH 16/38] Don't fire `TooManyParameters` on `records`. #java21 PiperOrigin-RevId: 695858248 --- .../errorprone/bugpatterns/TooManyParameters.java | 11 ++++++++--- .../bugpatterns/TooManyParametersTest.java | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/TooManyParameters.java b/core/src/main/java/com/google/errorprone/bugpatterns/TooManyParameters.java index 592cec9a7e0..39f62011fc5 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/TooManyParameters.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/TooManyParameters.java @@ -21,6 +21,7 @@ import static com.google.errorprone.matchers.Description.NO_MATCH; import static com.google.errorprone.util.ASTHelpers.getSymbol; import static com.google.errorprone.util.ASTHelpers.hasAnnotation; +import static com.google.errorprone.util.ASTHelpers.isRecord; import static com.google.errorprone.util.ASTHelpers.methodIsPublicAndNotAnOverride; import com.google.common.collect.ImmutableSet; @@ -84,12 +85,13 @@ public Description matchMethod(MethodTree tree, VisitorState state) { return NO_MATCH; } + String name = getSymbol(tree).isConstructor() ? "constructor" : "method"; String message = String.format( - "Consider using a builder pattern instead of a method with %s parameters. Data shows" - + " that defining methods with > 5 parameters often leads to bugs. See also" + "Consider using a builder pattern instead of a %s with %s parameters. Data shows" + + " that defining %s with > 5 parameters often leads to bugs. See also" + " Effective Java, Item 2.", - paramCount); + name, paramCount, name); return buildDescription(tree).setMessage(message).build(); } @@ -100,6 +102,9 @@ private static boolean shouldApplyApiChecks(MethodTree tree, VisitorState state) .anyMatch(a -> hasAnnotation(symbol.owner, a, state))) { return false; } + if (isRecord(symbol)) { + return false; + } return METHOD_ANNOTATIONS_TO_IGNORE.stream().noneMatch(a -> hasAnnotation(tree, a, state)) && methodIsPublicAndNotAnOverride(symbol, state); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/TooManyParametersTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/TooManyParametersTest.java index 3dad94d74c5..03a9dd97544 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/TooManyParametersTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/TooManyParametersTest.java @@ -81,6 +81,20 @@ private ConstructorTest(int a, int b, int c, int d, int e, int f, int g) {} .doTest(); } + @Test + public void recordConstructor() { + compilationHelper + .setArgs(ImmutableList.of("-XepOpt:" + TOO_MANY_PARAMETERS_FLAG_NAME + "=3")) + .addSourceLines( + "RecordExample.java", + """ + public record RecordExample(int p0, int p1, int p2, int p3, int p4, int p5) { + public RecordExample {} + } + """) + .doTest(); + } + @Test public void constructor_withAtInject() { compilationHelper @@ -114,6 +128,7 @@ public void ignoresAutoFactory() { "AutoFactory.java", """ package com.google.auto.factory; + public @interface AutoFactory {} """) .addSourceLines( From d4e5a5fe985d2e59858f6802fc52d58710f09d44 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 13 Nov 2024 08:33:19 -0800 Subject: [PATCH 17/38] Double-check that the ImmutableChecker covers records PiperOrigin-RevId: 696147096 --- .../threadsafety/ImmutableCheckerTest.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableCheckerTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableCheckerTest.java index 9f626182004..7150dd00611 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableCheckerTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableCheckerTest.java @@ -3556,4 +3556,35 @@ public void enumBound() { """) .doTest(); } + + @Test + public void mutableRecord() { + compilationHelper + .addSourceLines( + "Test.java", + """ + import java.util.List; + import com.google.errorprone.annotations.Immutable; + + @Immutable + // BUG: Diagnostic contains: 'R' has field 'xs' + record R(List xs) {} + """) + .doTest(); + } + + @Test + public void immutableRecord() { + compilationHelper + .addSourceLines( + "Test.java", + """ + import com.google.common.collect.ImmutableList; + import com.google.errorprone.annotations.Immutable; + + @Immutable + record R(ImmutableList xs) {} + """) + .doTest(); + } } From e73278264e42ffb76bdd9ae5063efc003291cc0b Mon Sep 17 00:00:00 2001 From: markbrady Date: Wed, 13 Nov 2024 10:49:11 -0800 Subject: [PATCH 18/38] StatementSwitchToExpressionSwitch: for return switch transformation, retain comments appearing in the switch block before the first case PiperOrigin-RevId: 696193684 --- .../StatementSwitchToExpressionSwitch.java | 47 +++++++++-- ...StatementSwitchToExpressionSwitchTest.java | 80 +++++++++++++++++++ 2 files changed, 119 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java b/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java index ce273dc7587..d5b09870f15 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java @@ -78,6 +78,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.function.Predicate; import java.util.regex.Pattern; import javax.inject.Inject; import javax.lang.model.element.ElementKind; @@ -662,7 +663,12 @@ private static SuggestedFix convertToReturnSwitch( transformReturnOrThrowBlock(caseTree, state, getStatements(caseTree)); if (firstCaseInGroup) { - groupedCaseCommentsAccumulator = new StringBuilder(); + groupedCaseCommentsAccumulator = + caseIndex == 0 + ? new StringBuilder( + extractCommentsBeforeFirstCase(switchTree, allSwitchComments).orElse("")) + : new StringBuilder(); + replacementCodeBuilder.append("\n "); if (!isDefaultCase) { replacementCodeBuilder.append("case "); @@ -988,6 +994,21 @@ private static int extractLhsComments( return lhsEnd; } + /** + * Extracts any comments appearing within the switch tree before the first case. Comments are + * merged into a single string separated by newlines. Precondition: the switch tree has at least + * one case. + */ + private static Optional extractCommentsBeforeFirstCase( + SwitchTree switchTree, ImmutableList allSwitchComments) { + // Indexing relative to the start position of the switch statement + int switchStart = getStartPosition(switchTree); + int firstCaseStartIndex = getStartPosition(switchTree.getCases().get(0)) - switchStart; + + return filterAndRenderComments( + allSwitchComments, comment -> comment.getPos() < firstCaseStartIndex); + } + /** * Extracts any comments appearing after the specified {@code caseIndex} but before the subsequent * case or end of the {@code switchTree}. Comments are merged into a single string separated by @@ -1009,12 +1030,22 @@ private static Optional extractCommentsAfterCase( ? state.getEndPosition(switchTree) - switchStart : getStartPosition(switchTree.getCases().get(caseIndex + 1)) - switchStart; - String filteredComments = - allSwitchComments.stream() - // Comments after the end of the current case and before the start of the next case - .filter( - comment -> - comment.getPos() >= caseEndIndex && comment.getPos() < nextCaseStartIndex) + return filterAndRenderComments( + allSwitchComments, + comment -> comment.getPos() >= caseEndIndex && comment.getPos() < nextCaseStartIndex); + } + + /** + * Filters comments according to the supplied predicate ({@code commentFilter}), removes + * fall-through and empty comments, and renders them into a single optional string. If no comments + * remain, returns {@code Optional.empty()}. + */ + private static Optional filterAndRenderComments( + ImmutableList comments, Predicate commentFilter) { + + String rendered = + comments.stream() + .filter(commentFilter) .map(ErrorProneComment::getText) // Remove "fall thru" comments .map(commentText -> removeFallThruLines(commentText)) @@ -1022,7 +1053,7 @@ private static Optional extractCommentsAfterCase( .filter(commentText -> !commentText.isEmpty()) .collect(joining("\n")); - return filteredComments.isEmpty() ? Optional.empty() : Optional.of(filteredComments); + return rendered.isEmpty() ? Optional.empty() : Optional.of(rendered); } /** diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java index bdb756a3105..357b46452b4 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java @@ -2107,6 +2107,86 @@ public int foo(Side side) { .doTest(BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH); } + @Test + public void switchByEnum_returnSwitchCommentsBeforeFirstCase_errorAndRetained() { + assume().that(Runtime.version().feature()).isAtLeast(14); + + // Check correct generated code + refactoringHelper + .addInputLines( + "Test.java", + """ + class Test { + enum Side { + HEART, + SPADE, + DIAMOND, + CLUB + }; + + public Test(int foo) {} + + public int invoke() { + return 123; + } + + public int foo(Side side) { + switch (side) { + // Abracadabra + /* foo */ case HEART: + // Card trick + case DIAMOND: + return invoke(); + case SPADE: + throw new RuntimeException(); + case CLUB: + throw new NullPointerException(); + } + // This should never happen + int z = invoke(); + z++; + throw new RuntimeException("Switch was not exhaustive at runtime " + z); + } + } + """) + .addOutputLines( + "Test.java", + """ + class Test { + enum Side { + HEART, + SPADE, + DIAMOND, + CLUB + }; + + public Test(int foo) {} + + public int invoke() { + return 123; + } + + public int foo(Side side) { + return switch (side) { + case HEART, DIAMOND -> + // Abracadabra + /* foo */ + // Card trick + invoke(); + case SPADE -> throw new RuntimeException(); + case CLUB -> throw new NullPointerException(); + }; + // This should never happen + + } + } + """) + .setArgs( + ImmutableList.of( + "-XepOpt:StatementSwitchToExpressionSwitch:EnableReturnSwitchConversion")) + .doTest(BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH); + } + @Test public void switchByEnum_switchInReturnSwitchWithShouldNeverHappen_error() { assume().that(Runtime.version().feature()).isAtLeast(14); From 9285aa116288a14ed773cb71d52287c2cf939eaa Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 13 Nov 2024 15:14:31 -0800 Subject: [PATCH 19/38] Don't complain about sealed classes in InterfaceWithOnlyStatics PiperOrigin-RevId: 696286882 --- .../bugpatterns/InterfaceWithOnlyStatics.java | 2 +- .../bugpatterns/InterfaceWithOnlyStaticsTest.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/InterfaceWithOnlyStatics.java b/core/src/main/java/com/google/errorprone/bugpatterns/InterfaceWithOnlyStatics.java index b59d2a97701..3ce75a97878 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/InterfaceWithOnlyStatics.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/InterfaceWithOnlyStatics.java @@ -62,7 +62,7 @@ public Description matchClass(ClassTree tree, VisitorState state) { } List members = tree.getMembers(); ClassSymbol symbol = getSymbol(tree); - if (!symbol.isInterface() || symbol.isAnnotationType()) { + if (!symbol.isInterface() || symbol.isAnnotationType() || symbol.isSealed()) { return Description.NO_MATCH; } int staticMembers = 0; diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/InterfaceWithOnlyStaticsTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/InterfaceWithOnlyStaticsTest.java index dd8dfb136c7..96f6977678b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/InterfaceWithOnlyStaticsTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/InterfaceWithOnlyStaticsTest.java @@ -206,4 +206,19 @@ private Test() {} """) .doTest(); } + + @Test + public void negativeSealed() { + testHelper + .addSourceLines( + "Test.java", + """ + sealed interface Test { + record A() implements Test {} + + record B() implements Test {} + } + """) + .doTest(); + } } From 2124ebf984c36585e7a632af1a986817f973dcaa Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 13 Nov 2024 16:02:53 -0800 Subject: [PATCH 20/38] Add support for trivial instance method references to Inliner This is sufficient to handling inlining getter methods on the same instance. PiperOrigin-RevId: 696301080 --- .../bugpatterns/inlineme/Inliner.java | 58 ++++++++++++++++++- .../bugpatterns/inlineme/InlinerTest.java | 55 ++++++++++++++++++ 2 files changed, 111 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/inlineme/Inliner.java b/core/src/main/java/com/google/errorprone/bugpatterns/inlineme/Inliner.java index 6d428bf5fe9..4073c267ec0 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/inlineme/Inliner.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/inlineme/Inliner.java @@ -39,6 +39,7 @@ import com.google.errorprone.ErrorProneFlags; import com.google.errorprone.VisitorState; import com.google.errorprone.bugpatterns.BugChecker; +import com.google.errorprone.bugpatterns.BugChecker.MemberReferenceTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.NewClassTreeMatcher; import com.google.errorprone.fixes.SuggestedFix; @@ -47,6 +48,7 @@ import com.google.errorprone.util.MoreAnnotations; import com.sun.source.tree.ExpressionStatementTree; import com.sun.source.tree.ExpressionTree; +import com.sun.source.tree.MemberReferenceTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.NewClassTree; import com.sun.source.tree.Tree; @@ -71,7 +73,7 @@ severity = WARNING, tags = Inliner.FINDING_TAG) public final class Inliner extends BugChecker - implements MethodInvocationTreeMatcher, NewClassTreeMatcher { + implements MethodInvocationTreeMatcher, NewClassTreeMatcher, MemberReferenceTreeMatcher { public static final String FINDING_TAG = "JavaInlineMe"; @@ -141,6 +143,54 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState return match(tree, symbol, callingVars, receiverString, receiver, state); } + private static final Pattern MEMBER_REFERENCE_PATTERN = + Pattern.compile( + "(return\\b+)?((?[^\b]+)\\.)?(?\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)\\(\\)"); + + @Override + public Description matchMemberReference(MemberReferenceTree tree, VisitorState state) { + MethodSymbol symbol = getSymbol(tree); + if (symbol.isStatic()) { + // TODO: b/165938605 - handle static member references + return Description.NO_MATCH; + } + if (!hasDirectAnnotationWithSimpleName(symbol, INLINE_ME)) { + return Description.NO_MATCH; + } + Optional inlineMeMaybe = InlineMeData.createFromSymbol(symbol); + if (inlineMeMaybe.isEmpty()) { + return Description.NO_MATCH; + } + InlineMeData inlineMe = inlineMeMaybe.get(); + if (!inlineMe.imports().isEmpty() || !inlineMe.staticImports().isEmpty()) { + // TODO: b/165938605 - handle imports + return Description.NO_MATCH; + } + Api api = Api.create(symbol, state); + if (!matchesApiPrefixes(api)) { + return Description.NO_MATCH; + } + if (skipCallsitesWithComments + && stringContainsComments(state.getSourceForNode(tree), state.context)) { + return Description.NO_MATCH; + } + Matcher matcher = MEMBER_REFERENCE_PATTERN.matcher(inlineMe.replacement()); + if (!matcher.matches()) { + return Description.NO_MATCH; + } + String qualifier = matcher.group("qualifier"); + if (!qualifier.equals("this")) { + return Description.NO_MATCH; + } + String identifier = matcher.group("identifier"); + SuggestedFix fix = + SuggestedFix.replace( + state.getEndPosition(tree.getQualifierExpression()), + state.getEndPosition(tree), + "::" + identifier); + return maybeCheckFixCompiles(tree, state, fix, api); + } + private Description match( ExpressionTree tree, MethodSymbol symbol, @@ -270,6 +320,11 @@ && stringContainsComments(state.getSourceForNode(tree), state.context)) { SuggestedFix fix = builder.build(); + return maybeCheckFixCompiles(tree, state, fix, api); + } + + private Description maybeCheckFixCompiles( + ExpressionTree tree, VisitorState state, SuggestedFix fix, Api api) { if (checkFixCompiles && fix.getImportsToAdd().isEmpty()) { // If there are no new imports being added (then there are no new dependencies). Therefore, we // can verify that the fix compiles (if CHECK_FIX_COMPILES is enabled). @@ -277,7 +332,6 @@ && stringContainsComments(state.getSourceForNode(tree), state.context)) { ? describe(tree, fix, api) : Description.NO_MATCH; } - return describe(tree, fix, api); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inlineme/InlinerTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inlineme/InlinerTest.java index 530b44218e7..fa64e592b22 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inlineme/InlinerTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inlineme/InlinerTest.java @@ -1564,6 +1564,61 @@ void doTest() { .doTest(); } + @Test + public void methodReference() { + refactoringTestHelper + .addInputLines( + "Client.java", + """ + package p; + + import com.google.errorprone.annotations.InlineMe; + + public final class Client { + @Deprecated + @InlineMe(replacement = "this.instanceAfter()") + public void instanceBefore() { + instanceAfter(); + } + + public void instanceAfter() {} + } + """) + .expectUnchanged() + .addInputLines( + "Caller.java", + """ + import java.util.function.Consumer; + import p.Client; + + public final class Caller { + public void doTest() { + Client client = new Client(); + Consumer c; + Runnable r; + r = client::instanceBefore; + c = Client::instanceBefore; + } + } + """) + .addOutputLines( + "out/Caller.java", + """ + import java.util.function.Consumer; + import p.Client; + public final class Caller { + public void doTest() { + Client client = new Client(); + Consumer c; + Runnable r; + r = client::instanceAfter; + c = Client::instanceAfter; + } + } + """) + .doTest(BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH); + } + private BugCheckerRefactoringTestHelper bugCheckerWithPrefixFlag(String prefix) { return BugCheckerRefactoringTestHelper.newInstance(Inliner.class, getClass()) .setArgs("-XepOpt:" + PREFIX_FLAG + "=" + prefix); From 5d8adc530fb16679a42c728f4f4197a51f6a36c2 Mon Sep 17 00:00:00 2001 From: ghm Date: Thu, 14 Nov 2024 16:01:23 -0800 Subject: [PATCH 21/38] WrongOneOf: don't assume the expression in a label is an identifier. It's no longer required to be (!). PiperOrigin-RevId: 696680228 --- .../errorprone/bugpatterns/WrongOneof.java | 5 ++- .../bugpatterns/ArrayEqualsTest.java | 12 ++++--- .../bugpatterns/ArrayHashCodeTest.java | 9 +++-- .../bugpatterns/ArrayToStringTest.java | 18 ++++++---- .../bugpatterns/AssertFalseTest.java | 6 ++-- .../AsyncFunctionReturnsNullTest.java | 6 ++-- .../bugpatterns/BadComparableTest.java | 6 ++-- .../errorprone/bugpatterns/BadImportTest.java | 12 ++++--- .../bugpatterns/BadShiftAmountTest.java | 6 ++-- .../bugpatterns/BanClassLoaderTest.java | 6 ++-- .../errorprone/bugpatterns/BanJNDITest.java | 9 +++-- .../ByteBufferBackingArrayTest.java | 6 ++-- .../bugpatterns/CannotMockFinalClassTest.java | 9 +++-- .../ChainedAssertionLosesContextTest.java | 6 ++-- ...ainingConstructorIgnoresParameterTest.java | 6 ++-- .../bugpatterns/CheckReturnValueTest.java | 6 ++-- .../bugpatterns/ClassCanBeStaticTest.java | 12 ++++--- .../CollectionToArraySafeParameterTest.java | 6 ++-- .../CollectorShouldNotUseStateTest.java | 6 ++-- .../ComparableAndComparatorTest.java | 6 ++-- .../bugpatterns/ComparableTypeTest.java | 6 ++-- .../ComparisonContractViolatedTest.java | 6 ++-- .../bugpatterns/ComparisonOutOfRangeTest.java | 6 ++-- .../bugpatterns/DeadExceptionTest.java | 9 +++-- .../errorprone/bugpatterns/DepAnnTest.java | 12 ++++--- .../bugpatterns/EmptyCatchTest.java | 6 ++-- .../bugpatterns/EmptyIfStatementTest.java | 6 ++-- .../bugpatterns/EqualsHashCodeTest.java | 6 ++-- .../EqualsIncompatibleTypeTest.java | 9 +++-- .../errorprone/bugpatterns/EqualsNaNTest.java | 6 ++-- .../bugpatterns/EqualsReferenceTest.java | 6 ++-- ...neousThreadPoolConstructorCheckerTest.java | 6 ++-- .../bugpatterns/FallThroughTest.java | 6 ++-- .../errorprone/bugpatterns/FinallyTest.java | 12 ++++--- ...oatingPointAssertionWithinEpsilonTest.java | 12 ++++--- .../FunctionalInterfaceMethodChangedTest.java | 6 ++-- .../FutureReturnValueIgnoredTest.java | 6 ++-- ...resGetCheckedIllegalExceptionTypeTest.java | 6 ++-- ...ualsShouldNotBeUsedInEqualsMethodTest.java | 6 ++-- .../bugpatterns/GetClassOnClassTest.java | 6 ++-- .../bugpatterns/HidingFieldTest.java | 9 +++-- .../ImplementAssertionWithChainingTest.java | 6 ++-- .../InconsistentCapitalizationTest.java | 3 +- .../IncrementInForLoopAndHeaderTest.java | 6 ++-- .../bugpatterns/InsecureCipherModeTest.java | 6 ++-- .../InstanceOfAndCastMatchWrongTypeTest.java | 6 ++-- .../bugpatterns/InvalidPatternSyntaxTest.java | 6 ++-- .../bugpatterns/IterableAndIteratorTest.java | 6 ++-- .../bugpatterns/JUnit3TestNotRunTest.java | 21 +++++++---- .../bugpatterns/JUnit4SetUpNotRunTest.java | 12 ++++--- .../bugpatterns/JUnit4TearDownNotRunTest.java | 12 ++++--- .../bugpatterns/JUnit4TestNotRunTest.java | 24 ++++++++----- .../bugpatterns/JUnitAssertSameCheckTest.java | 6 ++-- .../JUnitParameterMethodNotFoundTest.java | 15 +++++--- .../LambdaFunctionalInterfaceTest.java | 6 ++-- .../bugpatterns/LiteEnumValueOfTest.java | 6 ++-- .../LockOnNonEnclosingClassLiteralTest.java | 6 ++-- .../LongLiteralLowerCaseSuffixTest.java | 12 ++++--- .../MisleadingEscapedSpaceTest.java | 24 ++++++++----- .../bugpatterns/MissingFailTest.java | 15 +++++--- .../bugpatterns/MisusedWeekYearTest.java | 9 +++-- ...ModifyCollectionInEnhancedForLoopTest.java | 6 ++-- .../ModifySourceCollectionInStreamTest.java | 6 ++-- .../ModifyingCollectionWithItselfTest.java | 6 ++-- ...MultipleParallelOrSequentialCallsTest.java | 12 ++++--- ...ultipleUnaryOperatorsInMethodCallTest.java | 6 ++-- .../NestedInstanceOfConditionsTest.java | 6 ++-- .../bugpatterns/NoAllocationCheckerTest.java | 6 ++-- .../NonAtomicVolatileUpdateTest.java | 6 ++-- .../bugpatterns/NonRuntimeAnnotationTest.java | 6 ++-- .../bugpatterns/ObjectToStringTest.java | 6 ++-- .../bugpatterns/OptionalNotPresentTest.java | 6 ++-- .../OverrideThrowableToStringTest.java | 12 ++++--- .../errorprone/bugpatterns/OverridesTest.java | 24 ++++++++----- .../PreconditionsInvalidPlaceholderTest.java | 6 ++-- ...imitiveArrayPassedToVarargsMethodTest.java | 6 ++-- ...rivateSecurityContractProtoAccessTest.java | 6 ++-- .../ProtocolBufferOrdinalTest.java | 6 ++-- .../bugpatterns/RestrictedApiCheckerTest.java | 6 ++-- ...eOperationExceptionAsLinkageErrorTest.java | 6 ++-- .../bugpatterns/ReturnValueIgnoredTest.java | 6 ++-- .../bugpatterns/RxReturnValueIgnoredTest.java | 6 ++-- .../bugpatterns/SelfAssertionTest.java | 6 ++-- .../bugpatterns/SelfAssignmentTest.java | 9 +++-- .../bugpatterns/SelfComparisonTest.java | 6 ++-- .../bugpatterns/SelfEqualsTest.java | 12 ++++--- .../bugpatterns/ShouldHaveEvenArgsTest.java | 12 ++++--- .../SizeGreaterThanOrEqualsZeroTest.java | 6 ++-- .../StaticQualifiedUsingExpressionTest.java | 9 +++-- .../StringBuilderInitWithCharTest.java | 6 ++-- .../bugpatterns/StringSplitterTest.java | 6 ++-- .../SuppressWarningsDeprecatedTest.java | 6 ++-- .../bugpatterns/SwigMemoryLeakTest.java | 6 ++-- .../bugpatterns/ThreadJoinLoopTest.java | 12 ++++--- .../ThrowIfUncheckedKnownCheckedTest.java | 6 ++-- .../ThrowsUncheckedExceptionTest.java | 6 ++-- .../bugpatterns/TreeToStringTest.java | 6 ++-- .../bugpatterns/TruthAssertExpectedTest.java | 6 ++-- .../bugpatterns/TruthConstantAssertsTest.java | 6 ++-- .../bugpatterns/TryFailThrowableTest.java | 6 ++-- .../bugpatterns/URLEqualsHashCodeTest.java | 6 ++-- .../bugpatterns/UngroupedOverloadsTest.java | 36 ++++++++++++------- .../UnnecessaryBoxedAssignmentTest.java | 6 ++-- .../UnnecessaryBoxedVariableTest.java | 6 ++-- .../UnnecessaryLongToIntConversionTest.java | 6 ++-- .../UnsafeReflectiveConstructionCastTest.java | 3 +- .../bugpatterns/WaitNotInLoopTest.java | 6 ++-- ...BinderIdentityRestoredDangerouslyTest.java | 3 +- .../android/FragmentInjectionTest.java | 3 +- .../android/FragmentNotInstantiableTest.java | 30 ++++++++++------ .../android/HardCodedSdCardPathTest.java | 6 ++-- .../android/IsLoggableTagLengthTest.java | 3 +- .../android/MislabeledAndroidStringTest.java | 3 +- .../RectIntersectReturnValueIgnoredTest.java | 9 +++-- .../WakelockReleasedDangerouslyTest.java | 6 ++-- .../CollectionIncompatibleTypeTest.java | 12 ++++--- .../IncompatibleArgumentTypeTest.java | 12 ++++--- .../FloggerRedundantIsEnabledTest.java | 12 ++++--- ...stedInjectAndInjectOnConstructorsTest.java | 6 ++-- ...dInjectAndInjectOnSameConstructorTest.java | 6 ++-- .../inject/AutoFactoryAtInjectTest.java | 6 ++-- .../inject/CloseableProvidesTest.java | 6 ++-- .../InjectOnMemberAndConstructorTest.java | 3 +- .../InjectedConstructorAnnotationsTest.java | 6 ++-- ...validTargetingOnScopingAnnotationTest.java | 6 ++-- .../JavaxInjectOnAbstractMethodTest.java | 6 ++-- .../inject/JavaxInjectOnFinalFieldTest.java | 6 ++-- .../inject/MissingRuntimeRetentionTest.java | 6 ++-- .../MoreThanOneInjectableConstructorTest.java | 6 ++-- .../inject/MoreThanOneQualifierTest.java | 6 ++-- ...MoreThanOneScopeAnnotationOnClassTest.java | 6 ++-- ...appingQualifierAndScopeAnnotationTest.java | 6 ++-- .../inject/QualifierWithTypeUseTest.java | 6 ++-- ...otationOnInterfaceOrAbstractClassTest.java | 6 ++-- .../AndroidInjectionBeforeSuperTest.java | 33 +++++++++++------ .../guice/AssistedInjectScopingTest.java | 6 ++-- .../inject/guice/AssistedParametersTest.java | 6 ++-- .../BindingToUnqualifiedCommonTypeTest.java | 6 ++-- .../inject/guice/InjectOnFinalFieldTest.java | 6 ++-- .../OverridesGuiceInjectableMethodTest.java | 6 ++-- .../OverridesJavaxInjectableMethodTest.java | 6 ++-- .../ProvidesMethodOutsideOfModuleTest.java | 6 ++-- .../nullness/EqualsBrokenForNullTest.java | 6 ++-- .../nullness/NullablePrimitiveTest.java | 6 ++-- .../nullness/UnnecessaryCheckNotNullTest.java | 12 ++++--- .../nullness/UnsafeWildcardTest.java | 3 +- .../InconsistentOverloadsTest.java | 24 ++++++++----- .../time/TimeUnitMismatchTest.java | 6 ++-- .../NullnessPropagationTest.java | 24 ++++++++----- 149 files changed, 814 insertions(+), 409 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/WrongOneof.java b/core/src/main/java/com/google/errorprone/bugpatterns/WrongOneof.java index 1929409b825..4df02a65efb 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/WrongOneof.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/WrongOneof.java @@ -23,6 +23,7 @@ import static com.google.errorprone.predicates.TypePredicates.isDescendantOf; import static com.google.errorprone.util.ASTHelpers.enumValues; import static com.google.errorprone.util.ASTHelpers.getReceiver; +import static com.google.errorprone.util.ASTHelpers.getSymbol; import static com.google.errorprone.util.ASTHelpers.getType; import static com.google.errorprone.util.ASTHelpers.stripParentheses; import static com.google.errorprone.util.Reachability.canCompleteNormally; @@ -38,7 +39,6 @@ import com.google.errorprone.predicates.TypePredicate; import com.sun.source.tree.CaseTree; import com.sun.source.tree.ExpressionTree; -import com.sun.source.tree.IdentifierTree; import com.sun.source.tree.MemberSelectTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.StatementTree; @@ -97,8 +97,7 @@ private void processSwitch( if (caseTree.getExpression() == null) { break; } - allowableGetters.add( - getter(((IdentifierTree) caseTree.getExpression()).getName().toString())); + allowableGetters.add(getter(getSymbol(caseTree.getExpression()).getSimpleName().toString())); scanForInvalidGetters(getters, allowableGetters, caseTree, constantReceiver, state); diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ArrayEqualsTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ArrayEqualsTest.java index 1b81fd1f0a6..8032b99b2c3 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ArrayEqualsTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ArrayEqualsTest.java @@ -118,7 +118,8 @@ public void bothMethodCalls() { System.out.println("arrays are not equal!"); } } - }""") + }\ + """) .doTest(); } @@ -162,7 +163,8 @@ public void objectArray() { System.out.println("arrays are not equal!"); } } - }""") + }\ + """) .doTest(); } @@ -230,7 +232,8 @@ public void secondArray() { System.out.println("Objects are not equal!"); } } - }""") + }\ + """) .doTest(); } @@ -282,7 +285,8 @@ public void secondArray() { System.out.println("arrays are not equal!"); } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ArrayHashCodeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ArrayHashCodeTest.java index f57d4f24def..4976c6e15f7 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ArrayHashCodeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ArrayHashCodeTest.java @@ -104,7 +104,8 @@ public void varargsHashCodeOnMoreThanOneArg() { // Arrays.deepHashCode(multidimensionalStringArray)) hashCode = Objects.hashCode(obj1, obj2, multidimensionalStringArray); } -}""") +}\ +""") .doTest(); } @@ -147,7 +148,8 @@ public void varagsHashCodeOnObjectOrStringArray() { hashCode = Objects.hashCode(objArray); hashCode = Objects.hashCode((Object[]) stringArray); } - }""") + }\ + """) .doTest(); } @@ -193,7 +195,8 @@ public void varagsHashCodeOnObjectOrStringArray() { hashCode = Objects.hash(objArray); hashCode = Objects.hash((Object[]) stringArray); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ArrayToStringTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ArrayToStringTest.java index 6e46908d040..2f151036060 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ArrayToStringTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ArrayToStringTest.java @@ -102,7 +102,8 @@ public void arrayOfArrays() { // BUG: Diagnostic contains: Arrays.deepToString(a) System.out.println(a); } - }""") + }\ + """) .doTest(); } @@ -129,7 +130,8 @@ public void objectEquals() { System.out.println("string is not empty!"); } } - }""") + }\ + """) .doTest(); } @@ -305,7 +307,8 @@ public void stringVariableAddsArrayAndAssigns() { // BUG: Diagnostic contains: += Arrays.toString(a) b += a; } - }""") + }\ + """) .doTest(); } @@ -332,7 +335,8 @@ public void concatenateCompoundAssign_int() { String b = " a string "; b += a; } - }""") + }\ + """) .doTest(); } @@ -362,7 +366,8 @@ public void stringLiteralRightOperandIsArray() { // BUG: Diagnostic contains: + Arrays.toString(a) String b = "a string" + a; } - }""") + }\ + """) .doTest(); } @@ -388,7 +393,8 @@ public void notArray_refactored() { String b = " a string"; String c = a + b; } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/AssertFalseTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/AssertFalseTest.java index 10883b78bbb..76e2a97c2f6 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/AssertFalseTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/AssertFalseTest.java @@ -50,7 +50,8 @@ public void assertTrue() { public void assertFalseFromCondition() { assert 0 == 1; } - }""") + }\ + """) .doTest(); } @@ -70,7 +71,8 @@ public void assertFalse() { // BUG: Diagnostic contains: throw new AssertionError() assert false; } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/AsyncFunctionReturnsNullTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/AsyncFunctionReturnsNullTest.java index d04d9904eff..0abe157bd5b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/AsyncFunctionReturnsNullTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/AsyncFunctionReturnsNullTest.java @@ -69,7 +69,8 @@ public ListenableFuture apply(Object input) throws Exception { return immediateFuture(input.toString()); } } - }""") + }\ + """) .doTest(); } @@ -139,7 +140,8 @@ public ListenableFuture apply(String input) throws Exception { interface MyNonAsyncFunction { ListenableFuture apply(@Nullable I input) throws Exception; } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/BadComparableTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/BadComparableTest.java index 63594f2716f..fae1062fcf3 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/BadComparableTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/BadComparableTest.java @@ -85,7 +85,8 @@ public int compare(File lhs, File rhs) { return (int) (rhs.lastModified() - lhs.lastModified()); } }; -}""") +}\ +""") .doTest(); } @@ -231,7 +232,8 @@ public char compare(byte n1, byte n2) { return (char) (n1 - n2); } }; - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/BadImportTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/BadImportTest.java index cfa2c8ea462..f8853c247fb 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/BadImportTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/BadImportTest.java @@ -243,7 +243,8 @@ Builder returnRaw() { void classLiteral() { System.out.println(Builder.class); } -}""") +}\ +""") .doTest(); } @@ -354,7 +355,8 @@ void useNestedBuilder() { new Builder(); } } - }""") + }\ + """) .doTest(); } @@ -438,7 +440,8 @@ Builder returnRaw() { void classLiteral() { System.out.println(Builder.class); } -}""") +}\ +""") .addOutputLines( "BadImportPositiveCases_expected.java", """ @@ -498,7 +501,8 @@ ImmutableList.Builder returnRaw() { void classLiteral() { System.out.println(ImmutableList.Builder.class); } -}""") +}\ +""") .doTest(TestMode.AST_MATCH); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/BadShiftAmountTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/BadShiftAmountTest.java index 7b0eb68bf4f..4a56e6bde5d 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/BadShiftAmountTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/BadShiftAmountTest.java @@ -78,7 +78,8 @@ public void foo() { // BUG: Diagnostic contains: (long) c >>> 32 result += c >>> 32; } - }""") + }\ + """) .doTest(); } @@ -104,7 +105,8 @@ public void foo() { result += x >>> 3; result += (long) (x & 0xff) >> 40; } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/BanClassLoaderTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/BanClassLoaderTest.java index c089d8ab5b0..bae671992d5 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/BanClassLoaderTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/BanClassLoaderTest.java @@ -83,7 +83,8 @@ public static final Class methodHandlesDefineClass(byte[] bytes) // BUG: Diagnostic contains: BanClassLoader return MethodHandles.lookup().defineClass(bytes); } -}""") +}\ +""") .doTest(); } @@ -113,7 +114,8 @@ public final Class overrideClassLoader() throws ClassNotFoundException { private class NotClassLoader { protected void loadClass() {} } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/BanJNDITest.java b/core/src/test/java/com/google/errorprone/bugpatterns/BanJNDITest.java index a5024402357..910ca6986de 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/BanJNDITest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/BanJNDITest.java @@ -169,7 +169,8 @@ private Object subclassesJavaNamingcontext() throws NamingException { // BUG: Diagnostic contains: BanJNDI return c.lookup("hello"); } -}""") +}\ +""") .doTest(); } @@ -197,7 +198,8 @@ class BanJNDIPositiveCases { private void callsList() throws NamingException { FakeDirContext.list(((Name) new Object())); } -}""") +}\ +""") .doTest(); } @@ -225,7 +227,8 @@ class BanJNDIPositiveCases { private void callsList() throws NamingException { FakeDirContext.list(((Name) new Object())); } -}""") +}\ +""") .expectUnchanged() .setArgs("-XepCompilingTestOnlyCode") .doTest(); diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ByteBufferBackingArrayTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ByteBufferBackingArrayTest.java index 7654fa0f6ff..f84c8b94c71 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ByteBufferBackingArrayTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ByteBufferBackingArrayTest.java @@ -104,7 +104,8 @@ void array_precededByNotAValidMethod_isFlagged() { // BUG: Diagnostic contains: ByteBuffer.array() buff.array(); } -}""") +}\ +""") .doTest(); } @@ -248,7 +249,8 @@ void array_inLambdaExpression_precededByByteBufferAllocate_isNotFlagged() { return null; }; } -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/CannotMockFinalClassTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/CannotMockFinalClassTest.java index f038e3d0b57..3bdd0e3bab2 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/CannotMockFinalClassTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/CannotMockFinalClassTest.java @@ -56,7 +56,8 @@ public void method() { // BUG: Diagnostic contains: Mockito cannot mock FinalClass local = Mockito.mock(FinalClass.class); } - }""") + }\ + """) .doTest(); } @@ -105,7 +106,8 @@ static class NonFinalClass {} public void method() { NonFinalClass local = Mockito.mock(NonFinalClass.class); } - }""") + }\ + """) .doTest(); } @@ -127,7 +129,8 @@ static final class FinalClass {} public void method() { FinalClass local = Mockito.mock(FinalClass.class); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ChainedAssertionLosesContextTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ChainedAssertionLosesContextTest.java index 494f0f7140f..dbcc05ffb63 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ChainedAssertionLosesContextTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ChainedAssertionLosesContextTest.java @@ -126,7 +126,8 @@ Foo otherFoo() { return this; } } -}""") +}\ +""") .doTest(); } @@ -190,7 +191,8 @@ Foo otherFoo() { return this; } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ChainingConstructorIgnoresParameterTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ChainingConstructorIgnoresParameterTest.java index e912ac10e52..ac363a8ff00 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ChainingConstructorIgnoresParameterTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ChainingConstructorIgnoresParameterTest.java @@ -122,7 +122,8 @@ static class MultipleQueuedErrors { enum Location { TEST_TARGET } -}""") +}\ +""") .doTest(); } @@ -232,7 +233,8 @@ static class Varargs2 { this("something"); } } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/CheckReturnValueTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/CheckReturnValueTest.java index 8dd9d36d324..daec8cbf32d 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/CheckReturnValueTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/CheckReturnValueTest.java @@ -229,7 +229,8 @@ public static void ignoresCheck() { check(); } } -}""") +}\ +""") .doTest(); } @@ -347,7 +348,8 @@ public void testMethodReference(boolean predicate) { callSupplier(this::mustCheck); callSupplier(predicate ? this::mustCheck : this::nothingToCheck); } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ClassCanBeStaticTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ClassCanBeStaticTest.java index 04eb27e00be..b8182650abc 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ClassCanBeStaticTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ClassCanBeStaticTest.java @@ -113,7 +113,8 @@ int localMethod() { } } } - }""") + }\ + """) .setArgs("--release", "11") .doTest(); } @@ -138,7 +139,8 @@ public class ClassCanBeStaticPositiveCase1 { class Inner1 { int innerVar; } - }""") + }\ + """) .doTest(); } @@ -168,7 +170,8 @@ int localMethod(int outerVar2) { return outerVar2; } } - }""") + }\ + """) .doTest(); } @@ -193,7 +196,8 @@ static class NonStaticOuter { // BUG: Diagnostic contains: public static class Inner3 public class Inner3 {} } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/CollectionToArraySafeParameterTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/CollectionToArraySafeParameterTest.java index 83db1c94113..74c01c08a3a 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/CollectionToArraySafeParameterTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/CollectionToArraySafeParameterTest.java @@ -77,7 +77,8 @@ void test(FooBar foo) { class FooBar extends HashSet {} class Foo extends HashSet {} - }""") + }\ + """) .doTest(); } @@ -141,7 +142,8 @@ Integer[] toArray(Integer[] someArray) { return new Integer[10]; } } -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/CollectorShouldNotUseStateTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/CollectorShouldNotUseStateTest.java index 687ffb869e1..53a382a5f61 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/CollectorShouldNotUseStateTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/CollectorShouldNotUseStateTest.java @@ -87,7 +87,8 @@ public void accept(Builder objectBuilder, Object o) { (left, right) -> left.addAll(right.build()), ImmutableList.Builder::build); } - }""") + }\ + """) .doTest(); } @@ -126,7 +127,8 @@ public void accept(Builder objectBuilder, Object o) { (left, right) -> left.addAll(right.build()), ImmutableList.Builder::build); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ComparableAndComparatorTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ComparableAndComparatorTest.java index 353f8aae6a3..9e98d0e1a5e 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ComparableAndComparatorTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ComparableAndComparatorTest.java @@ -75,7 +75,8 @@ public int compareTo(SubClass o) { return 0; } } - }""") + }\ + """) .doTest(); } @@ -161,7 +162,8 @@ public int compare(Integer one, Integer two) { return 0; } } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ComparableTypeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ComparableTypeTest.java index cce753effe1..92500df8428 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ComparableTypeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ComparableTypeTest.java @@ -149,7 +149,8 @@ public int compareTo(Integer o) { return 0; } } -}""") +}\ +""") .doTest(); } @@ -255,7 +256,8 @@ public int compareTo(Object o) { return 0; } } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ComparisonContractViolatedTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ComparisonContractViolatedTest.java index d2c421320a9..62d459ba035 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ComparisonContractViolatedTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ComparisonContractViolatedTest.java @@ -143,7 +143,8 @@ public int compare(Struct o1, Struct o2) { return o1.equals(o2) ? 0 : POSITIVE_CONSTANT; } }; - }""") + }\ + """) .doTest(); } @@ -179,7 +180,8 @@ public int compareTo(IntOrInfinity o) { return (o instanceof NegativeInfinity) ? 0 : -1; } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ComparisonOutOfRangeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ComparisonOutOfRangeTest.java index 59e1ccdb51c..f25dcedde72 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ComparisonOutOfRangeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ComparisonOutOfRangeTest.java @@ -166,7 +166,8 @@ void longs(long l) { // BUG: Diagnostic contains: false result = l == Long.MIN_VALUE * 2.0; } - }""") + }\ + """) .doTest(); } @@ -277,7 +278,8 @@ void longs(long l) { String binaryTreeMixingByteWithNonNumeric(byte b) { return "value is: " + b; } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/DeadExceptionTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/DeadExceptionTest.java index 4932feabfcb..95ccc22f351 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/DeadExceptionTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/DeadExceptionTest.java @@ -98,7 +98,8 @@ public void testLooksLikeAJunitTestMethod() { // BUG: Diagnostic contains: throw new Exception new Exception(); } - }""") + }\ + """) .doTest(); } @@ -120,7 +121,8 @@ public void noError() { public Exception returnsException() { return new RuntimeException("returned"); } - }""") + }\ + """) .doTest(); } @@ -162,7 +164,8 @@ public void shouldAllowTestingOfExceptionConstructorSideEffects() { // expected } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/DepAnnTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/DepAnnTest.java index 3c89147ad34..a78c3f2ee17 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/DepAnnTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/DepAnnTest.java @@ -76,7 +76,8 @@ interface Interface {} */ // BUG: Diagnostic contains: @Deprecated public void deprecatedMethood() {} - }""") + }\ + """) .doTest(); } @@ -139,7 +140,8 @@ public void deprecatedMethodWithMalformedComment() {} public void suppressed() {} public void newMethod() {} - }""") + }\ + """) .doTest(); } @@ -175,7 +177,8 @@ class SummaryRowKey

{} public abstract void m2(); } - }""") + }\ + """) .doTest(); } @@ -226,7 +229,8 @@ interface Interface {} */ // BUG: Diagnostic contains: @Deprecated public void deprecatedMethood() {} - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/EmptyCatchTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/EmptyCatchTest.java index 0382293f9ca..a4f96d06a06 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/EmptyCatchTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/EmptyCatchTest.java @@ -73,7 +73,8 @@ public void expectedException() { } catch (Exception expected) { } } - }""") + }\ + """) .doTest(); } @@ -193,7 +194,8 @@ public void catchIsLoggedOnly() { System.out.println("Caught an exception: " + t); } } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/EmptyIfStatementTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/EmptyIfStatementTest.java index 0e6e1f3a66a..5cfcb679920 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/EmptyIfStatementTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/EmptyIfStatementTest.java @@ -85,7 +85,8 @@ public static void positiveCase5() { System.out.println("foo"); } } - }""") + }\ + """) .doTest(); } @@ -129,7 +130,8 @@ else if (i == 12) ; else System.out.println("not 10, 11, or 12"); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/EqualsHashCodeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/EqualsHashCodeTest.java index 20b823c8a4e..460d77cd48d 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/EqualsHashCodeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/EqualsHashCodeTest.java @@ -42,7 +42,8 @@ public boolean equals(Object o) { return false; } } -}""") +}\ +""") .doTest(); } @@ -71,7 +72,8 @@ public int hashCode() { } public static class Neither {} - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/EqualsIncompatibleTypeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/EqualsIncompatibleTypeTest.java index 75cb3095c06..fd5529c29d3 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/EqualsIncompatibleTypeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/EqualsIncompatibleTypeTest.java @@ -194,7 +194,8 @@ void testSomeGenerics( // BUG: Diagnostic contains: T and String are incompatible iClazz.equals(strClazz); } -}""") +}\ +""") .doTest(); } @@ -392,7 +393,8 @@ abstract class F2 { void checkOtherEquals(F1 f1, F2 f2) { f2.equals(f1); } - }""") + }\ + """) .doTest(); } @@ -527,7 +529,8 @@ void something(J j1, J j2) { // Technically this could work, since there's nothing stopping A1 == A2, etc. boolean equals = j1.equals(j2); } -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/EqualsNaNTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/EqualsNaNTest.java index 9ed6d8061af..bee6f7fd51a 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/EqualsNaNTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/EqualsNaNTest.java @@ -60,7 +60,8 @@ public class EqualsNaNPositiveCases { // BUG: Diagnostic contains: Double.isNaN(123456) static final boolean INT_IS_NAN = 123456 == Double.NaN; - }""") + }\ + """) .doTest(); } @@ -78,7 +79,8 @@ public void negativeCase() { public class EqualsNaNNegativeCases { static final boolean NAN_AFTER_MATH = (0.0 / 0.0) == 1.0; static final boolean NORMAL_COMPARISON = 1.0 == 2.0; - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/EqualsReferenceTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/EqualsReferenceTest.java index cd7d42cae63..ae35efb3e6b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/EqualsReferenceTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/EqualsReferenceTest.java @@ -71,7 +71,8 @@ public boolean equals(Object o) { return equals(o); } } - }""") + }\ + """) .doTest(); } @@ -146,7 +147,8 @@ public Object getValue() { return null; } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ErroneousThreadPoolConstructorCheckerTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ErroneousThreadPoolConstructorCheckerTest.java index bb1fefe98c7..687b803bcf7 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ErroneousThreadPoolConstructorCheckerTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ErroneousThreadPoolConstructorCheckerTest.java @@ -127,7 +127,8 @@ private void createThreadPoolWithUnboundedPriorityBlockingQueue( SECONDS, new PriorityBlockingQueue<>(initialCapacity, comparingInt(Object::hashCode))); } -}""") +}\ +""") .doTest(); } @@ -215,7 +216,8 @@ private void createThreadPoolWithBoundedSynchronousQueue() { new ThreadPoolExecutor( CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, SECONDS, new SynchronousQueue<>()); } -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/FallThroughTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/FallThroughTest.java index 7d2eb947a1f..ab4e645f498 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/FallThroughTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/FallThroughTest.java @@ -109,7 +109,8 @@ public int everyBodyIsDoingIt(int a, int b) { return 0; } } - }""") + }\ + """) .doTest(); } @@ -264,7 +265,8 @@ int foo(int i) { } } } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/FinallyTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/FinallyTest.java index b00d773ed64..3afcd32819a 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/FinallyTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/FinallyTest.java @@ -165,7 +165,8 @@ public void test8() { } } } -}""") +}\ +""") .doTest(); } @@ -290,7 +291,8 @@ public void throwFromNestedCatchInFinally() throws Exception { } } } - }""") + }\ + """) .doTest(); } @@ -379,7 +381,8 @@ public void test7() { } } } - }""") + }\ + """) .doTest(); } @@ -448,7 +451,8 @@ public void nestedTryInFinally2() throws Exception { } } } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/FloatingPointAssertionWithinEpsilonTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/FloatingPointAssertionWithinEpsilonTest.java index e44212ff07b..3b397a77ec8 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/FloatingPointAssertionWithinEpsilonTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/FloatingPointAssertionWithinEpsilonTest.java @@ -90,7 +90,8 @@ public void testDouble() { // BUG: Diagnostic contains: 1.1e-16 assertEquals("equal!", 1.0, 1.0, TOLERANCE2); } - }""") + }\ + """) .doTest(); } @@ -145,7 +146,8 @@ public void testZeroCases() { assertEquals(1f, 1f, 0f); } - }""") + }\ + """) .doTest(); } @@ -207,7 +209,8 @@ public void testDouble() { // BUG: Diagnostic contains: 1.1e-16 assertEquals("equal!", 1.0, 1.0, TOLERANCE2); } - }""") + }\ + """) .addOutputLines( "FloatingPointAssertionWithinEpsilonPositiveCases_expected.java", """ @@ -245,7 +248,8 @@ public void testDouble() { assertEquals(1.0, 1.0, 0); assertEquals("equal!", 1.0, 1.0, 0); } - }""") + }\ + """) .doTest(TestMode.AST_MATCH); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/FunctionalInterfaceMethodChangedTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/FunctionalInterfaceMethodChangedTest.java index 16861402b2e..770ebafb7fc 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/FunctionalInterfaceMethodChangedTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/FunctionalInterfaceMethodChangedTest.java @@ -126,7 +126,8 @@ default String superSam() { return null; } } - }""") + }\ + """) .doTest(); } @@ -203,7 +204,8 @@ default Void call() throws Exception { return null; } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/FutureReturnValueIgnoredTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/FutureReturnValueIgnoredTest.java index cf778ea4121..a7ea95e7a0e 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/FutureReturnValueIgnoredTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/FutureReturnValueIgnoredTest.java @@ -238,7 +238,8 @@ public Object apply(Object string) { }, runnable -> runnable.run()); } -}""") +}\ +""") .doTest(); } @@ -540,7 +541,8 @@ protected Object handleInvocation(Object o, Method method, Object[] params) { } }; } -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/FuturesGetCheckedIllegalExceptionTypeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/FuturesGetCheckedIllegalExceptionTypeTest.java index e2dc3bcad25..db141f55146 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/FuturesGetCheckedIllegalExceptionTypeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/FuturesGetCheckedIllegalExceptionTypeTest.java @@ -94,7 +94,8 @@ public InnerClassWithExplicitConstructorException() {} } public class InnerClassWithImplicitConstructorException extends Exception {} -}""") +}\ +""") .doTest(); } @@ -147,7 +148,8 @@ public static class StaticNestedWithImplicitConstructorException extends Excepti public static class ProtectedConstructorException extends Exception { protected ProtectedConstructorException() {} } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/FuzzyEqualsShouldNotBeUsedInEqualsMethodTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/FuzzyEqualsShouldNotBeUsedInEqualsMethodTest.java index b8f58f6882e..352b2294723 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/FuzzyEqualsShouldNotBeUsedInEqualsMethodTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/FuzzyEqualsShouldNotBeUsedInEqualsMethodTest.java @@ -58,7 +58,8 @@ public boolean equals(Object other) { return DoubleMath.fuzzyEquals(x, y, z); } } - }""") + }\ + """) .doTest(); } @@ -93,7 +94,8 @@ public boolean equals(Object other, double a) { return DoubleMath.fuzzyEquals(0, 1, 0.2); } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/GetClassOnClassTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/GetClassOnClassTest.java index 815375bf824..9e7acdd0ae8 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/GetClassOnClassTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/GetClassOnClassTest.java @@ -59,7 +59,8 @@ public void getClassOnClass3() { // BUG: Diagnostic contains: String.class.getName() System.out.println(String.class.getClass().getName()); } - }""") + }\ + """) .doTest(); } @@ -91,7 +92,8 @@ public static boolean getClass(Object a) { return true; } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/HidingFieldTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/HidingFieldTest.java index 3daa3f6abaf..eb9f983a160 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/HidingFieldTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/HidingFieldTest.java @@ -95,7 +95,8 @@ public static class ClassG extends ClassF { // BUG: Diagnostic contains: superclass: ClassF String varThree; } -}""") +}\ +""") .addSourceLines( "HidingFieldPositiveCases2.java", """ @@ -124,7 +125,8 @@ public class ClassB extends HidingFieldPositiveCases1.ClassB { // BUG: Diagnostic contains: superclass: ClassA public int varOne = 2; } -}""") +}\ +""") .doTest(); } @@ -178,7 +180,8 @@ public void varThree() {} public void varTwo() {} } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ImplementAssertionWithChainingTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ImplementAssertionWithChainingTest.java index 488012b49c9..27942d51a16 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ImplementAssertionWithChainingTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ImplementAssertionWithChainingTest.java @@ -125,7 +125,8 @@ Foo otherFoo() { } private enum Kind {} -}""") +}\ +""") .doTest(); } @@ -198,7 +199,8 @@ Foo otherFoo() { return this; } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/InconsistentCapitalizationTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/InconsistentCapitalizationTest.java index c0460ceb5ed..fe8bb976b78 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/InconsistentCapitalizationTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/InconsistentCapitalizationTest.java @@ -194,7 +194,8 @@ static class Child extends Parent { } } } -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/IncrementInForLoopAndHeaderTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/IncrementInForLoopAndHeaderTest.java index 8ee5dd68783..0ef8c3ad0d0 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/IncrementInForLoopAndHeaderTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/IncrementInForLoopAndHeaderTest.java @@ -116,7 +116,8 @@ public void expressionStatement() { // BUG: Diagnostic contains: increment for (int i = 0; i < 10; i++) i++; } - }""") + }\ + """) .doTest(); } @@ -189,7 +190,8 @@ public void otherVarInc() { a++; } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/InsecureCipherModeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/InsecureCipherModeTest.java index 0c0cbfaa347..8d59d2fa8fe 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/InsecureCipherModeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/InsecureCipherModeTest.java @@ -257,7 +257,8 @@ public void keyOperations(StringProvider provider) { // We don't handle any exception as this code is not meant to be executed. } } -}""") +}\ +""") .doTest(); } @@ -410,7 +411,8 @@ public void ellipticCurveDiffieHellman() { // We don't handle any exception as this code is not meant to be executed. } } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/InstanceOfAndCastMatchWrongTypeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/InstanceOfAndCastMatchWrongTypeTest.java index abdf04bf1df..eabcdd1a67a 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/InstanceOfAndCastMatchWrongTypeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/InstanceOfAndCastMatchWrongTypeTest.java @@ -192,7 +192,8 @@ public static String testCall() { } } - class SuperClass {}""") + class SuperClass {}\ + """) .doTest(); } @@ -470,7 +471,8 @@ static class SuperNegativeClass {} static class SubNegativeClass extends SuperNegativeClass {} static class DisjointClass {} -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/InvalidPatternSyntaxTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/InvalidPatternSyntaxTest.java index 9ce3d39d738..85990470c26 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/InvalidPatternSyntaxTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/InvalidPatternSyntaxTest.java @@ -67,7 +67,8 @@ public class InvalidPatternSyntaxPositiveCases { // BUG: Diagnostic contains: "".split(INVALID, 0); } - }""") + }\ + """) .doTest(); } @@ -104,7 +105,8 @@ public void foo(String x) { "".split(x); "".split(x, 0); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/IterableAndIteratorTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/IterableAndIteratorTest.java index 28dda8e892c..da5aaa53a5b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/IterableAndIteratorTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/IterableAndIteratorTest.java @@ -143,7 +143,8 @@ public Iterator iterator() { return this; } } -}""") +}\ +""") .doTest(); } @@ -214,7 +215,8 @@ public Iterator iterator() { return l; } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/JUnit3TestNotRunTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/JUnit3TestNotRunTest.java index 366631a087b..a6c7ad88ba7 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/JUnit3TestNotRunTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/JUnit3TestNotRunTest.java @@ -66,7 +66,8 @@ public void tesgName() {} // tentative - can cause false positives // BUG: Diagnostic contains: JUnit3TestNotRun public void textName() {} - }""") + }\ + """) .doTest(); } @@ -401,7 +402,8 @@ public void ignoredTest2() {} @Ignore @Test public void ignoredTest() {} - }""") + }\ + """) .doTest(); } @@ -437,7 +439,8 @@ public void tstName() {} @Test public void TestName() {} - }""") + }\ + """) .doTest(); } @@ -469,7 +472,8 @@ public void tesMisspelled() {} @Test public void tesBothIssuesAtOnce() {} - }""") + }\ + """) .doTest(); } @@ -498,7 +502,8 @@ public void tesMisspelled() {} @Test public void tesBothIssuesAtOnce() {} -}""") +}\ +""") .doTest(); } @@ -530,7 +535,8 @@ public void tesMisspelled() {} @Test public void tesBothIssuesAtOnce() {} - }""") + }\ + """) // needed as a dependency .addSourceLines( "JUnit3TestNotRunNegativeCase5.java", @@ -555,7 +561,8 @@ public void tesMisspelled() {} @Test public void tesBothIssuesAtOnce() {} - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/JUnit4SetUpNotRunTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/JUnit4SetUpNotRunTest.java index 9412760815e..f67fa13bc9e 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/JUnit4SetUpNotRunTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/JUnit4SetUpNotRunTest.java @@ -110,7 +110,8 @@ class J4OverriddenSetUp extends BaseTestClass { class J4OverriddenSetUpPublic extends BaseTestClass { // BUG: Diagnostic contains: @Before @Override public void setUp() {} -}""") +}\ +""") .doTest(); } @@ -134,7 +135,8 @@ public class JUnit4SetUpNotRunPositiveCaseCustomBefore { public void setUp() {} } - @interface Before {}""") + @interface Before {}\ + """) .doTest(); } @@ -201,7 +203,8 @@ public void initMocks() {} protected void badVisibility() {} } - @interface Before {}""") + @interface Before {}\ + """) .doTest(); } @@ -288,7 +291,8 @@ public void setUp() {} @RunWith(JUnit4.class) class J4SetUpExtendsAnnotatedMethod extends SetUpAnnotatedBaseClass { public void setUp() {} -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/JUnit4TearDownNotRunTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/JUnit4TearDownNotRunTest.java index e665cdbdf0f..2503b07d03a 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/JUnit4TearDownNotRunTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/JUnit4TearDownNotRunTest.java @@ -90,7 +90,8 @@ class J4TearDownHasOverride extends TearDownUnannotatedBaseClass { class J4TearDownHasPublicOverride extends TearDownUnannotatedBaseClass { // BUG: Diagnostic contains: @After @Override public void tearDown() {} - }""") + }\ + """) .doTest(); } @@ -114,7 +115,8 @@ public class JUnit4TearDownNotRunPositiveCaseCustomAfter { public void tearDown() {} } - @interface After {}""") + @interface After {}\ + """) .doTest(); } @@ -138,7 +140,8 @@ public class JUnit4TearDownNotRunPositiveCaseCustomAfter2 { public void tidyUp() {} } - @interface After {}""") + @interface After {}\ + """) .doTest(); } @@ -222,7 +225,8 @@ public void tearDown() {} class J4TearDownInheritsFromAnnotatedMethod2 extends TearDownAnnotatedBaseClass { @After public void tearDown() {} - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/JUnit4TestNotRunTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/JUnit4TestNotRunTest.java index 59b86392000..404c367b61e 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/JUnit4TestNotRunTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/JUnit4TestNotRunTest.java @@ -56,7 +56,8 @@ public void testThisIsATest() {} // BUG: Diagnostic contains: @Test public static void testThisIsAStaticTest() {} - }""") + }\ + """) .doTest(); } @@ -83,7 +84,8 @@ public void testThisIsATest() {} // BUG: Diagnostic contains: @Test public static void testThisIsAStaticTest() {} - }""") + }\ + """) .doTest(); } @@ -653,7 +655,8 @@ public void negativeCase1() { */ public class JUnit4TestNotRunNegativeCase1 { public void testThisIsATest() {} - }""") + }\ + """) .doTest(); } @@ -676,7 +679,8 @@ public void negativeCase2() { @RunWith(JUnit38ClassRunner.class) public class JUnit4TestNotRunNegativeCase2 { public void testThisIsATest() {} - }""") + }\ + """) .doTest(); } @@ -726,7 +730,8 @@ public void testTest3(int foo) {} public int testSomething() { return 42; } -}""") +}\ +""") .doTest(); } @@ -750,7 +755,8 @@ public void negativeCase4() { @RunWith(JUnit4.class) public class JUnit4TestNotRunNegativeCase4 extends TestCase { public void testThisIsATest() {} -}""") +}\ +""") .doTest(); } @@ -783,7 +789,8 @@ public void testTearDown() {} @Test public void testOverrideThis() {} - }""") + }\ + """) .addSourceLines( "JUnit4TestNotRunNegativeCase5.java", """ @@ -807,7 +814,8 @@ public void testTearDown() {} @Override public void testOverrideThis() {} -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/JUnitAssertSameCheckTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/JUnitAssertSameCheckTest.java index 36ed0ba988a..3f1ef7827b0 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/JUnitAssertSameCheckTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/JUnitAssertSameCheckTest.java @@ -64,7 +64,8 @@ public void test(Object obj) { // BUG: Diagnostic contains: An object is tested for reference equality to itself using JUnit junit.framework.Assert.assertSame("message", obj, obj); } -}""") +}\ +""") .doTest(); } @@ -89,7 +90,8 @@ public void test(Object obj1, Object obj2) { junit.framework.Assert.assertSame(obj1, obj2); junit.framework.Assert.assertSame("message", obj1, obj2); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/JUnitParameterMethodNotFoundTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/JUnitParameterMethodNotFoundTest.java index 3df8bc05499..eba7e08f5ab 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/JUnitParameterMethodNotFoundTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/JUnitParameterMethodNotFoundTest.java @@ -160,7 +160,8 @@ public Object dataProviderInner() { return new Object[] {1}; } } -}""") +}\ +""") .doTest(); } @@ -182,7 +183,8 @@ public class JUnitParameterMethodNotFoundNegativeCaseNonJUnitParamsRunner { @Test @Parameters(method = "named1") public void paramStaticProvider() {} - }""") + }\ + """) .doTest(); } @@ -202,7 +204,8 @@ public abstract class JUnitParameterMethodNotFoundNegativeCaseBaseClass { public Object named1() { return new Object[] {1}; } - }""") + }\ + """) .addSourceLines( "JUnitParameterMethodNotFoundNegativeCaseSuperClass.java", """ @@ -219,7 +222,8 @@ public class JUnitParameterMethodNotFoundNegativeCaseSuperClass @Test @Parameters(method = "named1") public void testNamed(int a) {} - }""") + }\ + """) .doTest(); } @@ -259,7 +263,8 @@ public Object dataProvider() { return new Object[] {1}; } } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/LambdaFunctionalInterfaceTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/LambdaFunctionalInterfaceTest.java index 06dd80ce5f2..121c732687f 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/LambdaFunctionalInterfaceTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/LambdaFunctionalInterfaceTest.java @@ -196,7 +196,8 @@ public int getSumAll() { return sumAll(o -> 2); } } -}""") +}\ +""") .doTest(); } @@ -293,7 +294,8 @@ public Double getMu() { return findOptimalMuLambda(mu -> 0L, 3.0); } } -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/LiteEnumValueOfTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/LiteEnumValueOfTest.java index 39f35ea3081..8b5d58976fa 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/LiteEnumValueOfTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/LiteEnumValueOfTest.java @@ -36,7 +36,8 @@ public final class LiteEnumValueOfTest { """ package android.os; - public interface Parcel {}""") + public interface Parcel {}\ + """) .addSourceLines( "Parcelable.java", """ @@ -56,7 +57,8 @@ interface Creator { interface ClassLoaderCreator extends Creator { T createFromParcel(Parcel source, ClassLoader loader); } - }""") + }\ + """) .addSourceLines( "FakeLiteEnum.java", """ diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/LockOnNonEnclosingClassLiteralTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/LockOnNonEnclosingClassLiteralTest.java index 0e7bf3d65c4..4aeaefded5c 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/LockOnNonEnclosingClassLiteralTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/LockOnNonEnclosingClassLiteralTest.java @@ -60,7 +60,8 @@ public void methodContainsSynchronizedBlock() { } } } -}""") +}\ +""") .doTest(); } @@ -93,7 +94,8 @@ public void methodContainsSynchronizedBlock() { } } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/LongLiteralLowerCaseSuffixTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/LongLiteralLowerCaseSuffixTest.java index d7e4a00fca3..bb2dbb105ed 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/LongLiteralLowerCaseSuffixTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/LongLiteralLowerCaseSuffixTest.java @@ -117,7 +117,8 @@ public void negativeOctalExtraSpacesLowerCase() { long value = - 06543l; } -}""") +}\ +""") .doTest(); } @@ -142,7 +143,8 @@ public void underscoredLowerCase() { // BUG: Diagnostic contains: value = 0_1__2L long value = 0_1__2l; } -}""") +}\ +""") .doTest(); } @@ -200,7 +202,8 @@ public void zeroHexUpperCase() { public void negativeHexUpperCase() { long value = -0x80L; } - }""") + }\ + """) .doTest(); } @@ -290,7 +293,8 @@ public void negativeOctalExtraSpacesLowerCase() { long value = - 06543l; } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/MisleadingEscapedSpaceTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/MisleadingEscapedSpaceTest.java index 8bfa78708b2..ab2fb40ec07 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/MisleadingEscapedSpaceTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/MisleadingEscapedSpaceTest.java @@ -39,7 +39,8 @@ public void misleadingEscape() { class Test { // BUG: Diagnostic contains: private static final String FOO = " \\s "; - }""") + }\ + """) .doTest(); } @@ -53,7 +54,8 @@ public void literalBackslashS() { """ class Test { private static final String FOO = " \\\\s "; - }""") + }\ + """) .doTest(); } @@ -68,7 +70,8 @@ public void asSingleCharacter_misleading() { class Test { // BUG: Diagnostic contains: private static final char x = '\\s'; - }""") + }\ + """) .doTest(); } @@ -90,7 +93,8 @@ class Test { foo \\s bar \\s baz \"""; - }""") + }\ + """) .doTest(); } @@ -107,7 +111,8 @@ class Test { foo \\s bar \\s \"""; - }""") + }\ + """) .doTest(); } @@ -123,7 +128,8 @@ class Test { private static final String FOO = \""" foo \\s\\s\\s\\s \"""; - }""") + }\ + """) .doTest(); } @@ -137,7 +143,8 @@ public void withinCommentInBrokenUpString_noFinding() { """ class Test { private static final String FOO = "foo" + /* \\s */ " bar"; - }""") + }\ + """) .doTest(); } @@ -170,7 +177,8 @@ public void escapedSpaceAtEndOfString() { class Test { // BUG: Diagnostic contains: private static final String FOO = "foo\\s"; - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/MissingFailTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/MissingFailTest.java index b9a985b27e3..afbea6d9e40 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/MissingFailTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/MissingFailTest.java @@ -176,7 +176,8 @@ private static void dummyMethod() {} private static void assertDummy() {} private static void verifyDummy() {} - }""") + }\ + """) .doTest(); } @@ -216,7 +217,8 @@ public void expectedException_helperMethod() { } private static void dummyMethod() {} - }""") + }\ + """) .doTest(); } @@ -257,7 +259,8 @@ public void catchAssert() { private static void dummyMethod() {} private static void assertDummy() {} - }""") + }\ + """) .doTest(); } @@ -728,7 +731,8 @@ String dummy() { return ""; } } -}""") +}\ +""") .doTest(); } @@ -761,7 +765,8 @@ public void catchAssert() { private static void dummyMethod() {} private static void assertDummy() {} - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/MisusedWeekYearTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/MisusedWeekYearTest.java index 54242d0601a..3b9f57aab2b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/MisusedWeekYearTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/MisusedWeekYearTest.java @@ -128,7 +128,8 @@ void testDateTimeFormatter() { // BUG: Diagnostic contains: java.time.format.DateTimeFormatter.ofPattern(WEEK_YEAR_PATTERN); } -}""") +}\ +""") .doTest(); } @@ -175,7 +176,8 @@ void testApplyPatternAndApplyLocalizedPattern() { // BUG: Diagnostic contains: sdf.applyLocalizedPattern("YYYY-MM-dd"); } -}""") +}\ +""") .doTest(); } @@ -228,7 +230,8 @@ void testSubtype() { mySdf.applyPattern("YYYY-MM-dd"); mySdf.applyLocalizedPattern("YYYY-MM-dd"); } -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ModifyCollectionInEnhancedForLoopTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ModifyCollectionInEnhancedForLoopTest.java index 95fdf4c076e..f245aa2c6c3 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ModifyCollectionInEnhancedForLoopTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ModifyCollectionInEnhancedForLoopTest.java @@ -127,7 +127,8 @@ public static void testMapEntrySet(HashMap map) { map.remove(a.getKey()); } } - }""") + }\ + """) .doTest(); } @@ -233,7 +234,8 @@ private static void customConcurrent(MyBlockingQueue mbq) { mbq.add(i); } } -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ModifySourceCollectionInStreamTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ModifySourceCollectionInStreamTest.java index 94d9f6e8b5b..96cb6aecbaa 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ModifySourceCollectionInStreamTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ModifySourceCollectionInStreamTest.java @@ -116,7 +116,8 @@ private List mutateStreamSourceLambdaExpression( private List getMutableValues() { return mutableValues; } -}""") +}\ +""") .doTest(); } @@ -224,7 +225,8 @@ private interface CustomContainer { boolean add(T t); } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ModifyingCollectionWithItselfTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ModifyingCollectionWithItselfTest.java index e1f5c62aa51..ad23e1fe045 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ModifyingCollectionWithItselfTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ModifyingCollectionWithItselfTest.java @@ -102,7 +102,8 @@ void expressionStatementChecks() { b = a.removeAll(a); } } - }""") + }\ + """) .doTest(); } @@ -139,7 +140,8 @@ public boolean retainAll(List b) { public boolean containsAll(List b) { return a.containsAll(b); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/MultipleParallelOrSequentialCallsTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/MultipleParallelOrSequentialCallsTest.java index b8a4c320427..912b07c948f 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/MultipleParallelOrSequentialCallsTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/MultipleParallelOrSequentialCallsTest.java @@ -176,7 +176,8 @@ private boolean testClass() { return true; } } -}""") +}\ +""") .doTest(); } @@ -236,7 +237,8 @@ public SomeObject parallel() { return null; } } - }""") + }\ + """) .doTest(); } @@ -377,7 +379,8 @@ private boolean testClass() { return true; } } -}""") +}\ +""") .addOutputLines( "MultipleParallelOrSequentialCallsPositiveCases_expected.java", """ @@ -506,7 +509,8 @@ private boolean testClass() { return true; } } -}""") +}\ +""") .doTest(TestMode.AST_MATCH); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/MultipleUnaryOperatorsInMethodCallTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/MultipleUnaryOperatorsInMethodCallTest.java index 7157796044e..cd151e5e8e4 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/MultipleUnaryOperatorsInMethodCallTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/MultipleUnaryOperatorsInMethodCallTest.java @@ -73,7 +73,8 @@ public static void threeArgs(int a, int b, int c) {} public static int someFunction(int a) { return 0; } - }""") + }\ + """) .doTest(); } @@ -101,7 +102,8 @@ public static void tests(int a, int b, int[] xs) { } public static void testMethod(int one, int two) {} - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/NestedInstanceOfConditionsTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/NestedInstanceOfConditionsTest.java index 97a39f1f498..64df764781c 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/NestedInstanceOfConditionsTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/NestedInstanceOfConditionsTest.java @@ -111,7 +111,8 @@ static class ClassA {} static class ClassB {} static class ClassC {} - }""") + }\ + """) .doTest(); } @@ -209,7 +210,8 @@ public static class SubClass extends SuperClass {} /** test class */ public static class DisjointClass {} ; -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/NoAllocationCheckerTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/NoAllocationCheckerTest.java index 5fc2c51cc60..b280af967a1 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/NoAllocationCheckerTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/NoAllocationCheckerTest.java @@ -541,7 +541,8 @@ public static class NoAllocationSubclass extends NoAllocationParentClass { // BUG: Diagnostic contains: @NoAllocation public void method() {} } - }""") + }\ + """) .doTest(); } @@ -1081,7 +1082,8 @@ public static class NoAllocationSubclassWithSuppression extends NoAllocationPare @SuppressWarnings("NoAllocation") public void method() {} } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/NonAtomicVolatileUpdateTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/NonAtomicVolatileUpdateTest.java index 84dc6559c8d..491e3e9803c 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/NonAtomicVolatileUpdateTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/NonAtomicVolatileUpdateTest.java @@ -103,7 +103,8 @@ public void stringUpdate() { // BUG: Diagnostic contains: myVolatileString = myVolatileString + "update"; } - }""") + }\ + """) .doTest(); } @@ -167,7 +168,8 @@ public void synchronizedBlock() { myVolatileString = myVolatileString + "update"; } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/NonRuntimeAnnotationTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/NonRuntimeAnnotationTest.java index 3d4857b48f6..fb422d52ea4 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/NonRuntimeAnnotationTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/NonRuntimeAnnotationTest.java @@ -65,7 +65,8 @@ public NonRuntime testAnnotation() { /** Annotation that is implicitly NOT retained at runtime */ public @interface NotSpecified {} -}""") +}\ +""") .doTest(); } @@ -93,7 +94,8 @@ public Runtime testAnnotation() { /** Annotation that is retained at runtime */ @Retention(RetentionPolicy.RUNTIME) public @interface Runtime {} -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ObjectToStringTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ObjectToStringTest.java index bd0b9b31e6b..b47c11ae80b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ObjectToStringTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ObjectToStringTest.java @@ -68,7 +68,8 @@ void genericClassShowsErasure() { // BUG: Diagnostic contains: `FinalGenericClassWithoutToString@ System.out.println(finalGenericClassWithoutToString.toString()); } - }""") + }\ + """) .doTest(); } @@ -148,7 +149,8 @@ public void overridePresentInAbstractClassInHierarchy(Duration durationArg) { unusedString = durationArg.toString(); System.out.println("test joda string " + durationArg); } -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/OptionalNotPresentTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/OptionalNotPresentTest.java index b5930f6f9d3..9d3670d1cd6 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/OptionalNotPresentTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/OptionalNotPresentTest.java @@ -89,7 +89,8 @@ public String getWhenPresent_nestedCheck(Optional optional) { } return ""; } - }""") + }\ + """) .doTest(); } @@ -196,7 +197,8 @@ public String getWhenAbsent_methodScoped(Optional optional) { } return optional.get(); } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/OverrideThrowableToStringTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/OverrideThrowableToStringTest.java index 20dd1e403f5..8047b80ee9a 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/OverrideThrowableToStringTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/OverrideThrowableToStringTest.java @@ -72,7 +72,8 @@ public String toString() { return ""; } } - }""") + }\ + """) .doTest(); } @@ -118,7 +119,8 @@ public String getMessage() { return ""; } } - }""") + }\ + """) .doTest(); } @@ -164,7 +166,8 @@ public String toString() { return ""; } } - }""") + }\ + """) .addOutputLines( "OverrideThrowableToStringPositiveCases_expected.java", """ @@ -202,7 +205,8 @@ public String getMessage() { return ""; } } - }""") + }\ + """) .doTest(TestMode.AST_MATCH); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/OverridesTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/OverridesTest.java index c077fa07b61..920e907b982 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/OverridesTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/OverridesTest.java @@ -122,7 +122,8 @@ abstract class ImplementsAndExtends2 extends MyBase implements MyInterface { // BUG: Diagnostic contains: public abstract void g(Object... xs); } -}""") +}\ +""") .doTest(); } @@ -163,7 +164,8 @@ abstract class SubThree extends SubTwo { // BUG: Diagnostic contains: abstract void varargsMethod(Object[] newNames); } -}""") +}\ +""") .doTest(); } @@ -204,7 +206,8 @@ abstract class SubThree extends SubTwo { // BUG: Diagnostic contains: abstract void arrayMethod(Object... newNames); } -}""") +}\ +""") .doTest(); } @@ -244,7 +247,8 @@ abstract class Child2 extends Base { // BUG: Diagnostic contains: Varargs abstract void varargsMethod(@Note final Map /*dsa*/ [ /* [ */ ] /* dsa */ xs); } -}""") +}\ +""") .doTest(); } @@ -281,7 +285,8 @@ void foo(Base base) { base.varargsMethod(null, new Object[] {}, new Object[] {}, new Object[] {}, new Object[] {}); } } -}""") +}\ +""") .doTest(); } @@ -362,7 +367,8 @@ public Builder varargsMethod(String... args) { return this; } } -}""") +}\ +""") .doTest(); } @@ -396,7 +402,8 @@ abstract class SubThree extends SubTwo { @Override abstract void varargsMethod(Object... newNames); } - }""") + }\ + """) .doTest(); } @@ -430,7 +437,8 @@ abstract class SubThree extends SubTwo { @Override abstract void arrayMethod(Object[] xs); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/PreconditionsInvalidPlaceholderTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/PreconditionsInvalidPlaceholderTest.java index 8b3ef393a36..e6d0d511f61 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/PreconditionsInvalidPlaceholderTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/PreconditionsInvalidPlaceholderTest.java @@ -59,7 +59,8 @@ public void verifyFoo(int x) { // BUG: Diagnostic contains: Verify.verify(x > 0, "%d > 0", x); } - }""") + }\ + """) .doTest(); } @@ -95,7 +96,8 @@ public static void checkNotNull(Object foo, String bar, Object baz) {} public void checkSelf() { checkNotNull(foo, "Foo", this); } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/PrimitiveArrayPassedToVarargsMethodTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/PrimitiveArrayPassedToVarargsMethodTest.java index a67618f4c03..aa15815c527 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/PrimitiveArrayPassedToVarargsMethodTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/PrimitiveArrayPassedToVarargsMethodTest.java @@ -66,7 +66,8 @@ public void doIt() { // BUG: Diagnostic contains: Arrays.asList(intArray); } - }""") + }\ + """) .doTest(); } @@ -96,7 +97,8 @@ public void doIt() { intArrayVarargsMethod(intArray); objectVarargsMethodWithMultipleParams(new Object()); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/PrivateSecurityContractProtoAccessTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/PrivateSecurityContractProtoAccessTest.java index 7a79cb14f02..6d9516bad94 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/PrivateSecurityContractProtoAccessTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/PrivateSecurityContractProtoAccessTest.java @@ -87,7 +87,8 @@ static ByteString readSafeHtmlProtoBuilderBytes(SafeHtmlProto.Builder safeHtmlPr // BUG: Diagnostic contains: Forbidden access to a private proto field return safeHtmlProto.getPrivateDoNotAccessOrElseSafeHtmlWrappedValueBytes(); } -}""") +}\ +""") .doTest(); } @@ -115,7 +116,8 @@ public class PrivateSecurityContractProtoAccessNegativeCases { static { safeHtml = SafeHtmls.fromProto(safeHtmlProto); } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ProtocolBufferOrdinalTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ProtocolBufferOrdinalTest.java index 6c0c00ef394..20561a34d54 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ProtocolBufferOrdinalTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ProtocolBufferOrdinalTest.java @@ -67,7 +67,8 @@ public int getNumber() { return number; } } - }""") + }\ + """) .doTest(); } @@ -87,7 +88,8 @@ public class ProtocolBufferOrdinalNegativeCases { public static void checkProtoEnum() { TestEnum.TEST_ENUM_VAL.getNumber(); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/RestrictedApiCheckerTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/RestrictedApiCheckerTest.java index 6a75bd876c6..a0e97c4d3e6 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/RestrictedApiCheckerTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/RestrictedApiCheckerTest.java @@ -46,7 +46,8 @@ protected RestrictedApiCheckerTest(Class checker) { import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) - public @interface Allowlist {}""") + public @interface Allowlist {}\ + """) .addSourceLines( "RestrictedApiMethods.java", """ @@ -120,7 +121,8 @@ interface IFaceWithRestriction { } @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) -@interface AllowlistWithWarning {}""") +@interface AllowlistWithWarning {}\ +""") .matchAllDiagnostics(); refactoringTest = BugCheckerRefactoringTestHelper.newInstance(checker, RestrictedApiCheckerTest.class); diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/RethrowReflectiveOperationExceptionAsLinkageErrorTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/RethrowReflectiveOperationExceptionAsLinkageErrorTest.java index 6601707e09b..bf0f21f2fab 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/RethrowReflectiveOperationExceptionAsLinkageErrorTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/RethrowReflectiveOperationExceptionAsLinkageErrorTest.java @@ -81,7 +81,8 @@ void multiLineCatchBlock() { throw new AssertionError(e1); } } - }""") + }\ + """) .doTest(); } @@ -143,7 +144,8 @@ void multiCatchExceptions() { void throwNewReflectiveOperationException() { throw new AssertionError(new ReflectiveOperationException("Test")); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ReturnValueIgnoredTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ReturnValueIgnoredTest.java index 2d573fd9f8f..2b4f1c5453a 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ReturnValueIgnoredTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ReturnValueIgnoredTest.java @@ -186,7 +186,8 @@ public class ReturnValueIgnoredPositiveCases { // BUG: Diagnostic contains: Return value of 'toString' must be used Arrays.toString(objects); } - }""") + }\ + """) .doTest(); } @@ -250,7 +251,8 @@ public void arraysNoReturnValues() { Arrays.fill(numbers, 0); Arrays.sort(numbers); } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/RxReturnValueIgnoredTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/RxReturnValueIgnoredTest.java index 455f1c1bc43..3ef52fd703d 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/RxReturnValueIgnoredTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/RxReturnValueIgnoredTest.java @@ -237,7 +237,8 @@ static void getFromMap() { // BUG: Diagnostic contains: Rx objects must be checked. map4.get(null); } -}""") +}\ +""") .doTest(); } @@ -342,7 +343,8 @@ void checkIgnore() { getFlowable(); getMaybe(); } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/SelfAssertionTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/SelfAssertionTest.java index e442fa300d5..4bc441f7b6a 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/SelfAssertionTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/SelfAssertionTest.java @@ -101,7 +101,8 @@ public void testAssertWithMessageNotSame() { // BUG: Diagnostic contains: assertWithMessage("msg").that(test).isNotSameInstanceAs(test); } - }""") + }\ + """) .doTest(); } @@ -129,7 +130,8 @@ public void testEq() { public void testNeq() { assertThat(Boolean.TRUE.toString()).isNotEqualTo(Boolean.FALSE.toString()); } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/SelfAssignmentTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/SelfAssignmentTest.java index cd665b13e5f..26eca86152e 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/SelfAssignmentTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/SelfAssignmentTest.java @@ -92,7 +92,8 @@ public void testCast(int x) { // BUG: Diagnostic contains: this.a = (int) x; this.a = (int) a; } - }""") + }\ + """) .doTest(); } @@ -203,7 +204,8 @@ private static class Foobar { Foo foo; Bar bar; } - }""") + }\ + """) .doTest(); } @@ -305,7 +307,8 @@ public static int[] getIntArr() { return new int[10]; } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/SelfComparisonTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/SelfComparisonTest.java index 4867362da1e..f698cf4074e 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/SelfComparisonTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/SelfComparisonTest.java @@ -120,7 +120,8 @@ public int test5() { return compareTo(this); } } - }""") + }\ + """) .doTest(); } @@ -167,7 +168,8 @@ public int compareTo(CopmarisonTest obj) { return testField.compareTo(obj.testField); } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/SelfEqualsTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/SelfEqualsTest.java index 3b403c90409..121bd114eca 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/SelfEqualsTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/SelfEqualsTest.java @@ -135,7 +135,8 @@ public void testSub() { // BUG: Diagnostic contains: sc.equals(sc); } - }""") + }\ + """) .doTest(); } @@ -184,7 +185,8 @@ public void testAssertThatEq(SelfEqualsNegativeCases obj) { public void testAssertThatNeq(SelfEqualsNegativeCases obj) { assertThat(obj).isNotEqualTo(obj); } - }""") + }\ + """) .doTest(); } @@ -259,7 +261,8 @@ private static class ForTesting { public ForTesting testing; public String string; } - }""") + }\ + """) .doTest(); } @@ -296,7 +299,8 @@ public boolean equals(Object o) { public int hashCode() { return field != null ? field.hashCode() : 0; } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ShouldHaveEvenArgsTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ShouldHaveEvenArgsTest.java index ae60d79438b..15d8a9955ee 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ShouldHaveEvenArgsTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ShouldHaveEvenArgsTest.java @@ -90,7 +90,8 @@ public void testWithOddArgsWithCorrespondence() { // BUG: Diagnostic contains: even number of arguments .containsExactly("hello", "there", "hello", "there", "rest"); } - }""") + }\ + """) .doTest(); } @@ -145,7 +146,8 @@ public void testWithArray() { assertThat(map).containsExactly(key, value, (Object[]) args); assertThat(map).containsExactly(key, value, key, value, key, value); } - }""") + }\ + """) .doTest(); } @@ -204,7 +206,8 @@ public void testWithOddArgsWithCorrespondence() { // BUG: Diagnostic contains: even number of arguments .containsExactly("hello", "there", "hello", "there", "rest"); } - }""") + }\ + """) .doTest(); } @@ -256,7 +259,8 @@ public void testWithArray() { assertThat(multimap).containsExactly(key, value, (Object[]) args); assertThat(multimap).containsExactly(key, value, key, value, key, value); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/SizeGreaterThanOrEqualsZeroTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/SizeGreaterThanOrEqualsZeroTest.java index b3b8b28fcff..b681db4532b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/SizeGreaterThanOrEqualsZeroTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/SizeGreaterThanOrEqualsZeroTest.java @@ -179,7 +179,8 @@ List getIntList() { return intList; } } -}""") +}\ +""") .doTest(); } @@ -271,7 +272,8 @@ public int size() { return length; } } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/StaticQualifiedUsingExpressionTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/StaticQualifiedUsingExpressionTest.java index 515d4c46cc2..62f864ff9bb 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/StaticQualifiedUsingExpressionTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/StaticQualifiedUsingExpressionTest.java @@ -199,7 +199,8 @@ public void test7() { // x = C.foo(); int x = new C().foo(); } - }""") + }\ + """) .doTest(); } @@ -227,7 +228,8 @@ public int test1() { // return TestClass.staticTestMethod() return new TestClass().staticTestMethod(); } - }""") + }\ + """) .doTest(); } @@ -278,7 +280,8 @@ public void testJavacAltname() { public void testEclipseAltname() { this.staticTestMethod(); } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/StringBuilderInitWithCharTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/StringBuilderInitWithCharTest.java index 98e894e35ef..f4468b6c04b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/StringBuilderInitWithCharTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/StringBuilderInitWithCharTest.java @@ -51,7 +51,8 @@ public class StringBuilderInitWithCharPositiveCases { // BUG: Diagnostic contains: new StringBuilder().append(c) new StringBuilder(c); } - }""") + }\ + """) .doTest(); } @@ -72,7 +73,8 @@ public class StringBuilderInitWithCharNegativeCases { new StringBuilder(5); new StringBuilder(); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/StringSplitterTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/StringSplitterTest.java index 3f74ecbcb38..cc0ab07f89a 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/StringSplitterTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/StringSplitterTest.java @@ -503,7 +503,8 @@ public void StringSplitOneArg() { // BUG: Diagnostic contains: String[] xs = foo.split(":"); } - }""") + }\ + """) .doTest(); } @@ -530,7 +531,8 @@ public void StringSplitTwoArgsOneNegative() { String foo = "a:b"; foo.split(":", -1); } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/SuppressWarningsDeprecatedTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/SuppressWarningsDeprecatedTest.java index c8883d8c658..da18dc2218d 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/SuppressWarningsDeprecatedTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/SuppressWarningsDeprecatedTest.java @@ -107,7 +107,8 @@ public static void positiveCase8() {} // BUG: Diagnostic contains: @SuppressWarnings(value = "deprecation") @SuppressWarnings(value = "deprecated") public static void positiveCase9() {} - }""") + }\ + """) .doTest(); } @@ -152,7 +153,8 @@ public static void negativeCase6() { class Bar {} Bar b = null; } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/SwigMemoryLeakTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/SwigMemoryLeakTest.java index 291ae69433c..57731616977 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/SwigMemoryLeakTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/SwigMemoryLeakTest.java @@ -61,7 +61,8 @@ public synchronized void delete() { swigCPtr = 0; } } -}""") +}\ +""") .doTest(); } @@ -101,7 +102,8 @@ public synchronized void delete() { } private static native void nativeDelete(long cptr); - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ThreadJoinLoopTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ThreadJoinLoopTest.java index d7fa779c8da..c2deeb2cc93 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ThreadJoinLoopTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ThreadJoinLoopTest.java @@ -205,7 +205,8 @@ public void whileInThread() { } } } - }""") + }\ + """) .doTest(); } @@ -334,7 +335,8 @@ public void tryAssigningThread(Thread thread) { } } } - }""") + }\ + """) .doTest(); } @@ -512,7 +514,8 @@ public void whileInThread() { } } } - }""") + }\ + """) .addOutputLines( "ThreadJoinLoopPositiveCases_expected.java", """ @@ -592,7 +595,8 @@ public void whileInThread() { Uninterruptibles.joinUninterruptibly(this); } } - }""") + }\ + """) .doTest(TestMode.AST_MATCH); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ThrowIfUncheckedKnownCheckedTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ThrowIfUncheckedKnownCheckedTest.java index 10594f8b635..3adf6cd21bd 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ThrowIfUncheckedKnownCheckedTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ThrowIfUncheckedKnownCheckedTest.java @@ -71,7 +71,8 @@ void checkedGeneric(E e) { } void foo() throws IOException, ExecutionException {} - }""") + }\ + """) .doTest(); } @@ -146,7 +147,8 @@ void nullException() { throwIfUnchecked(null); // throws NPE propagateIfPossible(null); // no-op } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ThrowsUncheckedExceptionTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ThrowsUncheckedExceptionTest.java index 3d46649513f..cc00e49be0d 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ThrowsUncheckedExceptionTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ThrowsUncheckedExceptionTest.java @@ -69,7 +69,8 @@ public void doEverything() throws RuntimeException, IOException, IndexOutOfBound public void doBetter() throws RuntimeException, AssertionError { throw new RuntimeException("thrown"); } -}""") +}\ +""") .doTest(); } @@ -95,7 +96,8 @@ public void doSomething() { public void doMore() throws IOException { throw new FileNotFoundException("thrown"); } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/TreeToStringTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/TreeToStringTest.java index 53510d5ccec..109a5f3e660 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/TreeToStringTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/TreeToStringTest.java @@ -151,7 +151,8 @@ public boolean matches(ClassTree classTree, VisitorState state) { } }; } -}""") +}\ +""") .doTest(); } @@ -179,7 +180,8 @@ private static void foo(VisitorState state) { ASTHelpers.getSymbol(tree).getSimpleName().toString(); } } - }""") + }\ + """) .addModules( "jdk.compiler/com.sun.tools.javac.code", "jdk.compiler/com.sun.tools.javac.util") .doTest(); diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/TruthAssertExpectedTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/TruthAssertExpectedTest.java index 75836afb144..42affb6a947 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/TruthAssertExpectedTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/TruthAssertExpectedTest.java @@ -86,7 +86,8 @@ private void lists() { // assertThat(ImmutableList.of(this)).containsExactlyElementsIn(EXPECTED_LIST).inOrder(); assertThat(EXPECTED_LIST).containsExactlyElementsIn(ImmutableList.of(this)).inOrder(); } -}""") +}\ +""") .doTest(); } @@ -146,7 +147,8 @@ private void constantValues() { assertThat(expected).isEqualTo(10L); assertThat(expected).isEqualTo(CONSTANT); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/TruthConstantAssertsTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/TruthConstantAssertsTest.java index 0df28772544..a0769197a4c 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/TruthConstantAssertsTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/TruthConstantAssertsTest.java @@ -77,7 +77,8 @@ private static TruthConstantAssertsPositiveCases someStaticMethod() { private TruthConstantAssertsPositiveCases memberMethod() { return new TruthConstantAssertsPositiveCases(); } -}""") +}\ +""") .doTest(); } @@ -109,7 +110,8 @@ public void testNegativeCases() { private static TruthConstantAssertsNegativeCases getObject() { return new TruthConstantAssertsNegativeCases(); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/TryFailThrowableTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/TryFailThrowableTest.java index 49aa017ca8e..a26ab6e191c 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/TryFailThrowableTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/TryFailThrowableTest.java @@ -216,7 +216,8 @@ public static void catchesError_nestedNoBlock() { } catch (Error e) { } } -}""") +}\ +""") .doTest(); } @@ -395,7 +396,8 @@ public void testInTestCase() { private static void dummyRecover() {} private static void dummyMethod() {} - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/URLEqualsHashCodeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/URLEqualsHashCodeTest.java index e10854a020e..e04a6186a25 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/URLEqualsHashCodeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/URLEqualsHashCodeTest.java @@ -137,7 +137,8 @@ public void immutableSetOfURL() { // BUG: Diagnostic contains: java.net.URL ImmutableSet urlSet2 = ImmutableSet.builder().build(); } - }""") + }\ + """) .doTest(); } @@ -203,7 +204,8 @@ private static class ExtendedMap extends HashMap { public void hashMapExtendedClass() { ExtendedMap urlMap; } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UngroupedOverloadsTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UngroupedOverloadsTest.java index d40c6dd8d15..862c467df6c 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UngroupedOverloadsTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UngroupedOverloadsTest.java @@ -80,7 +80,8 @@ public void foo(int x, int y) { } public void norf() {} - }""") + }\ + """) .doTest(); } @@ -166,7 +167,8 @@ public void foo() { public void norf(int x, int y, int w) { norf(x + w, y + w); } - }""") + }\ + """) .doTest(); } @@ -221,7 +223,8 @@ public void foo(int x) {} public void foo() { foo(foo); } - }""") + }\ + """) .doTest(); } @@ -275,7 +278,8 @@ public void quux(int x) { public void foo() { foo(42); } - }""") + }\ + """) .doTest(); } @@ -324,7 +328,8 @@ public void quux(int x) { public void foo() { foo(42); } -}""") +}\ +""") .setArgs(ImmutableList.of("-XepOpt:UngroupedOverloads:BatchFindings")) .doTest(); } @@ -375,7 +380,8 @@ public void baz(String x, String y) { public int foo() { return this.foo; } - }""") + }\ + """) .doTest(); } @@ -414,7 +420,8 @@ public void bar(int x, int y, int z) { public void quux() {} public void bar(String s) {} - }""") + }\ + """) .addOutputLines( "UngroupedOverloadsRefactoringComments_expected.java", """ @@ -447,7 +454,8 @@ public void bar(String s) {} public static final String BAZ = "baz"; // Stuff about `baz` continues. public void quux() {} - }""") + }\ + """) .doTest(); } @@ -494,7 +502,8 @@ public void norf() {} public void quux(int x, int y, int z) {} public void thud() {} - }""") + }\ + """) .addOutputLines( "UngroupedOverloadsRefactoringMultiple_expected.java", """ @@ -535,7 +544,8 @@ public void quux(int x, int y, int z) {} public void norf() {} public void thud() {} - }""") + }\ + """) .doTest(); } @@ -577,7 +587,8 @@ public void quux(int x, int y) {} public void foo(int x, int y, int z) {} public void bar(int x, int y) {} - }""") + }\ + """) .addOutputLines( "UngroupedOverloadsRefactoringInterleaved_expected.java", """ @@ -613,7 +624,8 @@ public void quux() {} public void quux(int x) {} public void quux(int x, int y) {} - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryBoxedAssignmentTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryBoxedAssignmentTest.java index 5152e81965d..836ddfa058a 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryBoxedAssignmentTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryBoxedAssignmentTest.java @@ -103,7 +103,8 @@ Integer positive_wrappedAgain(int aInteger) { void negative_methodReference() { Function toBoolean = Boolean::valueOf; } - }""") + }\ + """) .addOutputLines( "UnnecessaryBoxedAssignmentCases_expected.java", """ @@ -175,7 +176,8 @@ Integer positive_wrappedAgain(int aInteger) { void negative_methodReference() { Function toBoolean = Boolean::valueOf; } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryBoxedVariableTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryBoxedVariableTest.java index c8b1eeb04ce..74c5212ed8e 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryBoxedVariableTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryBoxedVariableTest.java @@ -237,7 +237,8 @@ private void methodPrimitiveArg(int i) {} private Integer methodBoxedArg(Integer i) { return i; } - }""") + }\ + """) .addOutputLines( "UnnecessaryBoxedVariableCases_expected.java", """ @@ -435,7 +436,8 @@ private void methodPrimitiveArg(int i) {} private Integer methodBoxedArg(Integer i) { return i; } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryLongToIntConversionTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryLongToIntConversionTest.java index 9c34f79ecd8..e60a3c4fc70 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryLongToIntConversionTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryLongToIntConversionTest.java @@ -103,7 +103,8 @@ public void intValue() { // BUG: Diagnostic contains: UnnecessaryLongToIntConversion acceptsLong(x.intValue()); } -}""") +}\ +""") .doTest(); } @@ -218,7 +219,8 @@ public void toIntExactForIntParameter() { long x = 1; acceptsInt(Math.toIntExact(x)); } -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UnsafeReflectiveConstructionCastTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UnsafeReflectiveConstructionCastTest.java index aae527bdfcc..ae434e4e93f 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UnsafeReflectiveConstructionCastTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UnsafeReflectiveConstructionCastTest.java @@ -180,7 +180,8 @@ public T get(String className) { } } } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/WaitNotInLoopTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/WaitNotInLoopTest.java index fc300957034..6a5a14c29e2 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/WaitNotInLoopTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/WaitNotInLoopTest.java @@ -110,7 +110,8 @@ public void testAwaitUntil(Condition cond) throws Exception { // BUG: Diagnostic contains: awaitUntil(java.util.Date) must always be called in a loop cond.awaitUntil(new Date()); } -}""") +}\ +""") .doTest(); } @@ -214,7 +215,8 @@ private void wait(Object obj) {} public void testNotObjectWait() { wait(new Object()); } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/android/BinderIdentityRestoredDangerouslyTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/android/BinderIdentityRestoredDangerouslyTest.java index da963d9a162..8116775f42d 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/android/BinderIdentityRestoredDangerouslyTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/android/BinderIdentityRestoredDangerouslyTest.java @@ -41,7 +41,8 @@ public static final long clearCallingIdentity() { } public static final void restoreCallingIdentity(long token) {} - }""") + }\ + """) .setArgs(ImmutableList.of("-XDandroidCompatible=true")); @Test diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/android/FragmentInjectionTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/android/FragmentInjectionTest.java index ade90eeffe6..0ce68ef4a83 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/android/FragmentInjectionTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/android/FragmentInjectionTest.java @@ -40,7 +40,8 @@ public class PreferenceActivity { protected boolean isValidFragment(String className) { return true; } - }""") + }\ + """) .setArgs(ImmutableList.of("-XDandroidCompatible=true")); @Test diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/android/FragmentNotInstantiableTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/android/FragmentNotInstantiableTest.java index 2ddc85e10d7..a53d878403b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/android/FragmentNotInstantiableTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/android/FragmentNotInstantiableTest.java @@ -117,7 +117,8 @@ class LocalFragment extends Fragment {} return new LocalFragment(); } } - }""") + }\ + """) .doTest(); } @@ -202,7 +203,8 @@ public class ImplicitlyStaticInnerFragment extends Fragment {} class ImplicitlyStaticAndPublicInnerFragment extends Fragment {} } - }""") + }\ + """) .doTest(); } @@ -280,7 +282,8 @@ class LocalFragment extends Fragment {} return new LocalFragment(); } } - }""") + }\ + """) .addSourceLines( "CustomFragment.java", """ @@ -289,7 +292,8 @@ class LocalFragment extends Fragment {} /** * @author jasonlong@google.com (Jason Long) */ - public class CustomFragment {}""") + public class CustomFragment {}\ + """) .addSourceLines( "CustomFragmentNotInstantiablePositiveCases.java", """ @@ -354,7 +358,8 @@ class LocalFragment extends CustomFragment {} return new LocalFragment(); } } - }""") + }\ + """) .doTest(); } @@ -439,7 +444,8 @@ public class ImplicitlyStaticInnerFragment extends Fragment {} class ImplicitlyStaticAndPublicInnerFragment extends Fragment {} } - }""") + }\ + """) .addSourceLines( "CustomFragment.java", """ @@ -448,7 +454,8 @@ class ImplicitlyStaticAndPublicInnerFragment extends Fragment {} /** * @author jasonlong@google.com (Jason Long) */ - public class CustomFragment {}""") + public class CustomFragment {}\ + """) .addSourceLines( "CustomFragmentNotInstantiableNegativeCases.java", """ @@ -507,7 +514,8 @@ public class ImplicitlyStaticInnerFragment extends CustomFragment {} class ImplicitlyStaticAndPublicInnerFragment extends CustomFragment {} } - }""") + }\ + """) .doTest(); } @@ -519,13 +527,15 @@ private CompilationTestHelper createCompilationTestHelper( """ package android.app; - public class Fragment {}""") + public class Fragment {}\ + """) .addSourceLines( "Fragment.java", """ package android.support.v4.app; - public class Fragment {}""") + public class Fragment {}\ + """) .setArgs(ImmutableList.of("-XDandroidCompatible=true")); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/android/HardCodedSdCardPathTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/android/HardCodedSdCardPathTest.java index 11042158b9b..46f2f391e83 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/android/HardCodedSdCardPathTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/android/HardCodedSdCardPathTest.java @@ -79,7 +79,8 @@ public class HardCodedSdCardPathPositiveCases { // BUG: Diagnostic contains: Context static final String PATH11 = "/data" + "/" + "user"; - }""") + }\ + """) .doTest(); } @@ -127,7 +128,8 @@ public class HardCodedSdCardPathNegativeCases { static final String FRAGMENT4 = "1user"; static final String PATH5 = FRAGMENT3 + "/" + FRAGMENT4; - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/android/IsLoggableTagLengthTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/android/IsLoggableTagLengthTest.java index 78d2d551b33..6242eb38635 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/android/IsLoggableTagLengthTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/android/IsLoggableTagLengthTest.java @@ -41,7 +41,8 @@ public static boolean isLoggable(String tag, int level) { } public static final int INFO = 0; - }""") + }\ + """) .setArgs(ImmutableList.of("-XDandroidCompatible=true")); @Test diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/android/MislabeledAndroidStringTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/android/MislabeledAndroidStringTest.java index fe744b8c58a..25ae3c9f630 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/android/MislabeledAndroidStringTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/android/MislabeledAndroidStringTest.java @@ -133,7 +133,8 @@ public static final class string { public static final int no = 1; public static final int copy = 2; } - }""") + }\ + """) .setArgs(ImmutableList.of("-XDandroidCompatible=true")); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/android/RectIntersectReturnValueIgnoredTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/android/RectIntersectReturnValueIgnoredTest.java index e75af23159b..2bc89234c8e 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/android/RectIntersectReturnValueIgnoredTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/android/RectIntersectReturnValueIgnoredTest.java @@ -44,7 +44,8 @@ public boolean intersect(Rect other) { } public void setEmpty() {} - }""") + }\ + """) .setArgs(ImmutableList.of("-XDandroidCompatible=true")); @Test @@ -93,7 +94,8 @@ void checkInField(RectContainer container) { container.rect.intersect( container.xPos, container.yPos, container.xPos + 10, container.yPos + 20); } -}""") +}\ +""") .doTest(); } @@ -156,7 +158,8 @@ void checkInMethod(int length, int width) { RectContainer container = new RectContainer(); container.intersect(length, width); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/android/WakelockReleasedDangerouslyTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/android/WakelockReleasedDangerouslyTest.java index 28f4ce8c46c..56e7f68a331 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/android/WakelockReleasedDangerouslyTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/android/WakelockReleasedDangerouslyTest.java @@ -51,7 +51,8 @@ public void release() {} public void setReferenceCounted(boolean referenceCounted) {} } - }""") + }\ + """) .expectUnchanged(); private final CompilationTestHelper compilationHelper = CompilationTestHelper.newInstance(WakelockReleasedDangerously.class, getClass()) @@ -74,7 +75,8 @@ public void release() {} public void setReferenceCounted(boolean referenceCounted) {} } - }""") + }\ + """) .setArgs(ImmutableList.of("-XDandroidCompatible=true")); @Test diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/collectionincompatibletype/CollectionIncompatibleTypeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/collectionincompatibletype/CollectionIncompatibleTypeTest.java index 18f0bde8092..46116afe447 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/collectionincompatibletype/CollectionIncompatibleTypeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/collectionincompatibletype/CollectionIncompatibleTypeTest.java @@ -292,7 +292,8 @@ public boolean oneFinalClassAndOneNonFinalClass( // BUG: Diagnostic contains: return collection.contains(nonFinalClass1); } -}""") +}\ +""") .doTest(); } @@ -567,7 +568,8 @@ public void classToken( Set>> iterables, Class arrayListClass) { iterables.contains(arrayListClass); } -}""") +}\ +""") .doTest(); } @@ -587,7 +589,8 @@ public void test() { Properties properties = new Properties(); properties.get(""); } - }""") + }\ + """) .doTest(); } @@ -606,7 +609,8 @@ public class CollectionIncompatibleTypeClassCast extends HashMap { public void test(K k) { get(k); } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/collectionincompatibletype/IncompatibleArgumentTypeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/collectionincompatibletype/IncompatibleArgumentTypeTest.java index b685033f07a..9fcf7d60bf0 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/collectionincompatibletype/IncompatibleArgumentTypeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/collectionincompatibletype/IncompatibleArgumentTypeTest.java @@ -81,7 +81,8 @@ void testVarargs(A stringA) { // OK, everything compatible w/ Object Object o = stringA.varargs("foo", 2L, 1.0d, "a"); } -}""") +}\ +""") .doTest(); } @@ -155,7 +156,8 @@ void extraStuff() { // enforce it here. new Foo().new Sub().new SubSub().>methodVarIsFree(123); } -}""") +}\ +""") .doTest(); } @@ -234,7 +236,8 @@ void testVarArgs(Multimap intToString) { Integer[] keys = {123, 345}; intToString.containsAllKeys(123, (Object[]) keys); } -}""") +}\ +""") .doTest(); } @@ -293,7 +296,8 @@ void testArraySpecialization( // BUG: Diagnostic contains: String[] is not compatible with the required type: Number[] arrayTest.doSomething(strings); } -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/flogger/FloggerRedundantIsEnabledTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/flogger/FloggerRedundantIsEnabledTest.java index c3295101e82..85ca8761f5d 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/flogger/FloggerRedundantIsEnabledTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/flogger/FloggerRedundantIsEnabledTest.java @@ -137,7 +137,8 @@ public void checkSevere(FluentLogger logger) { logger.atSevere().log("test"); } } - }""") + }\ + """) .doTest(); } @@ -232,7 +233,8 @@ public boolean isEnabled() { return true; } } -}""") +}\ +""") .doTest(); } @@ -341,7 +343,8 @@ public void checkSevere(FluentLogger logger) { logger.atSevere().log("test"); } } - }""") + }\ + """) .addOutputLines( "FloggerRedundantIsEnabledPositiveCases_expected.java", """ @@ -415,7 +418,8 @@ public void checkWarning(FluentLogger logger) { public void checkSevere(FluentLogger logger) { logger.atSevere().log("test"); } - }""") + }\ + """) .doTest(TestMode.AST_MATCH); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/AssistedInjectAndInjectOnConstructorsTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/AssistedInjectAndInjectOnConstructorsTest.java index ae7a671583b..eaad33b1b8c 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/AssistedInjectAndInjectOnConstructorsTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/AssistedInjectAndInjectOnConstructorsTest.java @@ -84,7 +84,8 @@ public TestClass3(int n) {} public TestClass3(String s) {} } -}""") +}\ +""") .doTest(); } @@ -145,7 +146,8 @@ public TestClass6() {} @AssistedInject public TestClass6(int n) {} } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/AssistedInjectAndInjectOnSameConstructorTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/AssistedInjectAndInjectOnSameConstructorTest.java index b0aa1b95a74..2d33e3bf6f8 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/AssistedInjectAndInjectOnSameConstructorTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/AssistedInjectAndInjectOnSameConstructorTest.java @@ -61,7 +61,8 @@ public class TestClass2 { @AssistedInject public TestClass2() {} } -}""") +}\ +""") .doTest(); } @@ -141,7 +142,8 @@ public class TestClass8 { @AssistedInject public TestClass8() {} } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/AutoFactoryAtInjectTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/AutoFactoryAtInjectTest.java index 471f873e928..2dbb1abf9f6 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/AutoFactoryAtInjectTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/AutoFactoryAtInjectTest.java @@ -63,7 +63,8 @@ static class HasAutoFactoryOnConstructor { @AutoFactory HasAutoFactoryOnConstructor() {} } - }""") + }\ + """) .doTest(); } @@ -103,7 +104,8 @@ static class OnDifferentConstructors { @AutoFactory OnDifferentConstructors(Object object) {} } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/CloseableProvidesTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/CloseableProvidesTest.java index 2e366812005..49a64f0663f 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/CloseableProvidesTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/CloseableProvidesTest.java @@ -67,7 +67,8 @@ ImplementsClosable providesImplementsClosable() { PrintWriter providesPrintWriter() throws Exception { return new PrintWriter("some_file_path", StandardCharsets.UTF_8.name()); } - }""") + }\ + """) .doTest(); } @@ -103,7 +104,8 @@ DoesNotImplementsClosable providesDoesNotImplementsClosable() { Object providesObject() { return new Object(); } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/InjectOnMemberAndConstructorTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/InjectOnMemberAndConstructorTest.java index 0cb41dabbdf..a0bb7409a83 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/InjectOnMemberAndConstructorTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/InjectOnMemberAndConstructorTest.java @@ -113,7 +113,8 @@ public class MixedInject { @Inject public MixedInject() {} } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/InjectedConstructorAnnotationsTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/InjectedConstructorAnnotationsTest.java index 1b966c9a261..cbe90d5dd1b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/InjectedConstructorAnnotationsTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/InjectedConstructorAnnotationsTest.java @@ -64,7 +64,8 @@ public class TestClass3 { // BUG: Diagnostic contains: @Inject public TestClass3 @TestBindingAnnotation @Inject(optional = true) public TestClass3() {} } - }""") + }\ + """) .doTest(); } @@ -110,7 +111,8 @@ public class TestClass4 { @TestAnnotation public TestClass4() {} } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/InvalidTargetingOnScopingAnnotationTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/InvalidTargetingOnScopingAnnotationTest.java index ceeaf68d6f0..2fce2bbb0c9 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/InvalidTargetingOnScopingAnnotationTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/InvalidTargetingOnScopingAnnotationTest.java @@ -96,7 +96,8 @@ public class InvalidTargetingOnScopingAnnotationPositiveCases { @ScopeAnnotation @Retention(RUNTIME) public @interface TestAnnotation7 {} - }""") + }\ + """) .doTest(); } @@ -145,7 +146,8 @@ public class InvalidTargetingOnScopingAnnotationNegativeCases { @Target(PARAMETER) @Retention(RUNTIME) public @interface TestAnnotation4 {} -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/JavaxInjectOnAbstractMethodTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/JavaxInjectOnAbstractMethodTest.java index 98165d4c82d..bb7396c4295 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/JavaxInjectOnAbstractMethodTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/JavaxInjectOnAbstractMethodTest.java @@ -99,7 +99,8 @@ interface HasDefault { @javax.inject.Inject default void foo() {} } -}""") +}\ +""") .doTest(); } @@ -155,7 +156,8 @@ public abstract class TestClass6 { @javax.inject.Inject abstract void abstractMethod(); } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/JavaxInjectOnFinalFieldTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/JavaxInjectOnFinalFieldTest.java index 561476448fc..6a07ffb71c9 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/JavaxInjectOnFinalFieldTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/JavaxInjectOnFinalFieldTest.java @@ -52,7 +52,8 @@ public class TestClass1 { @Inject public final int n = 0; } - }""") + }\ + """) .doTest(); } @@ -89,7 +90,8 @@ public class TestClass4 { @Inject final void method() {} } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/MissingRuntimeRetentionTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/MissingRuntimeRetentionTest.java index 0b7daeb5dc6..1bbe9927fd5 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/MissingRuntimeRetentionTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/MissingRuntimeRetentionTest.java @@ -103,7 +103,8 @@ public class MissingRuntimeRetentionPositiveCases { @Target({TYPE, METHOD}) // BUG: Diagnostic contains: @Retention(RUNTIME) public @interface TestAnnotation7 {} - }""") + }\ + """) .doTest(); } @@ -168,7 +169,8 @@ public class MissingRuntimeRetentionNegativeCases { @com.google.inject.multibindings.MapKey @Retention(RUNTIME) public @interface TestAnnotation7 {} - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/MoreThanOneInjectableConstructorTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/MoreThanOneInjectableConstructorTest.java index 39d90192e69..d11ddde4062 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/MoreThanOneInjectableConstructorTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/MoreThanOneInjectableConstructorTest.java @@ -94,7 +94,8 @@ public TestClass4(int m, int n) {} @Inject public TestClass4(int m, int n, boolean x) {} } -}""") +}\ +""") .doTest(); } @@ -172,7 +173,8 @@ public TestClass7() {} @Inject public TestClass7(int n) {} } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/MoreThanOneQualifierTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/MoreThanOneQualifierTest.java index b3fe88213cc..e47426cf7f1 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/MoreThanOneQualifierTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/MoreThanOneQualifierTest.java @@ -165,7 +165,8 @@ public void setN( @BindingAnnotation @Retention(RUNTIME) public @interface Bar2 {} -}""") +}\ +""") .doTest(); } @@ -233,7 +234,8 @@ public void setN(@Bar int n) {} @BindingAnnotation @Retention(RUNTIME) public @interface Bar {} -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/MoreThanOneScopeAnnotationOnClassTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/MoreThanOneScopeAnnotationOnClassTest.java index c95f88568f9..29d63eb26a3 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/MoreThanOneScopeAnnotationOnClassTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/MoreThanOneScopeAnnotationOnClassTest.java @@ -67,7 +67,8 @@ class TestClass2 {} @SessionScoped // BUG: Diagnostic contains: class TestClass3 {} - }""") + }\ + """) .doTest(); } @@ -145,7 +146,8 @@ public class DaggerProductionSubcomponent {} /** Suppression through secondary name */ @SuppressWarnings("MoreThanOneScopeAnnotationOnClass") public class TestClass6 {} -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/OverlappingQualifierAndScopeAnnotationTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/OverlappingQualifierAndScopeAnnotationTest.java index 85f3fd57009..e028c6d0ca5 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/OverlappingQualifierAndScopeAnnotationTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/OverlappingQualifierAndScopeAnnotationTest.java @@ -62,7 +62,8 @@ public class OverlappingQualifierAndScopeAnnotationPositiveCases { @com.google.inject.BindingAnnotation // BUG: Diagnostic contains: OverlappingQualifierAndScopeAnnotation @interface JavaxScopeAndGuiceBindingAnnotation {} - }""") + }\ + """) .doTest(); } @@ -111,7 +112,8 @@ public class OverlappingQualifierAndScopeAnnotationNegativeCases { @javax.inject.Scope @com.google.inject.BindingAnnotation @interface JavaxScopeAndGuiceBindingAnnotation {} - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/QualifierWithTypeUseTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/QualifierWithTypeUseTest.java index 37aae2df01b..7b90ba4a1e9 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/QualifierWithTypeUseTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/QualifierWithTypeUseTest.java @@ -70,7 +70,8 @@ public class QualifierWithTypeUsePositiveCases { // BUG: Diagnostic contains: remove @Target(ElementType.TYPE_USE) @interface BindingAnnotation3 {} - }""") + }\ + """) .doTest(); } @@ -95,7 +96,8 @@ public class QualifierWithTypeUseNegativeCases { @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface NotAQualifier {} - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/ScopeAnnotationOnInterfaceOrAbstractClassTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/ScopeAnnotationOnInterfaceOrAbstractClassTest.java index 2929c632eb0..67519b6627a 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/ScopeAnnotationOnInterfaceOrAbstractClassTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/ScopeAnnotationOnInterfaceOrAbstractClassTest.java @@ -58,7 +58,8 @@ public abstract class TestClass1 {} // BUG: Diagnostic contains: remove @Singleton public interface TestClass2 {} -}""") +}\ +""") .doTest(); } @@ -109,7 +110,8 @@ interface DaggerInterfaceComponent { @CustomScope abstract class DaggerAbstractClassSubcomponent {} } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/dagger/AndroidInjectionBeforeSuperTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/dagger/AndroidInjectionBeforeSuperTest.java index e0270ea3b43..7bd13336477 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/dagger/AndroidInjectionBeforeSuperTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/dagger/AndroidInjectionBeforeSuperTest.java @@ -34,7 +34,8 @@ public final class AndroidInjectionBeforeSuperTest { public class Activity { public void onCreate(android.os.Bundle bundle) {} - }""") + }\ + """) .addSourceLines( "Fragment.java", """ @@ -44,7 +45,8 @@ public class Fragment { public void onAttach(android.app.Activity activity) {} public void onAttach(android.content.Context context) {} - }""") + }\ + """) .addSourceLines( "Service.java", """ @@ -56,31 +58,36 @@ public void onCreate() {} public android.os.IBinder onBind(android.content.Intent intent) { return null; } - }""") + }\ + """) .addSourceLines( "Context.java", """ package android.content; - public class Context {}""") + public class Context {}\ + """) .addSourceLines( "Intent.java", """ package android.content; - public class Intent {}""") + public class Intent {}\ + """) .addSourceLines( "Bundle.java", """ package android.os; - public class Bundle {}""") + public class Bundle {}\ + """) .addSourceLines( "IBinder.java", """ package android.os; - public interface IBinder {}"""); + public interface IBinder {}\ + """); @Test public void positiveCase() { @@ -161,7 +168,8 @@ public IBinder onBind(Intent intent) { return null; } } - }""") + }\ + """) .addSourceLines( "AndroidInjection.java", """ @@ -181,7 +189,8 @@ public static void inject(Activity activity) {} public static void inject(Fragment fragment) {} public static void inject(Service service) {} -}""") +}\ +""") .doTest(); } @@ -269,7 +278,8 @@ public IBinder onBind(Intent intent) { return null; } } - }""") + }\ + """) .addSourceLines( "AndroidInjection.java", """ @@ -289,7 +299,8 @@ public static void inject(Activity activity) {} public static void inject(Fragment fragment) {} public static void inject(Service service) {} -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/AssistedInjectScopingTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/AssistedInjectScopingTest.java index 3082e263b79..84fe8ae62d3 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/AssistedInjectScopingTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/AssistedInjectScopingTest.java @@ -101,7 +101,8 @@ public class TestClass6 { @javax.inject.Inject public TestClass6(String unassisted, @Assisted String assisted) {} } - }""") + }\ + """) .doTest(); } @@ -202,7 +203,8 @@ public TestClass10(@Assisted String assisted, int i) {} public TestClass10(int i, @Assisted String assisted) {} } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/AssistedParametersTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/AssistedParametersTest.java index 25b40b11503..cede5b72f77 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/AssistedParametersTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/AssistedParametersTest.java @@ -93,7 +93,8 @@ class GenericClass { // BUG: Diagnostic contains: int: a, b GenericClass(@Assisted Integer a, @Assisted int b) {} } -}""") +}\ +""") .doTest(); } @@ -156,7 +157,8 @@ public class TestClass5 { public TestClass5( @Assisted("foo") List x, @Assisted("foo") List y, String z) {} } -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/BindingToUnqualifiedCommonTypeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/BindingToUnqualifiedCommonTypeTest.java index 6563b1a7613..182e16500c1 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/BindingToUnqualifiedCommonTypeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/BindingToUnqualifiedCommonTypeTest.java @@ -78,7 +78,8 @@ String providesGreeting() { return "hi"; } } - }""") + }\ + """) .doTest(); } @@ -170,7 +171,8 @@ class A {} @BindingAnnotation @Retention(RetentionPolicy.RUNTIME) @interface MyBindingAnnotation {} -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/InjectOnFinalFieldTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/InjectOnFinalFieldTest.java index 444b1ebb0d4..f4a66866850 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/InjectOnFinalFieldTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/InjectOnFinalFieldTest.java @@ -57,7 +57,8 @@ public class TestClass1 { // BUG: Diagnostic contains: Object c final Object c = null; } - }""") + }\ + """) .doTest(); } @@ -94,7 +95,8 @@ public class TestClass4 { @Inject final void method() {} } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/OverridesGuiceInjectableMethodTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/OverridesGuiceInjectableMethodTest.java index 340f0acaffe..ee89b61d971 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/OverridesGuiceInjectableMethodTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/OverridesGuiceInjectableMethodTest.java @@ -97,7 +97,8 @@ public class TestClass7 extends TestClass1 { // BUG: Diagnostic contains: @Inject public void foo() {} } -}""") +}\ +""") .doTest(); } @@ -165,7 +166,8 @@ public void foo() {} /** Class that extends a class with an injected method, but doesn't override it. */ public class TestClass7 extends TestClass1 {} -}""") +}\ +""") .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/OverridesJavaxInjectableMethodTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/OverridesJavaxInjectableMethodTest.java index 0962f498cd2..991432417b0 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/OverridesJavaxInjectableMethodTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/OverridesJavaxInjectableMethodTest.java @@ -73,7 +73,8 @@ public class TestClass3 extends TestClass2 { // BUG: Diagnostic contains: @Inject public void foo() {} } -}""") +}\ +""") .doTest(); } @@ -140,7 +141,8 @@ public class TestClass9 extends TestClass3 { @SuppressWarnings("OverridesJavaxInjectableMethod") public void foo() {} } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/ProvidesMethodOutsideOfModuleTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/ProvidesMethodOutsideOfModuleTest.java index e87d5e7fdfb..da73b4493aa 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/ProvidesMethodOutsideOfModuleTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/inject/guice/ProvidesMethodOutsideOfModuleTest.java @@ -81,7 +81,8 @@ int thisIsNotOk() { return 42; } } - }""") + }\ + """) .doTest(); } @@ -148,7 +149,8 @@ int providesFoo() { return 42; } } - }""") + }\ + """) .doTest(); } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/nullness/EqualsBrokenForNullTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/nullness/EqualsBrokenForNullTest.java index b60082bf736..000907558b1 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/nullness/EqualsBrokenForNullTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/nullness/EqualsBrokenForNullTest.java @@ -216,7 +216,8 @@ public boolean equals(Object o) { return that.a == a; } } - }""") + }\ + """) .doTest(); } @@ -352,7 +353,8 @@ public boolean equals(Object o) { return that.a == a; } } -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/nullness/NullablePrimitiveTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/nullness/NullablePrimitiveTest.java index 55bd25cc18b..3af10f241aa 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/nullness/NullablePrimitiveTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/nullness/NullablePrimitiveTest.java @@ -59,7 +59,8 @@ public void method( public int method() { return 0; } - }""") + }\ + """) .doTest(); } @@ -85,7 +86,8 @@ public void method(@Nullable Integer a) {} public Integer method() { return Integer.valueOf(0); } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/nullness/UnnecessaryCheckNotNullTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/nullness/UnnecessaryCheckNotNullTest.java index d66509f2596..32c3e603c52 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/nullness/UnnecessaryCheckNotNullTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/nullness/UnnecessaryCheckNotNullTest.java @@ -239,7 +239,8 @@ public void error_fully_qualified_import_requireNonNull() { // BUG: Diagnostic contains: remove this line java.util.Objects.requireNonNull("string literal"); } - }""") + }\ + """) .doTest(); } @@ -288,7 +289,8 @@ public void go() { com.google.common.base.Verify.verifyNotNull(testObj, "this is ok"); java.util.Objects.requireNonNull(testObj, "this is ok"); } - }""") + }\ + """) .doTest(); } @@ -429,7 +431,8 @@ public Tester getTester() { return tester; } } - }""") + }\ + """) .doTest(); } @@ -455,7 +458,8 @@ public void test() { Preconditions.checkNotNull(obj1, "%s should not be null", "obj1"); Preconditions.checkNotNull(obj1.toString()); } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/nullness/UnsafeWildcardTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/nullness/UnsafeWildcardTest.java index 9dcf2cc4099..01d21b42ac7 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/nullness/UnsafeWildcardTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/nullness/UnsafeWildcardTest.java @@ -76,7 +76,8 @@ public static void main(String... args) { // BUG: Diagnostic contains: impossible new Impl<>(Stream.of(null, null)).apply("boom"); } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/overloading/InconsistentOverloadsTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/overloading/InconsistentOverloadsTest.java index 35389f6d257..6ddcfe5c91b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/overloading/InconsistentOverloadsTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/overloading/InconsistentOverloadsTest.java @@ -66,7 +66,8 @@ public void quux(int x, int y, String string) {} public void norf(int x, int y) {} public void norf(Object object, String string) {} - }""") + }\ + """) .doTest(); } @@ -110,7 +111,8 @@ int quux(@Bar @Baz Object object) { // BUG: Diagnostic contains: norf(String string, Object object) abstract int norf(Object object, @Baz @Bar String string); - }""") + }\ + """) .doTest(); } @@ -151,7 +153,8 @@ public void quux(int x, int y, String string) {} // BUG: Diagnostic contains: quux(int x, int y, Object object) public void quux(Object object, int y, int x) {} - }""") + }\ + """) .doTest(); } @@ -179,7 +182,8 @@ public void bar(int x) {} // BUG: Diagnostic contains: bar(int x, List> strings) public void bar(List> strings, int x) {} -}""") +}\ +""") .doTest(); } @@ -213,7 +217,8 @@ public void foo(int z, int x, int y) {} public void bar(int x, int y, String string, Object object) {} public void baz(int x) {} - }""") + }\ + """) .doTest(); } @@ -234,7 +239,8 @@ public void foo(int x, int y, Object object) {} // BUG: Diagnostic contains: foo(Object object, int x, int y, String string) public void foo(String string, int y, Object object, int x) {} - }""") + }\ + """) .doTest(); } @@ -264,7 +270,8 @@ public void foo(int y, int x, String... rest) {} abstract void bar(float y, String string, float x, float z); abstract void bar(Object... rest); - }""") + }\ + """) .doTest(); } @@ -301,7 +308,8 @@ void someMethod(int bar, String foo, List baz) {} // String> fizz) void someMethod(int bar, String foo, List baz, Map fizz) {} } -}""") +}\ +""") .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/time/TimeUnitMismatchTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/time/TimeUnitMismatchTest.java index 09588927822..600a30eb57d 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/time/TimeUnitMismatchTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/time/TimeUnitMismatchTest.java @@ -133,7 +133,8 @@ void optionalGet() { // BUG: Diagnostic contains: expected milliseconds but was nanoseconds long millis = maybeNanos.get(); } - }""") + }\ + """) .doTest(); } @@ -218,7 +219,8 @@ void optionalGet() { Optional maybeNanos = Optional.of(0L); long nanos = maybeNanos.get(); } - }""") + }\ + """) .doTest(); } diff --git a/core/src/test/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessPropagationTest.java b/core/src/test/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessPropagationTest.java index 216792412ef..6f939270560 100644 --- a/core/src/test/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessPropagationTest.java +++ b/core/src/test/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessPropagationTest.java @@ -290,7 +290,8 @@ public void stringConcatenation(String a, String b) { // BUG: Diagnostic contains: (Non-null) triggerNullnessChecker(null + (String) null); } -}""") +}\ +""") .doTest(); } @@ -628,7 +629,8 @@ public void optionalMethodsReturnNonNullUnlessAnnotated() { // BUG: Diagnostic contains: (Nullable) triggerNullnessChecker(myOptional.orNull()); } -}""") +}\ +""") .doTest(); } @@ -894,7 +896,8 @@ public void loop2() { comingValue = new Object(); } } -}""") +}\ +""") .doTest(); } @@ -1160,7 +1163,8 @@ public void equalOneNullableOtherNonNull(String nullableParam) { } // TODO(eaftan): tests for bottom? -}""") +}\ +""") .doTest(); } @@ -1426,7 +1430,8 @@ public void notEqualOneNullableOtherNonNull(String nullableParam) { } // TODO(eaftan): tests for bottom? -}""") +}\ +""") .doTest(); } @@ -1615,7 +1620,8 @@ void method() { static class HasStaticFields { static String staticStringField; } -}""") +}\ +""") .doTest(); } @@ -1783,7 +1789,8 @@ public void nullableAssignmentToPrimitiveFieldExpressionValue() { // BUG: Diagnostic contains: (Non-null) triggerNullnessCheckerOnPrimitive(mc.field = boxedIntReturningMethod()); } -}""") +}\ +""") .doTest(); } @@ -1830,7 +1837,8 @@ void tryWithResources() throws Exception { T something() { return null; } -}""") +}\ +""") .doTest(); } From f1308a004e113b70958358e6baea118f41a0ea5c Mon Sep 17 00:00:00 2001 From: ghm Date: Fri, 15 Nov 2024 03:18:03 -0800 Subject: [PATCH 22/38] Bump the source version of `maven-javadoc-plugin` up to 17. PiperOrigin-RevId: 696827801 --- pom.xml | 22 ++++++++++++++++++++-- type_annotations/pom.xml | 4 ++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index ef51b6e1583..6ff240e40b1 100644 --- a/pom.xml +++ b/pom.xml @@ -170,11 +170,29 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.3.1 + 3.11.1 - 8 + 17 true Error Prone ${project.version} API + src/main/java:${project.build.directory}/generated-sources/protobuf/java + + --add-exports=java.base/jdk.internal.javac=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED + + + **/module-info.java + diff --git a/type_annotations/pom.xml b/type_annotations/pom.xml index 365123af188..33492170e44 100644 --- a/type_annotations/pom.xml +++ b/type_annotations/pom.xml @@ -50,8 +50,8 @@ org.apache.maven.plugins maven-compiler-plugin - 8 - 8 + 17 + 17 From 3b16d6147af7b8ac0a682893daddf9b0055e5f89 Mon Sep 17 00:00:00 2001 From: ghm Date: Fri, 15 Nov 2024 04:02:58 -0800 Subject: [PATCH 23/38] Remove the reflective CaseTree methods from ASTHelpers. PiperOrigin-RevId: 696836584 --- .../google/errorprone/util/ASTHelpers.java | 114 +----------------- .../bugpatterns/MissingCasesInEnumSwitch.java | 2 +- .../StatementSwitchToExpressionSwitch.java | 7 +- .../TraditionalSwitchExpression.java | 7 +- .../bugpatterns/UnnecessaryBreakInSwitch.java | 7 +- .../UnnecessaryDefaultInEnumSwitch.java | 2 +- 6 files changed, 14 insertions(+), 125 deletions(-) diff --git a/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java b/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java index 0b762e849bb..b99cb8cc36c 100644 --- a/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java +++ b/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java @@ -2713,38 +2713,14 @@ private static boolean hasMatchingMethods( return false; } - private static final Method CASE_TREE_GET_LABELS = getCaseTreeGetLabelsMethod(); - - private static @Nullable Method getCaseTreeGetLabelsMethod() { - try { - return CaseTree.class.getMethod("getLabels"); - } catch (NoSuchMethodException e) { - return null; - } - } - - @SuppressWarnings("unchecked") // reflection - private static List getCaseLabels(CaseTree caseTree) { - if (CASE_TREE_GET_LABELS == null) { - return ImmutableList.of(); - } - try { - return (List) CASE_TREE_GET_LABELS.invoke(caseTree); - } catch (ReflectiveOperationException e) { - throw new LinkageError(e.getMessage(), e); - } - } - - // getExpression() is being used for compatibility with earlier JDK versions - @SuppressWarnings("deprecation") public static Optional getSwitchDefault(SwitchTree switchTree) { return switchTree.getCases().stream() .filter( (CaseTree c) -> { - if (c.getExpression() != null) { + if (!c.getExpressions().isEmpty()) { return false; } - List labels = getCaseLabels(c); + List labels = c.getLabels(); return labels.isEmpty() || (labels.size() == 1 && getOnlyElement(labels).getKind().name().equals("DEFAULT_CASE_LABEL")); @@ -2752,92 +2728,6 @@ public static Optional getSwitchDefault(SwitchTree switchTre .findFirst(); } - private static final Method CASE_TREE_GET_EXPRESSIONS = getCaseTreeGetExpressionsMethod(); - - private static @Nullable Method getCaseTreeGetExpressionsMethod() { - try { - return CaseTree.class.getMethod("getExpressions"); - } catch (NoSuchMethodException e) { - return null; - } - } - - /** - * Returns true if the given {@link CaseTree} is in the form: {@code case -> - * }. - */ - public static boolean isRuleKind(CaseTree caseTree) { - if (GET_CASE_KIND_METHOD == null) { - return false; - } - Enum kind; - try { - kind = (Enum) GET_CASE_KIND_METHOD.invoke(caseTree); - } catch (ReflectiveOperationException e) { - return false; - } - return kind.name().equals("RULE"); - } - - private static final Method GET_CASE_KIND_METHOD = getGetCaseKindMethod(); - - private static @Nullable Method getGetCaseKindMethod() { - try { - return CaseTree.class.getMethod("getCaseKind"); - } catch (NoSuchMethodException e) { - return null; - } - } - - /** - * Returns the statement or expression after the arrow for a {@link CaseTree} of the form: {@code - * case -> }. - */ - public static @Nullable Tree getCaseTreeBody(CaseTree caseTree) { - if (GET_CASE_BODY_METHOD == null) { - return null; - } - try { - return (Tree) GET_CASE_BODY_METHOD.invoke(caseTree); - } catch (ReflectiveOperationException e) { - throw new LinkageError(e.getMessage(), e); - } - } - - private static final @Nullable Method GET_CASE_BODY_METHOD = getGetCaseBodyMethod(); - - private static @Nullable Method getGetCaseBodyMethod() { - try { - return CaseTree.class.getMethod("getBody"); - } catch (NoSuchMethodException e) { - return null; - } - } - - /** - * Retrieves a stream containing all case expressions, in order, for a given {@code CaseTree}. - * This method acts as a facade to the {@code CaseTree.getExpressions()} API, falling back to - * legacy APIs when necessary. - */ - @SuppressWarnings({ - "deprecation", // getExpression() is being used for compatibility with earlier JDK versions - "unchecked", // reflection - }) - public static Stream getCaseExpressions(CaseTree caseTree) { - if (Runtime.version().feature() < 12) { - // "default" case gives an empty stream - return Stream.ofNullable(caseTree.getExpression()); - } - if (CASE_TREE_GET_EXPRESSIONS == null) { - return Stream.empty(); - } - try { - return ((List) CASE_TREE_GET_EXPRESSIONS.invoke(caseTree)).stream(); - } catch (ReflectiveOperationException e) { - throw new LinkageError(e.getMessage(), e); - } - } - private static final Supplier NULL_MARKED_NAME = memoize(state -> state.getName("org.jspecify.annotations.NullMarked")); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitch.java b/core/src/main/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitch.java index 1d9ce7d08c2..b15dbd8e8ef 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitch.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitch.java @@ -53,7 +53,7 @@ public Description matchSwitch(SwitchTree tree, VisitorState state) { } ImmutableSet handled = tree.getCases().stream() - .flatMap(ASTHelpers::getCaseExpressions) + .flatMap(c -> c.getExpressions().stream()) .filter(IdentifierTree.class::isInstance) .map(e -> ((IdentifierTree) e).getName().toString()) .collect(toImmutableSet()); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java b/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java index d5b09870f15..2c0cf618024 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java @@ -22,7 +22,6 @@ import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; import static com.google.errorprone.matchers.Description.NO_MATCH; -import static com.google.errorprone.util.ASTHelpers.getCaseExpressions; import static com.google.errorprone.util.ASTHelpers.getStartPosition; import static com.google.errorprone.util.ASTHelpers.getSymbol; import static com.sun.source.tree.Tree.Kind.BLOCK; @@ -208,11 +207,11 @@ private static AnalysisResult analyzeSwitchTree(SwitchTree switchTree, VisitorSt // One-pass scan through each case in switch for (int caseIndex = 0; caseIndex < cases.size(); caseIndex++) { CaseTree caseTree = cases.get(caseIndex); - boolean isDefaultCase = (getCaseExpressions(caseTree).count() == 0); + boolean isDefaultCase = caseTree.getExpressions().isEmpty(); hasDefaultCase |= isDefaultCase; // Accumulate enum values included in this case handledEnumValues.addAll( - getCaseExpressions(caseTree) + caseTree.getExpressions().stream() .filter(IdentifierTree.class::isInstance) .map(expressionTree -> ((IdentifierTree) expressionTree).getName().toString()) .collect(toImmutableSet())); @@ -1123,7 +1122,7 @@ private static String removeFallThruLines(String comments) { /** Prints source for all expressions in a given {@code case}, separated by commas. */ private static String printCaseExpressions(CaseTree caseTree, VisitorState state) { - return getCaseExpressions(caseTree).map(state::getSourceForNode).collect(joining(", ")); + return caseTree.getExpressions().stream().map(state::getSourceForNode).collect(joining(", ")); } /** diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/TraditionalSwitchExpression.java b/core/src/main/java/com/google/errorprone/bugpatterns/TraditionalSwitchExpression.java index 090b40e0175..749ac7305f7 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/TraditionalSwitchExpression.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/TraditionalSwitchExpression.java @@ -18,13 +18,14 @@ import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; import static com.google.errorprone.matchers.Description.NO_MATCH; -import static com.google.errorprone.util.ASTHelpers.isRuleKind; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; import com.google.errorprone.matchers.Description; import com.sun.source.tree.CaseTree; +import com.sun.source.tree.CaseTree.CaseKind; import com.sun.source.tree.Tree; +import com.sun.source.tree.Tree.Kind; /** A {@link BugChecker}; see the associated {@link BugPattern} annotation for details. */ @BugPattern(summary = "Prefer -> switches for switch expressions", severity = WARNING) @@ -32,11 +33,11 @@ public class TraditionalSwitchExpression extends BugChecker implements BugChecke @Override public Description matchCase(CaseTree tree, VisitorState state) { - if (isRuleKind(tree)) { + if (tree.getCaseKind().equals(CaseKind.RULE)) { return NO_MATCH; } Tree parent = state.getPath().getParentPath().getLeaf(); - if (!parent.getKind().name().equals("SWITCH_EXPRESSION")) { + if (!parent.getKind().equals(Kind.SWITCH_EXPRESSION)) { return NO_MATCH; } return describeMatch(parent); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryBreakInSwitch.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryBreakInSwitch.java index 0aeba268bf0..114125eaf3a 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryBreakInSwitch.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryBreakInSwitch.java @@ -19,17 +19,16 @@ import static com.google.common.collect.Iterables.getLast; import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; import static com.google.errorprone.matchers.Description.NO_MATCH; -import static com.google.errorprone.util.ASTHelpers.isRuleKind; import com.google.common.collect.ImmutableList; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; import com.google.errorprone.fixes.SuggestedFix; import com.google.errorprone.matchers.Description; -import com.google.errorprone.util.ASTHelpers; import com.sun.source.tree.BlockTree; import com.sun.source.tree.BreakTree; import com.sun.source.tree.CaseTree; +import com.sun.source.tree.CaseTree.CaseKind; import com.sun.source.tree.IfTree; import com.sun.source.tree.Tree; import com.sun.source.util.SimpleTreeVisitor; @@ -41,10 +40,10 @@ public class UnnecessaryBreakInSwitch extends BugChecker implements BugChecker.CaseTreeMatcher { @Override public Description matchCase(CaseTree tree, VisitorState state) { - if (!isRuleKind(tree)) { + if (!tree.getCaseKind().equals(CaseKind.RULE)) { return NO_MATCH; } - Tree body = ASTHelpers.getCaseTreeBody(tree); + Tree body = tree.getBody(); ImmutableList unnecessaryBreaks = unnecessaryBreaks(body); if (unnecessaryBreaks.isEmpty()) { return NO_MATCH; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryDefaultInEnumSwitch.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryDefaultInEnumSwitch.java index 5f792aa73d9..9b4a1493650 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryDefaultInEnumSwitch.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryDefaultInEnumSwitch.java @@ -231,7 +231,7 @@ private static boolean trivialDefault(List defaultState private static SetView unhandledCases(SwitchTree tree, TypeSymbol switchType) { ImmutableSet handledCases = tree.getCases().stream() - .flatMap(ASTHelpers::getCaseExpressions) + .flatMap(e -> e.getExpressions().stream()) .filter(IdentifierTree.class::isInstance) .map(p -> ((IdentifierTree) p).getName().toString()) .collect(toImmutableSet()); From 0d556b3d75b53445bb7f6f24526e959895519047 Mon Sep 17 00:00:00 2001 From: ghm Date: Fri, 15 Nov 2024 06:51:53 -0800 Subject: [PATCH 24/38] Introduce `ASTHelpers.isSwitchDefault`, and use it to burn down uses of `CaseTree.getExpression`, which is deprecated (with good reason!) PiperOrigin-RevId: 696872604 --- .../google/errorprone/util/ASTHelpers.java | 25 ++++++++++--------- .../google/errorprone/util/Reachability.java | 3 ++- .../bugpatterns/MissingCasesInEnumSwitch.java | 3 ++- .../StatementSwitchToExpressionSwitch.java | 7 +++--- .../errorprone/bugpatterns/SwitchDefault.java | 5 ++-- .../UnnecessaryDefaultInEnumSwitch.java | 3 ++- .../refaster/ControlFlowVisitor.java | 3 ++- 7 files changed, 28 insertions(+), 21 deletions(-) diff --git a/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java b/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java index b99cb8cc36c..a6f7e327d0a 100644 --- a/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java +++ b/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java @@ -2714,18 +2714,19 @@ private static boolean hasMatchingMethods( } public static Optional getSwitchDefault(SwitchTree switchTree) { - return switchTree.getCases().stream() - .filter( - (CaseTree c) -> { - if (!c.getExpressions().isEmpty()) { - return false; - } - List labels = c.getLabels(); - return labels.isEmpty() - || (labels.size() == 1 - && getOnlyElement(labels).getKind().name().equals("DEFAULT_CASE_LABEL")); - }) - .findFirst(); + return switchTree.getCases().stream().filter(c -> isSwitchDefault(c)).findFirst(); + } + + /** Returns whether {@code caseTree} is the default case of a switch statement. */ + public static boolean isSwitchDefault(CaseTree caseTree) { + if (!caseTree.getExpressions().isEmpty()) { + return false; + } + List labels = caseTree.getLabels(); + return labels.isEmpty() + || (labels.size() == 1 + // DEFAULT_CASE_LABEL is in Java 21, so we're stuck stringifying for now. + && getOnlyElement(labels).getKind().name().equals("DEFAULT_CASE_LABEL")); } private static final Supplier NULL_MARKED_NAME = diff --git a/check_api/src/main/java/com/google/errorprone/util/Reachability.java b/check_api/src/main/java/com/google/errorprone/util/Reachability.java index 12e644fa8ac..f48ad5abf27 100644 --- a/check_api/src/main/java/com/google/errorprone/util/Reachability.java +++ b/check_api/src/main/java/com/google/errorprone/util/Reachability.java @@ -19,6 +19,7 @@ import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.collect.Iterables.getLast; import static com.google.errorprone.util.ASTHelpers.getSymbol; +import static com.google.errorprone.util.ASTHelpers.isSwitchDefault; import static java.util.Objects.requireNonNull; import com.google.errorprone.annotations.CanIgnoreReturnValue; @@ -241,7 +242,7 @@ public Boolean visitSwitch(SwitchTree tree, Void unused) { return true; } // (4) - if (tree.getCases().stream().noneMatch(c -> c.getExpression() == null)) { + if (tree.getCases().stream().noneMatch(c -> isSwitchDefault(c))) { return true; } // (5) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitch.java b/core/src/main/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitch.java index b15dbd8e8ef..b861bcf3780 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitch.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitch.java @@ -18,6 +18,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; +import static com.google.errorprone.util.ASTHelpers.isSwitchDefault; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; @@ -48,7 +49,7 @@ public Description matchSwitch(SwitchTree tree, VisitorState state) { return Description.NO_MATCH; } // default case is present - if (tree.getCases().stream().anyMatch(c -> c.getExpression() == null)) { + if (tree.getCases().stream().anyMatch(c -> isSwitchDefault(c))) { return Description.NO_MATCH; } ImmutableSet handled = diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java b/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java index 2c0cf618024..43f648e0c35 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java @@ -24,6 +24,7 @@ import static com.google.errorprone.matchers.Description.NO_MATCH; import static com.google.errorprone.util.ASTHelpers.getStartPosition; import static com.google.errorprone.util.ASTHelpers.getSymbol; +import static com.google.errorprone.util.ASTHelpers.isSwitchDefault; import static com.sun.source.tree.Tree.Kind.BLOCK; import static com.sun.source.tree.Tree.Kind.BREAK; import static com.sun.source.tree.Tree.Kind.EXPRESSION_STATEMENT; @@ -536,7 +537,7 @@ private static SuggestedFix convertDirectlyToExpressionSwitch( boolean firstCaseInGroup = true; for (int caseIndex = 0; caseIndex < cases.size(); caseIndex++) { CaseTree caseTree = cases.get(caseIndex); - boolean isDefaultCase = caseTree.getExpression() == null; + boolean isDefaultCase = isSwitchDefault(caseTree); // For readability, filter out trailing unlabelled break statement because these become a // No-Op when used inside expression switches @@ -656,7 +657,7 @@ private static SuggestedFix convertToReturnSwitch( boolean firstCaseInGroup = true; for (int caseIndex = 0; caseIndex < cases.size(); caseIndex++) { CaseTree caseTree = cases.get(caseIndex); - boolean isDefaultCase = caseTree.getExpression() == null; + boolean isDefaultCase = isSwitchDefault(caseTree); String transformedBlockSource = transformReturnOrThrowBlock(caseTree, state, getStatements(caseTree)); @@ -825,7 +826,7 @@ private static SuggestedFix convertToAssignmentSwitch( boolean firstCaseInGroup = true; for (int caseIndex = 0; caseIndex < cases.size(); caseIndex++) { CaseTree caseTree = cases.get(caseIndex); - boolean isDefaultCase = caseTree.getExpression() == null; + boolean isDefaultCase = isSwitchDefault(caseTree); ImmutableList filteredStatements = filterOutRedundantBreak(caseTree); String transformedBlockSource = diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/SwitchDefault.java b/core/src/main/java/com/google/errorprone/bugpatterns/SwitchDefault.java index 4bd82b4c43b..a59e834257d 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/SwitchDefault.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/SwitchDefault.java @@ -21,6 +21,7 @@ import static com.google.errorprone.matchers.Description.NO_MATCH; import static com.google.errorprone.util.ASTHelpers.getStartPosition; import static com.google.errorprone.util.ASTHelpers.getSwitchDefault; +import static com.google.errorprone.util.ASTHelpers.isSwitchDefault; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; @@ -55,7 +56,7 @@ public Description matchSwitch(SwitchTree tree, VisitorState state) { while (it.hasNext()) { CaseTree caseTree = it.next(); defaultStatementGroup.add(caseTree); - if (caseTree.getExpression() == null) { + if (isSwitchDefault(caseTree)) { while (it.hasNext() && isNullOrEmpty(caseTree.getStatements())) { caseTree = it.next(); defaultStatementGroup.add(caseTree); @@ -96,7 +97,7 @@ public Description matchSwitch(SwitchTree tree, VisitorState state) { // If the last statement group falls out of the switch, add a `break;` before moving // the default to the end. CaseTree last = getLast(tree.getCases()); - if (last.getExpression() == null || Reachability.canCompleteNormally(last)) { + if (isSwitchDefault(last) || Reachability.canCompleteNormally(last)) { replacement = "break;\n" + replacement; } fix.replace(start, end, "").postfixWith(getLast(tree.getCases()), replacement); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryDefaultInEnumSwitch.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryDefaultInEnumSwitch.java index 9b4a1493650..cc4b5443944 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryDefaultInEnumSwitch.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryDefaultInEnumSwitch.java @@ -22,6 +22,7 @@ import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; import static com.google.errorprone.matchers.Description.NO_MATCH; import static com.google.errorprone.util.ASTHelpers.getStartPosition; +import static com.google.errorprone.util.ASTHelpers.isSwitchDefault; import static com.google.errorprone.util.Reachability.canCompleteNormally; import com.google.common.collect.ImmutableSet; @@ -79,7 +80,7 @@ public Description matchSwitch(SwitchTree switchTree, VisitorState state) { CaseTree caseBeforeDefault = null; CaseTree defaultCase = null; for (CaseTree caseTree : switchTree.getCases()) { - if (caseTree.getExpression() == null) { + if (isSwitchDefault(caseTree)) { defaultCase = caseTree; break; } else { diff --git a/core/src/main/java/com/google/errorprone/refaster/ControlFlowVisitor.java b/core/src/main/java/com/google/errorprone/refaster/ControlFlowVisitor.java index 12bca95267d..f855e98c212 100644 --- a/core/src/main/java/com/google/errorprone/refaster/ControlFlowVisitor.java +++ b/core/src/main/java/com/google/errorprone/refaster/ControlFlowVisitor.java @@ -19,6 +19,7 @@ import static com.google.errorprone.refaster.ControlFlowVisitor.Result.ALWAYS_RETURNS; import static com.google.errorprone.refaster.ControlFlowVisitor.Result.MAY_BREAK_OR_RETURN; import static com.google.errorprone.refaster.ControlFlowVisitor.Result.NEVER_EXITS; +import static com.google.errorprone.util.ASTHelpers.isSwitchDefault; import com.google.errorprone.refaster.ControlFlowVisitor.BreakContext; import com.google.errorprone.refaster.ControlFlowVisitor.Result; @@ -221,7 +222,7 @@ public Result visitSwitch(SwitchTree node, BreakContext cxt) { cxt.loopDepth++; try { for (CaseTree caseTree : node.getCases()) { - if (caseTree.getExpression() == null) { + if (isSwitchDefault(caseTree)) { seenDefault = true; } From e5fd194fa21ef9a01e8d4c72489906247aad81c8 Mon Sep 17 00:00:00 2001 From: ghm Date: Fri, 15 Nov 2024 07:14:29 -0800 Subject: [PATCH 25/38] Add new tree types to ErrorProneScanner. Some of these aren't actually that new. PiperOrigin-RevId: 696877937 --- .../errorprone/bugpatterns/BugChecker.java | 58 ++++++- .../errorprone/scanner/ErrorProneScanner.java | 147 +++++++++++++++++- 2 files changed, 197 insertions(+), 8 deletions(-) diff --git a/check_api/src/main/java/com/google/errorprone/bugpatterns/BugChecker.java b/check_api/src/main/java/com/google/errorprone/bugpatterns/BugChecker.java index b553381082e..0fdae63adb7 100644 --- a/check_api/src/main/java/com/google/errorprone/bugpatterns/BugChecker.java +++ b/check_api/src/main/java/com/google/errorprone/bugpatterns/BugChecker.java @@ -43,6 +43,7 @@ import com.sun.source.tree.AssertTree; import com.sun.source.tree.AssignmentTree; import com.sun.source.tree.BinaryTree; +import com.sun.source.tree.BindingPatternTree; import com.sun.source.tree.BlockTree; import com.sun.source.tree.BreakTree; import com.sun.source.tree.CaseTree; @@ -55,6 +56,7 @@ import com.sun.source.tree.DoWhileLoopTree; import com.sun.source.tree.EmptyStatementTree; import com.sun.source.tree.EnhancedForLoopTree; +import com.sun.source.tree.ExportsTree; import com.sun.source.tree.ExpressionStatementTree; import com.sun.source.tree.ForLoopTree; import com.sun.source.tree.IdentifierTree; @@ -70,12 +72,18 @@ import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.MethodTree; import com.sun.source.tree.ModifiersTree; +import com.sun.source.tree.ModuleTree; import com.sun.source.tree.NewArrayTree; import com.sun.source.tree.NewClassTree; +import com.sun.source.tree.OpensTree; +import com.sun.source.tree.PackageTree; import com.sun.source.tree.ParameterizedTypeTree; import com.sun.source.tree.ParenthesizedTree; import com.sun.source.tree.PrimitiveTypeTree; +import com.sun.source.tree.ProvidesTree; +import com.sun.source.tree.RequiresTree; import com.sun.source.tree.ReturnTree; +import com.sun.source.tree.SwitchExpressionTree; import com.sun.source.tree.SwitchTree; import com.sun.source.tree.SynchronizedTree; import com.sun.source.tree.ThrowTree; @@ -85,9 +93,11 @@ import com.sun.source.tree.TypeParameterTree; import com.sun.source.tree.UnaryTree; import com.sun.source.tree.UnionTypeTree; +import com.sun.source.tree.UsesTree; import com.sun.source.tree.VariableTree; import com.sun.source.tree.WhileLoopTree; import com.sun.source.tree.WildcardTree; +import com.sun.source.tree.YieldTree; import com.sun.source.util.TreePath; import com.sun.source.util.TreePathScanner; import com.sun.source.util.TreeScanner; @@ -342,14 +352,14 @@ public Void scan(Tree tree, Void unused) { return ImmutableRangeSet.copyOf(suppressedRegions); } - public interface AnnotationTreeMatcher extends Suppressible { - Description matchAnnotation(AnnotationTree tree, VisitorState state); - } - public interface AnnotatedTypeTreeMatcher extends Suppressible { Description matchAnnotatedType(AnnotatedTypeTree tree, VisitorState state); } + public interface AnnotationTreeMatcher extends Suppressible { + Description matchAnnotation(AnnotationTree tree, VisitorState state); + } + public interface ArrayAccessTreeMatcher extends Suppressible { Description matchArrayAccess(ArrayAccessTree tree, VisitorState state); } @@ -370,6 +380,10 @@ public interface BinaryTreeMatcher extends Suppressible { Description matchBinary(BinaryTree tree, VisitorState state); } + public interface BindingPatternTreeMatcher extends Suppressible { + Description matchBindingPattern(BindingPatternTree tree, VisitorState state); + } + public interface BlockTreeMatcher extends Suppressible { Description matchBlock(BlockTree tree, VisitorState state); } @@ -420,6 +434,10 @@ public interface EnhancedForLoopTreeMatcher extends Suppressible { // Intentionally skip ErroneousTreeMatcher -- we don't analyze malformed expressions. + public interface ExportsTreeMatcher extends Suppressible { + Description matchExports(ExportsTree tree, VisitorState state); + } + public interface ExpressionStatementTreeMatcher extends Suppressible { Description matchExpressionStatement(ExpressionStatementTree tree, VisitorState state); } @@ -480,6 +498,10 @@ public interface ModifiersTreeMatcher extends Suppressible { Description matchModifiers(ModifiersTree tree, VisitorState state); } + public interface ModuleTreeMatcher extends Suppressible { + Description matchModule(ModuleTree tree, VisitorState state); + } + public interface NewArrayTreeMatcher extends Suppressible { Description matchNewArray(NewArrayTree tree, VisitorState state); } @@ -491,6 +513,14 @@ public interface NewClassTreeMatcher extends Suppressible { // Intentionally skip OtherTreeMatcher. It seems to be used only for let expressions, which are // generated by javac to implement autoboxing. We are only interested in source-level constructs. + public interface OpensTreeMatcher extends Suppressible { + Description matchOpens(OpensTree tree, VisitorState state); + } + + public interface PackageTreeMatcher extends Suppressible { + Description matchPackage(PackageTree tree, VisitorState state); + } + public interface ParameterizedTypeTreeMatcher extends Suppressible { Description matchParameterizedType(ParameterizedTypeTree tree, VisitorState state); } @@ -503,10 +533,22 @@ public interface PrimitiveTypeTreeMatcher extends Suppressible { Description matchPrimitiveType(PrimitiveTypeTree tree, VisitorState state); } + public interface ProvidesTreeMatcher extends Suppressible { + Description matchProvides(ProvidesTree tree, VisitorState state); + } + + public interface RequiresTreeMatcher extends Suppressible { + Description matchRequires(RequiresTree tree, VisitorState state); + } + public interface ReturnTreeMatcher extends Suppressible { Description matchReturn(ReturnTree tree, VisitorState state); } + public interface SwitchExpressionTreeMatcher extends Suppressible { + Description matchSwitchExpression(SwitchExpressionTree tree, VisitorState state); + } + public interface SwitchTreeMatcher extends Suppressible { Description matchSwitch(SwitchTree tree, VisitorState state); } @@ -539,6 +581,10 @@ public interface UnionTypeTreeMatcher extends Suppressible { Description matchUnionType(UnionTypeTree tree, VisitorState state); } + public interface UsesTreeMatcher extends Suppressible { + Description matchUses(UsesTree tree, VisitorState state); + } + public interface VariableTreeMatcher extends Suppressible { Description matchVariable(VariableTree tree, VisitorState state); } @@ -551,6 +597,10 @@ public interface WildcardTreeMatcher extends Suppressible { Description matchWildcard(WildcardTree tree, VisitorState state); } + public interface YieldTreeMatcher extends Suppressible { + Description matchYield(YieldTree tree, VisitorState state); + } + @Override public boolean equals(Object obj) { if (!(obj instanceof BugChecker)) { diff --git a/check_api/src/main/java/com/google/errorprone/scanner/ErrorProneScanner.java b/check_api/src/main/java/com/google/errorprone/scanner/ErrorProneScanner.java index 90eb6a63243..b6a2960d042 100644 --- a/check_api/src/main/java/com/google/errorprone/scanner/ErrorProneScanner.java +++ b/check_api/src/main/java/com/google/errorprone/scanner/ErrorProneScanner.java @@ -32,6 +32,7 @@ import com.google.errorprone.bugpatterns.BugChecker.AssertTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.AssignmentTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.BinaryTreeMatcher; +import com.google.errorprone.bugpatterns.BugChecker.BindingPatternTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.BlockTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.BreakTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.CaseTreeMatcher; @@ -44,6 +45,7 @@ import com.google.errorprone.bugpatterns.BugChecker.DoWhileLoopTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.EmptyStatementTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.EnhancedForLoopTreeMatcher; +import com.google.errorprone.bugpatterns.BugChecker.ExportsTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.ExpressionStatementTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.ForLoopTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.IdentifierTreeMatcher; @@ -59,12 +61,18 @@ import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.ModifiersTreeMatcher; +import com.google.errorprone.bugpatterns.BugChecker.ModuleTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.NewArrayTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.NewClassTreeMatcher; +import com.google.errorprone.bugpatterns.BugChecker.OpensTreeMatcher; +import com.google.errorprone.bugpatterns.BugChecker.PackageTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.ParameterizedTypeTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.ParenthesizedTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.PrimitiveTypeTreeMatcher; +import com.google.errorprone.bugpatterns.BugChecker.ProvidesTreeMatcher; +import com.google.errorprone.bugpatterns.BugChecker.RequiresTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.ReturnTreeMatcher; +import com.google.errorprone.bugpatterns.BugChecker.SwitchExpressionTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.SwitchTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.SynchronizedTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.ThrowTreeMatcher; @@ -73,9 +81,11 @@ import com.google.errorprone.bugpatterns.BugChecker.TypeParameterTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.UnaryTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.UnionTypeTreeMatcher; +import com.google.errorprone.bugpatterns.BugChecker.UsesTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.VariableTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.WhileLoopTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.WildcardTreeMatcher; +import com.google.errorprone.bugpatterns.BugChecker.YieldTreeMatcher; import com.google.errorprone.matchers.Description; import com.google.errorprone.matchers.Suppressible; import com.google.errorprone.util.ASTHelpers; @@ -86,6 +96,7 @@ import com.sun.source.tree.AssertTree; import com.sun.source.tree.AssignmentTree; import com.sun.source.tree.BinaryTree; +import com.sun.source.tree.BindingPatternTree; import com.sun.source.tree.BlockTree; import com.sun.source.tree.BreakTree; import com.sun.source.tree.CaseTree; @@ -98,6 +109,7 @@ import com.sun.source.tree.DoWhileLoopTree; import com.sun.source.tree.EmptyStatementTree; import com.sun.source.tree.EnhancedForLoopTree; +import com.sun.source.tree.ExportsTree; import com.sun.source.tree.ExpressionStatementTree; import com.sun.source.tree.ForLoopTree; import com.sun.source.tree.IdentifierTree; @@ -113,12 +125,18 @@ import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.MethodTree; import com.sun.source.tree.ModifiersTree; +import com.sun.source.tree.ModuleTree; import com.sun.source.tree.NewArrayTree; import com.sun.source.tree.NewClassTree; +import com.sun.source.tree.OpensTree; +import com.sun.source.tree.PackageTree; import com.sun.source.tree.ParameterizedTypeTree; import com.sun.source.tree.ParenthesizedTree; import com.sun.source.tree.PrimitiveTypeTree; +import com.sun.source.tree.ProvidesTree; +import com.sun.source.tree.RequiresTree; import com.sun.source.tree.ReturnTree; +import com.sun.source.tree.SwitchExpressionTree; import com.sun.source.tree.SwitchTree; import com.sun.source.tree.SynchronizedTree; import com.sun.source.tree.ThrowTree; @@ -128,9 +146,11 @@ import com.sun.source.tree.TypeParameterTree; import com.sun.source.tree.UnaryTree; import com.sun.source.tree.UnionTypeTree; +import com.sun.source.tree.UsesTree; import com.sun.source.tree.VariableTree; import com.sun.source.tree.WhileLoopTree; import com.sun.source.tree.WildcardTree; +import com.sun.source.tree.YieldTree; import com.sun.source.util.TreePath; import com.sun.tools.javac.code.Symbol.CompletionFailure; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; @@ -213,13 +233,14 @@ protected Set getCustomSuppressionAnnotations(VisitorState state return customSuppressionAnnotations.get(state); } - private final List annotationMatchers = new ArrayList<>(); private final List annotatedTypeMatchers = new ArrayList<>(); + private final List annotationMatchers = new ArrayList<>(); private final List arrayAccessMatchers = new ArrayList<>(); private final List arrayTypeMatchers = new ArrayList<>(); private final List assertMatchers = new ArrayList<>(); private final List assignmentMatchers = new ArrayList<>(); private final List binaryMatchers = new ArrayList<>(); + private final List bindingPatternMatchers = new ArrayList<>(); private final List blockMatchers = new ArrayList<>(); private final List breakMatchers = new ArrayList<>(); private final List caseMatchers = new ArrayList<>(); @@ -233,6 +254,7 @@ protected Set getCustomSuppressionAnnotations(VisitorState state private final List doWhileLoopMatchers = new ArrayList<>(); private final List emptyStatementMatchers = new ArrayList<>(); private final List enhancedForLoopMatchers = new ArrayList<>(); + private final List exportsMatchers = new ArrayList<>(); private final List expressionStatementMatchers = new ArrayList<>(); private final List forLoopMatchers = new ArrayList<>(); @@ -249,12 +271,18 @@ protected Set getCustomSuppressionAnnotations(VisitorState state private final List methodMatchers = new ArrayList<>(); private final List methodInvocationMatchers = new ArrayList<>(); private final List modifiersMatchers = new ArrayList<>(); + private final List moduleMatchers = new ArrayList<>(); private final List newArrayMatchers = new ArrayList<>(); private final List newClassMatchers = new ArrayList<>(); + private final List opensMatchers = new ArrayList<>(); + private final List packageMatchers = new ArrayList<>(); private final List parameterizedTypeMatchers = new ArrayList<>(); private final List parenthesizedMatchers = new ArrayList<>(); private final List primitiveTypeMatchers = new ArrayList<>(); + private final List providesMatchers = new ArrayList<>(); + private final List requiresMatchers = new ArrayList<>(); private final List returnMatchers = new ArrayList<>(); + private final List switchExpressionMatchers = new ArrayList<>(); private final List switchMatchers = new ArrayList<>(); private final List synchronizedMatchers = new ArrayList<>(); private final List throwMatchers = new ArrayList<>(); @@ -263,21 +291,23 @@ protected Set getCustomSuppressionAnnotations(VisitorState state private final List typeParameterMatchers = new ArrayList<>(); private final List unaryMatchers = new ArrayList<>(); private final List unionTypeMatchers = new ArrayList<>(); + private final List usesMatchers = new ArrayList<>(); private final List variableMatchers = new ArrayList<>(); private final List whileLoopMatchers = new ArrayList<>(); private final List wildcardMatchers = new ArrayList<>(); + private final List yieldMatchers = new ArrayList<>(); private void registerNodeTypes( BugChecker checker, ImmutableSet.Builder> customSuppressionAnnotationClasses) { customSuppressionAnnotationClasses.addAll(checker.customSuppressionAnnotations()); - if (checker instanceof AnnotationTreeMatcher) { - annotationMatchers.add((AnnotationTreeMatcher) checker); - } if (checker instanceof AnnotatedTypeTreeMatcher) { annotatedTypeMatchers.add((AnnotatedTypeTreeMatcher) checker); } + if (checker instanceof AnnotationTreeMatcher) { + annotationMatchers.add((AnnotationTreeMatcher) checker); + } if (checker instanceof ArrayAccessTreeMatcher) { arrayAccessMatchers.add((ArrayAccessTreeMatcher) checker); } @@ -293,6 +323,9 @@ private void registerNodeTypes( if (checker instanceof BinaryTreeMatcher) { binaryMatchers.add((BinaryTreeMatcher) checker); } + if (checker instanceof BindingPatternTreeMatcher) { + bindingPatternMatchers.add((BindingPatternTreeMatcher) checker); + } if (checker instanceof BlockTreeMatcher) { blockMatchers.add((BlockTreeMatcher) checker); } @@ -329,6 +362,9 @@ private void registerNodeTypes( if (checker instanceof EnhancedForLoopTreeMatcher) { enhancedForLoopMatchers.add((EnhancedForLoopTreeMatcher) checker); } + if (checker instanceof ExportsTreeMatcher) { + exportsMatchers.add((ExportsTreeMatcher) checker); + } if (checker instanceof ExpressionStatementTreeMatcher) { expressionStatementMatchers.add((ExpressionStatementTreeMatcher) checker); } @@ -374,12 +410,21 @@ private void registerNodeTypes( if (checker instanceof ModifiersTreeMatcher) { modifiersMatchers.add((ModifiersTreeMatcher) checker); } + if (checker instanceof ModuleTreeMatcher) { + moduleMatchers.add((ModuleTreeMatcher) checker); + } if (checker instanceof NewArrayTreeMatcher) { newArrayMatchers.add((NewArrayTreeMatcher) checker); } if (checker instanceof NewClassTreeMatcher) { newClassMatchers.add((NewClassTreeMatcher) checker); } + if (checker instanceof OpensTreeMatcher) { + opensMatchers.add((OpensTreeMatcher) checker); + } + if (checker instanceof PackageTreeMatcher) { + packageMatchers.add((PackageTreeMatcher) checker); + } if (checker instanceof ParameterizedTypeTreeMatcher) { parameterizedTypeMatchers.add((ParameterizedTypeTreeMatcher) checker); } @@ -389,9 +434,18 @@ private void registerNodeTypes( if (checker instanceof PrimitiveTypeTreeMatcher) { primitiveTypeMatchers.add((PrimitiveTypeTreeMatcher) checker); } + if (checker instanceof ProvidesTreeMatcher) { + providesMatchers.add((ProvidesTreeMatcher) checker); + } + if (checker instanceof RequiresTreeMatcher) { + requiresMatchers.add((RequiresTreeMatcher) checker); + } if (checker instanceof ReturnTreeMatcher) { returnMatchers.add((ReturnTreeMatcher) checker); } + if (checker instanceof SwitchExpressionTreeMatcher) { + switchExpressionMatchers.add((SwitchExpressionTreeMatcher) checker); + } if (checker instanceof SwitchTreeMatcher) { switchMatchers.add((SwitchTreeMatcher) checker); } @@ -416,6 +470,9 @@ private void registerNodeTypes( if (checker instanceof UnionTypeTreeMatcher) { unionTypeMatchers.add((UnionTypeTreeMatcher) checker); } + if (checker instanceof UsesTreeMatcher) { + usesMatchers.add((UsesTreeMatcher) checker); + } if (checker instanceof VariableTreeMatcher) { variableMatchers.add((VariableTreeMatcher) checker); } @@ -425,6 +482,9 @@ private void registerNodeTypes( if (checker instanceof WildcardTreeMatcher) { wildcardMatchers.add((WildcardTreeMatcher) checker); } + if (checker instanceof YieldTreeMatcher) { + yieldMatchers.add((YieldTreeMatcher) checker); + } } @FunctionalInterface @@ -513,6 +573,17 @@ public Void visitBinary(BinaryTree tree, VisitorState visitorState) { return super.visitBinary(tree, state); } + @Override + public Void visitBindingPattern(BindingPatternTree tree, VisitorState visitorState) { + VisitorState state = + processMatchers( + bindingPatternMatchers, + tree, + BindingPatternTreeMatcher::matchBindingPattern, + visitorState); + return super.visitBindingPattern(tree, state); + } + @Override public Void visitBlock(BlockTree tree, VisitorState visitorState) { VisitorState state = @@ -620,6 +691,13 @@ public Void visitEnhancedForLoop(EnhancedForLoopTree tree, VisitorState visitorS return super.visitEnhancedForLoop(tree, state); } + @Override + public Void visitExports(ExportsTree tree, VisitorState visitorState) { + VisitorState state = + processMatchers(exportsMatchers, tree, ExportsTreeMatcher::matchExports, visitorState); + return super.visitExports(tree, state); + } + // Intentionally skip visitErroneous -- we don't analyze malformed expressions. @Override @@ -760,6 +838,14 @@ public Void visitModifiers(ModifiersTree tree, VisitorState visitorState) { return super.visitModifiers(tree, state); } + @Override + public Void visitModule(ModuleTree tree, VisitorState visitorState) { + VisitorState state = + processMatchers(moduleMatchers, tree, ModuleTreeMatcher::matchModule, visitorState); + + return super.visitModule(tree, state); + } + @Override public Void visitNewArray(NewArrayTree tree, VisitorState visitorState) { VisitorState state = @@ -774,6 +860,20 @@ public Void visitNewClass(NewClassTree tree, VisitorState visitorState) { return super.visitNewClass(tree, state); } + @Override + public Void visitOpens(OpensTree tree, VisitorState visitorState) { + VisitorState state = + processMatchers(opensMatchers, tree, OpensTreeMatcher::matchOpens, visitorState); + return super.visitOpens(tree, state); + } + + @Override + public Void visitPackage(PackageTree tree, VisitorState visitorState) { + VisitorState state = + processMatchers(packageMatchers, tree, PackageTreeMatcher::matchPackage, visitorState); + return super.visitPackage(tree, state); + } + // Intentionally skip visitOther. It seems to be used only for let expressions, which are // generated by javac to implement autoboxing. We are only interested in source-level constructs. @@ -810,6 +910,20 @@ public Void visitPrimitiveType(PrimitiveTypeTree tree, VisitorState visitorState return super.visitPrimitiveType(tree, state); } + @Override + public Void visitProvides(ProvidesTree tree, VisitorState visitorState) { + VisitorState state = + processMatchers(providesMatchers, tree, ProvidesTreeMatcher::matchProvides, visitorState); + return super.visitProvides(tree, state); + } + + @Override + public Void visitRequires(RequiresTree tree, VisitorState visitorState) { + VisitorState state = + processMatchers(requiresMatchers, tree, RequiresTreeMatcher::matchRequires, visitorState); + return super.visitRequires(tree, state); + } + @Override public Void visitReturn(ReturnTree tree, VisitorState visitorState) { VisitorState state = @@ -817,6 +931,17 @@ public Void visitReturn(ReturnTree tree, VisitorState visitorState) { return super.visitReturn(tree, state); } + @Override + public Void visitSwitchExpression(SwitchExpressionTree tree, VisitorState visitorState) { + VisitorState state = + processMatchers( + switchExpressionMatchers, + tree, + SwitchExpressionTreeMatcher::matchSwitchExpression, + visitorState); + return super.visitSwitchExpression(tree, state); + } + @Override public Void visitSwitch(SwitchTree tree, VisitorState visitorState) { VisitorState state = @@ -878,6 +1003,13 @@ public Void visitUnionType(UnionTypeTree tree, VisitorState visitorState) { return super.visitUnionType(tree, state); } + @Override + public Void visitUses(UsesTree tree, VisitorState visitorState) { + VisitorState state = + processMatchers(usesMatchers, tree, UsesTreeMatcher::matchUses, visitorState); + return super.visitUses(tree, state); + } + @Override public Void visitVariable(VariableTree tree, VisitorState visitorState) { VisitorState state = @@ -900,6 +1032,13 @@ public Void visitWildcard(WildcardTree tree, VisitorState visitorState) { return super.visitWildcard(tree, state); } + @Override + public Void visitYield(YieldTree tree, VisitorState visitorState) { + VisitorState state = + processMatchers(yieldMatchers, tree, YieldTreeMatcher::matchYield, visitorState); + return super.visitYield(tree, state); + } + /** * Handles an exception thrown by an individual BugPattern. By default, wraps the exception in an * {@link ErrorProneError} and rethrows. May be overridden by subclasses, for example to log the From 69b6e6473897d6cc358576950d165ed1a036f211 Mon Sep 17 00:00:00 2001 From: ghm Date: Fri, 15 Nov 2024 07:58:40 -0800 Subject: [PATCH 26/38] Run PatternMatchingInstanceof over EP. PiperOrigin-RevId: 696888475 --- .../NullnessPropagationTransfer.java | 6 ++--- .../errorprone/fixes/SuggestedFixes.java | 6 +---- .../AnnotationHasArgumentWithValue.java | 3 +-- .../errorprone/matchers/AnnotationType.java | 7 +++-- .../google/errorprone/matchers/Matchers.java | 3 +-- .../errorprone/matchers/StringLiteral.java | 3 +-- .../google/errorprone/util/ASTHelpers.java | 21 +++++---------- .../AbstractMustBeClosedChecker.java | 3 +-- .../bugpatterns/AnnotationPosition.java | 9 +++---- .../bugpatterns/AutoValueImmutableFields.java | 27 +++++++++---------- .../errorprone/bugpatterns/ClassName.java | 3 +-- .../ComputeIfAbsentAmbiguousReference.java | 3 +-- .../errorprone/bugpatterns/DeeplyNested.java | 3 +-- .../bugpatterns/DifferentNameButSame.java | 3 +-- .../DoubleBraceInitialization.java | 3 +-- .../bugpatterns/EqualsGetClass.java | 3 +-- .../errorprone/bugpatterns/FallThrough.java | 3 +-- .../errorprone/bugpatterns/Finally.java | 6 ++--- .../InstanceOfAndCastMatchWrongType.java | 3 +-- .../bugpatterns/InterfaceWithOnlyStatics.java | 6 ++--- .../bugpatterns/IsInstanceOfClass.java | 6 ++--- .../errorprone/bugpatterns/JdkObsolete.java | 3 +-- .../MemoizeConstantVisitorStateLookups.java | 3 +-- .../MixedMutabilityReturnType.java | 3 +-- .../NestedInstanceOfConditions.java | 6 ++--- .../bugpatterns/OptionalMapUnusedValue.java | 3 +-- .../SizeGreaterThanOrEqualsZero.java | 3 +-- .../StatementSwitchToExpressionSwitch.java | 6 ++--- .../bugpatterns/StreamResourceLeak.java | 3 +-- .../bugpatterns/StringSplitter.java | 7 +++-- .../errorprone/bugpatterns/TreeToString.java | 3 +-- .../TruthContainsExactlyElementsInUsage.java | 6 ++--- .../bugpatterns/UngroupedOverloads.java | 3 +-- .../bugpatterns/UnnecessaryStringBuilder.java | 3 +-- .../android/FragmentInjection.java | 3 +-- .../CanIgnoreReturnValueSuggester.java | 3 +-- .../flogger/FloggerRequiredModifiers.java | 3 +-- .../nullness/EqualsBrokenForNull.java | 3 +-- .../threadsafety/GuardedByBinder.java | 6 ++--- .../time/PreferJavaTimeOverload.java | 9 +++---- .../errorprone/refaster/BlockTemplate.java | 3 +-- .../refaster/ExpressionTemplate.java | 27 +++++++------------ .../google/errorprone/refaster/Inliner.java | 3 +-- .../PlaceholderVerificationVisitor.java | 3 +-- .../errorprone/refaster/UFreeIdent.java | 3 +-- .../refaster/UIntersectionClassType.java | 3 +-- .../errorprone/refaster/UTemplater.java | 3 +-- .../google/errorprone/refaster/UTypeVar.java | 3 +-- .../google/errorprone/refaster/Unifier.java | 3 +-- 49 files changed, 91 insertions(+), 169 deletions(-) diff --git a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessPropagationTransfer.java b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessPropagationTransfer.java index af9a791f342..c133ea6c0e8 100644 --- a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessPropagationTransfer.java +++ b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessPropagationTransfer.java @@ -476,8 +476,7 @@ Nullness visitAssignment(AssignmentNode node, SubNodeValues inputs, Updates upda setNonnullIfTrackable(updates, ((ArrayAccessNode) target).getArray()); } - if (target instanceof FieldAccessNode) { - FieldAccessNode fieldAccess = (FieldAccessNode) target; + if (target instanceof FieldAccessNode fieldAccess) { if (!fieldAccess.isStatic()) { setNonnullIfTrackable(updates, fieldAccess.getReceiver()); } @@ -967,8 +966,7 @@ static final class MemberName { @Override public boolean equals(Object obj) { - if (obj instanceof MemberName) { - MemberName other = (MemberName) obj; + if (obj instanceof MemberName other) { return clazz.equals(other.clazz) && member.equals(other.member); } return false; diff --git a/check_api/src/main/java/com/google/errorprone/fixes/SuggestedFixes.java b/check_api/src/main/java/com/google/errorprone/fixes/SuggestedFixes.java index 7223c0de2a8..8f394c4cb2b 100644 --- a/check_api/src/main/java/com/google/errorprone/fixes/SuggestedFixes.java +++ b/check_api/src/main/java/com/google/errorprone/fixes/SuggestedFixes.java @@ -1593,11 +1593,7 @@ public static Optional suggestExemptingAnnotation( } private static boolean isAnonymousClassTree(Tree t) { - if (t instanceof ClassTree) { - ClassTree classTree = (ClassTree) t; - return classTree.getSimpleName().contentEquals(""); - } - return false; + return t instanceof ClassTree classTree && classTree.getSimpleName().contentEquals(""); } /** diff --git a/check_api/src/main/java/com/google/errorprone/matchers/AnnotationHasArgumentWithValue.java b/check_api/src/main/java/com/google/errorprone/matchers/AnnotationHasArgumentWithValue.java index 4c31e38dddd..59c279bb56a 100644 --- a/check_api/src/main/java/com/google/errorprone/matchers/AnnotationHasArgumentWithValue.java +++ b/check_api/src/main/java/com/google/errorprone/matchers/AnnotationHasArgumentWithValue.java @@ -45,8 +45,7 @@ public boolean matches(AnnotationTree annotationTree, VisitorState state) { expressionTree = ASTHelpers.stripParentheses(expressionTree); - if (expressionTree instanceof NewArrayTree) { - NewArrayTree arrayTree = (NewArrayTree) expressionTree; + if (expressionTree instanceof NewArrayTree arrayTree) { for (ExpressionTree elementTree : arrayTree.getInitializers()) { if (valueMatcher.matches(elementTree, state)) { return true; diff --git a/check_api/src/main/java/com/google/errorprone/matchers/AnnotationType.java b/check_api/src/main/java/com/google/errorprone/matchers/AnnotationType.java index 996025efef9..c37ca1cd5bf 100644 --- a/check_api/src/main/java/com/google/errorprone/matchers/AnnotationType.java +++ b/check_api/src/main/java/com/google/errorprone/matchers/AnnotationType.java @@ -36,11 +36,10 @@ public AnnotationType(String annotationClassName) { @Override public boolean matches(AnnotationTree annotationTree, VisitorState state) { Tree type = annotationTree.getAnnotationType(); - if (type.getKind() == Tree.Kind.IDENTIFIER && type instanceof JCTree.JCIdent) { - JCTree.JCIdent jcIdent = (JCTree.JCIdent) type; + if (type.getKind() == Tree.Kind.IDENTIFIER && type instanceof JCTree.JCIdent jcIdent) { return jcIdent.sym.getQualifiedName().contentEquals(annotationClassName); - } else if (type.getKind() == Tree.Kind.MEMBER_SELECT && type instanceof JCTree.JCFieldAccess) { - JCTree.JCFieldAccess jcFieldAccess = (JCTree.JCFieldAccess) type; + } else if (type.getKind() == Tree.Kind.MEMBER_SELECT + && type instanceof JCTree.JCFieldAccess jcFieldAccess) { return jcFieldAccess.sym.getQualifiedName().contentEquals(annotationClassName); } else { return false; diff --git a/check_api/src/main/java/com/google/errorprone/matchers/Matchers.java b/check_api/src/main/java/com/google/errorprone/matchers/Matchers.java index a3844158b2b..915244d4fc1 100644 --- a/check_api/src/main/java/com/google/errorprone/matchers/Matchers.java +++ b/check_api/src/main/java/com/google/errorprone/matchers/Matchers.java @@ -296,8 +296,7 @@ public static Matcher receiverSameAsArgument(int a ExpressionTree arg = args.get(argNum); JCExpression methodSelect = (JCExpression) t.getMethodSelect(); - if (methodSelect instanceof JCFieldAccess) { - JCFieldAccess fieldAccess = (JCFieldAccess) methodSelect; + if (methodSelect instanceof JCFieldAccess fieldAccess) { return ASTHelpers.sameVariable(fieldAccess.getExpression(), arg); } else if (methodSelect instanceof JCIdent) { // A bare method call: "equals(foo)". Receiver is implicitly "this". diff --git a/check_api/src/main/java/com/google/errorprone/matchers/StringLiteral.java b/check_api/src/main/java/com/google/errorprone/matchers/StringLiteral.java index 45771ddc67d..187614aaf47 100644 --- a/check_api/src/main/java/com/google/errorprone/matchers/StringLiteral.java +++ b/check_api/src/main/java/com/google/errorprone/matchers/StringLiteral.java @@ -40,8 +40,7 @@ public StringLiteral(Pattern pattern) { @Override public boolean matches(ExpressionTree expressionTree, VisitorState state) { - if (expressionTree instanceof LiteralTree) { - LiteralTree literalTree = (LiteralTree) expressionTree; + if (expressionTree instanceof LiteralTree literalTree) { Object actualValue = literalTree.getValue(); return actualValue instanceof String && matcher.test((String) actualValue); } else { diff --git a/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java b/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java index a6f7e327d0a..ee5af5f2673 100644 --- a/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java +++ b/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java @@ -508,11 +508,9 @@ public static Stream enclosingElements(Symbol sym) { *

TODO(eaftan): Are there other places this could be used? */ public static Type getReturnType(ExpressionTree expressionTree) { - if (expressionTree instanceof JCFieldAccess) { - JCFieldAccess methodCall = (JCFieldAccess) expressionTree; + if (expressionTree instanceof JCFieldAccess methodCall) { return methodCall.type.getReturnType(); - } else if (expressionTree instanceof JCIdent) { - JCIdent methodCall = (JCIdent) expressionTree; + } else if (expressionTree instanceof JCIdent methodCall) { return methodCall.type.getReturnType(); } else if (expressionTree instanceof JCMethodInvocation) { return getReturnType(((JCMethodInvocation) expressionTree).getMethodSelect()); @@ -554,11 +552,9 @@ public static Type getReturnType(ExpressionTree expressionTree) { * } */ public static Type getReceiverType(ExpressionTree expressionTree) { - if (expressionTree instanceof JCFieldAccess) { - JCFieldAccess methodSelectFieldAccess = (JCFieldAccess) expressionTree; + if (expressionTree instanceof JCFieldAccess methodSelectFieldAccess) { return methodSelectFieldAccess.selected.type; - } else if (expressionTree instanceof JCIdent) { - JCIdent methodCall = (JCIdent) expressionTree; + } else if (expressionTree instanceof JCIdent methodCall) { return methodCall.sym.owner.type; } else if (expressionTree instanceof JCMethodInvocation) { return getReceiverType(((JCMethodInvocation) expressionTree).getMethodSelect()); @@ -1127,8 +1123,7 @@ public static LinkedHashSet enumValues(TypeSymbol enumType) { Scope scope = enumType.members(); Deque values = new ArrayDeque<>(); for (Symbol sym : scope.getSymbols()) { - if (sym instanceof VarSymbol) { - VarSymbol var = (VarSymbol) sym; + if (sym instanceof VarSymbol var) { if ((var.flags() & Flags.ENUM) != 0) { /* * Javac gives us the members backwards, apparently. It's worth making an effort to @@ -1154,8 +1149,7 @@ public static boolean isGeneratedConstructor(MethodTree tree) { public static List getConstructors(ClassTree classTree) { List constructors = new ArrayList<>(); for (Tree member : classTree.getMembers()) { - if (member instanceof MethodTree) { - MethodTree methodTree = (MethodTree) member; + if (member instanceof MethodTree methodTree) { if (getSymbol(methodTree).isConstructor()) { constructors.add(methodTree); } @@ -2606,8 +2600,7 @@ public Void visitForAll(Type.ForAll t, Type other) { @Override public Void visitWildcardType(WildcardType t, Type type) { - if (type instanceof WildcardType) { - WildcardType other = (WildcardType) type; + if (type instanceof WildcardType other) { scan(t.getExtendsBound(), other.getExtendsBound()); scan(t.getSuperBound(), other.getSuperBound()); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AbstractMustBeClosedChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/AbstractMustBeClosedChecker.java index fc3c4585ee0..f94e659cb6d 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AbstractMustBeClosedChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AbstractMustBeClosedChecker.java @@ -314,8 +314,7 @@ && isSameType(type.getReturnType(), streamType, state)) { break; case VARIABLE: Symbol sym = getSymbol(path.getLeaf()); - if (sym instanceof VarSymbol) { - VarSymbol var = (VarSymbol) sym; + if (sym instanceof VarSymbol var) { if (var.getKind() == ElementKind.RESOURCE_VARIABLE || isClosedInFinallyClause(var, path, state) || ASTHelpers.variableIsStaticFinal(var)) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AnnotationPosition.java b/core/src/main/java/com/google/errorprone/bugpatterns/AnnotationPosition.java index 45e450351ee..2e22d0c84c1 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AnnotationPosition.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AnnotationPosition.java @@ -153,8 +153,7 @@ private Description handle(Tree tree, Name name, ModifiersTree modifiers, Visito private static List annotationTokens( Tree tree, VisitorState state, int annotationEnd) { int endPos; - if (tree instanceof JCMethodDecl) { - JCMethodDecl methodTree = (JCMethodDecl) tree; + if (tree instanceof JCMethodDecl methodTree) { if (methodTree.getReturnType() != null) { endPos = getStartPosition(methodTree.getReturnType()); } else if (!methodTree.getParameters().isEmpty()) { @@ -167,15 +166,13 @@ private static List annotationTokens( } else { endPos = state.getEndPosition(methodTree); } - } else if (tree instanceof JCVariableDecl) { - JCVariableDecl variableTree = (JCVariableDecl) tree; + } else if (tree instanceof JCVariableDecl variableTree) { endPos = getStartPosition(variableTree.getType()); if (endPos == -1) { // handle 'var' endPos = state.getEndPosition(variableTree.getModifiers()); } - } else if (tree instanceof JCClassDecl) { - JCClassDecl classTree = (JCClassDecl) tree; + } else if (tree instanceof JCClassDecl classTree) { endPos = classTree.getMembers().isEmpty() ? state.getEndPosition(classTree) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AutoValueImmutableFields.java b/core/src/main/java/com/google/errorprone/bugpatterns/AutoValueImmutableFields.java index 8ba9ad3bc4f..3ccb868be97 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AutoValueImmutableFields.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AutoValueImmutableFields.java @@ -131,20 +131,19 @@ private static Matcher returning(String type) { public Description matchClass(ClassTree tree, VisitorState state) { if (ASTHelpers.hasAnnotation(tree, "com.google.auto.value.AutoValue", state)) { for (Tree memberTree : tree.getMembers()) { - if (memberTree instanceof MethodTree && !isSuppressed(memberTree, state)) { - MethodTree methodTree = (MethodTree) memberTree; - if (ABSTRACT_MATCHER.matches(methodTree, state)) { - for (Map.Entry> entry : REPLACEMENT_TO_MATCHERS.entries()) { - if (entry.getValue().matches(methodTree, state)) { - state.reportMatch( - buildDescription(methodTree) - .setMessage( - String.format( - "AutoValue instances should be deeply immutable. Therefore, we" - + " recommend returning %s instead.", - entry.getKey())) - .build()); - } + if (memberTree instanceof MethodTree methodTree + && !isSuppressed(memberTree, state) + && ABSTRACT_MATCHER.matches(methodTree, state)) { + for (Map.Entry> entry : REPLACEMENT_TO_MATCHERS.entries()) { + if (entry.getValue().matches(methodTree, state)) { + state.reportMatch( + buildDescription(methodTree) + .setMessage( + String.format( + "AutoValue instances should be deeply immutable. Therefore, we" + + " recommend returning %s instead.", + entry.getKey())) + .build()); } } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ClassName.java b/core/src/main/java/com/google/errorprone/bugpatterns/ClassName.java index b6e290efbcd..cc19081d19e 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ClassName.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ClassName.java @@ -51,8 +51,7 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s String filename = Files.getNameWithoutExtension(ASTHelpers.getFileName(tree)); List names = new ArrayList<>(); for (Tree member : tree.getTypeDecls()) { - if (member instanceof ClassTree) { - ClassTree classMember = (ClassTree) member; + if (member instanceof ClassTree classMember) { if (isSuppressed(classMember, state)) { // If any top-level classes have @SuppressWarnings("ClassName"), ignore // this compilation unit. We can't rely on the normal suppression diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ComputeIfAbsentAmbiguousReference.java b/core/src/main/java/com/google/errorprone/bugpatterns/ComputeIfAbsentAmbiguousReference.java index 9c4b7aaba57..044db5eba8b 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ComputeIfAbsentAmbiguousReference.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ComputeIfAbsentAmbiguousReference.java @@ -87,8 +87,7 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState return NO_MATCH; } ExpressionTree onlyArgument = tree.getArguments().get(0); - if (onlyArgument instanceof IdentifierTree) { - IdentifierTree onlyArgumentIdentifier = (IdentifierTree) onlyArgument; + if (onlyArgument instanceof IdentifierTree onlyArgumentIdentifier) { Name constructorParamName = oneArgConstructors.get(0).getParameters().get(0).getSimpleName(); if (constructorParamName.equals(onlyArgumentIdentifier.getName())) { return NO_MATCH; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/DeeplyNested.java b/core/src/main/java/com/google/errorprone/bugpatterns/DeeplyNested.java index 54febe9afb0..4eba5050e96 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/DeeplyNested.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/DeeplyNested.java @@ -156,9 +156,8 @@ private static Fix buildFix(TreePath path, VisitorState state) { replacement.append("return builder.build();"); fix.replace(enclosing, replacement.toString()); return fix.build(); - } else if (enclosing instanceof VariableTree && isStatic(getSymbol(enclosing))) { + } else if (enclosing instanceof VariableTree variableTree && isStatic(getSymbol(enclosing))) { // update `static FOO = ` to declare a helper method named create - VariableTree variableTree = (VariableTree) enclosing; String factory = String.format( "create%s", diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/DifferentNameButSame.java b/core/src/main/java/com/google/errorprone/bugpatterns/DifferentNameButSame.java index ff98ae9a804..10a12544ce5 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/DifferentNameButSame.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/DifferentNameButSame.java @@ -108,8 +108,7 @@ public Void visitMemberSelect(MemberSelectTree memberSelectTree, Void unused) { @Override public Void visitIdentifier(IdentifierTree identifierTree, Void unused) { Tree parent = getCurrentPath().getParentPath().getLeaf(); - if (parent instanceof NewClassTree) { - NewClassTree newClassTree = (NewClassTree) parent; + if (parent instanceof NewClassTree newClassTree) { if (newClassTree.getIdentifier().equals(identifierTree) && newClassTree.getEnclosingExpression() != null) { // don't try to fix instantiations with explicit enclosing instances, e.g. `a.new B();` diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/DoubleBraceInitialization.java b/core/src/main/java/com/google/errorprone/bugpatterns/DoubleBraceInitialization.java index fb4cf30ee6b..e8546616b60 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/DoubleBraceInitialization.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/DoubleBraceInitialization.java @@ -145,8 +145,7 @@ Optional maybeFix(NewClassTree tree, VisitorState state, BlockTree block) { if (enclosing instanceof ParenthesizedTree) { continue; } - if (enclosing instanceof VariableTree) { - VariableTree enclosingVariable = (VariableTree) enclosing; + if (enclosing instanceof VariableTree enclosingVariable) { toReplace = enclosingVariable.getInitializer(); typeTree = enclosingVariable.getType(); VarSymbol symbol = ASTHelpers.getSymbol(enclosingVariable); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/EqualsGetClass.java b/core/src/main/java/com/google/errorprone/bugpatterns/EqualsGetClass.java index 4167c800e53..6619a76b8d0 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/EqualsGetClass.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/EqualsGetClass.java @@ -245,8 +245,7 @@ private void makeAlwaysFalse() { enclosingPath = enclosingPath.getParentPath(); } Tree enclosing = enclosingPath.getLeaf(); - if (enclosing instanceof IfTree) { - IfTree ifTree = (IfTree) enclosing; + if (enclosing instanceof IfTree ifTree) { if (ifTree.getElseStatement() == null) { fix.replace(ifTree, ""); } else { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/FallThrough.java b/core/src/main/java/com/google/errorprone/bugpatterns/FallThrough.java index ae4579fb3aa..2d638ce1383 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/FallThrough.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/FallThrough.java @@ -96,8 +96,7 @@ private static int caseEndPosition(VisitorState state, CaseTree caseTree) { // end of the block if (caseTree.getStatements().size() == 1) { StatementTree only = getOnlyElement(caseTree.getStatements()); - if (only instanceof BlockTree) { - BlockTree blockTree = (BlockTree) only; + if (only instanceof BlockTree blockTree) { return blockTree.getStatements().isEmpty() ? getStartPosition(blockTree) : state.getEndPosition(getLast(blockTree.getStatements())); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/Finally.java b/core/src/main/java/com/google/errorprone/bugpatterns/Finally.java index 1b34e8ead9c..ed5feb2f5b9 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/Finally.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/Finally.java @@ -139,8 +139,7 @@ public boolean matches(T tree, VisitorState state) { /** Match a tree in the ancestor chain given the ancestor's immediate descendant. */ protected MatchResult matchAncestor(Tree leaf, Tree prevTree) { - if (leaf instanceof TryTree) { - TryTree tryTree = (TryTree) leaf; + if (leaf instanceof TryTree tryTree) { if (tryTree.getFinallyBlock() != null && tryTree.getFinallyBlock().equals(prevTree)) { return MatchResult.FOUND_ERROR; } @@ -214,8 +213,7 @@ protected MatchResult matchAncestor(Tree leaf, Tree prevTree) { private static class FinallyThrowMatcher extends FinallyCompletionMatcher { @Override protected MatchResult matchAncestor(Tree tree, Tree prevTree) { - if (tree instanceof TryTree) { - TryTree tryTree = (TryTree) tree; + if (tree instanceof TryTree tryTree) { if (tryTree.getBlock().equals(prevTree) && !tryTree.getCatches().isEmpty()) { // The current ancestor is a try block with associated catch blocks. return MatchResult.NO_MATCH; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/InstanceOfAndCastMatchWrongType.java b/core/src/main/java/com/google/errorprone/bugpatterns/InstanceOfAndCastMatchWrongType.java index 1bec8f914b2..3b620fa9fbd 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/InstanceOfAndCastMatchWrongType.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/InstanceOfAndCastMatchWrongType.java @@ -214,8 +214,7 @@ private static boolean expressionsEqual(ExpressionTree expr1, ExpressionTree exp && expressionsEqual(arrayAccessTree1.getIndex(), arrayAccessTree2.getIndex()); } - if (expr1 instanceof LiteralTree) { - LiteralTree literalTree1 = (LiteralTree) expr1; + if (expr1 instanceof LiteralTree literalTree1) { LiteralTree literalTree2 = (LiteralTree) expr2; return literalTree1.getValue().equals(literalTree2.getValue()); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/InterfaceWithOnlyStatics.java b/core/src/main/java/com/google/errorprone/bugpatterns/InterfaceWithOnlyStatics.java index 3ce75a97878..39480d27a06 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/InterfaceWithOnlyStatics.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/InterfaceWithOnlyStatics.java @@ -83,14 +83,12 @@ public Description matchClass(ClassTree tree, VisitorState state) { } SuggestedFix.Builder suggestedFix = SuggestedFix.builder(); for (Tree member : members) { - if (member instanceof VariableTree) { - VariableTree variableTree = (VariableTree) member; + if (member instanceof VariableTree variableTree) { SuggestedFixes.addModifiers( variableTree, state, Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC) .ifPresent(suggestedFix::merge); } - if (member instanceof MethodTree) { - MethodTree methodTree = (MethodTree) member; + if (member instanceof MethodTree methodTree) { SuggestedFixes.addModifiers(methodTree, state, Modifier.PUBLIC) .ifPresent(suggestedFix::merge); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/IsInstanceOfClass.java b/core/src/main/java/com/google/errorprone/bugpatterns/IsInstanceOfClass.java index c447e254599..53155b8dd7e 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/IsInstanceOfClass.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/IsInstanceOfClass.java @@ -123,9 +123,8 @@ static Operand create(Kind kind, CharSequence value, CharSequence source) { static Operand classify(JCTree tree, VisitorState state) { CharSequence source = state.getSourceForNode(tree); - if (tree instanceof MethodInvocationTree) { + if (tree instanceof MethodInvocationTree receiverInvocation) { // expr.getClass() -> "expr" - MethodInvocationTree receiverInvocation = (MethodInvocationTree) tree; MethodSymbol sym = ASTHelpers.getSymbol(receiverInvocation); if (sym.getSimpleName().contentEquals("getClass") && sym.params().isEmpty()) { if (receiverInvocation.getMethodSelect() instanceof IdentifierTree) { @@ -137,9 +136,8 @@ static Operand classify(JCTree tree, VisitorState state) { state.getSourceForNode(ASTHelpers.getReceiver(receiverInvocation)), source); } - } else if (tree instanceof MemberSelectTree) { + } else if (tree instanceof MemberSelectTree select) { // Foo.class -> "Foo" - MemberSelectTree select = (MemberSelectTree) tree; if (select.getIdentifier().contentEquals("class")) { return Operand.create(Kind.LITERAL, state.getSourceForNode(select.getExpression()), source); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/JdkObsolete.java b/core/src/main/java/com/google/errorprone/bugpatterns/JdkObsolete.java index 73dfbf362ec..4d5529dad96 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/JdkObsolete.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/JdkObsolete.java @@ -252,8 +252,7 @@ private Description describeIfObsolete( type = ASTHelpers.getType(parent); } else if (parent instanceof ReturnTree || parent instanceof LambdaExpressionTree) { type = getMethodOrLambdaReturnType(state); - } else if (parent instanceof MethodInvocationTree) { - MethodInvocationTree tree = (MethodInvocationTree) parent; + } else if (parent instanceof MethodInvocationTree tree) { int idx = tree.getArguments().indexOf(state.getPath().getLeaf()); if (idx == -1) { return null; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/MemoizeConstantVisitorStateLookups.java b/core/src/main/java/com/google/errorprone/bugpatterns/MemoizeConstantVisitorStateLookups.java index 459b6b4d09e..a3aee1a41f5 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/MemoizeConstantVisitorStateLookups.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/MemoizeConstantVisitorStateLookups.java @@ -179,8 +179,7 @@ private void handleConstantLookup(MethodInvocationTree tree) { String argumentValue = ASTHelpers.constValue(argumentExpr, String.class); if (argumentValue != null) { ExpressionTree methodSelect = tree.getMethodSelect(); - if (methodSelect instanceof JCFieldAccess) { - JCFieldAccess fieldAccess = (JCFieldAccess) methodSelect; + if (methodSelect instanceof JCFieldAccess fieldAccess) { Name method = fieldAccess.name; result.add(new CallSite(method, argumentValue, argumentExpr, tree)); } else { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/MixedMutabilityReturnType.java b/core/src/main/java/com/google/errorprone/bugpatterns/MixedMutabilityReturnType.java index fe7151e95fd..fed19ec3fe4 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/MixedMutabilityReturnType.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/MixedMutabilityReturnType.java @@ -406,8 +406,7 @@ public Void visitIdentifier(IdentifierTree identifier, Void unused) { if (!getSymbol(identifier).equals(symbol)) { return null; } - if (parent instanceof VariableTree) { - VariableTree variable = (VariableTree) parent; + if (parent instanceof VariableTree variable) { fix.replace(variable.getType(), qualifyType(state, fix, details.builderType())); return null; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/NestedInstanceOfConditions.java b/core/src/main/java/com/google/errorprone/bugpatterns/NestedInstanceOfConditions.java index d9bb153a589..c31bf255a58 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/NestedInstanceOfConditions.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/NestedInstanceOfConditions.java @@ -48,8 +48,7 @@ public Description matchIf(IfTree ifTree, VisitorState visitorState) { ExpressionTree expressionTree = stripParentheses(ifTree.getCondition()); - if (expressionTree instanceof InstanceOfTree) { - InstanceOfTree instanceOfTree = (InstanceOfTree) expressionTree; + if (expressionTree instanceof InstanceOfTree instanceOfTree) { if (!(instanceOfTree.getExpression() instanceof IdentifierTree)) { return Description.NO_MATCH; @@ -115,8 +114,7 @@ public boolean matches(Tree tree, VisitorState state) { if (tree instanceof IfTree) { ExpressionTree conditionTree = ASTHelpers.stripParentheses(((IfTree) tree).getCondition()); - if (conditionTree instanceof InstanceOfTree) { - InstanceOfTree instanceOfTree = (InstanceOfTree) conditionTree; + if (conditionTree instanceof InstanceOfTree instanceOfTree) { Types types = state.getTypes(); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/OptionalMapUnusedValue.java b/core/src/main/java/com/google/errorprone/bugpatterns/OptionalMapUnusedValue.java index 3f7d2c9c7dd..5c76c180357 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/OptionalMapUnusedValue.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/OptionalMapUnusedValue.java @@ -63,8 +63,7 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState // TODO(b/170476239): Cover all the cases in which the argument is void-compatible, see // JLS 15.12.2.1 private static boolean isVoidCompatibleLambda(ExpressionTree tree, VisitorState state) { - if (tree instanceof LambdaExpressionTree) { - LambdaExpressionTree lambdaTree = (LambdaExpressionTree) tree; + if (tree instanceof LambdaExpressionTree lambdaTree) { if (lambdaTree.getBodyKind().equals(LambdaExpressionTree.BodyKind.EXPRESSION)) { return kindIs(Kind.METHOD_INVOCATION).matches(lambdaTree.getBody(), state); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/SizeGreaterThanOrEqualsZero.java b/core/src/main/java/com/google/errorprone/bugpatterns/SizeGreaterThanOrEqualsZero.java index ebbcc000c21..4cc70ade709 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/SizeGreaterThanOrEqualsZero.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/SizeGreaterThanOrEqualsZero.java @@ -149,8 +149,7 @@ public Description matchBinary(BinaryTree tree, VisitorState state) { expressionType == ExpressionType.GREATER_THAN_EQUAL ? tree.getLeftOperand() : tree.getRightOperand(); - if (operand instanceof MethodInvocationTree) { - MethodInvocationTree callToSize = (MethodInvocationTree) operand; + if (operand instanceof MethodInvocationTree callToSize) { if (SIZE_OR_LENGTH_INSTANCE_METHOD.matches(callToSize, state)) { return provideReplacementForInstanceMethodInvocation( tree, callToSize, state, expressionType); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java b/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java index 43f648e0c35..cbe93d3b8b6 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java @@ -420,8 +420,7 @@ private static AssignmentSwitchAnalysisState analyzeCaseForAssignmentSwitch( Optional caseAssignmentTreeOptional = Optional.empty(); // The assignment could be a normal assignment ("=") or a compound assignment (e.g. "+=") - if (expression instanceof CompoundAssignmentTree) { - CompoundAssignmentTree compoundAssignmentTree = (CompoundAssignmentTree) expression; + if (expression instanceof CompoundAssignmentTree compoundAssignmentTree) { caseAssignmentTargetOptional = Optional.of(compoundAssignmentTree.getVariable()); caseAssignmentKindOptional = Optional.of(compoundAssignmentTree.getKind()); caseAssignmentTreeOptional = Optional.of(expression); @@ -755,8 +754,7 @@ private static List followingStatementsInBlock( // NOMUTANTS--should early return above if (pathToEnclosing != null) { Tree enclosing = pathToEnclosing.getLeaf(); - if (enclosing instanceof BlockTree) { - BlockTree blockTree = (BlockTree) enclosing; + if (enclosing instanceof BlockTree blockTree) { // Path from root -> switchTree TreePath rootToSwitchPath = TreePath.getPath(pathToEnclosing, switchTree); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/StreamResourceLeak.java b/core/src/main/java/com/google/errorprone/bugpatterns/StreamResourceLeak.java index e72b4edd6e0..7cb05590cd3 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/StreamResourceLeak.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/StreamResourceLeak.java @@ -76,11 +76,10 @@ private static SuggestedFix definiteFix(ExpressionTree tree, VisitorState state) String streamType = SuggestedFixes.prettyType(state, fix, ASTHelpers.getReturnType(tree)); if (parent instanceof MemberSelectTree) { StatementTree statement = state.findEnclosing(StatementTree.class); - if (statement instanceof VariableTree) { + if (statement instanceof VariableTree var) { // Variables need to be declared outside the try-with-resources: // e.g. `int count = Files.lines(p).count();` // -> `int count; try (Stream stream = Files.lines(p)) { count = stream.count(); }` - VariableTree var = (VariableTree) statement; int pos = getStartPosition(var); int initPos = getStartPosition(var.getInitializer()); int eqPos = pos + state.getSourceForNode(var).substring(0, initPos - pos).lastIndexOf('='); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/StringSplitter.java b/core/src/main/java/com/google/errorprone/bugpatterns/StringSplitter.java index 69a00ea0e80..fb0deedaa91 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/StringSplitter.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/StringSplitter.java @@ -97,8 +97,7 @@ public Optional buildFix(MethodInvocationTree tree, VisitorState state) { SuggestedFix.builder(), tree, arg, state, "split", /* mutableList= */ false) .build()); } - if (parent instanceof ArrayAccessTree) { - ArrayAccessTree arrayAccessTree = (ArrayAccessTree) parent; + if (parent instanceof ArrayAccessTree arrayAccessTree) { if (!arrayAccessTree.getExpression().equals(tree)) { return Optional.empty(); } @@ -168,8 +167,8 @@ public Boolean visitArrayAccess(ArrayAccessTree tree, Void unused) { return false; } Tree parent = getCurrentPath().getParentPath().getLeaf(); - if (parent instanceof AssignmentTree && ((AssignmentTree) parent).getVariable() == tree) { - AssignmentTree assignmentTree = (AssignmentTree) parent; + if (parent instanceof AssignmentTree assignmentTree + && ((AssignmentTree) parent).getVariable() == tree) { fix.replace( /* startPos= */ state.getEndPosition(expression), /* endPos= */ getStartPosition(index), diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/TreeToString.java b/core/src/main/java/com/google/errorprone/bugpatterns/TreeToString.java index 3fda587d9a2..ba4e5db58e7 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/TreeToString.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/TreeToString.java @@ -118,8 +118,7 @@ private static Optional fix(Tree target, Tree replace, VisitorState state) private static String createStringReplacement( VisitorState state, VarSymbol visitorStateSymbol, Tree target) { String visitorStateVariable = visitorStateSymbol.getSimpleName().toString(); - if (target instanceof MethodInvocationTree) { - MethodInvocationTree targetMethodInvocationTree = (MethodInvocationTree) target; + if (target instanceof MethodInvocationTree targetMethodInvocationTree) { if (TREEMAKER_LITERAL_CREATOR.matches(targetMethodInvocationTree, state)) { return String.format( "%s.getConstantExpression(%s)", diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/TruthContainsExactlyElementsInUsage.java b/core/src/main/java/com/google/errorprone/bugpatterns/TruthContainsExactlyElementsInUsage.java index 79fc1c32bee..e07cca6366c 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/TruthContainsExactlyElementsInUsage.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/TruthContainsExactlyElementsInUsage.java @@ -77,12 +77,10 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState // Returns the arguments from the expression. If it is not a valid expression, returns empty. private static Optional> getArgumentsFromNewIterableExpression( ExpressionTree expression, VisitorState state) { - if (expression instanceof MethodInvocationTree + if (expression instanceof MethodInvocationTree paramMethodInvocationTree && NEW_ITERABLE_MATCHERS.matches(expression, state)) { - MethodInvocationTree paramMethodInvocationTree = (MethodInvocationTree) expression; return Optional.of(ImmutableList.copyOf(paramMethodInvocationTree.getArguments())); - } else if (expression instanceof NewArrayTree) { - NewArrayTree newArrayTree = (NewArrayTree) expression; + } else if (expression instanceof NewArrayTree newArrayTree) { return Optional.of(ImmutableList.copyOf(newArrayTree.getInitializers())); } return Optional.empty(); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UngroupedOverloads.java b/core/src/main/java/com/google/errorprone/bugpatterns/UngroupedOverloads.java index 015399b539e..8cd18064d12 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UngroupedOverloads.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UngroupedOverloads.java @@ -96,8 +96,7 @@ public Description matchClass(ClassTree classTree, VisitorState state) { LinkedHashMultimap methods = LinkedHashMultimap.create(); for (int i = 0; i < classTree.getMembers().size(); ++i) { Tree member = classTree.getMembers().get(i); - if (member instanceof MethodTree) { - MethodTree methodTree = (MethodTree) member; + if (member instanceof MethodTree methodTree) { if (!ASTHelpers.isGeneratedConstructor(methodTree)) { methods.put(OverloadKey.create(methodTree), MemberWithIndex.create(i, methodTree)); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryStringBuilder.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryStringBuilder.java index 15219e14e14..c44e1de9857 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryStringBuilder.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryStringBuilder.java @@ -125,8 +125,7 @@ public Description matchNewClass(NewClassTree tree, VisitorState state) { path.getLeaf(), SuggestedFix.replace(path.getLeaf(), replacement(state, parts))); } Tree leaf = target.path().getLeaf(); - if (leaf instanceof VariableTree) { - VariableTree variableTree = (VariableTree) leaf; + if (leaf instanceof VariableTree variableTree) { if (isRewritableVariable(variableTree, state)) { SuggestedFix.Builder fix = SuggestedFix.builder(); if (state.getEndPosition(variableTree.getType()) != Position.NOPOS) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/android/FragmentInjection.java b/core/src/main/java/com/google/errorprone/bugpatterns/android/FragmentInjection.java index e4232014be6..a26cc770190 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/android/FragmentInjection.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/android/FragmentInjection.java @@ -124,8 +124,7 @@ public Description matchClass(ClassTree tree, VisitorState state) { private static @Nullable MethodTree getMethod( Matcher methodMatcher, ClassTree classTree, VisitorState state) { for (Tree member : classTree.getMembers()) { - if (member instanceof MethodTree) { - MethodTree memberTree = (MethodTree) member; + if (member instanceof MethodTree memberTree) { if (methodMatcher.matches(memberTree, state)) { return memberTree; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/checkreturnvalue/CanIgnoreReturnValueSuggester.java b/core/src/main/java/com/google/errorprone/bugpatterns/checkreturnvalue/CanIgnoreReturnValueSuggester.java index 7a7cf8836ba..1c59f571d2e 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/checkreturnvalue/CanIgnoreReturnValueSuggester.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/checkreturnvalue/CanIgnoreReturnValueSuggester.java @@ -156,8 +156,7 @@ public Description matchMethod(MethodTree methodTree, VisitorState state) { // if the method _only_ returns an input param, bail out if (methodTree.getBody() != null && methodTree.getBody().getStatements().size() == 1) { StatementTree onlyStatement = methodTree.getBody().getStatements().get(0); - if (onlyStatement instanceof ReturnTree) { - ReturnTree returnTree = (ReturnTree) onlyStatement; + if (onlyStatement instanceof ReturnTree returnTree) { if (returnTree.getExpression() instanceof IdentifierTree) { return Description.NO_MATCH; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerRequiredModifiers.java b/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerRequiredModifiers.java index 73919c6f551..dc249d93658 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerRequiredModifiers.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerRequiredModifiers.java @@ -253,8 +253,7 @@ private Description replaceWithFieldLookup(ExpressionTree expr, VisitorState sta TreePath path = state.getPath(); do { - if (e instanceof AssignmentTree) { - AssignmentTree assignment = (AssignmentTree) e; + if (e instanceof AssignmentTree assignment) { if (ASTHelpers.getSymbol(assignment.getVariable()).equals(target)) { state.incrementCounter(this, "skip-self-assignment"); return NO_MATCH; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/EqualsBrokenForNull.java b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/EqualsBrokenForNull.java index 72d948df121..89a105fd8ee 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/EqualsBrokenForNull.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/EqualsBrokenForNull.java @@ -99,8 +99,7 @@ public Void visitVariable(VariableTree variableTree, Void unused) { // Track variables assigned from our parameter. Tree initializer = variableTree.getInitializer(); VarSymbol symbol = getSymbol(variableTree); - if (isConsideredFinal(symbol) && initializer instanceof InstanceOfTree) { - InstanceOfTree instanceOf = (InstanceOfTree) initializer; + if (isConsideredFinal(symbol) && initializer instanceof InstanceOfTree instanceOf) { if (instanceOf.getExpression() instanceof IdentifierTree && incomingVariableSymbols.contains(getSymbol(instanceOf.getExpression()))) { impliesNonNull.add(getSymbol(variableTree)); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByBinder.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByBinder.java index 000442e1922..065be87d61a 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByBinder.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByBinder.java @@ -266,8 +266,7 @@ private GuardedByExpression bindSelect(GuardedByExpression base, Symbol sym) { public GuardedByExpression visitIdentifier(IdentifierTree node, BinderContext context) { Symbol symbol = context.resolver.resolveIdentifier(node); checkGuardedBy(symbol != null, "Could not resolve %s", node); - if (symbol instanceof Symbol.VarSymbol) { - Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) symbol; + if (symbol instanceof Symbol.VarSymbol varSymbol) { switch (varSymbol.getKind()) { case LOCAL_VARIABLE: case PARAMETER: @@ -282,8 +281,7 @@ public GuardedByExpression visitIdentifier(IdentifierTree node, BinderContext co default: throw new IllegalGuardedBy(varSymbol.getKind().toString()); } - } else if (symbol instanceof Symbol.MethodSymbol) { - Symbol.MethodSymbol methodSymbol = (Symbol.MethodSymbol) symbol; + } else if (symbol instanceof Symbol.MethodSymbol methodSymbol) { return F.select(computeBase(context, symbol), methodSymbol); } else if (symbol instanceof Symbol.ClassSymbol) { if (node.getName().contentEquals("this")) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/time/PreferJavaTimeOverload.java b/core/src/main/java/com/google/errorprone/bugpatterns/time/PreferJavaTimeOverload.java index aecfab273e2..27398097bcc 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/time/PreferJavaTimeOverload.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/time/PreferJavaTimeOverload.java @@ -212,12 +212,10 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState JODA_DURATION_FACTORY_MATCHERS.entrySet()) { if (entry.getKey().matches(arg0, state)) { String value = null; - if (arg0 instanceof MethodInvocationTree) { - MethodInvocationTree jodaDurationCreation = (MethodInvocationTree) arg0; + if (arg0 instanceof MethodInvocationTree jodaDurationCreation) { value = state.getSourceForNode(jodaDurationCreation.getArguments().get(0)); } - if (arg0 instanceof NewClassTree) { - NewClassTree jodaDurationCreation = (NewClassTree) arg0; + if (arg0 instanceof NewClassTree jodaDurationCreation) { value = state.getSourceForNode(jodaDurationCreation.getArguments().get(0)); } @@ -260,8 +258,7 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState // If the Joda Instant is being constructed inline, then unwrap it. if (JODA_INSTANT_CONSTRUCTOR_MATCHER.matches(arg0, state)) { - if (arg0 instanceof NewClassTree) { - NewClassTree jodaInstantCreation = (NewClassTree) arg0; + if (arg0 instanceof NewClassTree jodaInstantCreation) { String value = state.getSourceForNode(jodaInstantCreation.getArguments().get(0)); fix.replace(arg0, String.format("%s.ofEpochMilli(%s)", qualifiedInstant, value)); return describeMatch(tree, fix.build()); diff --git a/core/src/main/java/com/google/errorprone/refaster/BlockTemplate.java b/core/src/main/java/com/google/errorprone/refaster/BlockTemplate.java index 4fbda65e210..7360864fc55 100644 --- a/core/src/main/java/com/google/errorprone/refaster/BlockTemplate.java +++ b/core/src/main/java/com/google/errorprone/refaster/BlockTemplate.java @@ -95,8 +95,7 @@ public BlockTemplate withStatements(Iterable templateState @Override public Iterable match(JCTree tree, Context context) { // TODO(lowasser): consider nonconsecutive matches? - if (tree instanceof JCBlock) { - JCBlock block = (JCBlock) tree; + if (tree instanceof JCBlock block) { ImmutableList targetStatements = ImmutableList.copyOf(block.getStatements()); return matchesStartingAnywhere(block, 0, targetStatements, context) .first() diff --git a/core/src/main/java/com/google/errorprone/refaster/ExpressionTemplate.java b/core/src/main/java/com/google/errorprone/refaster/ExpressionTemplate.java index dde63b964e8..a42bdf4029e 100644 --- a/core/src/main/java/com/google/errorprone/refaster/ExpressionTemplate.java +++ b/core/src/main/java/com/google/errorprone/refaster/ExpressionTemplate.java @@ -124,8 +124,7 @@ public ExpressionTemplate negation() { /** Returns the matches of this template against the specified target AST. */ @Override public Iterable match(JCTree target, Context context) { - if (target instanceof JCExpression) { - JCExpression targetExpr = (JCExpression) target; + if (target instanceof JCExpression targetExpr) { Optional unifier = unify(targetExpr, new Unifier(context)).first(); if (unifier.isPresent()) { return ImmutableList.of(new ExpressionTemplateMatch(targetExpr, unifier.get())); @@ -263,33 +262,25 @@ private static int getPrecedence(JCTree leaf, Context context) { // a different value than "0L + Integer.MIN_VALUE + Integer.MIN_VALUE" due // to integer promotion rules. - if (parent instanceof JCConditional) { + if (parent instanceof JCConditional conditional) { // This intentionally differs from Pretty, because Pretty appears buggy: // http://mail.openjdk.java.net/pipermail/compiler-dev/2013-September/007303.html - JCConditional conditional = (JCConditional) parent; return TreeInfo.condPrec + ((conditional.cond == leaf) ? 1 : 0); - } else if (parent instanceof JCAssign) { - JCAssign assign = (JCAssign) parent; + } else if (parent instanceof JCAssign assign) { return TreeInfo.assignPrec + ((assign.lhs == leaf) ? 1 : 0); - } else if (parent instanceof JCAssignOp) { - JCAssignOp assignOp = (JCAssignOp) parent; + } else if (parent instanceof JCAssignOp assignOp) { return TreeInfo.assignopPrec + ((assignOp.lhs == leaf) ? 1 : 0); } else if (parent instanceof JCUnary) { return TreeInfo.opPrec(parent.getTag()); - } else if (parent instanceof JCBinary) { - JCBinary binary = (JCBinary) parent; + } else if (parent instanceof JCBinary binary) { return TreeInfo.opPrec(parent.getTag()) + ((binary.rhs == leaf) ? 1 : 0); - } else if (parent instanceof JCTypeCast) { - JCTypeCast typeCast = (JCTypeCast) parent; + } else if (parent instanceof JCTypeCast typeCast) { return (typeCast.expr == leaf) ? TreeInfo.prefixPrec : TreeInfo.noPrec; - } else if (parent instanceof JCInstanceOf) { - JCInstanceOf instanceOf = (JCInstanceOf) parent; + } else if (parent instanceof JCInstanceOf instanceOf) { return TreeInfo.ordPrec + ((instanceOf.getType() == leaf) ? 1 : 0); - } else if (parent instanceof JCArrayAccess) { - JCArrayAccess arrayAccess = (JCArrayAccess) parent; + } else if (parent instanceof JCArrayAccess arrayAccess) { return (arrayAccess.indexed == leaf) ? TreeInfo.postfixPrec : TreeInfo.noPrec; - } else if (parent instanceof JCFieldAccess) { - JCFieldAccess fieldAccess = (JCFieldAccess) parent; + } else if (parent instanceof JCFieldAccess fieldAccess) { return (fieldAccess.selected == leaf) ? TreeInfo.postfixPrec : TreeInfo.noPrec; } else { return TreeInfo.noPrec; diff --git a/core/src/main/java/com/google/errorprone/refaster/Inliner.java b/core/src/main/java/com/google/errorprone/refaster/Inliner.java index 92769196344..de36473bdd8 100644 --- a/core/src/main/java/com/google/errorprone/refaster/Inliner.java +++ b/core/src/main/java/com/google/errorprone/refaster/Inliner.java @@ -187,9 +187,8 @@ public com.sun.tools.javac.util.List inlineList( Iterable> elements) throws CouldNotResolveImportException { ListBuffer result = new ListBuffer<>(); for (Inlineable e : elements) { - if (e instanceof URepeated) { + if (e instanceof URepeated repeated) { // URepeated is bound to a list of expressions. - URepeated repeated = (URepeated) e; for (JCExpression expr : getBinding(repeated.key())) { @SuppressWarnings("unchecked") // URepeated is an Inlineable, so if e is also an Inlineable, diff --git a/core/src/main/java/com/google/errorprone/refaster/PlaceholderVerificationVisitor.java b/core/src/main/java/com/google/errorprone/refaster/PlaceholderVerificationVisitor.java index ff5a3973d9e..fd870ba5c1a 100644 --- a/core/src/main/java/com/google/errorprone/refaster/PlaceholderVerificationVisitor.java +++ b/core/src/main/java/com/google/errorprone/refaster/PlaceholderVerificationVisitor.java @@ -75,8 +75,7 @@ public Boolean scan(Tree node, Unifier unifier) { return true; } } - if (node instanceof JCExpression) { - JCExpression expr = (JCExpression) node; + if (node instanceof JCExpression expr) { for (UFreeIdent.Key key : Iterables.filter(unifier.getBindings().keySet(), UFreeIdent.Key.class)) { JCExpression keyBinding = unifier.getBinding(key); diff --git a/core/src/main/java/com/google/errorprone/refaster/UFreeIdent.java b/core/src/main/java/com/google/errorprone/refaster/UFreeIdent.java index 41228b5bd87..6e91400853d 100644 --- a/core/src/main/java/com/google/errorprone/refaster/UFreeIdent.java +++ b/core/src/main/java/com/google/errorprone/refaster/UFreeIdent.java @@ -70,8 +70,7 @@ public Choice visitIdentifier(IdentifierTree node, Unifier unifier) { @Override protected Choice defaultAction(Tree target, Unifier unifier) { - if (target instanceof JCExpression) { - JCExpression expression = (JCExpression) target; + if (target instanceof JCExpression expression) { JCExpression currentBinding = unifier.getBinding(key()); diff --git a/core/src/main/java/com/google/errorprone/refaster/UIntersectionClassType.java b/core/src/main/java/com/google/errorprone/refaster/UIntersectionClassType.java index 5979acf0346..5d479fe6ad9 100644 --- a/core/src/main/java/com/google/errorprone/refaster/UIntersectionClassType.java +++ b/core/src/main/java/com/google/errorprone/refaster/UIntersectionClassType.java @@ -48,8 +48,7 @@ public IntersectionClassType inline(Inliner inliner) throws CouldNotResolveImpor @Override public Choice visitClassType(ClassType t, Unifier unifier) { - if (t instanceof IntersectionClassType) { - IntersectionClassType intersection = (IntersectionClassType) t; + if (t instanceof IntersectionClassType intersection) { return unifyList(unifier, bounds(), intersection.getComponents()); } return Choice.none(); diff --git a/core/src/main/java/com/google/errorprone/refaster/UTemplater.java b/core/src/main/java/com/google/errorprone/refaster/UTemplater.java index 02c738557d3..49a775b686a 100644 --- a/core/src/main/java/com/google/errorprone/refaster/UTemplater.java +++ b/core/src/main/java/com/google/errorprone/refaster/UTemplater.java @@ -153,8 +153,7 @@ public static Template createTemplate(Context context, MethodTree decl) { UType genericType = templater.template(declSym.type); ImmutableList typeParameters; UMethodType methodType; - if (genericType instanceof UForAll) { - UForAll forAllType = (UForAll) genericType; + if (genericType instanceof UForAll forAllType) { typeParameters = forAllType.getTypeVars(); methodType = (UMethodType) forAllType.getQuantifiedType(); } else if (genericType instanceof UMethodType) { diff --git a/core/src/main/java/com/google/errorprone/refaster/UTypeVar.java b/core/src/main/java/com/google/errorprone/refaster/UTypeVar.java index 1e5fa03c0b1..102d779b23f 100644 --- a/core/src/main/java/com/google/errorprone/refaster/UTypeVar.java +++ b/core/src/main/java/com/google/errorprone/refaster/UTypeVar.java @@ -140,8 +140,7 @@ public int hashCode() { public boolean equals(@Nullable Object obj) { if (this == obj) { return true; - } else if (obj instanceof UTypeVar) { - UTypeVar typeVar = (UTypeVar) obj; + } else if (obj instanceof UTypeVar typeVar) { return name.equals(typeVar.name) && lowerBound.equals(typeVar.lowerBound) && upperBound.equals(typeVar.upperBound); diff --git a/core/src/main/java/com/google/errorprone/refaster/Unifier.java b/core/src/main/java/com/google/errorprone/refaster/Unifier.java index afad0a9939b..8483ba7ccd2 100644 --- a/core/src/main/java/com/google/errorprone/refaster/Unifier.java +++ b/core/src/main/java/com/google/errorprone/refaster/Unifier.java @@ -161,8 +161,7 @@ public static > Choice unifyList( int index; for (index = 0; index < toUnify.size(); index++) { U toUnifyNext = toUnify.get(index); - if (allowVarargs && toUnifyNext instanceof URepeated) { - URepeated repeated = (URepeated) toUnifyNext; + if (allowVarargs && toUnifyNext instanceof URepeated repeated) { int startIndex = index; return choice .condition(index + 1 == toUnify.size()) From 947e77e43b693a2473c668d5f2e3d5bb94e89ebb Mon Sep 17 00:00:00 2001 From: ghm Date: Fri, 15 Nov 2024 08:11:16 -0800 Subject: [PATCH 27/38] Add a check for redundant continue statements. I gave it a suitably generic name in case we generalise in the future. I'm curious about redundant trailing `return;`s from methods! Flume: unknown commit I didn't spot any obvious _bugs_ looking through, though of course it's hard to tell. PiperOrigin-RevId: 696892282 --- .../bugpatterns/RedundantControlFlow.java | 66 +++++++ .../scanner/BuiltInCheckerSuppliers.java | 2 + .../bugpatterns/RedundantControlFlowTest.java | 176 ++++++++++++++++++ docs/bugpattern/RedundantControlFlow.md | 54 ++++++ 4 files changed, 298 insertions(+) create mode 100644 core/src/main/java/com/google/errorprone/bugpatterns/RedundantControlFlow.java create mode 100644 core/src/test/java/com/google/errorprone/bugpatterns/RedundantControlFlowTest.java create mode 100644 docs/bugpattern/RedundantControlFlow.md diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/RedundantControlFlow.java b/core/src/main/java/com/google/errorprone/bugpatterns/RedundantControlFlow.java new file mode 100644 index 00000000000..9bbe0573889 --- /dev/null +++ b/core/src/main/java/com/google/errorprone/bugpatterns/RedundantControlFlow.java @@ -0,0 +1,66 @@ +/* + * Copyright 2024 The Error Prone Authors. + * + * 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.google.errorprone.bugpatterns; + +import static com.google.errorprone.matchers.Description.NO_MATCH; + +import com.google.errorprone.BugPattern; +import com.google.errorprone.BugPattern.SeverityLevel; +import com.google.errorprone.VisitorState; +import com.google.errorprone.bugpatterns.BugChecker.ContinueTreeMatcher; +import com.google.errorprone.fixes.SuggestedFix; +import com.google.errorprone.matchers.Description; +import com.sun.source.tree.BlockTree; +import com.sun.source.tree.ContinueTree; +import com.sun.source.tree.Tree; + +/** A bug checker; see the summary. */ +@BugPattern( + severity = SeverityLevel.WARNING, + summary = "This continue statement is redundant and can be removed. It may be misleading.") +public final class RedundantControlFlow extends BugChecker implements ContinueTreeMatcher { + @Override + public Description matchContinue(ContinueTree tree, VisitorState state) { + if (tree.getLabel() != null) { + return NO_MATCH; + } + Tree last = tree; + for (Tree parent : state.getPath()) { + switch (parent.getKind()) { + case FOR_LOOP: + case ENHANCED_FOR_LOOP: + case WHILE_LOOP: + case DO_WHILE_LOOP: + return describeMatch(tree, SuggestedFix.delete(tree)); + case CASE: + // It's arguable that "break" is clearer than "continue" from a switch if they both have + // the same effect, but it's not what we want to flag here. + return NO_MATCH; + case BLOCK: + var statements = ((BlockTree) parent).getStatements(); + if (statements.indexOf(last) != statements.size() - 1) { + return NO_MATCH; + } + // fall through + default: + // fall out + } + last = parent; + } + return NO_MATCH; + } +} diff --git a/core/src/main/java/com/google/errorprone/scanner/BuiltInCheckerSuppliers.java b/core/src/main/java/com/google/errorprone/scanner/BuiltInCheckerSuppliers.java index 49c549b9d59..7ddf1061ce9 100644 --- a/core/src/main/java/com/google/errorprone/scanner/BuiltInCheckerSuppliers.java +++ b/core/src/main/java/com/google/errorprone/scanner/BuiltInCheckerSuppliers.java @@ -325,6 +325,7 @@ import com.google.errorprone.bugpatterns.RandomCast; import com.google.errorprone.bugpatterns.RandomModInteger; import com.google.errorprone.bugpatterns.ReachabilityFenceUsage; +import com.google.errorprone.bugpatterns.RedundantControlFlow; import com.google.errorprone.bugpatterns.RedundantOverride; import com.google.errorprone.bugpatterns.RedundantSetterCall; import com.google.errorprone.bugpatterns.RedundantThrows; @@ -1061,6 +1062,7 @@ public static ScannerSupplier warningChecks() { ProtoTimestampGetSecondsGetNano.class, QualifierOrScopeOnInjectMethod.class, ReachabilityFenceUsage.class, + RedundantControlFlow.class, ReferenceEquality.class, RethrowReflectiveOperationExceptionAsLinkageError.class, ReturnAtTheEndOfVoidFunction.class, diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/RedundantControlFlowTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/RedundantControlFlowTest.java new file mode 100644 index 00000000000..5df2cac2adf --- /dev/null +++ b/core/src/test/java/com/google/errorprone/bugpatterns/RedundantControlFlowTest.java @@ -0,0 +1,176 @@ +/* + * Copyright 2024 The Error Prone Authors. + * + * 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.google.errorprone.bugpatterns; + +import com.google.errorprone.CompilationTestHelper; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public final class RedundantControlFlowTest { + private final CompilationTestHelper helper = + CompilationTestHelper.newInstance(RedundantControlFlow.class, getClass()); + + @Test + public void onlyStatementInForLoop() { + helper + .addSourceLines( + "Test.java", + """ + class Test { + void test(Iterable xs) { + for (String x : xs) { + // BUG: Diagnostic contains: + continue; + } + } + } + """) + .doTest(); + } + + @Test + public void onlyStatementInTerminalIf() { + helper + .addSourceLines( + "Test.java", + """ + class Test { + void test(Iterable xs) { + for (String x : xs) { + if (x.equals("foo")) { + // BUG: Diagnostic contains: + continue; + } + } + } + } + """) + .doTest(); + } + + @Test + public void onlyStatementInNestedIf() { + helper + .addSourceLines( + "Test.java", + """ + class Test { + void test(Iterable xs) { + for (String x : xs) { + if (x.equals("foo")) { + if (x.equals("bar")) { + // BUG: Diagnostic contains: + continue; + } + } + } + } + } + """) + .doTest(); + } + + @Test + public void onlyStatementInElse() { + helper + .addSourceLines( + "Test.java", + """ + class Test { + void test(Iterable xs) { + for (String x : xs) { + if (x.equals("foo")) { + } else { + // BUG: Diagnostic contains: + continue; + } + } + } + } + """) + .doTest(); + } + + @Test + public void negative() { + helper + .addSourceLines( + "Test.java", + """ + class Test { + String test(Iterable xs) { + for (String x : xs) { + if (x.equals("foo")) { + continue; + } + return x; + } + return null; + } + } + """) + .doTest(); + } + + @Test + public void labelledContinue_noFinding() { + helper + .addSourceLines( + "Test.java", + """ + class Test { + String test(Iterable xs) { + outer: + for (String x : xs) { + for (int i = 0; i < x.length(); i++) { + if (x.charAt(i) == 'a') { + continue outer; + } + } + } + return null; + } + } + """) + .doTest(); + } + + @Test + public void withinNestedIfs_statementsAfter() { + helper + .addSourceLines( + "Test.java", + """ + class Test { + String test(Iterable xs) { + for (String x : xs) { + if (x.equals("foo")) { + if (x.equals("bar")) { + continue; + } + } + return x; + } + return null; + } + } + """) + .doTest(); + } +} diff --git a/docs/bugpattern/RedundantControlFlow.md b/docs/bugpattern/RedundantControlFlow.md new file mode 100644 index 00000000000..8d8343a1bd7 --- /dev/null +++ b/docs/bugpattern/RedundantControlFlow.md @@ -0,0 +1,54 @@ +Unnecessary control flow statements may be misleading in some contexts. + +For instance, this method to find groups of prime order has a bug: + +```java +static ImmutableList filterGroupsOfPrimeOrder(Iterable groups) { + ImmutableList.Builder filtered = ImmutableList.builder(); + for (Group group : groups) { + for (int i = 2; i < group.order(); i++) { + if (group.order() % i == 0) { + continue; + } + } + filtered.add(group); + } + return filtered.build(); +} +``` + +The `continue` statement only breaks out of the innermost loop, so the input is +returned unchanged. + +The most readable alternative is probably to avoid a nested loop entirely: + +```java +static ImmutableList filterGroupsOfPrimeOrder(Iterable groups) { + ImmutableList.Builder filtered = ImmutableList.builder(); + for (Group group : groups) { + if (!isPrime(group.order())) { + continue; + } + filtered.add(group); + } + return filtered.build(); +} +``` + +A labelled break statement would also be correct, but is quite uncommon: + +```java +static ImmutableList filterGroupsOfPrimeOrder(Iterable groups) { + ImmutableList.Builder filtered = ImmutableList.builder(); + outer: + for (Group group : groups) { + for (int i = 2; i < group.order(); i++) { + if (group.order() % i == 0) { + continue outer; + } + } + filtered.add(group); + } + return filtered.build(); +} +``` From ecfc4fcca76a402992667d37dc7ed67caeafca09 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 15 Nov 2024 08:45:14 -0800 Subject: [PATCH 28/38] Remove language level override for type_annotations Now that the default is new enough to support type annotations, overriding it here isn't necessary. PiperOrigin-RevId: 696900786 --- type_annotations/pom.xml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/type_annotations/pom.xml b/type_annotations/pom.xml index 33492170e44..e04034cd3e9 100644 --- a/type_annotations/pom.xml +++ b/type_annotations/pom.xml @@ -43,18 +43,4 @@ http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 17 - 17 - - - - - From c4387562d4ea8a0c9e67bf88046be977997db176 Mon Sep 17 00:00:00 2001 From: markbrady Date: Fri, 15 Nov 2024 08:54:48 -0800 Subject: [PATCH 29/38] StatementSwitchToExpressionSwitch: for "assignment switch" and "direct conversion" transformations, retain comments appearing in the `switch` block before the first `case` PiperOrigin-RevId: 696903291 --- .../StatementSwitchToExpressionSwitch.java | 22 ++++++++++++++----- ...StatementSwitchToExpressionSwitchTest.java | 6 +++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java b/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java index cbe93d3b8b6..20ec1b00bac 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java @@ -544,7 +544,12 @@ private static SuggestedFix convertDirectlyToExpressionSwitch( String transformedBlockSource = transformBlock(caseTree, state, filteredStatements); if (firstCaseInGroup) { - groupedCaseCommentsAccumulator = new StringBuilder(); + groupedCaseCommentsAccumulator = + new StringBuilder( + caseIndex == 0 + ? extractCommentsBeforeFirstCase(switchTree, allSwitchComments).orElse("") + : ""); + replacementCodeBuilder.append("\n "); if (!isDefaultCase) { replacementCodeBuilder.append("case "); @@ -663,10 +668,10 @@ private static SuggestedFix convertToReturnSwitch( if (firstCaseInGroup) { groupedCaseCommentsAccumulator = - caseIndex == 0 - ? new StringBuilder( - extractCommentsBeforeFirstCase(switchTree, allSwitchComments).orElse("")) - : new StringBuilder(); + new StringBuilder( + caseIndex == 0 + ? extractCommentsBeforeFirstCase(switchTree, allSwitchComments).orElse("") + : ""); replacementCodeBuilder.append("\n "); if (!isDefaultCase) { @@ -831,7 +836,12 @@ private static SuggestedFix convertToAssignmentSwitch( transformAssignOrThrowBlock(caseTree, state, filteredStatements); if (firstCaseInGroup) { - groupedCaseCommentsAccumulator = new StringBuilder(); + groupedCaseCommentsAccumulator = + new StringBuilder( + caseIndex == 0 + ? extractCommentsBeforeFirstCase(switchTree, allSwitchComments).orElse("") + : ""); + replacementCodeBuilder.append("\n "); if (!isDefaultCase) { replacementCodeBuilder.append("case "); diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java index 357b46452b4..92e3c2bb662 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java @@ -154,6 +154,7 @@ public Test(int foo) {} public void foo(Side side) { // BUG: Diagnostic contains: [StatementSwitchToExpressionSwitch] switch (side) { + // Comment before first case case OBVERSE: // Explanatory comment System.out.println("this block cannot complete normally"); @@ -185,6 +186,7 @@ public Test(int foo) {} public void foo(Side side) { switch (side) { + // Comment before first case case OBVERSE: // Explanatory comment System.out.println("this block cannot complete normally"); @@ -211,6 +213,7 @@ public Test(int foo) {} public void foo(Side side) { switch (side) { case OBVERSE -> { + // Comment before first case // Explanatory comment System.out.println("this block cannot complete normally"); { @@ -3304,6 +3307,7 @@ public Test(int foo) { public int foo(Side side) { // BUG: Diagnostic contains: [StatementSwitchToExpressionSwitch] switch (side) { + /* Comment before first case */ case /* LHS comment */ HEART: // Inline comment x <<= 2; @@ -3347,6 +3351,7 @@ public Test(int foo) { public int foo(Side side) { switch (side) { + /* Comment before first case */ case /* LHS comment */ HEART: // Inline comment this.x <<= 2; @@ -3384,6 +3389,7 @@ public int foo(Side side) { this.x <<= switch (side) { case HEART -> + /* Comment before first case */ /* LHS comment */ // Inline comment 2; From 37895d36873032d16eb26b35389930b927d5f199 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 15 Nov 2024 08:57:07 -0800 Subject: [PATCH 30/38] Fix snapshot doc publishing after https://github.com/google/error-prone/commit/f1308a004e113b70958358e6baea118f41a0ea5c ``` rsync: [sender] change_dir "/home/runner/work/error-prone/error-prone/target/site/apidocs" failed: No such file or directory (2) rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1338) [sender=3.2.7] ``` https://github.com/google/error-prone/actions/runs/11855327714/job/33039721727 PiperOrigin-RevId: 696903927 --- util/generate-latest-docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/generate-latest-docs.sh b/util/generate-latest-docs.sh index 78f28efd320..9e3f872d550 100755 --- a/util/generate-latest-docs.sh +++ b/util/generate-latest-docs.sh @@ -28,7 +28,7 @@ git clone --quiet --branch=gh-pages https://x-access-token:${GITHUB_TOKEN}@githu ) mvn -P '!examples' javadoc:aggregate -rsync -a target/site/apidocs/ ${GH_PAGES_DIR}/api/latest +rsync -a target/reports/apidocs/ ${GH_PAGES_DIR}/api/latest # The "mvn clean" is necessary since the wiki docs are generated by an # annotation processor that also compiles the code. If Maven thinks the code From 2afd0cf070aaac862ce38e9785cd7e04f6130563 Mon Sep 17 00:00:00 2001 From: ghm Date: Fri, 15 Nov 2024 09:34:23 -0800 Subject: [PATCH 31/38] Run StatementSwitchToExpressionSwitch_refactoring over EP. PiperOrigin-RevId: 696913777 --- .../errorprone/BugPatternValidator.java | 9 +- .../BaseErrorProneJavaCompiler.java | 27 ++-- .../com/google/errorprone/BugCheckerInfo.java | 17 +- .../google/errorprone/ErrorProneAnalyzer.java | 9 +- .../google/errorprone/ErrorProneOptions.java | 44 ++---- .../google/errorprone/ImportOrderParser.java | 22 +-- .../JavacErrorDescriptionListener.java | 25 ++- .../com/google/errorprone/VisitorState.java | 34 ++-- .../google/errorprone/apply/SourceFile.java | 23 ++- .../errorprone/bugpatterns/BugChecker.java | 41 +++-- .../nullnesspropagation/Nullness.java | 17 +- .../NullnessAnnotations.java | 18 +-- .../inference/ProperInferenceVar.java | 17 +- .../errorprone/fixes/SuggestedFixes.java | 68 ++++---- .../matchers/ChildMultiMatcher.java | 14 +- .../google/errorprone/matchers/Matchers.java | 40 +++-- .../matchers/method/BaseMethodMatcher.java | 8 +- .../method/MethodInvocationMatcher.java | 47 +++--- .../errorprone/scanner/ScannerSupplier.java | 16 +- .../google/errorprone/util/ASTHelpers.java | 123 +++++++-------- .../com/google/errorprone/util/Comments.java | 17 +- .../errorprone/util/ErrorProneComment.java | 20 +-- .../errorprone/util/FindIdentifiers.java | 95 ++++++------ .../errorprone/util/MoreAnnotations.java | 52 +++---- .../errorprone/util/OperatorPrecedence.java | 82 ++++------ .../errorprone/util/SideEffectAnalysis.java | 12 +- .../errorprone/util/ASTHelpersTest.java | 53 +++---- .../AbstractMustBeClosedChecker.java | 56 ++++--- .../AbstractReferenceEquality.java | 7 +- .../bugpatterns/AbstractToString.java | 11 +- .../bugpatterns/AnnotationPosition.java | 15 +- .../bugpatterns/AssertionFailureIgnored.java | 9 +- .../bugpatterns/AttemptedNegativeZero.java | 11 +- .../errorprone/bugpatterns/BadImport.java | 14 +- .../BoxedPrimitiveConstructor.java | 74 ++++----- .../bugpatterns/CanBeStaticAnalyzer.java | 23 ++- .../bugpatterns/CanonicalDuration.java | 6 +- .../bugpatterns/CheckReturnValue.java | 55 +++---- .../bugpatterns/ClassCanBeStatic.java | 14 +- .../ComparisonContractViolated.java | 12 +- .../bugpatterns/ComparisonOutOfRange.java | 27 ++-- .../bugpatterns/ComplexBooleanConstant.java | 22 ++- .../errorprone/bugpatterns/ConstantField.java | 11 +- .../bugpatterns/ConstantOverflow.java | 145 +++++++----------- .../bugpatterns/ConstantPatternCompile.java | 13 +- .../bugpatterns/DefaultCharset.java | 11 +- .../bugpatterns/DeprecatedVariable.java | 7 +- .../DiscardedPostfixExpression.java | 7 +- .../errorprone/bugpatterns/EqualsNaN.java | 11 +- .../bugpatterns/ExpectedExceptionChecker.java | 15 +- .../errorprone/bugpatterns/Finally.java | 17 +- .../errorprone/bugpatterns/FloatCast.java | 17 +- .../FloatingPointLiteralPrecision.java | 20 +-- .../bugpatterns/ForEachIterable.java | 8 +- .../bugpatterns/IdentityBinaryExpression.java | 26 ++-- .../bugpatterns/IdentityHashMapBoxing.java | 13 +- .../ImplementAssertionWithChaining.java | 18 +-- .../errorprone/bugpatterns/IntLongMath.java | 20 +-- .../errorprone/bugpatterns/JdkObsolete.java | 20 ++- .../bugpatterns/LabelledBreakTarget.java | 9 +- .../bugpatterns/LoopConditionChecker.java | 16 +- .../bugpatterns/MethodCanBeStatic.java | 14 +- .../ModifyCollectionInEnhancedForLoop.java | 22 ++- .../bugpatterns/MultipleTopLevelClasses.java | 10 +- .../NarrowingCompoundAssignment.java | 103 +++++-------- .../bugpatterns/NoAllocationChecker.java | 10 +- .../bugpatterns/NonCanonicalType.java | 15 +- .../bugpatterns/NonFinalStaticField.java | 13 +- .../bugpatterns/NonRuntimeAnnotation.java | 7 +- .../PrivateConstructorForUtilityClass.java | 20 ++- .../ProtoStringFieldReferenceEquality.java | 7 +- .../bugpatterns/ReachabilityFenceUsage.java | 11 +- .../bugpatterns/ShortCircuitBoolean.java | 7 +- .../SizeGreaterThanOrEqualsZero.java | 11 +- .../StaticQualifiedUsingExpression.java | 9 +- .../bugpatterns/StringSplitter.java | 9 +- .../errorprone/bugpatterns/StronglyType.java | 14 +- .../bugpatterns/SystemConsoleNull.java | 7 +- .../bugpatterns/ThreeLetterTimeZoneID.java | 12 +- .../bugpatterns/ToStringReturnsNull.java | 14 +- .../bugpatterns/TruthAssertExpected.java | 14 +- .../bugpatterns/TruthGetOrDefault.java | 68 ++++---- .../bugpatterns/TypeParameterNaming.java | 10 +- .../bugpatterns/TypeParameterShadowing.java | 10 +- .../TypeParameterUnusedInFormals.java | 7 +- .../UnicodeDirectionalityCharacters.java | 30 ++-- .../bugpatterns/UnnecessaryAsync.java | 42 ++--- .../bugpatterns/UnnecessaryParentheses.java | 15 +- .../bugpatterns/UnnecessaryStringBuilder.java | 10 +- .../UnsynchronizedOverridesSynchronized.java | 13 +- .../bugpatterns/UnusedAnonymousClass.java | 18 +-- .../bugpatterns/UnusedVariable.java | 31 ++-- .../errorprone/bugpatterns/VarChecker.java | 14 +- .../bugpatterns/WildcardImport.java | 19 ++- .../errorprone/bugpatterns/XorPower.java | 18 +-- .../errorprone/bugpatterns/YodaCondition.java | 58 +++---- .../bugpatterns/apidiff/ApiDiff.java | 11 +- .../bugpatterns/apidiff/ApiDiffChecker.java | 10 +- .../AssertEqualsArgumentOrderChecker.java | 7 +- .../NameInCommentHeuristic.java | 17 +- .../NamedParameterComment.java | 7 +- .../argumentselectiondefects/Parameter.java | 18 ++- .../bugpatterns/checkreturnvalue/Api.java | 89 ++++++----- .../CollectionIncompatibleType.java | 26 ++-- .../bugpatterns/flogger/FloggerHelpers.java | 23 ++- .../formatstring/FormatStringValidation.java | 40 ++--- .../bugpatterns/inject/dagger/UseBinds.java | 15 +- .../inlineme/InlinabilityResult.java | 11 +- .../bugpatterns/javadoc/InvalidInlineTag.java | 13 +- .../nullness/EqualsBrokenForNull.java | 14 +- .../nullness/NullablePrimitiveArray.java | 8 +- .../nullness/NullableWildcard.java | 12 +- .../bugpatterns/nullness/NullnessUtils.java | 66 ++++---- .../nullness/ParameterMissingNullable.java | 11 +- .../threadsafety/ConstantExpressions.java | 26 ++-- .../threadsafety/DoubleCheckedLocking.java | 28 ++-- .../threadsafety/GuardedByBinder.java | 55 +++---- .../threadsafety/GuardedByExpression.java | 40 ++--- .../threadsafety/HeldLockAnalyzer.java | 15 +- .../threadsafety/ImmutableChecker.java | 9 +- .../threadsafety/StaticGuardedByInstance.java | 11 +- .../threadsafety/ThreadSafeChecker.java | 6 +- .../threadsafety/ThreadSafety.java | 22 +-- .../time/JavaTimeDefaultTimeZone.java | 22 ++- .../bugpatterns/time/NearbyCallers.java | 18 +-- .../time/TimeUnitConversionChecker.java | 56 +++---- .../bugpatterns/time/TimeUnitMismatch.java | 91 ++++++----- .../google/errorprone/refaster/Choice.java | 34 ++-- .../refaster/ControlFlowVisitor.java | 33 ++-- .../errorprone/refaster/UInstanceOf.java | 12 +- .../google/errorprone/refaster/ULiteral.java | 14 +- .../refaster/UPlaceholderStatement.java | 13 +- .../errorprone/refaster/UPrimitiveType.java | 37 ++--- .../errorprone/refaster/UTemplater.java | 13 +- .../errorprone/fixes/SuggestedFixesTest.java | 10 +- 135 files changed, 1423 insertions(+), 1942 deletions(-) diff --git a/annotation/src/main/java/com/google/errorprone/BugPatternValidator.java b/annotation/src/main/java/com/google/errorprone/BugPatternValidator.java index c73b3db1f98..6759496503c 100644 --- a/annotation/src/main/java/com/google/errorprone/BugPatternValidator.java +++ b/annotation/src/main/java/com/google/errorprone/BugPatternValidator.java @@ -37,17 +37,16 @@ public static void validate(BugPattern pattern) throws ValidationException { // linkType must be consistent with link element. switch (pattern.linkType()) { - case CUSTOM: + case CUSTOM -> { if (pattern.link().isEmpty()) { throw new ValidationException("Expected a custom link but none was provided"); } - break; - case AUTOGENERATED: - case NONE: + } + case AUTOGENERATED, NONE -> { if (!pattern.link().isEmpty()) { throw new ValidationException("Expected no custom link but found: " + pattern.link()); } - break; + } } } diff --git a/check_api/src/main/java/com/google/errorprone/BaseErrorProneJavaCompiler.java b/check_api/src/main/java/com/google/errorprone/BaseErrorProneJavaCompiler.java index 9515aa0ebca..04e37912164 100644 --- a/check_api/src/main/java/com/google/errorprone/BaseErrorProneJavaCompiler.java +++ b/check_api/src/main/java/com/google/errorprone/BaseErrorProneJavaCompiler.java @@ -139,14 +139,11 @@ private static ImmutableList defaultToLatestSupportedLanguageLevel( String overrideLanguageLevel; switch (JAVA_SPECIFICATION_VERSION.value()) { - case "1.7": - overrideLanguageLevel = "7"; - break; - case "1.8": - overrideLanguageLevel = "8"; - break; - default: + case "1.7" -> overrideLanguageLevel = "7"; + case "1.8" -> overrideLanguageLevel = "8"; + default -> { return args; + } } return ImmutableList.builder() @@ -169,15 +166,13 @@ static void checkCompilePolicy(@Nullable String compilePolicy) { + " pass -XDcompilePolicy=simple instead"); } switch (compilePolicy) { - case "byfile": - case "simple": - break; - default: - throw new InvalidCommandLineOptionException( - String.format( - "-XDcompilePolicy=%s is not supported by Error Prone," - + " pass -XDcompilePolicy=simple instead", - compilePolicy)); + case "byfile", "simple" -> {} + default -> + throw new InvalidCommandLineOptionException( + String.format( + "-XDcompilePolicy=%s is not supported by Error Prone," + + " pass -XDcompilePolicy=simple instead", + compilePolicy)); } } diff --git a/check_api/src/main/java/com/google/errorprone/BugCheckerInfo.java b/check_api/src/main/java/com/google/errorprone/BugCheckerInfo.java index ada95ca6c06..837037243de 100644 --- a/check_api/src/main/java/com/google/errorprone/BugCheckerInfo.java +++ b/check_api/src/main/java/com/google/errorprone/BugCheckerInfo.java @@ -173,22 +173,19 @@ public BugCheckerInfo withCustomDefaultSeverity(SeverityLevel defaultSeverity) { } private static @Nullable String createLinkUrl(String canonicalName, BugPattern pattern) { - switch (pattern.linkType()) { - case AUTOGENERATED: - return String.format("https://errorprone.info/bugpattern/%s", canonicalName); - case CUSTOM: + return switch (pattern.linkType()) { + case AUTOGENERATED -> String.format("https://errorprone.info/bugpattern/%s", canonicalName); + case CUSTOM -> { // annotation.link() must be provided. if (pattern.link().isEmpty()) { throw new IllegalStateException( "If linkType element of @BugPattern is CUSTOM, " + "a link element must also be provided."); } - return pattern.link(); - case NONE: - return null; - } - throw new AssertionError( - "Unexpected value for linkType element of @BugPattern: " + pattern.linkType()); + yield pattern.link(); + } + case NONE -> null; + }; } public String canonicalName() { diff --git a/check_api/src/main/java/com/google/errorprone/ErrorProneAnalyzer.java b/check_api/src/main/java/com/google/errorprone/ErrorProneAnalyzer.java index 589542587e8..1c04f3d1191 100644 --- a/check_api/src/main/java/com/google/errorprone/ErrorProneAnalyzer.java +++ b/check_api/src/main/java/com/google/errorprone/ErrorProneAnalyzer.java @@ -272,10 +272,11 @@ private boolean finishedCompilation(CompilationUnitTree tree) { OUTER: for (Tree decl : tree.getTypeDecls()) { switch (decl.getKind()) { - case EMPTY_STATEMENT: + case EMPTY_STATEMENT -> { // ignore ";" at the top level, which counts as an empty type decl continue OUTER; - case IMPORT: + } + case IMPORT -> { // The spec disallows mixing imports and empty top-level declarations (";"), but // javac has a bug that causes it to accept empty declarations interspersed with imports: // http://mail.openjdk.java.net/pipermail/compiler-dev/2013-August/006968.html @@ -283,8 +284,8 @@ private boolean finishedCompilation(CompilationUnitTree tree) { // Any import declarations after the first semi are incorrectly added to the list // of type declarations, so we have to skip over them here. continue OUTER; - default: - break; + } + default -> {} } if (!seen.contains(decl)) { return false; diff --git a/check_api/src/main/java/com/google/errorprone/ErrorProneOptions.java b/check_api/src/main/java/com/google/errorprone/ErrorProneOptions.java index d91852f6bc9..91e0f5c38d4 100644 --- a/check_api/src/main/java/com/google/errorprone/ErrorProneOptions.java +++ b/check_api/src/main/java/com/google/errorprone/ErrorProneOptions.java @@ -411,37 +411,18 @@ public static ErrorProneOptions processArgs(Iterable args) { Builder builder = new Builder(); for (String arg : args) { switch (arg) { - case IGNORE_SUPPRESSION_ANNOTATIONS: - builder.setIgnoreSuppressionAnnotations(true); - break; - case IGNORE_UNKNOWN_CHECKS_FLAG: - builder.setIgnoreUnknownChecks(true); - break; - case DISABLE_WARNINGS_IN_GENERATED_CODE_FLAG: - builder.setDisableWarningsInGeneratedCode(true); - break; - case ERRORS_AS_WARNINGS_FLAG: - builder.setDropErrorsToWarnings(true); - break; - case SUGGESTIONS_AS_WARNINGS_FLAG: - builder.setSuggestionsAsWarnings(true); - break; - case ENABLE_ALL_CHECKS: - builder.setEnableAllChecksAsWarnings(true); - break; - case DISABLE_ALL_CHECKS: - builder.setDisableAllChecks(true); - break; - case COMPILING_TEST_ONLY_CODE: - builder.setTestOnlyTarget(true); - break; - case COMPILING_PUBLICLY_VISIBLE_CODE: - builder.setPubliclyVisibleTarget(true); - break; - case DISABLE_ALL_WARNINGS: - builder.setDisableAllWarnings(true); - break; - default: + case IGNORE_SUPPRESSION_ANNOTATIONS -> builder.setIgnoreSuppressionAnnotations(true); + case IGNORE_UNKNOWN_CHECKS_FLAG -> builder.setIgnoreUnknownChecks(true); + case DISABLE_WARNINGS_IN_GENERATED_CODE_FLAG -> + builder.setDisableWarningsInGeneratedCode(true); + case ERRORS_AS_WARNINGS_FLAG -> builder.setDropErrorsToWarnings(true); + case SUGGESTIONS_AS_WARNINGS_FLAG -> builder.setSuggestionsAsWarnings(true); + case ENABLE_ALL_CHECKS -> builder.setEnableAllChecksAsWarnings(true); + case DISABLE_ALL_CHECKS -> builder.setDisableAllChecks(true); + case COMPILING_TEST_ONLY_CODE -> builder.setTestOnlyTarget(true); + case COMPILING_PUBLICLY_VISIBLE_CODE -> builder.setPubliclyVisibleTarget(true); + case DISABLE_ALL_WARNINGS -> builder.setDisableAllWarnings(true); + default -> { if (arg.startsWith(SEVERITY_PREFIX)) { builder.parseSeverity(arg); } else if (arg.startsWith(ErrorProneFlags.PREFIX)) { @@ -494,6 +475,7 @@ public static ErrorProneOptions processArgs(Iterable args) { } remainingArgs.add(arg); } + } } } diff --git a/check_api/src/main/java/com/google/errorprone/ImportOrderParser.java b/check_api/src/main/java/com/google/errorprone/ImportOrderParser.java index 064bb690e4b..6b46e06874f 100644 --- a/check_api/src/main/java/com/google/errorprone/ImportOrderParser.java +++ b/check_api/src/main/java/com/google/errorprone/ImportOrderParser.java @@ -27,20 +27,14 @@ public final class ImportOrderParser { * @return the {@link ImportOrganizer} */ public static ImportOrganizer getImportOrganizer(String importOrder) { - switch (importOrder) { - case "static-first": - return ImportOrganizer.STATIC_FIRST_ORGANIZER; - case "static-last": - return ImportOrganizer.STATIC_LAST_ORGANIZER; - case "android-static-first": - return ImportOrganizer.ANDROID_STATIC_FIRST_ORGANIZER; - case "android-static-last": - return ImportOrganizer.ANDROID_STATIC_LAST_ORGANIZER; - case "idea": - return ImportOrganizer.IDEA_ORGANIZER; - default: - throw new IllegalStateException("Unknown import order: '" + importOrder + "'"); - } + return switch (importOrder) { + case "static-first" -> ImportOrganizer.STATIC_FIRST_ORGANIZER; + case "static-last" -> ImportOrganizer.STATIC_LAST_ORGANIZER; + case "android-static-first" -> ImportOrganizer.ANDROID_STATIC_FIRST_ORGANIZER; + case "android-static-last" -> ImportOrganizer.ANDROID_STATIC_LAST_ORGANIZER; + case "idea" -> ImportOrganizer.IDEA_ORGANIZER; + default -> throw new IllegalStateException("Unknown import order: '" + importOrder + "'"); + }; } private ImportOrderParser() {} diff --git a/check_api/src/main/java/com/google/errorprone/JavacErrorDescriptionListener.java b/check_api/src/main/java/com/google/errorprone/JavacErrorDescriptionListener.java index 2e80455cc51..8cbbe8203b6 100644 --- a/check_api/src/main/java/com/google/errorprone/JavacErrorDescriptionListener.java +++ b/check_api/src/main/java/com/google/errorprone/JavacErrorDescriptionListener.java @@ -111,23 +111,16 @@ public void onDescribed(Description description) { JavaFileObject originalSource = log.useSource(sourceFile); try { JCDiagnostic.Factory factory = JCDiagnostic.Factory.instance(context); - JCDiagnostic.DiagnosticType type = JCDiagnostic.DiagnosticType.ERROR; DiagnosticPosition pos = description.position; - switch (description.severity()) { - case ERROR: - if (dontUseErrors) { - type = JCDiagnostic.DiagnosticType.WARNING; - } else { - type = JCDiagnostic.DiagnosticType.ERROR; - } - break; - case WARNING: - type = JCDiagnostic.DiagnosticType.WARNING; - break; - case SUGGESTION: - type = JCDiagnostic.DiagnosticType.NOTE; - break; - } + JCDiagnostic.DiagnosticType type = + switch (description.severity()) { + case ERROR -> + dontUseErrors + ? JCDiagnostic.DiagnosticType.WARNING + : JCDiagnostic.DiagnosticType.ERROR; + case WARNING -> JCDiagnostic.DiagnosticType.WARNING; + case SUGGESTION -> JCDiagnostic.DiagnosticType.NOTE; + }; log.report( factory.create( type, diff --git a/check_api/src/main/java/com/google/errorprone/VisitorState.java b/check_api/src/main/java/com/google/errorprone/VisitorState.java index 1139bdc9c7a..95c6eb70a0f 100644 --- a/check_api/src/main/java/com/google/errorprone/VisitorState.java +++ b/check_api/src/main/java/com/google/errorprone/VisitorState.java @@ -627,28 +627,18 @@ private static void validateTypeStr(String typeStr) { * the corresponding Type, or null otherwise. */ private @Nullable Type getPrimitiveOrVoidType(String typeStr) { - switch (typeStr) { - case "byte": - return getSymtab().byteType; - case "short": - return getSymtab().shortType; - case "int": - return getSymtab().intType; - case "long": - return getSymtab().longType; - case "float": - return getSymtab().floatType; - case "double": - return getSymtab().doubleType; - case "boolean": - return getSymtab().booleanType; - case "char": - return getSymtab().charType; - case "void": - return getSymtab().voidType; - default: - return null; - } + return switch (typeStr) { + case "byte" -> getSymtab().byteType; + case "short" -> getSymtab().shortType; + case "int" -> getSymtab().intType; + case "long" -> getSymtab().longType; + case "float" -> getSymtab().floatType; + case "double" -> getSymtab().doubleType; + case "boolean" -> getSymtab().booleanType; + case "char" -> getSymtab().charType; + case "void" -> getSymtab().voidType; + default -> null; + }; } /** Returns true if the compilation is targeting Android. */ diff --git a/check_api/src/main/java/com/google/errorprone/apply/SourceFile.java b/check_api/src/main/java/com/google/errorprone/apply/SourceFile.java index b5a6d69dd0e..995361af7d7 100644 --- a/check_api/src/main/java/com/google/errorprone/apply/SourceFile.java +++ b/check_api/src/main/java/com/google/errorprone/apply/SourceFile.java @@ -168,19 +168,18 @@ public void replaceChars(int startPosition, int endPosition, String replacement) void makeReplacements(Replacements changes) { ImmutableSet replacements = changes.ascending(); switch (replacements.size()) { - case 0: + case 0 -> { return; - case 1: - { - Replacement onlyReplacement = Iterables.getOnlyElement(replacements); - replaceChars( - onlyReplacement.startPosition(), - onlyReplacement.endPosition(), - onlyReplacement.replaceWith()); - return; - } - default: - break; + } + case 1 -> { + Replacement onlyReplacement = Iterables.getOnlyElement(replacements); + replaceChars( + onlyReplacement.startPosition(), + onlyReplacement.endPosition(), + onlyReplacement.replaceWith()); + return; + } + default -> {} } // Since we have many replacements to make all at once, it's better to start off with a clean diff --git a/check_api/src/main/java/com/google/errorprone/bugpatterns/BugChecker.java b/check_api/src/main/java/com/google/errorprone/bugpatterns/BugChecker.java index 0fdae63adb7..234cbda71fa 100644 --- a/check_api/src/main/java/com/google/errorprone/bugpatterns/BugChecker.java +++ b/check_api/src/main/java/com/google/errorprone/bugpatterns/BugChecker.java @@ -134,28 +134,25 @@ public BugChecker() { private static BiPredicate, VisitorState> suppressionPredicate( Set> suppressionClasses) { - switch (suppressionClasses.size()) { - case 0: - return (annos, state) -> false; - case 1: - { - Supplier self = - VisitorState.memoize( - state -> state.getName(Iterables.getOnlyElement(suppressionClasses).getName())); - return (annos, state) -> annos.contains(self.get(state)); - } - default: - { - Supplier> self = - VisitorState.memoize( - state -> - suppressionClasses.stream() - .map(Class::getName) - .map(state::getName) - .collect(toImmutableSet())); - return (annos, state) -> !Collections.disjoint(self.get(state), annos); - } - } + return switch (suppressionClasses.size()) { + case 0 -> (annos, state) -> false; + case 1 -> { + Supplier self = + VisitorState.memoize( + state -> state.getName(Iterables.getOnlyElement(suppressionClasses).getName())); + yield (annos, state) -> annos.contains(self.get(state)); + } + default -> { + Supplier> self = + VisitorState.memoize( + state -> + suppressionClasses.stream() + .map(Class::getName) + .map(state::getName) + .collect(toImmutableSet())); + yield (annos, state) -> !Collections.disjoint(self.get(state), annos); + } + }; } /** Helper to create a Description for the common case where there is a fix. */ diff --git a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/Nullness.java b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/Nullness.java index 4d4132ca484..7b7eb138998 100644 --- a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/Nullness.java +++ b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/Nullness.java @@ -104,17 +104,12 @@ public Nullness greatestLowerBound(Nullness other) { * get the set of all values, or {@code NULLABLE}. */ public Nullness deducedValueWhenNotEqual() { - switch (this) { - case NULLABLE: - case NONNULL: - return NULLABLE; - case NULL: - return NONNULL; - case BOTTOM: - return BOTTOM; - default: - throw new AssertionError("Inverse of " + this + " not defined"); - } + return switch (this) { + case NULLABLE, NONNULL -> NULLABLE; + case NULL -> NONNULL; + case BOTTOM -> BOTTOM; + default -> throw new AssertionError("Inverse of " + this + " not defined"); + }; } @Override diff --git a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessAnnotations.java b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessAnnotations.java index 0abee170320..342b059a729 100644 --- a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessAnnotations.java +++ b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessAnnotations.java @@ -122,18 +122,12 @@ public static Optional fromAnnotationsOn(@Nullable Symbol sym) { * (b/203207989). To reduce the chance that we hit the inner-class bug, we apply it only if the * first approach fails. */ - TypeMirror elementType; - switch (sym.getKind()) { - case METHOD: - elementType = ((ExecutableElement) sym).getReturnType(); - break; - case FIELD: - case PARAMETER: - elementType = sym.asType(); - break; - default: - elementType = null; - } + TypeMirror elementType = + switch (sym.getKind()) { + case METHOD -> ((ExecutableElement) sym).getReturnType(); + case FIELD, PARAMETER -> sym.asType(); + default -> null; + }; Optional fromElement = fromAnnotationsOn(elementType); if (fromElement.isPresent()) { return fromElement; diff --git a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/inference/ProperInferenceVar.java b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/inference/ProperInferenceVar.java index 849e4a46994..a1923e2742c 100644 --- a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/inference/ProperInferenceVar.java +++ b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/inference/ProperInferenceVar.java @@ -51,16 +51,11 @@ Nullness nullness() { abstract Nullness nullness(); static InferenceVariable create(Nullness nullness) { - switch (nullness) { - case BOTTOM: - return ProperInferenceVar.BOTTOM; - case NONNULL: - return ProperInferenceVar.NONNULL; - case NULL: - return ProperInferenceVar.NULL; - case NULLABLE: - return ProperInferenceVar.NULLABLE; - } - throw new RuntimeException("Unhandled nullness value: " + nullness); + return switch (nullness) { + case BOTTOM -> ProperInferenceVar.BOTTOM; + case NONNULL -> ProperInferenceVar.NONNULL; + case NULL -> ProperInferenceVar.NULL; + case NULLABLE -> ProperInferenceVar.NULLABLE; + }; } } diff --git a/check_api/src/main/java/com/google/errorprone/fixes/SuggestedFixes.java b/check_api/src/main/java/com/google/errorprone/fixes/SuggestedFixes.java index 8f394c4cb2b..7f13a755211 100644 --- a/check_api/src/main/java/com/google/errorprone/fixes/SuggestedFixes.java +++ b/check_api/src/main/java/com/google/errorprone/fixes/SuggestedFixes.java @@ -152,34 +152,21 @@ public final class SuggestedFixes { /** Parse a modifier token into a {@link Modifier}. */ private static @Nullable Modifier getTokModifierKind(ErrorProneToken tok) { - switch (tok.kind()) { - case PUBLIC: - return Modifier.PUBLIC; - case PROTECTED: - return Modifier.PROTECTED; - case PRIVATE: - return Modifier.PRIVATE; - case ABSTRACT: - return Modifier.ABSTRACT; - case STATIC: - return Modifier.STATIC; - case FINAL: - return Modifier.FINAL; - case TRANSIENT: - return Modifier.TRANSIENT; - case VOLATILE: - return Modifier.VOLATILE; - case SYNCHRONIZED: - return Modifier.SYNCHRONIZED; - case NATIVE: - return Modifier.NATIVE; - case STRICTFP: - return Modifier.STRICTFP; - case DEFAULT: - return Modifier.DEFAULT; - default: - return null; - } + return switch (tok.kind()) { + case PUBLIC -> Modifier.PUBLIC; + case PROTECTED -> Modifier.PROTECTED; + case PRIVATE -> Modifier.PRIVATE; + case ABSTRACT -> Modifier.ABSTRACT; + case STATIC -> Modifier.STATIC; + case FINAL -> Modifier.FINAL; + case TRANSIENT -> Modifier.TRANSIENT; + case VOLATILE -> Modifier.VOLATILE; + case SYNCHRONIZED -> Modifier.SYNCHRONIZED; + case NATIVE -> Modifier.NATIVE; + case STRICTFP -> Modifier.STRICTFP; + case DEFAULT -> Modifier.DEFAULT; + default -> null; + }; } /** Adds modifiers to the given class, method, or field declaration. */ @@ -1329,18 +1316,19 @@ private static boolean compilesWithFix( boolean diagnosticInSameCompilationUnit = diagnosticSource == null || diagnosticSource.toUri().equals(modifiedFileUri); switch (diagnostic.getKind()) { - case ERROR: + case ERROR -> { ++countErrors; if (!onlyInSameCompilationUnit || diagnosticInSameCompilationUnit) { return false; } - break; - case WARNING: + } + case WARNING -> { ++countWarnings; warningInSameCompilationUnit |= diagnosticInSameCompilationUnit; - break; - default: + } + default -> { continue; + } } if ((warningIsError && warningInSameCompilationUnit) @@ -1625,15 +1613,11 @@ private static ImmutableSet supportedTreeTypes(Element exemptingAnnot ImmutableSet.Builder types = ImmutableSet.builder(); for (ElementType t : targetAnnotation.value()) { switch (t) { - case TYPE: - types.add( - Tree.Kind.CLASS, Tree.Kind.ENUM, Tree.Kind.INTERFACE, Tree.Kind.ANNOTATION_TYPE); - break; - case METHOD: - types.add(Tree.Kind.METHOD); - break; - default: - break; + case TYPE -> + types.add( + Tree.Kind.CLASS, Tree.Kind.ENUM, Tree.Kind.INTERFACE, Tree.Kind.ANNOTATION_TYPE); + case METHOD -> types.add(Tree.Kind.METHOD); + default -> {} } } return types.build(); diff --git a/check_api/src/main/java/com/google/errorprone/matchers/ChildMultiMatcher.java b/check_api/src/main/java/com/google/errorprone/matchers/ChildMultiMatcher.java index 878a2921783..7c7de461251 100644 --- a/check_api/src/main/java/com/google/errorprone/matchers/ChildMultiMatcher.java +++ b/check_api/src/main/java/com/google/errorprone/matchers/ChildMultiMatcher.java @@ -99,15 +99,11 @@ private abstract static class ListMatcher { abstract MatchResult matches(List> matchables, Matcher nodeMatcher); public static ListMatcher create(MatchType matchType) { - switch (matchType) { - case ALL: - return new AllMatcher<>(); - case AT_LEAST_ONE: - return new AtLeastOneMatcher<>(); - case LAST: - return new LastMatcher<>(); - } - throw new AssertionError("Unexpected match type: " + matchType); + return switch (matchType) { + case ALL -> new AllMatcher<>(); + case AT_LEAST_ONE -> new AtLeastOneMatcher<>(); + case LAST -> new LastMatcher<>(); + }; } } diff --git a/check_api/src/main/java/com/google/errorprone/matchers/Matchers.java b/check_api/src/main/java/com/google/errorprone/matchers/Matchers.java index 915244d4fc1..96e8c37777b 100644 --- a/check_api/src/main/java/com/google/errorprone/matchers/Matchers.java +++ b/check_api/src/main/java/com/google/errorprone/matchers/Matchers.java @@ -584,21 +584,18 @@ public static Matcher nullLiteral() { /** Matches an AST node if it is a literal other than null. */ public static Matcher nonNullLiteral() { return (tree, state) -> { - switch (tree.getKind()) { - case MEMBER_SELECT: - return ((MemberSelectTree) tree).getIdentifier().contentEquals("class"); - case INT_LITERAL: - case LONG_LITERAL: - case FLOAT_LITERAL: - case DOUBLE_LITERAL: - case BOOLEAN_LITERAL: - case CHAR_LITERAL: - // fall through - case STRING_LITERAL: - return true; - default: - return false; - } + return switch (tree.getKind()) { + case MEMBER_SELECT -> ((MemberSelectTree) tree).getIdentifier().contentEquals("class"); + case INT_LITERAL, + LONG_LITERAL, + FLOAT_LITERAL, + DOUBLE_LITERAL, + BOOLEAN_LITERAL, + CHAR_LITERAL, + STRING_LITERAL -> + true; + default -> false; + }; }; } @@ -1191,16 +1188,15 @@ public static Matcher inLoop() { while (path != null) { Tree node = path.getLeaf(); switch (node.getKind()) { - case METHOD: - case CLASS: + case METHOD, CLASS -> { return false; - case WHILE_LOOP: - case FOR_LOOP: - case ENHANCED_FOR_LOOP: - case DO_WHILE_LOOP: + } + case WHILE_LOOP, FOR_LOOP, ENHANCED_FOR_LOOP, DO_WHILE_LOOP -> { return true; - default: + } + default -> { // continue below + } } path = path.getParentPath(); } diff --git a/check_api/src/main/java/com/google/errorprone/matchers/method/BaseMethodMatcher.java b/check_api/src/main/java/com/google/errorprone/matchers/method/BaseMethodMatcher.java index b1a356ff056..fa9bd44766e 100644 --- a/check_api/src/main/java/com/google/errorprone/matchers/method/BaseMethodMatcher.java +++ b/check_api/src/main/java/com/google/errorprone/matchers/method/BaseMethodMatcher.java @@ -45,12 +45,10 @@ interface BaseMethodMatcher { BaseMethodMatcher CONSTRUCTOR = tree -> { switch (tree.getKind()) { - case NEW_CLASS: - case METHOD_INVOCATION: - case MEMBER_REFERENCE: - break; - default: + case NEW_CLASS, METHOD_INVOCATION, MEMBER_REFERENCE -> {} + default -> { return null; + } } Symbol sym = ASTHelpers.getSymbol(tree); if (!(sym instanceof MethodSymbol)) { diff --git a/check_api/src/main/java/com/google/errorprone/matchers/method/MethodInvocationMatcher.java b/check_api/src/main/java/com/google/errorprone/matchers/method/MethodInvocationMatcher.java index 927c633864e..7def290342b 100644 --- a/check_api/src/main/java/com/google/errorprone/matchers/method/MethodInvocationMatcher.java +++ b/check_api/src/main/java/com/google/errorprone/matchers/method/MethodInvocationMatcher.java @@ -379,30 +379,31 @@ private static BiPredicate traverse( entry.getKey().comparisonKey(), traverse(mappings, mappings.get(entry.getValue()))); } - switch (type) { - case RECEIVER_SUPERTYPE: - return (ctx, state) -> { - Type receiverType = (Type) TokenType.RECEIVER_SUPERTYPE.extract(ctx, state); - // Have to iterate here because subclassing can't be checked by lookup. - for (Map.Entry> child : lookup.entrySet()) { - if (ASTHelpers.isSubtype( - receiverType, state.getTypeFromString((String) child.getKey()), state)) { - return child.getValue().test(ctx, state); + return switch (type) { + case RECEIVER_SUPERTYPE -> + (ctx, state) -> { + Type receiverType = (Type) TokenType.RECEIVER_SUPERTYPE.extract(ctx, state); + // Have to iterate here because subclassing can't be checked by lookup. + for (Map.Entry> child : + lookup.entrySet()) { + if (ASTHelpers.isSubtype( + receiverType, state.getTypeFromString((String) child.getKey()), state)) { + return child.getValue().test(ctx, state); + } } - } - return defaultBehavior.test(ctx, state); - }; - default: - return (ctx, state) -> { - // All other token types can be checked via a map lookup. - Object lookupKey = type.extract(ctx, state); - BiPredicate child = lookup.get(lookupKey); - if (child != null) { - return child.test(ctx, state); - } - return defaultBehavior.test(ctx, state); - }; - } + return defaultBehavior.test(ctx, state); + }; + default -> + (ctx, state) -> { + // All other token types can be checked via a map lookup. + Object lookupKey = type.extract(ctx, state); + BiPredicate child = lookup.get(lookupKey); + if (child != null) { + return child.test(ctx, state); + } + return defaultBehavior.test(ctx, state); + }; + }; } } diff --git a/check_api/src/main/java/com/google/errorprone/scanner/ScannerSupplier.java b/check_api/src/main/java/com/google/errorprone/scanner/ScannerSupplier.java index 35eee823f0a..92167d27b85 100644 --- a/check_api/src/main/java/com/google/errorprone/scanner/ScannerSupplier.java +++ b/check_api/src/main/java/com/google/errorprone/scanner/ScannerSupplier.java @@ -202,19 +202,19 @@ public ScannerSupplier applyOverrides(ErrorProneOptions errorProneOptions) { } for (BugCheckerInfo check : checksByAltName.get(checkName)) { switch (newSeverity) { - case OFF: + case OFF -> { if (!check.disableable()) { throw new InvalidCommandLineOptionException( check.canonicalName() + " may not be disabled"); } severities.remove(check.canonicalName()); disabled.add(check.canonicalName()); - break; - case DEFAULT: + } + case DEFAULT -> { severities.put(check.canonicalName(), check.defaultSeverity()); disabled.remove(check.canonicalName()); - break; - case WARN: + } + case WARN -> { // Demoting an enabled check from an error to a warning is a form of disabling if (!disabled().contains(check.canonicalName()) && !check.disableable() @@ -225,11 +225,11 @@ public ScannerSupplier applyOverrides(ErrorProneOptions errorProneOptions) { } severities.put(check.canonicalName(), SeverityLevel.WARNING); disabled.remove(check.canonicalName()); - break; - case ERROR: + } + case ERROR -> { severities.put(check.canonicalName(), SeverityLevel.ERROR); disabled.remove(check.canonicalName()); - break; + } } } }); diff --git a/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java b/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java index ee5af5f2673..57a9b94b5e8 100644 --- a/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java +++ b/check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java @@ -364,20 +364,24 @@ public static boolean isEffectivelyPrivate(Symbol symbol) { /** Checks whether an expression requires parentheses. */ public static boolean requiresParentheses(ExpressionTree expression, VisitorState state) { switch (expression.getKind()) { - case IDENTIFIER: - case MEMBER_SELECT: - case METHOD_INVOCATION: - case ARRAY_ACCESS: - case PARENTHESIZED: - case NEW_CLASS: - case MEMBER_REFERENCE: + case IDENTIFIER, + MEMBER_SELECT, + METHOD_INVOCATION, + ARRAY_ACCESS, + PARENTHESIZED, + NEW_CLASS, + MEMBER_REFERENCE -> { return false; - case LAMBDA_EXPRESSION: + } + case LAMBDA_EXPRESSION -> { // Parenthesizing e.g. `x -> (y -> z)` is unnecessary but helpful Tree parent = state.getPath().getParentPath().getLeaf(); return parent.getKind().equals(Kind.LAMBDA_EXPRESSION) && stripParentheses(((LambdaExpressionTree) parent).getBody()).equals(expression); - default: // continue below + } + default -> { + // continue below + } } if (expression instanceof LiteralTree) { if (!isSameType(getType(expression), state.getSymtab().stringType, state)) { @@ -446,12 +450,13 @@ public static Stream enclosingElements(Symbol sym) { public static @Nullable MethodTree findEnclosingMethod(VisitorState state) { for (Tree parent : state.getPath()) { switch (parent.getKind()) { - case METHOD: + case METHOD -> { return (MethodTree) parent; - case CLASS: - case LAMBDA_EXPRESSION: + } + case CLASS, LAMBDA_EXPRESSION -> { return null; - default: // fall out + } + default -> {} } } return null; @@ -1650,14 +1655,11 @@ private static Stream generatedValues(Attribute.Compound attribute) { } public static boolean isSuper(Tree tree) { - switch (tree.getKind()) { - case IDENTIFIER: - return ((IdentifierTree) tree).getName().contentEquals("super"); - case MEMBER_SELECT: - return ((MemberSelectTree) tree).getIdentifier().contentEquals("super"); - default: - return false; - } + return switch (tree.getKind()) { + case IDENTIFIER -> ((IdentifierTree) tree).getName().contentEquals("super"); + case MEMBER_SELECT -> ((MemberSelectTree) tree).getIdentifier().contentEquals("super"); + default -> false; + }; } /** @@ -1708,19 +1710,11 @@ static TargetType create(Type type, TreePath path) { */ private static @Nullable Type unaryNumericPromotion(Type type, VisitorState state) { Type unboxed = unboxAndEnsureNumeric(type, state); - switch (unboxed.getTag()) { - case BYTE: - case SHORT: - case CHAR: - return state.getSymtab().intType; - case INT: - case LONG: - case FLOAT: - case DOUBLE: - return unboxed; - default: - throw new AssertionError("Should not reach here: " + type); - } + return switch (unboxed.getTag()) { + case BYTE, SHORT, CHAR -> state.getSymtab().intType; + case INT, LONG, FLOAT, DOUBLE -> unboxed; + default -> throw new AssertionError("Should not reach here: " + type); + }; } /** @@ -1816,30 +1810,32 @@ private static boolean canHaveTargetType(Tree tree) { return false; } switch (tree.getKind()) { - case IDENTIFIER: - case MEMBER_SELECT: + case IDENTIFIER, MEMBER_SELECT -> { if (!(ASTHelpers.getSymbol(tree) instanceof VarSymbol)) { // If we're selecting other than a member (e.g. a type or a method) then this doesn't // have a target type. return false; } - break; - case PRIMITIVE_TYPE: - case ARRAY_TYPE: - case PARAMETERIZED_TYPE: - case EXTENDS_WILDCARD: - case SUPER_WILDCARD: - case UNBOUNDED_WILDCARD: - case ANNOTATED_TYPE: - case INTERSECTION_TYPE: - case TYPE_ANNOTATION: + } + case PRIMITIVE_TYPE, + ARRAY_TYPE, + PARAMETERIZED_TYPE, + EXTENDS_WILDCARD, + SUPER_WILDCARD, + UNBOUNDED_WILDCARD, + ANNOTATED_TYPE, + INTERSECTION_TYPE, + TYPE_ANNOTATION -> { // These are all things that only appear in type uses, so they can't have a target type. return false; - case ANNOTATION: + } + case ANNOTATION -> { // Annotations can only appear on elements which don't have target types. return false; - default: + } + default -> { // Continue. + } } return true; } @@ -1925,22 +1921,21 @@ public Type visitClass(ClassTree node, Void unused) { Type expressionType = getType(tree.getExpression()); Types types = state.getTypes(); switch (tree.getKind()) { - case LEFT_SHIFT_ASSIGNMENT: - case RIGHT_SHIFT_ASSIGNMENT: - case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT: + case LEFT_SHIFT_ASSIGNMENT, RIGHT_SHIFT_ASSIGNMENT, UNSIGNED_RIGHT_SHIFT_ASSIGNMENT -> { // Shift operators perform *unary* numeric promotion on the operands, separately. if (tree.getExpression().equals(current)) { return unaryNumericPromotion(expressionType, state); } - break; - case PLUS_ASSIGNMENT: + } + case PLUS_ASSIGNMENT -> { Type stringType = state.getSymtab().stringType; if (types.isSuperType(variableType, stringType)) { return stringType; } - break; - default: + } + default -> { // Fall though. + } } // If we've got to here, we can only have boolean or numeric operands // (because the only compound assignment operator for String is +=). @@ -1993,11 +1988,13 @@ public Type visitParenthesized(ParenthesizedTree node, Void unused) { for (TreePath path = parent; path != null; path = path.getParentPath()) { Tree enclosing = path.getLeaf(); switch (enclosing.getKind()) { - case METHOD: + case METHOD -> { return getType(((MethodTree) enclosing).getReturnType()); - case LAMBDA_EXPRESSION: + } + case LAMBDA_EXPRESSION -> { return visitLambdaExpression((LambdaExpressionTree) enclosing, null); - default: // fall out + } + default -> {} } } throw new AssertionError("return not enclosed by method or lambda"); @@ -2492,12 +2489,10 @@ public static boolean isLocal(Symbol symbol) { /** Returns true if the symbol is static. Returns {@code false} for module symbols. */ public static boolean isStatic(Symbol symbol) { - switch (symbol.getKind()) { - case MODULE: - return false; - default: - return symbol.isStatic(); - } + return switch (symbol.getKind()) { + case MODULE -> false; + default -> symbol.isStatic(); + }; } /** diff --git a/check_api/src/main/java/com/google/errorprone/util/Comments.java b/check_api/src/main/java/com/google/errorprone/util/Comments.java index f7527516281..d06f1a017e0 100644 --- a/check_api/src/main/java/com/google/errorprone/util/Comments.java +++ b/check_api/src/main/java/com/google/errorprone/util/Comments.java @@ -91,17 +91,12 @@ public static ImmutableList> findCommentsForArguments( *

TODO(andrewrice) Update this method to handle block comments properly if we find the need */ public static String getTextFromComment(ErrorProneComment comment) { - switch (comment.getStyle()) { - case BLOCK: - return comment.getText().replaceAll("^\\s*/\\*\\s*(.*?)\\s*\\*/\\s*", "$1"); - case LINE: - return comment.getText().replaceAll("^\\s*//\\s*", ""); - case JAVADOC_LINE: - return comment.getText().replaceAll("^\\s*///\\s*", ""); - case JAVADOC_BLOCK: - return comment.getText().replaceAll("^\\s*/\\*\\*\\s*(.*?)\\s*\\*/\\s*", "$1"); - } - throw new AssertionError(comment.getStyle()); + return switch (comment.getStyle()) { + case BLOCK -> comment.getText().replaceAll("^\\s*/\\*\\s*(.*?)\\s*\\*/\\s*", "$1"); + case LINE -> comment.getText().replaceAll("^\\s*//\\s*", ""); + case JAVADOC_LINE -> comment.getText().replaceAll("^\\s*///\\s*", ""); + case JAVADOC_BLOCK -> comment.getText().replaceAll("^\\s*/\\*\\*\\s*(.*?)\\s*\\*/\\s*", "$1"); + }; } private static ImmutableList> findCommentsForArguments( diff --git a/check_api/src/main/java/com/google/errorprone/util/ErrorProneComment.java b/check_api/src/main/java/com/google/errorprone/util/ErrorProneComment.java index 28de1b2ca42..642b8e3ac2b 100644 --- a/check_api/src/main/java/com/google/errorprone/util/ErrorProneComment.java +++ b/check_api/src/main/java/com/google/errorprone/util/ErrorProneComment.java @@ -76,19 +76,13 @@ public enum ErrorProneCommentStyle { JAVADOC_BLOCK; static ErrorProneCommentStyle from(CommentStyle style) { - switch (style.name()) { - case "LINE": - return ErrorProneCommentStyle.LINE; - case "BLOCK": - return ErrorProneCommentStyle.BLOCK; - case "JAVADOC_LINE": - return ErrorProneCommentStyle.JAVADOC_LINE; - case "JAVADOC": - case "JAVADOC_BLOCK": - return ErrorProneCommentStyle.JAVADOC_BLOCK; - default: - throw new AssertionError(style); - } + return switch (style.name()) { + case "LINE" -> ErrorProneCommentStyle.LINE; + case "BLOCK" -> ErrorProneCommentStyle.BLOCK; + case "JAVADOC_LINE" -> ErrorProneCommentStyle.JAVADOC_LINE; + case "JAVADOC", "JAVADOC_BLOCK" -> ErrorProneCommentStyle.JAVADOC_BLOCK; + default -> throw new AssertionError(style); + }; } } diff --git a/check_api/src/main/java/com/google/errorprone/util/FindIdentifiers.java b/check_api/src/main/java/com/google/errorprone/util/FindIdentifiers.java index 98b1cee86f4..dc00e7c1fac 100644 --- a/check_api/src/main/java/com/google/errorprone/util/FindIdentifiers.java +++ b/check_api/src/main/java/com/google/errorprone/util/FindIdentifiers.java @@ -160,31 +160,26 @@ public static ImmutableSet findAllIdents(VisitorState state) { Tree prev = state.getPath().getLeaf(); for (Tree curr : state.getPath().getParentPath()) { switch (curr.getKind()) { - case BLOCK: + case BLOCK -> { for (StatementTree stmt : ((BlockTree) curr).getStatements()) { if (stmt.equals(prev)) { break; } addIfVariable(stmt, result); } - break; - case LAMBDA_EXPRESSION: + } + case LAMBDA_EXPRESSION -> { for (VariableTree param : ((LambdaExpressionTree) curr).getParameters()) { result.add(ASTHelpers.getSymbol(param)); } - break; - case METHOD: + } + case METHOD -> { for (VariableTree param : ((MethodTree) curr).getParameters()) { result.add(ASTHelpers.getSymbol(param)); } - break; - case CATCH: - result.add(ASTHelpers.getSymbol(((CatchTree) curr).getParameter())); - break; - case CLASS: - case INTERFACE: - case ENUM: - case ANNOTATION_TYPE: + } + case CATCH -> result.add(ASTHelpers.getSymbol(((CatchTree) curr).getParameter())); + case CLASS, INTERFACE, ENUM, ANNOTATION_TYPE -> { // Collect fields declared in this class. If we are in a field initializer, only // include fields declared before this one. JLS 8.3.3 allows forward references if the // field is referred to by qualified name, but we don't support that. @@ -210,14 +205,11 @@ public static ImmutableSet findAllIdents(VisitorState state) { } result.addAll(varsList.build().reverse()); } - break; - case FOR_LOOP: - addAllIfVariable(((ForLoopTree) curr).getInitializer(), result); - break; - case ENHANCED_FOR_LOOP: - result.add(ASTHelpers.getSymbol(((EnhancedForLoopTree) curr).getVariable())); - break; - case TRY: + } + case FOR_LOOP -> addAllIfVariable(((ForLoopTree) curr).getInitializer(), result); + case ENHANCED_FOR_LOOP -> + result.add(ASTHelpers.getSymbol(((EnhancedForLoopTree) curr).getVariable())); + case TRY -> { TryTree tryTree = (TryTree) curr; boolean inResources = false; for (Tree resource : tryTree.getResources()) { @@ -238,8 +230,8 @@ public static ImmutableSet findAllIdents(VisitorState state) { // Case 2: We're in the block (not a catch or finally) addAllIfVariable(tryTree.getResources(), result); } - break; - case COMPILATION_UNIT: + } + case COMPILATION_UNIT -> { for (ImportTree importTree : ((CompilationUnitTree) curr).getImports()) { if (importTree.isStatic() && importTree.getQualifiedIdentifier().getKind() == Kind.MEMBER_SELECT) { @@ -262,10 +254,10 @@ public static ImmutableSet findAllIdents(VisitorState state) { } } } - break; - default: + } + default -> { // other node types don't introduce variables - break; + } } prev = curr; @@ -287,7 +279,7 @@ public static ImmutableSet findUnusedIdentifiers(VisitorState state) for (Tree curr : state.getPath().getParentPath()) { createFindIdentifiersScanner(usedSymbols, prev).scan(curr, null); switch (curr.getKind()) { - case BLOCK: + case BLOCK -> { // If we see a block then walk over each statement to see if it defines a variable for (StatementTree statement : ((BlockTree) curr).getStatements()) { if (statement.equals(prev)) { @@ -297,17 +289,16 @@ public static ImmutableSet findUnusedIdentifiers(VisitorState state) } addIfVariable(statement, definedVariables); } - break; - case FOR_LOOP: + } + case FOR_LOOP -> { ForLoopTree forLoop = (ForLoopTree) curr; forLoop.getInitializer().stream().forEach(t -> addIfVariable(t, definedVariables)); - break; - case ENHANCED_FOR_LOOP: + } + case ENHANCED_FOR_LOOP -> { EnhancedForLoopTree enhancedFor = (EnhancedForLoopTree) curr; addIfVariable(enhancedFor.getVariable(), definedVariables); - break; - default: - break; + } + default -> {} } prev = curr; } @@ -384,8 +375,7 @@ public Void visitIdentifier(IdentifierTree identifierTree, Void unused) { private static boolean isVisible(VarSymbol var, TreePath path) { switch (var.getKind()) { - case ENUM_CONSTANT: - case FIELD: + case ENUM_CONSTANT, FIELD -> { ImmutableList enclosingClasses = StreamSupport.stream(path.spliterator(), false) .filter(ClassTree.class::isInstance) @@ -431,8 +421,8 @@ private static boolean isVisible(VarSymbol var, TreePath path) { // that the only enum constants and fields usable by simple name are either defined // in the enclosing class or a superclass). return modifiers.contains(Modifier.PUBLIC) || modifiers.contains(Modifier.PROTECTED); - case PARAMETER: - case LOCAL_VARIABLE: + } + case PARAMETER, LOCAL_VARIABLE -> { // If we are in an anonymous inner class, lambda, or local class, any local variable or // method parameter we access that is defined outside the anonymous class/lambda must be // final or effectively final (JLS 8.1.3). @@ -449,11 +439,11 @@ private static boolean isVisible(VarSymbol var, TreePath path) { } } return true; - case EXCEPTION_PARAMETER: - case RESOURCE_VARIABLE: + } + case EXCEPTION_PARAMETER, RESOURCE_VARIABLE -> { return true; - default: - throw new IllegalArgumentException("Unexpected variable type: " + var.getKind()); + } + default -> throw new IllegalArgumentException("Unexpected variable type: " + var.getKind()); } } @@ -468,30 +458,33 @@ private static boolean inStaticContext(TreePath path) { for (Tree tree : path) { switch (tree.getKind()) { - case METHOD: + case METHOD -> { return isStatic(ASTHelpers.getSymbol(tree)); - case BLOCK: // static initializer + } + case BLOCK -> { + // static initializer if (((BlockTree) tree).isStatic()) { return true; } - break; - case VARIABLE: // variable initializer of static variable + } + case VARIABLE -> { + // variable initializer of static variable VariableTree variableTree = (VariableTree) tree; VarSymbol variableSym = ASTHelpers.getSymbol(variableTree); if (variableSym.getKind() == ElementKind.FIELD) { return Objects.equals(variableTree.getInitializer(), prev) && variableSym.isStatic(); } - break; - case METHOD_INVOCATION: // JLS 8.8.7.1 explicit constructor invocation + } + case METHOD_INVOCATION -> { + // JLS 8.8.7.1 explicit constructor invocation MethodSymbol methodSym = ASTHelpers.getSymbol((MethodInvocationTree) tree); if (methodSym.isConstructor() && (Objects.equals(methodSym.owner, enclosingClass) || Objects.equals(methodSym.owner, directSuperClass))) { return true; } - break; - default: - break; + } + default -> {} } prev = tree; } diff --git a/check_api/src/main/java/com/google/errorprone/util/MoreAnnotations.java b/check_api/src/main/java/com/google/errorprone/util/MoreAnnotations.java index 6e3d2695ee5..437ba19ad59 100644 --- a/check_api/src/main/java/com/google/errorprone/util/MoreAnnotations.java +++ b/check_api/src/main/java/com/google/errorprone/util/MoreAnnotations.java @@ -82,14 +82,11 @@ public static Stream getDeclarationAndTypeAttributes(Symbol sym) { * annotations won't be included when the symbol is not in the current compilation. */ public static Stream getTopLevelTypeAttributes(Symbol sym) { - Symbol typeAnnotationOwner; - switch (sym.getKind()) { - case PARAMETER: - typeAnnotationOwner = sym.owner; - break; - default: - typeAnnotationOwner = sym; - } + Symbol typeAnnotationOwner = + switch (sym.getKind()) { + case PARAMETER -> sym.owner; + default -> sym; + }; return typeAnnotationOwner.getRawTypeAttributes().stream() .filter(anno -> isAnnotationOnType(sym, anno.position)); } @@ -102,15 +99,11 @@ private static boolean isAnnotationOnType(Symbol sym, TypeAnnotationPosition pos if (!targetTypeMatches(sym, position)) { return false; } - Type type; - switch (sym.getKind()) { - case METHOD: - case CONSTRUCTOR: - type = ((MethodSymbol) sym).getReturnType(); - break; - default: - type = sym.asType(); - } + Type type = + switch (sym.getKind()) { + case METHOD, CONSTRUCTOR -> ((MethodSymbol) sym).getReturnType(); + default -> sym.asType(); + }; return isAnnotationOnType(type, position.location); } @@ -128,16 +121,17 @@ private static boolean isAnnotationOnType( private static boolean targetTypeMatches(Symbol sym, TypeAnnotationPosition position) { switch (sym.getKind()) { - case LOCAL_VARIABLE: + case LOCAL_VARIABLE -> { return position.type == TargetType.LOCAL_VARIABLE; - case FIELD: - // treated like a field - case ENUM_CONSTANT: + } + case FIELD, ENUM_CONSTANT -> { + // treated like a field return position.type == TargetType.FIELD; - case CONSTRUCTOR: - case METHOD: + } + case CONSTRUCTOR, METHOD -> { return position.type == TargetType.METHOD_RETURN; - case PARAMETER: + } + case PARAMETER -> { switch (position.type) { case METHOD_FORMAL_PARAMETER: int parameterIndex = position.parameter_index; @@ -153,13 +147,15 @@ private static boolean targetTypeMatches(Symbol sym, TypeAnnotationPosition posi default: return false; } - case CLASS: + } + case CLASS -> { // There are no type annotations on the top-level type of the class being declared, only // on other types in the signature (e.g. `class Foo extends Bar<@A Baz> {}`). return false; - default: - throw new AssertionError( - "unsupported element kind in MoreAnnotation#isAnnotationOnType: " + sym.getKind()); + } + default -> + throw new AssertionError( + "unsupported element kind in MoreAnnotation#isAnnotationOnType: " + sym.getKind()); } } diff --git a/check_api/src/main/java/com/google/errorprone/util/OperatorPrecedence.java b/check_api/src/main/java/com/google/errorprone/util/OperatorPrecedence.java index 3b65d2d962e..482f4855f5a 100644 --- a/check_api/src/main/java/com/google/errorprone/util/OperatorPrecedence.java +++ b/check_api/src/main/java/com/google/errorprone/util/OperatorPrecedence.java @@ -50,58 +50,34 @@ public boolean isHigher(OperatorPrecedence other) { } public static OperatorPrecedence from(Tree.Kind kind) { - switch (kind) { - case POSTFIX_DECREMENT: - case POSTFIX_INCREMENT: - return OperatorPrecedence.POSTFIX; - case PREFIX_DECREMENT: - case PREFIX_INCREMENT: - return OperatorPrecedence.UNARY; - case MULTIPLY: - case DIVIDE: - case REMAINDER: - return OperatorPrecedence.MULTIPLICATIVE; - case PLUS: - case MINUS: - return OperatorPrecedence.ADDITIVE; - case RIGHT_SHIFT: - case UNSIGNED_RIGHT_SHIFT: - case LEFT_SHIFT: - return OperatorPrecedence.SHIFT; - case LESS_THAN: - case LESS_THAN_EQUAL: - case GREATER_THAN: - case GREATER_THAN_EQUAL: - case INSTANCE_OF: - return OperatorPrecedence.RELATIONAL; - case EQUAL_TO: - case NOT_EQUAL_TO: - return OperatorPrecedence.EQUALITY; - case AND: - return OperatorPrecedence.AND; - case XOR: - return OperatorPrecedence.XOR; - case OR: - return OperatorPrecedence.OR; - case CONDITIONAL_AND: - return OperatorPrecedence.CONDITIONAL_AND; - case CONDITIONAL_OR: - return OperatorPrecedence.CONDITIONAL_OR; - case ASSIGNMENT: - case MULTIPLY_ASSIGNMENT: - case DIVIDE_ASSIGNMENT: - case REMAINDER_ASSIGNMENT: - case PLUS_ASSIGNMENT: - case MINUS_ASSIGNMENT: - case LEFT_SHIFT_ASSIGNMENT: - case AND_ASSIGNMENT: - case XOR_ASSIGNMENT: - case OR_ASSIGNMENT: - case RIGHT_SHIFT_ASSIGNMENT: - case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT: - return OperatorPrecedence.ASSIGNMENT; - default: - throw new IllegalArgumentException("Unexpected operator kind: " + kind); - } + return switch (kind) { + case POSTFIX_DECREMENT, POSTFIX_INCREMENT -> OperatorPrecedence.POSTFIX; + case PREFIX_DECREMENT, PREFIX_INCREMENT -> OperatorPrecedence.UNARY; + case MULTIPLY, DIVIDE, REMAINDER -> OperatorPrecedence.MULTIPLICATIVE; + case PLUS, MINUS -> OperatorPrecedence.ADDITIVE; + case RIGHT_SHIFT, UNSIGNED_RIGHT_SHIFT, LEFT_SHIFT -> OperatorPrecedence.SHIFT; + case LESS_THAN, LESS_THAN_EQUAL, GREATER_THAN, GREATER_THAN_EQUAL, INSTANCE_OF -> + OperatorPrecedence.RELATIONAL; + case EQUAL_TO, NOT_EQUAL_TO -> OperatorPrecedence.EQUALITY; + case AND -> OperatorPrecedence.AND; + case XOR -> OperatorPrecedence.XOR; + case OR -> OperatorPrecedence.OR; + case CONDITIONAL_AND -> OperatorPrecedence.CONDITIONAL_AND; + case CONDITIONAL_OR -> OperatorPrecedence.CONDITIONAL_OR; + case ASSIGNMENT, + MULTIPLY_ASSIGNMENT, + DIVIDE_ASSIGNMENT, + REMAINDER_ASSIGNMENT, + PLUS_ASSIGNMENT, + MINUS_ASSIGNMENT, + LEFT_SHIFT_ASSIGNMENT, + AND_ASSIGNMENT, + XOR_ASSIGNMENT, + OR_ASSIGNMENT, + RIGHT_SHIFT_ASSIGNMENT, + UNSIGNED_RIGHT_SHIFT_ASSIGNMENT -> + OperatorPrecedence.ASSIGNMENT; + default -> throw new IllegalArgumentException("Unexpected operator kind: " + kind); + }; } } diff --git a/check_api/src/main/java/com/google/errorprone/util/SideEffectAnalysis.java b/check_api/src/main/java/com/google/errorprone/util/SideEffectAnalysis.java index b2e658fd64a..dba9767b1ee 100644 --- a/check_api/src/main/java/com/google/errorprone/util/SideEffectAnalysis.java +++ b/check_api/src/main/java/com/google/errorprone/util/SideEffectAnalysis.java @@ -83,15 +83,9 @@ public Void visitNewClass(NewClassTree tree, Void unused) { public Void visitUnary(UnaryTree tree, Void unused) { JCUnary unary = (JCUnary) tree; switch (unary.getKind()) { - case PREFIX_DECREMENT: - case PREFIX_INCREMENT: - case POSTFIX_DECREMENT: - case POSTFIX_INCREMENT: - hasSideEffect = true; - break; - - default: - break; + case PREFIX_DECREMENT, PREFIX_INCREMENT, POSTFIX_DECREMENT, POSTFIX_INCREMENT -> + hasSideEffect = true; + default -> {} } return super.visitUnary(tree, null); } diff --git a/check_api/src/test/java/com/google/errorprone/util/ASTHelpersTest.java b/check_api/src/test/java/com/google/errorprone/util/ASTHelpersTest.java index ff4dd6c2aad..699c56524f3 100644 --- a/check_api/src/test/java/com/google/errorprone/util/ASTHelpersTest.java +++ b/check_api/src/test/java/com/google/errorprone/util/ASTHelpersTest.java @@ -1812,21 +1812,15 @@ public void test() {} public void typesWithModifiersTree() { for (Class clazz : ALL_TREE_TYPES) { switch (clazz.getSimpleName()) { - case "MethodTree": - assertGetModifiersInvoked(MethodTree.class, MethodTree::getModifiers); - break; - case "ClassTree": - assertGetModifiersInvoked(ClassTree.class, ClassTree::getModifiers); - break; - case "VariableTree": - assertGetModifiersInvoked(VariableTree.class, VariableTree::getModifiers); - break; - case "ModifiersTree": + case "MethodTree" -> assertGetModifiersInvoked(MethodTree.class, MethodTree::getModifiers); + case "ClassTree" -> assertGetModifiersInvoked(ClassTree.class, ClassTree::getModifiers); + case "VariableTree" -> + assertGetModifiersInvoked(VariableTree.class, VariableTree::getModifiers); + case "ModifiersTree" -> { ModifiersTree modifiersTree = mock(ModifiersTree.class); assertThat(ASTHelpers.getModifiers(modifiersTree)).isSameInstanceAs(modifiersTree); - break; - default: - assertMethodNotFound(clazz, "getModifiers"); + } + default -> assertMethodNotFound(clazz, "getModifiers"); } } } @@ -1844,26 +1838,19 @@ private static void assertGetModifiersInvoked( public void typesWithGetAnnotations() { for (Class clazz : ALL_TREE_TYPES) { switch (clazz.getSimpleName()) { - case "TypeParameterTree": - assertGetAnnotationsInvoked(TypeParameterTree.class, TypeParameterTree::getAnnotations); - break; - case "ModuleTree": - assertGetAnnotationsInvoked(ModuleTree.class, ModuleTree::getAnnotations); - break; - case "PackageTree": - assertGetAnnotationsInvoked(PackageTree.class, PackageTree::getAnnotations); - break; - case "NewArrayTree": - assertGetAnnotationsInvoked(NewArrayTree.class, NewArrayTree::getAnnotations); - break; - case "ModifiersTree": - assertGetAnnotationsInvoked(ModifiersTree.class, ModifiersTree::getAnnotations); - break; - case "AnnotatedTypeTree": - assertGetAnnotationsInvoked(AnnotatedTypeTree.class, AnnotatedTypeTree::getAnnotations); - break; - default: - assertMethodNotFound(clazz, "getAnnotations"); + case "TypeParameterTree" -> + assertGetAnnotationsInvoked(TypeParameterTree.class, TypeParameterTree::getAnnotations); + case "ModuleTree" -> + assertGetAnnotationsInvoked(ModuleTree.class, ModuleTree::getAnnotations); + case "PackageTree" -> + assertGetAnnotationsInvoked(PackageTree.class, PackageTree::getAnnotations); + case "NewArrayTree" -> + assertGetAnnotationsInvoked(NewArrayTree.class, NewArrayTree::getAnnotations); + case "ModifiersTree" -> + assertGetAnnotationsInvoked(ModifiersTree.class, ModifiersTree::getAnnotations); + case "AnnotatedTypeTree" -> + assertGetAnnotationsInvoked(AnnotatedTypeTree.class, AnnotatedTypeTree::getAnnotations); + default -> assertMethodNotFound(clazz, "getAnnotations"); } } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AbstractMustBeClosedChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/AbstractMustBeClosedChecker.java index f94e659cb6d..783bd07f656 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AbstractMustBeClosedChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AbstractMustBeClosedChecker.java @@ -111,17 +111,13 @@ String uniquifyName(String basename) { * @param tree must be either MethodInvocationTree or NewClassTree */ String suggestName(ExpressionTree tree) { - String symbolName; - switch (tree.getKind()) { - case NEW_CLASS: - symbolName = getSymbol(((NewClassTree) tree).getIdentifier()).getSimpleName().toString(); - break; - case METHOD_INVOCATION: - symbolName = getReturnType(tree).asElement().getSimpleName().toString(); - break; - default: - throw new AssertionError(tree.getKind()); - } + String symbolName = + switch (tree.getKind()) { + case NEW_CLASS -> + getSymbol(((NewClassTree) tree).getIdentifier()).getSimpleName().toString(); + case METHOD_INVOCATION -> getReturnType(tree).asElement().getSimpleName().toString(); + default -> throw new AssertionError(tree.getKind()); + }; return uniquifyName(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, symbolName)); } } @@ -256,7 +252,7 @@ private Optional checkClosed( TreePath prev = path; path = path.getParentPath(); switch (path.getLeaf().getKind()) { - case RETURN: + case RETURN -> { if (callerMethodTree != null) { // The invocation occurs within a return statement of a method, instead of a lambda // expression or anonymous class. @@ -276,18 +272,20 @@ private Optional checkClosed( } // If enclosingMethod returned null, we must be returning from a statement lambda. return handleTailPositionInLambda(state); - case LAMBDA_EXPRESSION: + } + case LAMBDA_EXPRESSION -> { // The method invocation is the body of an expression lambda. return handleTailPositionInLambda(state); - case CONDITIONAL_EXPRESSION: + } + case CONDITIONAL_EXPRESSION -> { ConditionalExpressionTree conditionalExpressionTree = (ConditionalExpressionTree) path.getLeaf(); if (conditionalExpressionTree.getTrueExpression().equals(prev.getLeaf()) || conditionalExpressionTree.getFalseExpression().equals(prev.getLeaf())) { continue OUTER; } - break; - case MEMBER_SELECT: + } + case MEMBER_SELECT -> { MemberSelectTree memberSelectTree = (MemberSelectTree) path.getLeaf(); if (memberSelectTree.getExpression().equals(prev.getLeaf())) { Type type = getType(memberSelectTree); @@ -300,8 +298,8 @@ && isSameType(type.getReturnType(), streamType, state)) { continue OUTER; } } - break; - case NEW_CLASS: + } + case NEW_CLASS -> { NewClassTree newClassTree = (NewClassTree) path.getLeaf(); if (isClosingDecorator(newClassTree, prev.getLeaf(), state)) { if (HAS_MUST_BE_CLOSED_ANNOTATION.matches(newClassTree, state)) { @@ -311,8 +309,8 @@ && isSameType(type.getReturnType(), streamType, state)) { // otherwise, enforce that the decorator must be closed continue OUTER; } - break; - case VARIABLE: + } + case VARIABLE -> { Symbol sym = getSymbol(path.getLeaf()); if (sym instanceof VarSymbol var) { if (var.getKind() == ElementKind.RESOURCE_VARIABLE @@ -321,13 +319,13 @@ && isSameType(type.getReturnType(), streamType, state)) { return Optional.empty(); } } - break; - case ASSIGNMENT: + } + case ASSIGNMENT -> { // We shouldn't suggest a try/finally fix when we know the variable is going to be saved // for later. return findingWithNoFix(); - default: - break; + } + default -> {} } // The constructor or method invocation does not occur within the resource variable // initializer of a try-with-resources statement. @@ -367,13 +365,13 @@ private static Optional findingWithNoFix() { private static @Nullable MethodTree enclosingMethod(VisitorState state) { for (Tree node : state.getPath().getParentPath()) { switch (node.getKind()) { - case LAMBDA_EXPRESSION: - case NEW_CLASS: + case LAMBDA_EXPRESSION, NEW_CLASS -> { return null; - case METHOD: + } + case METHOD -> { return (MethodTree) node; - default: - break; + } + default -> {} } } return null; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AbstractReferenceEquality.java b/core/src/main/java/com/google/errorprone/bugpatterns/AbstractReferenceEquality.java index 279f7a4d7f3..01ebac0eaf9 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AbstractReferenceEquality.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AbstractReferenceEquality.java @@ -64,11 +64,10 @@ public abstract class AbstractReferenceEquality extends BugChecker implements Bi @Override public final Description matchBinary(BinaryTree tree, VisitorState state) { switch (tree.getKind()) { - case EQUAL_TO: - case NOT_EQUAL_TO: - break; - default: + case EQUAL_TO, NOT_EQUAL_TO -> {} + default -> { return Description.NO_MATCH; + } } if (tree.getLeftOperand().getKind() == Kind.NULL_LITERAL || !matchArgument(tree.getLeftOperand(), state)) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AbstractToString.java b/core/src/main/java/com/google/errorprone/bugpatterns/AbstractToString.java index 7b20727d242..fc1fc05facc 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AbstractToString.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AbstractToString.java @@ -265,14 +265,13 @@ private static Type type(ExpressionTree tree) { private Optional getFix( ExpressionTree tree, VisitorState state, Tree parent, ToStringKind toStringKind) { switch (toStringKind) { - case IMPLICIT: - case FLOGGER: - case FORMAT_METHOD: + case IMPLICIT, FLOGGER, FORMAT_METHOD -> { return implicitToStringFix(tree, state); - case EXPLICIT: + } + case EXPLICIT -> { return toStringFix(parent, tree, state); - case NONE: - // fall out + } + case NONE -> {} } throw new AssertionError(); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AnnotationPosition.java b/core/src/main/java/com/google/errorprone/bugpatterns/AnnotationPosition.java index 2e22d0c84c1..5914ef3920a 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AnnotationPosition.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AnnotationPosition.java @@ -285,16 +285,11 @@ private static Position annotationPosition(Tree tree, AnnotationType annotationT if (tree instanceof ClassTree || annotationType == null) { return Position.BEFORE; } - switch (annotationType) { - case DECLARATION: - return Position.BEFORE; - case TYPE: - return Position.AFTER; - case NONE: - case BOTH: - return Position.EITHER; - } - throw new AssertionError(); + return switch (annotationType) { + case DECLARATION -> Position.BEFORE; + case TYPE -> Position.AFTER; + case NONE, BOTH -> Position.EITHER; + }; } private static ImmutableList annotationNames(List annotations) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AssertionFailureIgnored.java b/core/src/main/java/com/google/errorprone/bugpatterns/AssertionFailureIgnored.java index 46261739805..d0120a45463 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AssertionFailureIgnored.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AssertionFailureIgnored.java @@ -209,13 +209,14 @@ private static Optional catchesType( Tree prev = null; for (Tree parent : state.getPath()) { switch (parent.getKind()) { - case METHOD: - case LAMBDA_EXPRESSION: + case METHOD, LAMBDA_EXPRESSION -> { return null; - case TRY: + } + case TRY -> { JCTry tryStatement = (JCTry) parent; return tryStatement.getBlock().equals(prev) ? tryStatement : null; - default: // fall out + } + default -> {} } prev = parent; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AttemptedNegativeZero.java b/core/src/main/java/com/google/errorprone/bugpatterns/AttemptedNegativeZero.java index b6f7aef32b3..af6b9788007 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AttemptedNegativeZero.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AttemptedNegativeZero.java @@ -50,14 +50,11 @@ public Description matchUnary(UnaryTree tree, VisitorState state) { } String replacement; switch (targetType(state).type().getTag()) { - case DOUBLE: - replacement = "-0.0"; - break; - case FLOAT: - replacement = "-0.0f"; - break; - default: + case DOUBLE -> replacement = "-0.0"; + case FLOAT -> replacement = "-0.0f"; + default -> { return NO_MATCH; + } } return describeMatch(tree, SuggestedFix.builder().replace(tree, replacement).build()); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/BadImport.java b/core/src/main/java/com/google/errorprone/bugpatterns/BadImport.java index 402a27c33d7..86a4ffef072 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/BadImport.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/BadImport.java @@ -249,20 +249,18 @@ public IdentifierTree visitIdentifier(IdentifierTree node, Void unused) { private void moveTypeAnnotations(IdentifierTree node) { Tree parent = getCurrentPath().getParentPath().getLeaf(); switch (parent.getKind()) { - case METHOD: - case VARIABLE: - case ANNOTATED_TYPE: - moveTypeAnnotations(node, parent, state, builder); - break; - case PARAMETERIZED_TYPE: + case METHOD, VARIABLE, ANNOTATED_TYPE -> + moveTypeAnnotations(node, parent, state, builder); + case PARAMETERIZED_TYPE -> { Tree grandParent = getCurrentPath().getParentPath().getParentPath().getLeaf(); if (grandParent.getKind() == Kind.VARIABLE || grandParent.getKind() == Kind.METHOD) { moveTypeAnnotations(node, grandParent, state, builder); } - break; - default: + } + default -> { // Do nothing. + } } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/BoxedPrimitiveConstructor.java b/core/src/main/java/com/google/errorprone/bugpatterns/BoxedPrimitiveConstructor.java index 9c9727b7260..00a09b44ce1 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/BoxedPrimitiveConstructor.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/BoxedPrimitiveConstructor.java @@ -130,16 +130,13 @@ private static Fix buildFix(NewClassTree tree, VisitorState state) { String optionalCast = ""; String optionalSuffix = ""; switch (doubleAndFloatStatus) { - case PRIMITIVE_DOUBLE_INTO_FLOAT: - // new Float(double).compareTo($foo) => Float.compare((float) double, foo) - optionalCast = "(float) "; - break; - case BOXED_DOUBLE_INTO_FLOAT: - // new Float(Double).compareTo($foo) => Float.compare(Double.floatValue(), foo) - optionalSuffix = ".floatValue()"; - break; - default: - break; + case PRIMITIVE_DOUBLE_INTO_FLOAT -> + // new Float(double).compareTo($foo) => Float.compare((float) double, foo) + optionalCast = "(float) "; + case BOXED_DOUBLE_INTO_FLOAT -> + // new Float(Double).compareTo($foo) => Float.compare(Double.floatValue(), foo) + optionalSuffix = ".floatValue()"; + default -> {} } String replacement = String.format("%s.hashCode(", typeName); @@ -158,16 +155,13 @@ private static Fix buildFix(NewClassTree tree, VisitorState state) { String optionalCast = ""; String optionalSuffix = ""; switch (doubleAndFloatStatus) { - case PRIMITIVE_DOUBLE_INTO_FLOAT: - // new Float(double).compareTo($foo) => Float.compare((float) double, foo) - optionalCast = "(float) "; - break; - case BOXED_DOUBLE_INTO_FLOAT: - // new Float(Double).compareTo($foo) => Float.compare(Double.floatValue(), foo) - optionalSuffix = ".floatValue()"; - break; - default: - break; + case PRIMITIVE_DOUBLE_INTO_FLOAT -> + // new Float(double).compareTo($foo) => Float.compare((float) double, foo) + optionalCast = "(float) "; + case BOXED_DOUBLE_INTO_FLOAT -> + // new Float(Double).compareTo($foo) => Float.compare(Double.floatValue(), foo) + optionalSuffix = ".floatValue()"; + default -> {} } return SuggestedFix.builder() @@ -188,18 +182,15 @@ private static Fix buildFix(NewClassTree tree, VisitorState state) { String prefixToArg; String suffix = ""; switch (doubleAndFloatStatus) { - case PRIMITIVE_DOUBLE_INTO_FLOAT: - // new Float(double) => Float.valueOf((float) double) - prefixToArg = String.format("%s.valueOf(%s", typeName, "(float) "); - break; - case BOXED_DOUBLE_INTO_FLOAT: + case PRIMITIVE_DOUBLE_INTO_FLOAT -> + // new Float(double) => Float.valueOf((float) double) + prefixToArg = String.format("%s.valueOf(%s", typeName, "(float) "); + case BOXED_DOUBLE_INTO_FLOAT -> { // new Float(Double) => Double.floatValue() prefixToArg = ""; suffix = ".floatValue("; - break; - default: - prefixToArg = String.format("%s.valueOf(", typeName); - break; + } + default -> prefixToArg = String.format("%s.valueOf(", typeName); } return SuggestedFix.builder() @@ -247,19 +238,18 @@ private static DoubleAndFloatStatus doubleAndFloatStatus( } private static boolean shouldAutoboxFix(VisitorState state) { - switch (state.getPath().getParentPath().getLeaf().getKind()) { - case METHOD_INVOCATION: - // autoboxing a method argument affects overload resolution - return false; - case MEMBER_SELECT: - // can't select members on primitives (e.g. `theInteger.toString()`) - return false; - case TYPE_CAST: - // can't combine autoboxing and casts to reference types - return false; - default: - return true; - } + return switch (state.getPath().getParentPath().getLeaf().getKind()) { + case METHOD_INVOCATION -> + // autoboxing a method argument affects overload resolution + false; + case MEMBER_SELECT -> + // can't select members on primitives (e.g. `theInteger.toString()`) + false; + case TYPE_CAST -> + // can't combine autoboxing and casts to reference types + false; + default -> true; + }; } private static String literalFix(boolean value, boolean autoboxFix) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/CanBeStaticAnalyzer.java b/core/src/main/java/com/google/errorprone/bugpatterns/CanBeStaticAnalyzer.java index a4f3317feef..7d5587e77ad 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/CanBeStaticAnalyzer.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/CanBeStaticAnalyzer.java @@ -79,29 +79,26 @@ public void visitIdent(JCTree.JCIdent tree) { return; } switch (sym.getKind()) { - case TYPE_PARAMETER: - // declaring a class as non-static just to access a type parameter is silly - - // why not just re-declare the type parameter instead of capturing it? - // TODO(cushon): consider making the suggestion anyways, maybe with a fix? - // fall through - case FIELD: + case TYPE_PARAMETER, FIELD -> { + // declaring a class as non-static just to access a type parameter is silly - + // why not just re-declare the type parameter instead of capturing it? + // TODO(cushon): consider making the suggestion anyways, maybe with a fix? if (!isOwnedBy(sym, owner, state.getTypes())) { canPossiblyBeStatic = false; } - break; - case METHOD: + } + case METHOD -> { if (!isOwnedBy(sym, owner, state.getTypes())) { outerReferences.add((MethodSymbol) sym); } - break; - case CLASS: + } + case CLASS -> { Type enclosing = tree.type.getEnclosingType(); if (enclosing != null) { enclosing.accept(new TypeVariableScanner(), null); } - break; - default: - break; + } + default -> {} } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/CanonicalDuration.java b/core/src/main/java/com/google/errorprone/bugpatterns/CanonicalDuration.java index e84e865e497..aa385d3d2b8 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/CanonicalDuration.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/CanonicalDuration.java @@ -233,7 +233,7 @@ public Void scan(Tree tree, Void unused) { private Description handleAllZeros( VisitorState state, Api api, List allInvocationsInParentExpression) { switch (api) { - case JODA: + case JODA -> { for (MethodInvocationTree tree : allInvocationsInParentExpression) { ExpressionTree receiver = getReceiver(tree); SuggestedFix fix; @@ -256,9 +256,11 @@ private Description handleAllZeros( .build()); } return NO_MATCH; - case JAVA: + } + case JAVA -> { // don't rewrite e.g. `ofMillis(0)` to `ofDays(0)` return NO_MATCH; + } } throw new AssertionError(api); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/CheckReturnValue.java b/core/src/main/java/com/google/errorprone/bugpatterns/CheckReturnValue.java index d2780828adb..c8f88225265 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/CheckReturnValue.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/CheckReturnValue.java @@ -119,27 +119,21 @@ public class CheckReturnValue extends AbstractReturnValueIgnored @Override public Stream scopeMembers( RuleScope scope, MethodSymbol method, VisitorState context) { - switch (scope) { - case ENCLOSING_ELEMENTS: - return enclosingElements(method) - .filter(s -> s instanceof ClassSymbol || s instanceof PackageSymbol); - case GLOBAL: - case METHOD: - return Stream.of(method); - } - throw new AssertionError(scope); + return switch (scope) { + case ENCLOSING_ELEMENTS -> + enclosingElements(method) + .filter(s -> s instanceof ClassSymbol || s instanceof PackageSymbol); + case GLOBAL, METHOD -> Stream.of(method); + }; } @Override public MethodKind getMethodKind(MethodSymbol method) { - switch (method.getKind()) { - case METHOD: - return MethodKind.METHOD; - case CONSTRUCTOR: - return MethodKind.CONSTRUCTOR; - default: - return MethodKind.OTHER; - } + return switch (method.getKind()) { + case METHOD -> MethodKind.METHOD; + case CONSTRUCTOR -> MethodKind.CONSTRUCTOR; + default -> MethodKind.OTHER; + }; } }; @@ -279,16 +273,17 @@ public Description matchMethod(MethodTree tree, VisitorState state) { MethodSymbol method = ASTHelpers.getSymbol(tree); ImmutableList presentAnnotations = presentCrvRelevantAnnotations(method); switch (presentAnnotations.size()) { - case 0: + case 0 -> { return Description.NO_MATCH; - case 1: - break; - default: + } + case 1 -> {} + default -> { // TODO(cgdecker): We can check this with evaluator.checkForConflicts now, though I want to // think more about how we build and format error messages in that. return buildDescription(tree) .setMessage(conflictingAnnotations(presentAnnotations, "method")) .build(); + } } if (method.getKind() != ElementKind.METHOD) { @@ -393,16 +388,14 @@ private String apiTrailer(MethodSymbol symbol, VisitorState state) { */ return ""; } - switch (messageTrailerStyle) { - case NONE: - return ""; - case API_ERASED_SIGNATURE: - return "\n\nFull API: " - + surroundingClass(symbol) - + "#" - + methodNameAndParams(symbol, state.getTypes()); - } - throw new AssertionError(); + return switch (messageTrailerStyle) { + case NONE -> ""; + case API_ERASED_SIGNATURE -> + "\n\nFull API: " + + surroundingClass(symbol) + + "#" + + methodNameAndParams(symbol, state.getTypes()); + }; } enum MessageTrailerStyle { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ClassCanBeStatic.java b/core/src/main/java/com/google/errorprone/bugpatterns/ClassCanBeStatic.java index 9cfb3e0f044..9b0c13ee6c8 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ClassCanBeStatic.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ClassCanBeStatic.java @@ -58,23 +58,23 @@ public Description matchClass(ClassTree tree, VisitorState state) { return NO_MATCH; } switch (currentClass.owner.enclClass().getNestingKind()) { - case TOP_LEVEL: - break; - case MEMBER: + case TOP_LEVEL -> {} + case MEMBER -> { if (!SourceVersion.supportsStaticInnerClass(state.context) && currentClass.owner.enclClass().hasOuterInstance()) { // class is nested inside an inner class, so it can't be static return NO_MATCH; } - break; - case LOCAL: + } + case LOCAL -> { if (!SourceVersion.supportsStaticInnerClass(state.context)) { return NO_MATCH; } - break; - case ANONYMOUS: + } + case ANONYMOUS -> { // members of local and anonymous classes can't be static return NO_MATCH; + } } if (tree.getExtendsClause() != null && ASTHelpers.getType(tree.getExtendsClause()).tsym.hasOuterInstance()) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ComparisonContractViolated.java b/core/src/main/java/com/google/errorprone/bugpatterns/ComparisonContractViolated.java index a5c1c85bf6c..521d0d7be0d 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ComparisonContractViolated.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ComparisonContractViolated.java @@ -205,15 +205,11 @@ public Void visitReturn(ReturnTree node, VisitorState state) { return describeMatch(tree); } switch (conditionExpr.getKind()) { - case LESS_THAN: - case LESS_THAN_EQUAL: - break; - case GREATER_THAN: - case GREATER_THAN_EQUAL: - trueFirst = !trueFirst; - break; - default: + case LESS_THAN, LESS_THAN_EQUAL -> {} + case GREATER_THAN, GREATER_THAN_EQUAL -> trueFirst = !trueFirst; + default -> { return describeMatch(tree); + } } BinaryTree binaryExpr = (BinaryTree) conditionExpr; Type ty = ASTHelpers.getType(binaryExpr.getLeftOperand()); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ComparisonOutOfRange.java b/core/src/main/java/com/google/errorprone/bugpatterns/ComparisonOutOfRange.java index 445a0f8280f..a166cf8cee3 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ComparisonOutOfRange.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ComparisonOutOfRange.java @@ -100,24 +100,15 @@ class MatchAttempt> { } Description matchConstantResult() { - switch (tree.getKind()) { - case EQUAL_TO: - return matchOutOfBounds(/* willEvaluateTo= */ false); - case NOT_EQUAL_TO: - return matchOutOfBounds(/* willEvaluateTo= */ true); - - case LESS_THAN: - return matchMinAndMaxHaveSameResult(cmp -> cmp < 0); - case LESS_THAN_EQUAL: - return matchMinAndMaxHaveSameResult(cmp -> cmp <= 0); - case GREATER_THAN: - return matchMinAndMaxHaveSameResult(cmp -> cmp > 0); - case GREATER_THAN_EQUAL: - return matchMinAndMaxHaveSameResult(cmp -> cmp >= 0); - - default: - return NO_MATCH; - } + return switch (tree.getKind()) { + case EQUAL_TO -> matchOutOfBounds(/* willEvaluateTo= */ false); + case NOT_EQUAL_TO -> matchOutOfBounds(/* willEvaluateTo= */ true); + case LESS_THAN -> matchMinAndMaxHaveSameResult(cmp -> cmp < 0); + case LESS_THAN_EQUAL -> matchMinAndMaxHaveSameResult(cmp -> cmp <= 0); + case GREATER_THAN -> matchMinAndMaxHaveSameResult(cmp -> cmp > 0); + case GREATER_THAN_EQUAL -> matchMinAndMaxHaveSameResult(cmp -> cmp >= 0); + default -> NO_MATCH; + }; } Description matchOutOfBounds(boolean willEvaluateTo) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ComplexBooleanConstant.java b/core/src/main/java/com/google/errorprone/bugpatterns/ComplexBooleanConstant.java index 1edd0ecbe3a..dd8bcc05199 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ComplexBooleanConstant.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ComplexBooleanConstant.java @@ -76,36 +76,32 @@ public Description matchBinary(BinaryTree tree, VisitorState state) { if (r == null) { return null; } - switch (node.getKind()) { - case LOGICAL_COMPLEMENT: - return !r; - default: - return null; - } + return switch (node.getKind()) { + case LOGICAL_COMPLEMENT -> !r; + default -> null; + }; } }; Boolean lhs = tree.getLeftOperand().accept(boolValue, null); Boolean rhs = tree.getRightOperand().accept(boolValue, null); switch (tree.getKind()) { - case CONDITIONAL_AND: - case AND: + case CONDITIONAL_AND, AND -> { if (lhs != null && rhs != null) { return lhs && rhs; } if (Objects.equals(lhs, Boolean.FALSE) || Objects.equals(rhs, Boolean.FALSE)) { return false; } - break; - case CONDITIONAL_OR: - case OR: + } + case CONDITIONAL_OR, OR -> { if (lhs != null && rhs != null) { return lhs || rhs; } if (Objects.equals(lhs, Boolean.TRUE) || Objects.equals(rhs, Boolean.TRUE)) { return true; } - break; - default: // fall out + } + default -> {} } return null; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ConstantField.java b/core/src/main/java/com/google/errorprone/bugpatterns/ConstantField.java index 7edbc756178..0556e422444 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ConstantField.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ConstantField.java @@ -86,12 +86,9 @@ private static boolean canBecomeStaticMember(VarSymbol sym) { ClassSymbol owningClass = sym.enclClass(); // Enum anonymous classes aren't considered isInner() even though they can't hold static fields - switch (owningClass.getNestingKind()) { - case LOCAL: - case ANONYMOUS: - return false; - default: - return !owningClass.isInner(); - } + return switch (owningClass.getNestingKind()) { + case LOCAL, ANONYMOUS -> false; + default -> !owningClass.isInner(); + }; } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ConstantOverflow.java b/core/src/main/java/com/google/errorprone/bugpatterns/ConstantOverflow.java index 6d58c833688..0f147ea8ba7 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ConstantOverflow.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ConstantOverflow.java @@ -146,20 +146,19 @@ public Number visitParenthesized(ParenthesizedTree node, Void p) { } // assume that e.g. `Integer.MIN_VALUE - 1` is intentional switch (node.getKind()) { - case MINUS: + case MINUS -> { if ((lhs instanceof Long && lhs.longValue() == Long.MIN_VALUE) || (lhs instanceof Integer && lhs.intValue() == Integer.MIN_VALUE)) { return null; } - break; - case PLUS: + } + case PLUS -> { if ((lhs instanceof Long && lhs.longValue() == Long.MAX_VALUE) || (lhs instanceof Integer && lhs.intValue() == Integer.MAX_VALUE)) { return null; } - break; - default: - break; + } + default -> {} } if (lhs instanceof Long || rhs instanceof Long) { return binop(node.getKind(), lhs.longValue(), rhs.longValue()); @@ -198,104 +197,66 @@ public Number visitLiteral(LiteralTree node, Void unused) { }; private static @Nullable Long unop(Kind kind, long value) { - switch (kind) { - case UNARY_PLUS: - return +value; - case UNARY_MINUS: - return -value; - case BITWISE_COMPLEMENT: - return ~value; - default: - return null; - } + return switch (kind) { + case UNARY_PLUS -> +value; + case UNARY_MINUS -> -value; + case BITWISE_COMPLEMENT -> ~value; + default -> null; + }; } private static @Nullable Integer unop(Kind kind, int value) { - switch (kind) { - case UNARY_PLUS: - return +value; - case UNARY_MINUS: - return -value; - case BITWISE_COMPLEMENT: - return ~value; - default: - return null; - } + return switch (kind) { + case UNARY_PLUS -> +value; + case UNARY_MINUS -> -value; + case BITWISE_COMPLEMENT -> ~value; + default -> null; + }; } static @Nullable Long binop(Kind kind, long lhs, long rhs) { - switch (kind) { - case MULTIPLY: - return LongMath.checkedMultiply(lhs, rhs); - case DIVIDE: - return lhs / rhs; - case REMAINDER: - return lhs % rhs; - case PLUS: - return LongMath.checkedAdd(lhs, rhs); - case MINUS: - return LongMath.checkedSubtract(lhs, rhs); - case LEFT_SHIFT: - return lhs << rhs; - case RIGHT_SHIFT: - return lhs >> rhs; - case UNSIGNED_RIGHT_SHIFT: - return lhs >>> rhs; - case AND: - return lhs & rhs; - case XOR: - return lhs ^ rhs; - case OR: - return lhs | rhs; - default: - return null; - } + return switch (kind) { + case MULTIPLY -> LongMath.checkedMultiply(lhs, rhs); + case DIVIDE -> lhs / rhs; + case REMAINDER -> lhs % rhs; + case PLUS -> LongMath.checkedAdd(lhs, rhs); + case MINUS -> LongMath.checkedSubtract(lhs, rhs); + case LEFT_SHIFT -> lhs << rhs; + case RIGHT_SHIFT -> lhs >> rhs; + case UNSIGNED_RIGHT_SHIFT -> lhs >>> rhs; + case AND -> lhs & rhs; + case XOR -> lhs ^ rhs; + case OR -> lhs | rhs; + default -> null; + }; } static @Nullable Integer binop(Kind kind, int lhs, int rhs) { - switch (kind) { - case MULTIPLY: - return IntMath.checkedMultiply(lhs, rhs); - case DIVIDE: - return lhs / rhs; - case REMAINDER: - return lhs % rhs; - case PLUS: - return IntMath.checkedAdd(lhs, rhs); - case MINUS: - return IntMath.checkedSubtract(lhs, rhs); - case LEFT_SHIFT: - return lhs << rhs; - case RIGHT_SHIFT: - return lhs >> rhs; - case UNSIGNED_RIGHT_SHIFT: - return lhs >>> rhs; - case AND: - return lhs & rhs; - case XOR: - return lhs ^ rhs; - case OR: - return lhs | rhs; - default: - return null; - } + return switch (kind) { + case MULTIPLY -> IntMath.checkedMultiply(lhs, rhs); + case DIVIDE -> lhs / rhs; + case REMAINDER -> lhs % rhs; + case PLUS -> IntMath.checkedAdd(lhs, rhs); + case MINUS -> IntMath.checkedSubtract(lhs, rhs); + case LEFT_SHIFT -> lhs << rhs; + case RIGHT_SHIFT -> lhs >> rhs; + case UNSIGNED_RIGHT_SHIFT -> lhs >>> rhs; + case AND -> lhs & rhs; + case XOR -> lhs ^ rhs; + case OR -> lhs | rhs; + default -> null; + }; } private static @Nullable Number cast(TypeKind kind, Number value) { - switch (kind) { - case SHORT: - return value.shortValue(); - case INT: - return value.intValue(); - case LONG: - return value.longValue(); - case BYTE: - return value.byteValue(); - case CHAR: - return (int) (char) value.intValue(); - default: - return null; - } + return switch (kind) { + case SHORT -> value.shortValue(); + case INT -> value.intValue(); + case LONG -> value.longValue(); + case BYTE -> value.byteValue(); + case CHAR -> (int) (char) value.intValue(); + default -> null; + }; } private static @Nullable Number getIntegralConstant(Tree node) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ConstantPatternCompile.java b/core/src/main/java/com/google/errorprone/bugpatterns/ConstantPatternCompile.java index 74495a53baf..c52700a5147 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ConstantPatternCompile.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ConstantPatternCompile.java @@ -165,14 +165,11 @@ private static Optional handleVariable(VariableTree tree, VisitorS return Optional.empty(); } VarSymbol sym = getSymbol(tree); - switch (sym.getKind()) { - case RESOURCE_VARIABLE: - return Optional.of(SuggestedFix.emptyFix()); - case LOCAL_VARIABLE: - return Optional.of(fixLocal(tree, outerMethodTree, state)); - default: - return Optional.empty(); - } + return switch (sym.getKind()) { + case RESOURCE_VARIABLE -> Optional.of(SuggestedFix.emptyFix()); + case LOCAL_VARIABLE -> Optional.of(fixLocal(tree, outerMethodTree, state)); + default -> Optional.empty(); + }; } private static SuggestedFix fixLocal( diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/DefaultCharset.java b/core/src/main/java/com/google/errorprone/bugpatterns/DefaultCharset.java index 43bd5d0860d..452d18e49f3 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/DefaultCharset.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/DefaultCharset.java @@ -371,14 +371,11 @@ private static void variableTypeFix( Tree parent = state.getPath().getParentPath().getLeaf(); Symbol sym; switch (parent.getKind()) { - case VARIABLE: - sym = ASTHelpers.getSymbol((VariableTree) parent); - break; - case ASSIGNMENT: - sym = ASTHelpers.getSymbol(((AssignmentTree) parent).getVariable()); - break; - default: + case VARIABLE -> sym = ASTHelpers.getSymbol((VariableTree) parent); + case ASSIGNMENT -> sym = ASTHelpers.getSymbol(((AssignmentTree) parent).getVariable()); + default -> { return; + } } if (!ASTHelpers.isSameType( sym.type, state.getTypeFromString(original.getCanonicalName()), state)) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/DeprecatedVariable.java b/core/src/main/java/com/google/errorprone/bugpatterns/DeprecatedVariable.java index aa499ab7557..9268a2b92fa 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/DeprecatedVariable.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/DeprecatedVariable.java @@ -42,11 +42,10 @@ public Description matchVariable(VariableTree tree, VisitorState state) { return NO_MATCH; } switch (sym.getKind()) { - case LOCAL_VARIABLE: - case PARAMETER: - break; - default: + case LOCAL_VARIABLE, PARAMETER -> {} + default -> { return NO_MATCH; + } } Description.Builder description = buildDescription(tree); Optional.ofNullable( diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/DiscardedPostfixExpression.java b/core/src/main/java/com/google/errorprone/bugpatterns/DiscardedPostfixExpression.java index 4a08f838bc1..29767bb29a2 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/DiscardedPostfixExpression.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/DiscardedPostfixExpression.java @@ -40,11 +40,10 @@ public class DiscardedPostfixExpression extends BugChecker implements UnaryTreeM @Override public Description matchUnary(UnaryTree tree, VisitorState state) { switch (tree.getKind()) { - case POSTFIX_INCREMENT: - case POSTFIX_DECREMENT: - break; - default: + case POSTFIX_INCREMENT, POSTFIX_DECREMENT -> {} + default -> { return NO_MATCH; + } } Tree parent = state.getPath().getParentPath().getLeaf(); if (parent.getKind() != Kind.LAMBDA_EXPRESSION) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/EqualsNaN.java b/core/src/main/java/com/google/errorprone/bugpatterns/EqualsNaN.java index 1219537154f..c5751f4f121 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/EqualsNaN.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/EqualsNaN.java @@ -42,14 +42,11 @@ public class EqualsNaN extends BugChecker implements BinaryTreeMatcher { public Description matchBinary(BinaryTree tree, VisitorState state) { String prefix; switch (tree.getKind()) { - case EQUAL_TO: - prefix = ""; - break; - case NOT_EQUAL_TO: - prefix = "!"; - break; - default: + case EQUAL_TO -> prefix = ""; + case NOT_EQUAL_TO -> prefix = "!"; + default -> { return Description.NO_MATCH; + } } JCExpression left = (JCExpression) tree.getLeftOperand(); JCExpression right = (JCExpression) tree.getRightOperand(); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ExpectedExceptionChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/ExpectedExceptionChecker.java index 7ba994e3741..478772467c8 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ExpectedExceptionChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ExpectedExceptionChecker.java @@ -185,7 +185,7 @@ private static Fix buildFix( Symtab symtab = state.getSymtab(); List args = invocation.getArguments(); switch (symbol.getSimpleName().toString()) { - case "expect": + case "expect" -> { Type type = ASTHelpers.getType(getOnlyElement(invocation.getArguments())); if (isSubtype(type, symtab.classType, state)) { // expect(Class) @@ -210,8 +210,8 @@ private static Fix buildFix( String.format( "assertThat(thrown, %s);", state.getSourceForNode(getOnlyElement(args)))); } - break; - case "expectCause": + } + case "expectCause" -> { ExpressionTree matcher = getOnlyElement(invocation.getArguments()); if (IS_A.matches(matcher, state)) { fix.addStaticImport("com.google.common.truth.Truth.assertThat"); @@ -227,8 +227,8 @@ private static Fix buildFix( "assertThat(thrown.getCause(), %s);", state.getSourceForNode(getOnlyElement(args)))); } - break; - case "expectMessage": + } + case "expectMessage" -> { if (isSubtype( getOnlyElement(symbol.getParameters()).asType(), symtab.stringType, state)) { // expectedMessage(String) @@ -245,9 +245,8 @@ private static Fix buildFix( "assertThat(thrown.getMessage(), %s);", state.getSourceForNode(getOnlyElement(args)))); } - break; - default: - throw new AssertionError("unknown expect method: " + symbol.getSimpleName()); + } + default -> throw new AssertionError("unknown expect method: " + symbol.getSimpleName()); } } // remove all interactions with the ExpectedException rule diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/Finally.java b/core/src/main/java/com/google/errorprone/bugpatterns/Finally.java index ed5feb2f5b9..a8b082c6d62 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/Finally.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/Finally.java @@ -120,12 +120,10 @@ public boolean matches(T tree, VisitorState state) { Tree prevTree = null; for (Tree leaf : state.getPath()) { switch (leaf.getKind()) { - case METHOD: - case LAMBDA_EXPRESSION: - case CLASS: + case METHOD, LAMBDA_EXPRESSION, CLASS -> { return false; - default: - break; + } + default -> {} } MatchResult mr = matchAncestor(leaf, prevTree); if (mr != MatchResult.KEEP_LOOKING) { @@ -183,13 +181,10 @@ protected MatchResult matchAncestor(Tree leaf, Tree prevTree) { // (1) if (label == null) { switch (leaf.getKind()) { - case WHILE_LOOP: - case DO_WHILE_LOOP: - case FOR_LOOP: - case ENHANCED_FOR_LOOP: + case WHILE_LOOP, DO_WHILE_LOOP, FOR_LOOP, ENHANCED_FOR_LOOP -> { return MatchResult.NO_MATCH; - default: - break; + } + default -> {} } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/FloatCast.java b/core/src/main/java/com/google/errorprone/bugpatterns/FloatCast.java index 47d9833e4a7..132d29af47c 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/FloatCast.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/FloatCast.java @@ -80,21 +80,16 @@ public Description matchTypeCast(TypeCastTree tree, VisitorState state) { return NO_MATCH; } switch (castType.getKind()) { - case LONG: - case INT: - case SHORT: - case CHAR: - case BYTE: - break; - default: + case LONG, INT, SHORT, CHAR, BYTE -> {} + default -> { return NO_MATCH; + } } switch (operandType.getKind()) { - case FLOAT: - case DOUBLE: - break; - default: + case FLOAT, DOUBLE -> {} + default -> { return NO_MATCH; + } } if (IGNORED_METHODS.matches(tree.getExpression(), state)) { return NO_MATCH; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/FloatingPointLiteralPrecision.java b/core/src/main/java/com/google/errorprone/bugpatterns/FloatingPointLiteralPrecision.java index 8bafb574500..397fa1d96d2 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/FloatingPointLiteralPrecision.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/FloatingPointLiteralPrecision.java @@ -54,26 +54,22 @@ public Description matchLiteral(LiteralTree tree, VisitorState state) { String suffix; BigDecimal value; switch (type.getKind()) { - case DOUBLE: + case DOUBLE -> { value = new BigDecimal(Double.toString(constValue(tree, Double.class))); suffix = ""; - break; - case FLOAT: + } + case FLOAT -> { value = new BigDecimal(Float.toString(constValue(tree, Float.class))); suffix = "f"; - break; - default: + } + default -> { return NO_MATCH; + } } String source = state.getSourceForNode(tree); switch (source.charAt(source.length() - 1)) { - case 'f': - case 'F': - case 'd': - case 'D': - source = source.substring(0, source.length() - 1); - break; - default: // fall out + case 'f', 'F', 'd', 'D' -> source = source.substring(0, source.length() - 1); + default -> {} } source = CharMatcher.is('_').removeFrom(source); BigDecimal exact; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ForEachIterable.java b/core/src/main/java/com/google/errorprone/bugpatterns/ForEachIterable.java index 63d864b2b9c..55a9b8e6236 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ForEachIterable.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ForEachIterable.java @@ -156,12 +156,8 @@ private Description match( p -> { TreePath path = p.getParentPath().getParentPath(); switch (path.getParentPath().getLeaf().getKind()) { - case EXPRESSION_STATEMENT: - fix.delete(path.getParentPath().getLeaf()); - break; - default: - fix.replace(path.getLeaf(), replacement); - break; + case EXPRESSION_STATEMENT -> fix.delete(path.getParentPath().getLeaf()); + default -> fix.replace(path.getLeaf(), replacement); } }); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/IdentityBinaryExpression.java b/core/src/main/java/com/google/errorprone/bugpatterns/IdentityBinaryExpression.java index 9acfa49a80a..836ffde9415 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/IdentityBinaryExpression.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/IdentityBinaryExpression.java @@ -54,11 +54,13 @@ public class IdentityBinaryExpression extends BugChecker implements BinaryTreeMa public Description matchBinary(BinaryTree tree, VisitorState state) { if (constValue(tree.getLeftOperand()) != null) { switch (tree.getKind()) { - case LEFT_SHIFT: // bit field initialization, e.g. `1 << 1`, `1 << 2`, ... - case DIVIDE: // aspect ratios, e.g. `1.0f / 1.0f`, `2.0f / 3.0f`, ... - case MINUS: // character arithmetic, e.g. `'A' - 'A'`, `'B' - 'A'`, ... + case LEFT_SHIFT, DIVIDE, MINUS -> { + // bit field initialization, e.g. `1 << 1`, `1 << 2`, ... + // aspect ratios, e.g. `1.0f / 1.0f`, `2.0f / 3.0f`, ... + // character arithmetic, e.g. `'A' - 'A'`, `'B' - 'A'`, ... return NO_MATCH; - default: // fall out + } + default -> {} } } String replacement; @@ -108,15 +110,13 @@ public Description matchBinary(BinaryTree tree, VisitorState state) { return NO_MATCH; } switch (tree.getKind()) { - case NOT_EQUAL_TO: - // X != X is only true when X is NaN, so suggest isNaN(X) - replacement = isNanReplacement(tree, state).orElse(replacement); - break; - case EQUAL_TO: - // X == X is true unless X is NaN, so suggest !isNaN(X) - replacement = isNanReplacement(tree, state).map(r -> "!" + r).orElse(replacement); - break; - default: // fall out + case NOT_EQUAL_TO -> + // X != X is only true when X is NaN, so suggest isNaN(X) + replacement = isNanReplacement(tree, state).orElse(replacement); + case EQUAL_TO -> + // X == X is true unless X is NaN, so suggest !isNaN(X) + replacement = isNanReplacement(tree, state).map(r -> "!" + r).orElse(replacement); + default -> {} } Description.Builder description = buildDescription(tree); if (replacement != null) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/IdentityHashMapBoxing.java b/core/src/main/java/com/google/errorprone/bugpatterns/IdentityHashMapBoxing.java index 78ac3b24a7b..38e25ab3a05 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/IdentityHashMapBoxing.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/IdentityHashMapBoxing.java @@ -70,14 +70,9 @@ private Description checkTypes(ExpressionTree tree, VisitorState state) { return Description.NO_MATCH; } Type type = state.getTypes().unboxedType(argumentTypes.get(0)); - switch (type.getKind()) { - case DOUBLE: - case LONG: - case INT: - case FLOAT: - return describeMatch(tree); - default: - return Description.NO_MATCH; - } + return switch (type.getKind()) { + case DOUBLE, LONG, INT, FLOAT -> describeMatch(tree); + default -> Description.NO_MATCH; + }; } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ImplementAssertionWithChaining.java b/core/src/main/java/com/google/errorprone/bugpatterns/ImplementAssertionWithChaining.java index c722309ca47..21b0abc13e6 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ImplementAssertionWithChaining.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ImplementAssertionWithChaining.java @@ -121,17 +121,13 @@ public Description matchIf(IfTree ifTree, VisitorState state) { * Note that all these look "backward": If the code is "if (foo == bar) { fail }," then the * assertion is checking that the values are *not* equal. */ - switch (condition.getKind()) { - case LOGICAL_COMPLEMENT: - return findActualAndExpectedForPossibleEqualsCall( - stripParentheses(((UnaryTree) condition).getExpression()), state); - - case NOT_EQUAL_TO: - return findActualAndExpectedForBinaryOp((BinaryTree) condition, state); - - default: - return null; - } + return switch (condition.getKind()) { + case LOGICAL_COMPLEMENT -> + findActualAndExpectedForPossibleEqualsCall( + stripParentheses(((UnaryTree) condition).getExpression()), state); + case NOT_EQUAL_TO -> findActualAndExpectedForBinaryOp((BinaryTree) condition, state); + default -> null; + }; } private static @Nullable ImmutableList findActualAndExpectedForPossibleEqualsCall( diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/IntLongMath.java b/core/src/main/java/com/google/errorprone/bugpatterns/IntLongMath.java index de2e06c88d6..bb012cc99ce 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/IntLongMath.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/IntLongMath.java @@ -56,13 +56,15 @@ public Description matchReturn(ReturnTree tree, VisitorState state) { outer: for (Tree parent : state.getPath()) { switch (parent.getKind()) { - case METHOD: + case METHOD -> { type = ASTHelpers.getType(((MethodTree) parent).getReturnType()); break outer; - case LAMBDA_EXPRESSION: + } + case LAMBDA_EXPRESSION -> { type = state.getTypes().findDescriptorType(ASTHelpers.getType(parent)).getReturnType(); break outer; - default: // fall out + } + default -> {} } } if (type == null) { @@ -104,17 +106,11 @@ Description check(Type targetType, ExpressionTree init) { break; } switch (nested.getKind()) { - case DIVIDE: - case REMAINDER: - case AND: - case XOR: - case OR: - case RIGHT_SHIFT: + case DIVIDE, REMAINDER, AND, XOR, OR, RIGHT_SHIFT -> { // Skip binops that can't overflow; it doesn't matter whether they're performed on // longs or ints. - break; - default: - innerMost = (BinaryTree) nested; + } + default -> innerMost = (BinaryTree) nested; } nested = ((BinaryTree) nested).getLeftOperand(); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/JdkObsolete.java b/core/src/main/java/com/google/errorprone/bugpatterns/JdkObsolete.java index 4d5529dad96..a96302adddc 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/JdkObsolete.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/JdkObsolete.java @@ -233,13 +233,16 @@ private Description describeIfObsolete( private static @Nullable Type getMethodOrLambdaReturnType(VisitorState state) { for (Tree tree : state.getPath()) { switch (tree.getKind()) { - case LAMBDA_EXPRESSION: + case LAMBDA_EXPRESSION -> { return state.getTypes().findDescriptorType(ASTHelpers.getType(tree)).getReturnType(); - case METHOD: + } + case METHOD -> { return ASTHelpers.getType(tree).getReturnType(); - case CLASS: + } + case CLASS -> { return null; - default: // fall out + } + default -> {} } } return null; @@ -354,12 +357,13 @@ public Void visitIdentifier(IdentifierTree tree, Void unused) { TreePath path = state.getPath(); while (path != null) { switch (path.getLeaf().getKind()) { - case METHOD: + case METHOD -> { return path; - case CLASS: - case LAMBDA_EXPRESSION: + } + case CLASS, LAMBDA_EXPRESSION -> { return null; - default: // fall out + } + default -> {} } path = path.getParentPath(); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/LabelledBreakTarget.java b/core/src/main/java/com/google/errorprone/bugpatterns/LabelledBreakTarget.java index 0d4b02288ce..85dcc4985a7 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/LabelledBreakTarget.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/LabelledBreakTarget.java @@ -31,13 +31,10 @@ public class LabelledBreakTarget extends BugChecker implements LabeledStatementT @Override public Description matchLabeledStatement(LabeledStatementTree tree, VisitorState state) { switch (tree.getStatement().getKind()) { - case DO_WHILE_LOOP: - case ENHANCED_FOR_LOOP: - case FOR_LOOP: - case WHILE_LOOP: + case DO_WHILE_LOOP, ENHANCED_FOR_LOOP, FOR_LOOP, WHILE_LOOP -> { return NO_MATCH; - default: - break; + } + default -> {} } return describeMatch(tree); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/LoopConditionChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/LoopConditionChecker.java index 4b5959c78e8..3be72c92739 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/LoopConditionChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/LoopConditionChecker.java @@ -115,11 +115,11 @@ public Boolean visitIdentifier(IdentifierTree tree, Void unused) { Symbol sym = ASTHelpers.getSymbol(tree); if (sym instanceof Symbol.VarSymbol) { switch (sym.getKind()) { - case LOCAL_VARIABLE: - case PARAMETER: + case LOCAL_VARIABLE, PARAMETER -> { conditionVars.add((Symbol.VarSymbol) sym); return true; - default: // fall out + } + default -> {} } } return false; @@ -161,13 +161,9 @@ public UpdateScanner(ImmutableSet variables) { @Override public Void visitUnary(UnaryTree tree, Void unused) { switch (tree.getKind()) { - case POSTFIX_INCREMENT: - case PREFIX_INCREMENT: - case POSTFIX_DECREMENT: - case PREFIX_DECREMENT: - check(tree.getExpression()); - break; - default: // fall out + case POSTFIX_INCREMENT, PREFIX_INCREMENT, POSTFIX_DECREMENT, PREFIX_DECREMENT -> + check(tree.getExpression()); + default -> {} } return super.visitUnary(tree, null); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/MethodCanBeStatic.java b/core/src/main/java/com/google/errorprone/bugpatterns/MethodCanBeStatic.java index d6d1b2dc0f6..17f73a53277 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/MethodCanBeStatic.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/MethodCanBeStatic.java @@ -240,21 +240,21 @@ private static boolean isExcluded(MethodTree tree, VisitorState state) { return true; } switch (sym.owner.enclClass().getNestingKind()) { - case TOP_LEVEL: - break; - case MEMBER: + case TOP_LEVEL -> {} + case MEMBER -> { if (!SourceVersion.supportsStaticInnerClass(state.context) && sym.owner.enclClass().hasOuterInstance()) { return true; } - break; - case LOCAL: + } + case LOCAL -> { if (!SourceVersion.supportsStaticInnerClass(state.context)) { return true; } - break; - case ANONYMOUS: + } + case ANONYMOUS -> { return true; + } } return SERIALIZATION_METHODS.matches(tree, state); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ModifyCollectionInEnhancedForLoop.java b/core/src/main/java/com/google/errorprone/bugpatterns/ModifyCollectionInEnhancedForLoop.java index 7418e5fb5bf..327f42b1aaf 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ModifyCollectionInEnhancedForLoop.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ModifyCollectionInEnhancedForLoop.java @@ -112,29 +112,25 @@ private static boolean blockEndsInBreakOrReturn(VisitorState state) { if (idx == -1 || idx == statements.size()) { return false; } - switch (getLast(statements).getKind()) { - case BREAK: - case RETURN: - return true; - default: - return false; - } + return switch (getLast(statements).getKind()) { + case BREAK, RETURN -> true; + default -> false; + }; } /** Returns true if {@code collection} is modified by an enclosing loop. */ private static boolean enclosingLoop(VisitorState state, ExpressionTree collection) { for (Tree node : state.getPath()) { switch (node.getKind()) { - case METHOD: - case CLASS: - case LAMBDA_EXPRESSION: + case METHOD, CLASS, LAMBDA_EXPRESSION -> { return false; - case ENHANCED_FOR_LOOP: + } + case ENHANCED_FOR_LOOP -> { if (sameCollection(collection, ((EnhancedForLoopTree) node).getExpression(), state)) { return true; } - break; - default: // fall out + } + default -> {} } } return false; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/MultipleTopLevelClasses.java b/core/src/main/java/com/google/errorprone/bugpatterns/MultipleTopLevelClasses.java index df53b31f8fc..b1ae03d75fb 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/MultipleTopLevelClasses.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/MultipleTopLevelClasses.java @@ -51,10 +51,7 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s if (member instanceof ClassTree) { ClassTree classMember = (ClassTree) member; switch (classMember.getKind()) { - case CLASS: - case INTERFACE: - case ANNOTATION_TYPE: - case ENUM: + case CLASS, INTERFACE, ANNOTATION_TYPE, ENUM -> { if (isSuppressed(classMember, state)) { // If any top-level classes have @SuppressWarnings("TopLevel"), ignore // this compilation unit. We can't rely on the normal suppression @@ -63,9 +60,8 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s return NO_MATCH; } names.add(classMember.getSimpleName().toString()); - break; - default: - break; + } + default -> {} } } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/NarrowingCompoundAssignment.java b/core/src/main/java/com/google/errorprone/bugpatterns/NarrowingCompoundAssignment.java index 9876cffdfcf..c6b193505bc 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/NarrowingCompoundAssignment.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/NarrowingCompoundAssignment.java @@ -48,61 +48,37 @@ public class NarrowingCompoundAssignment extends BugChecker implements CompoundAssignmentTreeMatcher { static String assignmentToString(Tree.Kind kind) { - switch (kind) { - case MULTIPLY: - return "*"; - case DIVIDE: - return "/"; - case REMAINDER: - return "%"; - case PLUS: - return "+"; - case MINUS: - return "-"; - case LEFT_SHIFT: - return "<<"; - case AND: - return "&"; - case XOR: - return "^"; - case OR: - return "|"; - case RIGHT_SHIFT: - return ">>"; - case UNSIGNED_RIGHT_SHIFT: - return ">>>"; - default: - throw new IllegalArgumentException("Unexpected operator assignment kind: " + kind); - } + return switch (kind) { + case MULTIPLY -> "*"; + case DIVIDE -> "/"; + case REMAINDER -> "%"; + case PLUS -> "+"; + case MINUS -> "-"; + case LEFT_SHIFT -> "<<"; + case AND -> "&"; + case XOR -> "^"; + case OR -> "|"; + case RIGHT_SHIFT -> ">>"; + case UNSIGNED_RIGHT_SHIFT -> ">>>"; + default -> throw new IllegalArgumentException("Unexpected operator assignment kind: " + kind); + }; } static Kind regularAssignmentFromCompound(Kind kind) { - switch (kind) { - case MULTIPLY_ASSIGNMENT: - return Kind.MULTIPLY; - case DIVIDE_ASSIGNMENT: - return Kind.DIVIDE; - case REMAINDER_ASSIGNMENT: - return Kind.REMAINDER; - case PLUS_ASSIGNMENT: - return Kind.PLUS; - case MINUS_ASSIGNMENT: - return Kind.MINUS; - case LEFT_SHIFT_ASSIGNMENT: - return Kind.LEFT_SHIFT; - case AND_ASSIGNMENT: - return Kind.AND; - case XOR_ASSIGNMENT: - return Kind.XOR; - case OR_ASSIGNMENT: - return Kind.OR; - case RIGHT_SHIFT_ASSIGNMENT: - return Kind.RIGHT_SHIFT; - case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT: - return Kind.UNSIGNED_RIGHT_SHIFT; - default: - throw new IllegalArgumentException("Unexpected compound assignment kind: " + kind); - } + return switch (kind) { + case MULTIPLY_ASSIGNMENT -> Kind.MULTIPLY; + case DIVIDE_ASSIGNMENT -> Kind.DIVIDE; + case REMAINDER_ASSIGNMENT -> Kind.REMAINDER; + case PLUS_ASSIGNMENT -> Kind.PLUS; + case MINUS_ASSIGNMENT -> Kind.MINUS; + case LEFT_SHIFT_ASSIGNMENT -> Kind.LEFT_SHIFT; + case AND_ASSIGNMENT -> Kind.AND; + case XOR_ASSIGNMENT -> Kind.XOR; + case OR_ASSIGNMENT -> Kind.OR; + case RIGHT_SHIFT_ASSIGNMENT -> Kind.RIGHT_SHIFT; + case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT -> Kind.UNSIGNED_RIGHT_SHIFT; + default -> throw new IllegalArgumentException("Unexpected compound assignment kind: " + kind); + }; } @Override @@ -146,18 +122,16 @@ private static Optional rewriteCompoundAssignment( return Optional.absent(); } switch (tree.getKind()) { - case RIGHT_SHIFT_ASSIGNMENT: + case RIGHT_SHIFT_ASSIGNMENT -> { // narrowing the result of a signed right shift does not lose information return Optional.absent(); - case AND_ASSIGNMENT: - case XOR_ASSIGNMENT: - case OR_ASSIGNMENT: + } + case AND_ASSIGNMENT, XOR_ASSIGNMENT, OR_ASSIGNMENT -> { if (twiddlingConstantBitsOk(tree)) { return Optional.absent(); } - break; - default: - break; + } + default -> {} } Kind regularAssignmentKind = regularAssignmentFromCompound(tree.getKind()); String op = assignmentToString(regularAssignmentKind); @@ -186,14 +160,11 @@ private static Optional rewriteCompoundAssignment( private static boolean twiddlingConstantBitsOk(CompoundAssignmentTree tree) { int shift; switch (ASTHelpers.getType(tree.getVariable()).getKind()) { - case BYTE: - shift = 8; - break; - case SHORT: - shift = 16; - break; - default: + case BYTE -> shift = 8; + case SHORT -> shift = 16; + default -> { return false; + } } Object constValue = ASTHelpers.constValue(tree.getExpression()); if (!(constValue instanceof Integer || constValue instanceof Long)) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/NoAllocationChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/NoAllocationChecker.java index 611fead87fa..187bb669e07 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/NoAllocationChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/NoAllocationChecker.java @@ -193,14 +193,14 @@ public boolean matches(Tree tree, VisitorState state) { Tree node = path.getLeaf(); state = state.withPath(path); switch (node.getKind()) { - case METHOD: + case METHOD -> { // We've gotten to the top of the method without finding a throw. return false; - case THROW: - case ANNOTATION: + } + case THROW, ANNOTATION -> { return true; - default: - path = path.getParentPath(); + } + default -> path = path.getParentPath(); } } return false; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/NonCanonicalType.java b/core/src/main/java/com/google/errorprone/bugpatterns/NonCanonicalType.java index 1de0b2134f8..4f9803ab680 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/NonCanonicalType.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/NonCanonicalType.java @@ -122,9 +122,10 @@ private static String createDescription(String canonicalName, String nonCanonica */ private static String getNonCanonicalName(Tree tree) { switch (tree.getKind()) { - case IDENTIFIER: + case IDENTIFIER -> { return getSymbol(tree).getQualifiedName().toString(); - case MEMBER_SELECT: + } + case MEMBER_SELECT -> { MemberSelectTree memberSelectTree = (MemberSelectTree) tree; Symbol expressionSymbol = getSymbol(memberSelectTree.getExpression()); if (!(expressionSymbol instanceof TypeSymbol)) { @@ -133,12 +134,14 @@ private static String getNonCanonicalName(Tree tree) { return getNonCanonicalName(memberSelectTree.getExpression()) + "." + memberSelectTree.getIdentifier(); - case PARAMETERIZED_TYPE: + } + case PARAMETERIZED_TYPE -> { return getNonCanonicalName(((ParameterizedTypeTree) tree).getType()); - case ANNOTATED_TYPE: + } + case ANNOTATED_TYPE -> { return getNonCanonicalName(((AnnotatedTypeTree) tree).getUnderlyingType()); - default: - throw new AssertionError(tree.getKind()); + } + default -> throw new AssertionError(tree.getKind()); } } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/NonFinalStaticField.java b/core/src/main/java/com/google/errorprone/bugpatterns/NonFinalStaticField.java index a612b907d9a..f9a1d7cf660 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/NonFinalStaticField.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/NonFinalStaticField.java @@ -173,15 +173,10 @@ private void isMutated() { } private boolean isMutating(Kind kind) { - switch (kind) { - case POSTFIX_DECREMENT: - case POSTFIX_INCREMENT: - case PREFIX_DECREMENT: - case PREFIX_INCREMENT: - return true; - default: - return false; - } + return switch (kind) { + case POSTFIX_DECREMENT, POSTFIX_INCREMENT, PREFIX_DECREMENT, PREFIX_INCREMENT -> true; + default -> false; + }; } @Override diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/NonRuntimeAnnotation.java b/core/src/main/java/com/google/errorprone/bugpatterns/NonRuntimeAnnotation.java index b194227ad3f..8d0c9f81f66 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/NonRuntimeAnnotation.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/NonRuntimeAnnotation.java @@ -63,16 +63,15 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState } RetentionPolicy retention = state.getTypes().getRetention(type.asElement()); switch (retention) { - case RUNTIME: - break; - case SOURCE: - case CLASS: + case RUNTIME -> {} + case SOURCE, CLASS -> { return buildDescription(tree) .setMessage( String.format( "%s; %s has %s retention", message(), type.asElement().getSimpleName(), retention)) .build(); + } } return NO_MATCH; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/PrivateConstructorForUtilityClass.java b/core/src/main/java/com/google/errorprone/bugpatterns/PrivateConstructorForUtilityClass.java index 860fa2d6df9..a57a2075742 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/PrivateConstructorForUtilityClass.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/PrivateConstructorForUtilityClass.java @@ -106,23 +106,27 @@ private static boolean isInPrivateScope(VisitorState state) { private static boolean isInstance(Tree tree) { switch (tree.getKind()) { - case CLASS: + case CLASS -> { return !((ClassTree) tree).getModifiers().getFlags().contains(STATIC); - case METHOD: + } + case METHOD -> { return !((MethodTree) tree).getModifiers().getFlags().contains(STATIC); - case VARIABLE: + } + case VARIABLE -> { return !((VariableTree) tree).getModifiers().getFlags().contains(STATIC); - case BLOCK: + } + case BLOCK -> { return !((BlockTree) tree).isStatic(); - case ENUM: - case ANNOTATION_TYPE: - case INTERFACE: + } + case ENUM, ANNOTATION_TYPE, INTERFACE -> { return false; - default: + } + default -> { if (tree.getKind().name().equals("RECORD")) { return false; } throw new AssertionError("unknown member type:" + tree.getKind()); + } } } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ProtoStringFieldReferenceEquality.java b/core/src/main/java/com/google/errorprone/bugpatterns/ProtoStringFieldReferenceEquality.java index 81ea58f0278..17b92d05120 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ProtoStringFieldReferenceEquality.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ProtoStringFieldReferenceEquality.java @@ -50,11 +50,10 @@ public class ProtoStringFieldReferenceEquality extends BugChecker implements Bin @Override public Description matchBinary(BinaryTree tree, VisitorState state) { switch (tree.getKind()) { - case EQUAL_TO: - case NOT_EQUAL_TO: - break; - default: + case EQUAL_TO, NOT_EQUAL_TO -> {} + default -> { return NO_MATCH; + } } ExpressionTree lhs = tree.getLeftOperand(); ExpressionTree rhs = tree.getRightOperand(); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ReachabilityFenceUsage.java b/core/src/main/java/com/google/errorprone/bugpatterns/ReachabilityFenceUsage.java index 86d3ebd3527..8af6a79c465 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ReachabilityFenceUsage.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ReachabilityFenceUsage.java @@ -49,16 +49,15 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState OUTER: for (Tree enclosing : state.getPath().getParentPath()) { switch (enclosing.getKind()) { - case TRY: + case TRY -> { if (Objects.equals(((TryTree) enclosing).getFinallyBlock(), previous)) { return NO_MATCH; } - break; - case CLASS: - case METHOD: - case LAMBDA_EXPRESSION: + } + case CLASS, METHOD, LAMBDA_EXPRESSION -> { break OUTER; - default: // fall out + } + default -> {} } previous = enclosing; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ShortCircuitBoolean.java b/core/src/main/java/com/google/errorprone/bugpatterns/ShortCircuitBoolean.java index 4b09816c13f..100ad388e5d 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ShortCircuitBoolean.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ShortCircuitBoolean.java @@ -49,11 +49,10 @@ public class ShortCircuitBoolean extends BugChecker implements BinaryTreeMatcher @Override public Description matchBinary(BinaryTree tree, VisitorState state) { switch (tree.getKind()) { - case AND: - case OR: - break; - default: + case AND, OR -> {} + default -> { return NO_MATCH; + } } if (!isSameType(getType(tree), state.getSymtab().booleanType, state)) { return NO_MATCH; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/SizeGreaterThanOrEqualsZero.java b/core/src/main/java/com/google/errorprone/bugpatterns/SizeGreaterThanOrEqualsZero.java index 4cc70ade709..d65251e8aac 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/SizeGreaterThanOrEqualsZero.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/SizeGreaterThanOrEqualsZero.java @@ -265,16 +265,17 @@ private static ExpressionType isGreaterThanEqualToZero(BinaryTree tree) { ExpressionType returnType; switch (tree.getKind()) { - case GREATER_THAN_EQUAL: + case GREATER_THAN_EQUAL -> { literalOperand = tree.getRightOperand(); returnType = ExpressionType.GREATER_THAN_EQUAL; - break; - case LESS_THAN_EQUAL: + } + case LESS_THAN_EQUAL -> { literalOperand = tree.getLeftOperand(); returnType = ExpressionType.LESS_THAN_EQUAL; - break; - default: + } + default -> { return ExpressionType.MISMATCH; + } } if (literalOperand.getKind() != Kind.INT_LITERAL) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/StaticQualifiedUsingExpression.java b/core/src/main/java/com/google/errorprone/bugpatterns/StaticQualifiedUsingExpression.java index c48eca0847f..4c170a86047 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/StaticQualifiedUsingExpression.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/StaticQualifiedUsingExpression.java @@ -74,8 +74,7 @@ public Description matchMemberSelect(MemberSelectTree tree, VisitorState state) ClassSymbol owner = sym.owner.enclClass(); ExpressionTree expression = tree.getExpression(); switch (expression.getKind()) { - case MEMBER_SELECT: - case IDENTIFIER: + case MEMBER_SELECT, IDENTIFIER -> { // References to static variables should be qualified by the type name of the owning type, // or a sub-type. e.g.: if CONST is declared in Foo, and SubFoo extends Foo, // allow `Foo.CONST` and `SubFoo.CONST` (but not, say, `new Foo().CONST`. @@ -83,8 +82,10 @@ public Description matchMemberSelect(MemberSelectTree tree, VisitorState state) if (base instanceof ClassSymbol && base.isSubClass(owner, state.getTypes())) { return NO_MATCH; } - break; - default: // continue below + } + default -> { + // continue below + } } SuggestedFix.Builder fix = SuggestedFix.builder(); String replacement; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/StringSplitter.java b/core/src/main/java/com/google/errorprone/bugpatterns/StringSplitter.java index fb0deedaa91..774c8344f01 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/StringSplitter.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/StringSplitter.java @@ -302,12 +302,13 @@ private static SuggestedFix.Builder replaceWithSplitter( private static @Nullable TreePath findEnclosing(VisitorState state) { for (TreePath path = state.getPath(); path != null; path = path.getParentPath()) { switch (path.getLeaf().getKind()) { - case METHOD: - case LAMBDA_EXPRESSION: + case METHOD, LAMBDA_EXPRESSION -> { return path; - case CLASS: + } + case CLASS -> { return null; - default: // fall out + } + default -> {} } } return null; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/StronglyType.java b/core/src/main/java/com/google/errorprone/bugpatterns/StronglyType.java index 03d38150575..8889695eb3e 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/StronglyType.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/StronglyType.java @@ -204,14 +204,12 @@ private static String getWeakTypeIntitializerCode(VariableTree weakType, Visitor } private static String getMethodSelectOrNewClass(ExpressionTree tree, VisitorState state) { - switch (tree.getKind()) { - case METHOD_INVOCATION: - return state.getSourceForNode(((MethodInvocationTree) tree).getMethodSelect()); - case NEW_CLASS: - return "new " + state.getSourceForNode(((NewClassTree) tree).getIdentifier()); - default: - throw new AssertionError(); - } + return switch (tree.getKind()) { + case METHOD_INVOCATION -> + state.getSourceForNode(((MethodInvocationTree) tree).getMethodSelect()); + case NEW_CLASS -> "new " + state.getSourceForNode(((NewClassTree) tree).getIdentifier()); + default -> throw new AssertionError(); + }; } /** Finds the path to potential fields that we might want to strongly type. */ diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/SystemConsoleNull.java b/core/src/main/java/com/google/errorprone/bugpatterns/SystemConsoleNull.java index d3d55555cc6..99e089eefef 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/SystemConsoleNull.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/SystemConsoleNull.java @@ -89,11 +89,10 @@ private static boolean isNullCheck(Tree tree) { } BinaryTree binaryTree = (BinaryTree) tree; switch (binaryTree.getKind()) { - case EQUAL_TO: - case NOT_EQUAL_TO: - break; - default: + case EQUAL_TO, NOT_EQUAL_TO -> {} + default -> { return false; + } } return binaryTree.getLeftOperand().getKind().equals(Tree.Kind.NULL_LITERAL) || binaryTree.getRightOperand().getKind().equals(Tree.Kind.NULL_LITERAL); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ThreeLetterTimeZoneID.java b/core/src/main/java/com/google/errorprone/bugpatterns/ThreeLetterTimeZoneID.java index 6bbb900439a..e0dab1e34b1 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ThreeLetterTimeZoneID.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ThreeLetterTimeZoneID.java @@ -82,17 +82,19 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState @VisibleForTesting static Replacement getReplacement(String id, boolean inJodaTimeContext, String message) { switch (id) { - case "EST": + case "EST" -> { return handleNonDaylightSavingsZone( inJodaTimeContext, "America/New_York", "Etc/GMT+5", message); - case "HST": + } + case "HST" -> { return handleNonDaylightSavingsZone( inJodaTimeContext, "Pacific/Honolulu", "Etc/GMT+10", message); - case "MST": + } + case "MST" -> { return handleNonDaylightSavingsZone( inJodaTimeContext, "America/Denver", "Etc/GMT+7", message); - default: - // Fall through, we will handle it below. + } + default -> {} } String zoneIdReplacement = ZoneId.SHORT_IDS.get(id); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ToStringReturnsNull.java b/core/src/main/java/com/google/errorprone/bugpatterns/ToStringReturnsNull.java index 14e4d4d42db..298bf400a9d 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ToStringReturnsNull.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ToStringReturnsNull.java @@ -74,15 +74,11 @@ public Boolean visitReturn(ReturnTree node, Void unused) { private static class ReturnExpressionScanner extends BooleanScanner { @Override public Boolean scan(Tree tree, Void unused) { - switch (tree.getKind()) { - case NULL_LITERAL: - return true; - case PARENTHESIZED: - case CONDITIONAL_EXPRESSION: - return super.scan(tree, null); - default: - return false; - } + return switch (tree.getKind()) { + case NULL_LITERAL -> true; + case PARENTHESIZED, CONDITIONAL_EXPRESSION -> super.scan(tree, null); + default -> false; + }; } } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/TruthAssertExpected.java b/core/src/main/java/com/google/errorprone/bugpatterns/TruthAssertExpected.java index ad72c3c2d68..8ccbe3e999d 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/TruthAssertExpected.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/TruthAssertExpected.java @@ -201,14 +201,10 @@ private static Matcher hasReceiverMatching(Matcher (IdentifierTree) tree; + case MEMBER_SELECT, METHOD_INVOCATION -> getRootIdentifier(ASTHelpers.getReceiver(tree)); + default -> null; + }; } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/TruthGetOrDefault.java b/core/src/main/java/com/google/errorprone/bugpatterns/TruthGetOrDefault.java index 243bd0057f0..acfe4a6ec8e 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/TruthGetOrDefault.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/TruthGetOrDefault.java @@ -74,41 +74,39 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState ExpressionTree defaultVal = argMethodInvocationTree.getArguments().get(1); ExpressionTree expectedVal = getOnlyElement(tree.getArguments()); Match match = areValuesSame(defaultVal, expectedVal, state); - switch (match) { - case UNKNOWN: - return Description.NO_MATCH; - case DIFFERENT: - return describeMatch( - tree, - SuggestedFix.builder() - .replace( - argMethodInvocationTree, - state.getSourceForNode(ASTHelpers.getReceiver(argMethodInvocationTree))) - .replace( - state.getEndPosition(rec), - state.getEndPosition(tree.getMethodSelect()), - ".containsEntry") - .replace( - tree.getArguments().get(0), - state.getSourceForNode(argMethodInvocationTree.getArguments().get(0)) - + ", " - + state.getSourceForNode(tree.getArguments().get(0))) - .build()); - case SAME: - return describeMatch( - tree, - SuggestedFix.builder() - .replace(arg, state.getSourceForNode(ASTHelpers.getReceiver(arg))) - .replace( - state.getEndPosition(rec), - state.getEndPosition(tree.getMethodSelect()), - ".doesNotContainKey") - .replace( - tree.getArguments().get(0), - state.getSourceForNode(argMethodInvocationTree.getArguments().get(0))) - .build()); - } - return Description.NO_MATCH; + return switch (match) { + case UNKNOWN -> Description.NO_MATCH; + case DIFFERENT -> + describeMatch( + tree, + SuggestedFix.builder() + .replace( + argMethodInvocationTree, + state.getSourceForNode(ASTHelpers.getReceiver(argMethodInvocationTree))) + .replace( + state.getEndPosition(rec), + state.getEndPosition(tree.getMethodSelect()), + ".containsEntry") + .replace( + tree.getArguments().get(0), + state.getSourceForNode(argMethodInvocationTree.getArguments().get(0)) + + ", " + + state.getSourceForNode(tree.getArguments().get(0))) + .build()); + case SAME -> + describeMatch( + tree, + SuggestedFix.builder() + .replace(arg, state.getSourceForNode(ASTHelpers.getReceiver(arg))) + .replace( + state.getEndPosition(rec), + state.getEndPosition(tree.getMethodSelect()), + ".doesNotContainKey") + .replace( + tree.getArguments().get(0), + state.getSourceForNode(argMethodInvocationTree.getArguments().get(0))) + .build()); + }; } private enum Match { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/TypeParameterNaming.java b/core/src/main/java/com/google/errorprone/bugpatterns/TypeParameterNaming.java index b260d6936ba..4018aaf4205 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/TypeParameterNaming.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/TypeParameterNaming.java @@ -189,13 +189,11 @@ private static List typeVariablesEnclosing(Symbol sym) { while (!isStatic(sym)) { sym = sym.owner; switch (sym.getKind()) { - case PACKAGE: + case PACKAGE -> { break outer; - case METHOD: - case CLASS: - typeVarScopes.addAll(0, sym.getTypeParameters()); - break; - default: // fall out + } + case METHOD, CLASS -> typeVarScopes.addAll(0, sym.getTypeParameters()); + default -> {} } } return typeVarScopes; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/TypeParameterShadowing.java b/core/src/main/java/com/google/errorprone/bugpatterns/TypeParameterShadowing.java index 8e2392a2629..cc996ee4780 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/TypeParameterShadowing.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/TypeParameterShadowing.java @@ -163,13 +163,11 @@ private static List typeVariablesEnclosing(Symbol sym) { while (!isStatic(sym)) { sym = sym.owner; switch (sym.getKind()) { - case PACKAGE: + case PACKAGE -> { break outer; - case METHOD: - case CLASS: - typeVarScopes.addAll(sym.getTypeParameters()); - break; - default: // fall out + } + case METHOD, CLASS -> typeVarScopes.addAll(sym.getTypeParameters()); + default -> {} } } return typeVarScopes; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/TypeParameterUnusedInFormals.java b/core/src/main/java/com/google/errorprone/bugpatterns/TypeParameterUnusedInFormals.java index eed779e24df..6fc8414543c 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/TypeParameterUnusedInFormals.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/TypeParameterUnusedInFormals.java @@ -51,11 +51,10 @@ public Description matchMethod(MethodTree tree, VisitorState state) { // e.g. the following is OK: List newArrayList(); TypeVar retType; switch (methodSymbol.getReturnType().getKind()) { - case TYPEVAR: - retType = (TypeVar) methodSymbol.getReturnType(); - break; - default: + case TYPEVAR -> retType = (TypeVar) methodSymbol.getReturnType(); + default -> { return Description.NO_MATCH; + } } if (!methodSymbol.equals(retType.tsym.owner)) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnicodeDirectionalityCharacters.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnicodeDirectionalityCharacters.java index f0cdf0818fd..7ce24a0e5fb 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnicodeDirectionalityCharacters.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnicodeDirectionalityCharacters.java @@ -44,22 +44,20 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s // checker is expensive for large files, and also that the method-call overhead would // double the time spent in this loop. switch (c) { - case 0x202A: // Left-to-Right Embedding - case 0x202B: // Right-to-Left Embedding - case 0x202C: // Pop Directional Formatting - case 0x202D: // Left-to-Right Override - case 0x202E: // Right-to-Left Override - case 0x2066: // Left-to-Right Isolate - case 0x2067: // Right-to-Left Isolate - case 0x2068: // First Strong Isolate - case 0x2069: // Pop Directional Isolate - state.reportMatch( - describeMatch( - new FixedPosition(tree, i), - SuggestedFix.replace(i, i + 1, String.format("\\u%04x", (int) c)))); - break; - default: - break; + case 0x202A, // Left-to-Right Embedding + 0x202B, // Right-to-Left Embedding + 0x202C, // Pop Directional Formatting + 0x202D, // Left-to-Right Override + 0x202E, // Right-to-Left Override + 0x2066, // Left-to-Right Isolate + 0x2067, // Right-to-Left Isolate + 0x2068, // First Strong Isolate + 0x2069 -> // Pop Directional Isolate + state.reportMatch( + describeMatch( + new FixedPosition(tree, i), + SuggestedFix.replace(i, i + 1, String.format("\\u%04x", (int) c)))); + default -> {} } } return NO_MATCH; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryAsync.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryAsync.java index 748e12704c3..e15c4a437a4 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryAsync.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryAsync.java @@ -218,34 +218,26 @@ private boolean isVariableDeclarationItself(Tree parentTree) { private static String getPrimitiveType(Type type, Types types) { String name = types.erasure(type).toString(); - switch (name) { - case "java.util.concurrent.atomic.AtomicBoolean": - return "boolean"; - case "java.util.concurrent.atomic.AtomicReference": - return type.allparams().isEmpty() - ? "Object" - : type.allparams().get(0).tsym.getSimpleName().toString(); - case "java.util.concurrent.atomic.AtomicInteger": - return "int"; - case "java.util.concurrent.atomic.AtomicLong": - return "long"; - default: - throw new AssertionError(name); - } + return switch (name) { + case "java.util.concurrent.atomic.AtomicBoolean" -> "boolean"; + case "java.util.concurrent.atomic.AtomicReference" -> + type.allparams().isEmpty() + ? "Object" + : type.allparams().get(0).tsym.getSimpleName().toString(); + case "java.util.concurrent.atomic.AtomicInteger" -> "int"; + case "java.util.concurrent.atomic.AtomicLong" -> "long"; + default -> throw new AssertionError(name); + }; } private static String getDefaultInitializer(VarSymbol symbol, Types types) { String name = types.erasure(symbol.type).toString(); - switch (name) { - case "java.util.concurrent.atomic.AtomicBoolean": - return "false"; - case "java.util.concurrent.atomic.AtomicReference": - return "null"; - case "java.util.concurrent.atomic.AtomicInteger": - case "java.util.concurrent.atomic.AtomicLong": - return "0"; - default: - throw new AssertionError(name); - } + return switch (name) { + case "java.util.concurrent.atomic.AtomicBoolean" -> "false"; + case "java.util.concurrent.atomic.AtomicReference" -> "null"; + case "java.util.concurrent.atomic.AtomicInteger", "java.util.concurrent.atomic.AtomicLong" -> + "0"; + default -> throw new AssertionError(name); + }; } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryParentheses.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryParentheses.java index 474d1b4ffa9..7c10c016d5f 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryParentheses.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryParentheses.java @@ -43,19 +43,16 @@ public Description matchParenthesized(ParenthesizedTree tree, VisitorState state ExpressionTree expression = tree.getExpression(); Tree parent = state.getPath().getParentPath().getLeaf(); switch (parent.getKind()) { - case IF: - case WHILE_LOOP: - case DO_WHILE_LOOP: - case FOR_LOOP: - case SWITCH: - case SYNCHRONIZED: + case IF, WHILE_LOOP, DO_WHILE_LOOP, FOR_LOOP, SWITCH, SYNCHRONIZED -> { return NO_MATCH; - default: // fall out + } + default -> {} } switch (parent.getKind().name()) { - case "SWITCH_EXPRESSION": + case "SWITCH_EXPRESSION" -> { return NO_MATCH; - default: // fall out + } + default -> {} } if (ASTHelpers.requiresParentheses(expression, state)) { return NO_MATCH; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryStringBuilder.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryStringBuilder.java index c44e1de9857..b2bbf006f0c 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryStringBuilder.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryStringBuilder.java @@ -75,16 +75,16 @@ public Description matchNewClass(NewClassTree tree, VisitorState state) { } List parts = new ArrayList<>(); switch (tree.getArguments().size()) { - case 0: - break; - case 1: + case 0 -> {} + case 1 -> { ExpressionTree argument = getOnlyElement(tree.getArguments()); if (isSubtype(getType(argument), JAVA_LANG_CHARSEQUENCE.get(state), state)) { parts.add(argument); } - break; - default: + } + default -> { return NO_MATCH; + } } TreePath path = state.getPath(); while (true) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnsynchronizedOverridesSynchronized.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnsynchronizedOverridesSynchronized.java index 53d12dd7162..d4ed5639f5c 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnsynchronizedOverridesSynchronized.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnsynchronizedOverridesSynchronized.java @@ -104,14 +104,11 @@ private boolean ignore(MethodTree method, VisitorState state) { new TreeScanner() { @Override public Boolean visitBlock(BlockTree tree, Void unused) { - switch (tree.getStatements().size()) { - case 0: - return true; - case 1: - return scan(getOnlyElement(tree.getStatements()), null); - default: - return false; - } + return switch (tree.getStatements().size()) { + case 0 -> true; + case 1 -> scan(getOnlyElement(tree.getStatements()), null); + default -> false; + }; } @Override diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnusedAnonymousClass.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnusedAnonymousClass.java index 95ad0a94831..b9e973bdf32 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnusedAnonymousClass.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnusedAnonymousClass.java @@ -50,18 +50,16 @@ public Description matchNewClass(NewClassTree newClassTree, VisitorState state) } for (Tree def : newClassTree.getClassBody().getMembers()) { switch (def.getKind()) { - case VARIABLE: - { - VariableTree variableTree = (VariableTree) def; - if (variableTree.getInitializer() != null) { - return Description.NO_MATCH; - } - break; + case VARIABLE -> { + VariableTree variableTree = (VariableTree) def; + if (variableTree.getInitializer() != null) { + return Description.NO_MATCH; } - case BLOCK: + } + case BLOCK -> { return Description.NO_MATCH; - default: - break; + } + default -> {} } } if (!sideEffectFreeConstructor(ASTHelpers.getType(newClassTree.getIdentifier()).tsym, state)) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnusedVariable.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnusedVariable.java index cfb211d3d70..a80931ea707 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnusedVariable.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnusedVariable.java @@ -338,16 +338,12 @@ private static SuggestedFix makeAssignmentDeclaration( } private static String describeVariable(VarSymbol symbol) { - switch (symbol.getKind()) { - case FIELD: - return "field"; - case LOCAL_VARIABLE: - return "local variable"; - case PARAMETER: - return "parameter"; - default: - return "variable"; - } + return switch (symbol.getKind()) { + case FIELD -> "field"; + case LOCAL_VARIABLE -> "local variable"; + case PARAMETER -> "parameter"; + default -> "variable"; + }; } private static boolean hasNativeMethods(CompilationUnitTree tree) { @@ -675,18 +671,18 @@ && exemptedFieldBySuperType(getType(variableTree), state)) { return; } switch (symbol.getKind()) { - case FIELD: + case FIELD -> { // We are only interested in private fields and those which are not special. if (isFieldEligibleForChecking(variableTree, symbol)) { unusedElements.put(symbol, getCurrentPath()); usageSites.put(symbol, getCurrentPath()); } - break; - case LOCAL_VARIABLE: + } + case LOCAL_VARIABLE -> { unusedElements.put(symbol, getCurrentPath()); usageSites.put(symbol, getCurrentPath()); - break; - case PARAMETER: + } + case PARAMETER -> { // ignore the receiver parameter if (variableTree.getName().contentEquals("this")) { return; @@ -702,9 +698,8 @@ && exemptedFieldBySuperType(getType(variableTree), state)) { if (!isParameterSubjectToAnalysis(symbol)) { onlyCheckForReassignments.add(symbol); } - break; - default: - break; + } + default -> {} } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/VarChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/VarChecker.java index e69d8591055..1d8d5321ded 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/VarChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/VarChecker.java @@ -77,15 +77,11 @@ public Description matchVariable(VariableTree tree, VisitorState state) { // TODO(cushon): consider requiring @Var if the index is modified in the body of the loop return Description.NO_MATCH; } - switch (sym.getKind()) { - case PARAMETER: - case LOCAL_VARIABLE: - case EXCEPTION_PARAMETER: - case RESOURCE_VARIABLE: - return handleLocalOrParam(tree, state, sym); - default: - return Description.NO_MATCH; - } + return switch (sym.getKind()) { + case PARAMETER, LOCAL_VARIABLE, EXCEPTION_PARAMETER, RESOURCE_VARIABLE -> + handleLocalOrParam(tree, state, sym); + default -> Description.NO_MATCH; + }; } boolean forLoopVariable(VariableTree tree, TreePath path) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/WildcardImport.java b/core/src/main/java/com/google/errorprone/bugpatterns/WildcardImport.java index 73d550b5127..742dadf8488 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/WildcardImport.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/WildcardImport.java @@ -174,17 +174,16 @@ public void visitIdent(JCIdent tree) { return; } switch (sym.kind) { - case TYP: - seen.add( - TypeToImport.create(sym.getSimpleName().toString(), sym.owner, /* stat= */ false)); - break; - case VAR: - case MTH: - seen.add( - TypeToImport.create(sym.getSimpleName().toString(), sym.owner, /* stat= */ true)); - break; - default: + case TYP -> + seen.add( + TypeToImport.create( + sym.getSimpleName().toString(), sym.owner, /* stat= */ false)); + case VAR, MTH -> + seen.add( + TypeToImport.create(sym.getSimpleName().toString(), sym.owner, /* stat= */ true)); + default -> { return; + } } } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/XorPower.java b/core/src/main/java/com/google/errorprone/bugpatterns/XorPower.java index 5333881012c..b5bf8d89f5b 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/XorPower.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/XorPower.java @@ -49,11 +49,10 @@ public Description matchBinary(BinaryTree tree, VisitorState state) { return NO_MATCH; } switch (lhs.intValue()) { - case 2: - case 10: - break; - default: + case 2, 10 -> {} + default -> { return NO_MATCH; + } } Number rhs = ASTHelpers.constValue(tree.getRightOperand(), Number.class); if (rhs == null) { @@ -77,7 +76,7 @@ public Description matchBinary(BinaryTree tree, VisitorState state) { int start = getStartPosition(lhsTree); int end = state.getEndPosition(tree); switch (lhs.intValue()) { - case 2: + case 2 -> { if (rhs.intValue() <= (lhs instanceof Long ? 63 : 31)) { String replacement = String.format("1%s << %d", suffix, rhs); if (start != getStartPosition(tree)) { @@ -85,15 +84,14 @@ public Description matchBinary(BinaryTree tree, VisitorState state) { } description.addFix(SuggestedFix.replace(start, end, replacement)); } - break; - case 10: + } + case 10 -> { if (rhs.intValue() <= (lhs instanceof Long ? 18 : 9)) { description.addFix( SuggestedFix.replace(start, end, "1" + "0".repeat(rhs.intValue()) + suffix)); } - break; - default: - throw new AssertionError(lhs); + } + default -> throw new AssertionError(lhs); } return description.build(); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/YodaCondition.java b/core/src/main/java/com/google/errorprone/bugpatterns/YodaCondition.java index ce66fa31acc..4035fe96f13 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/YodaCondition.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/YodaCondition.java @@ -57,22 +57,16 @@ public final class YodaCondition extends BugChecker implements BinaryTreeMatcher, MethodInvocationTreeMatcher { @Override public Description matchBinary(BinaryTree tree, VisitorState state) { - switch (tree.getKind()) { - case EQUAL_TO: - case NOT_EQUAL_TO: - case LESS_THAN: - case GREATER_THAN: - case LESS_THAN_EQUAL: - case GREATER_THAN_EQUAL: - return fix( - tree, - tree.getLeftOperand(), - tree.getRightOperand(), - /* provideNullSafeFix= */ false, - state); - default: - return NO_MATCH; - } + return switch (tree.getKind()) { + case EQUAL_TO, NOT_EQUAL_TO, LESS_THAN, GREATER_THAN, LESS_THAN_EQUAL, GREATER_THAN_EQUAL -> + fix( + tree, + tree.getLeftOperand(), + tree.getRightOperand(), + /* provideNullSafeFix= */ false, + state); + default -> NO_MATCH; + }; } @Override @@ -171,30 +165,20 @@ private static boolean hasAdjacentComparison(VisitorState state) { } private static boolean isInequality(Tree tree) { - switch (tree.getKind()) { - case LESS_THAN: - case GREATER_THAN: - case LESS_THAN_EQUAL: - case GREATER_THAN_EQUAL: - return true; - default: - return false; - } + return switch (tree.getKind()) { + case LESS_THAN, GREATER_THAN, LESS_THAN_EQUAL, GREATER_THAN_EQUAL -> true; + default -> false; + }; } private static String inverse(Tree tree) { - switch (tree.getKind()) { - case LESS_THAN: - return ">"; - case GREATER_THAN: - return "<"; - case LESS_THAN_EQUAL: - return ">="; - case GREATER_THAN_EQUAL: - return "<="; - default: - throw new AssertionError(); - } + return switch (tree.getKind()) { + case LESS_THAN -> ">"; + case GREATER_THAN -> "<"; + case LESS_THAN_EQUAL -> ">="; + case GREATER_THAN_EQUAL -> "<="; + default -> throw new AssertionError(); + }; } private static boolean yodaCondition(ExpressionTree lhs, ExpressionTree rhs) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/ApiDiff.java b/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/ApiDiff.java index 042a1c47400..71666a91dd2 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/ApiDiff.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/ApiDiff.java @@ -79,19 +79,16 @@ public static ApiDiff fromProto(Diff diff) { ImmutableSetMultimap.builder(); for (ApiDiffProto.ClassDiff c : diff.getClassDiffList()) { switch (c.getDiffCase()) { - case EVERYTHING_DIFF: - unsupportedClasses.add(c.getEverythingDiff().getClassName()); - break; - case MEMBER_DIFF: + case EVERYTHING_DIFF -> unsupportedClasses.add(c.getEverythingDiff().getClassName()); + case MEMBER_DIFF -> { ApiDiffProto.MemberDiff memberDiff = c.getMemberDiff(); for (ApiDiffProto.ClassMember member : memberDiff.getMemberList()) { unsupportedMembersByClass.put( memberDiff.getClassName(), ClassMemberKey.create(member.getIdentifier(), member.getMemberDescriptor())); } - break; - default: - throw new AssertionError(c.getDiffCase()); + } + default -> throw new AssertionError(c.getDiffCase()); } } return new AutoValue_ApiDiff(unsupportedClasses.build(), unsupportedMembersByClass.build()); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/ApiDiffChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/ApiDiffChecker.java index 2ccd70757b9..e8e484fd6a7 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/ApiDiffChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/ApiDiffChecker.java @@ -129,20 +129,22 @@ private boolean hasAnnotationForbiddingUse(Symbol sym, VisitorState state) { return sym.enclClass(); } switch (tree.getKind()) { - case MEMBER_SELECT: - case METHOD_INVOCATION: + case MEMBER_SELECT, METHOD_INVOCATION -> { Type receiver = ASTHelpers.getType(ASTHelpers.getReceiver(tree)); if (receiver == null) { return null; } return receiver.tsym.enclClass(); - case IDENTIFIER: + } + case IDENTIFIER -> { // Simple names are implicitly qualified by an enclosing instance, so if we get here // we're inside the compilation unit that declares the receiver, and the diff doesn't // contain accurate information. return null; - default: + } + default -> { return null; + } } } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/AssertEqualsArgumentOrderChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/AssertEqualsArgumentOrderChecker.java index 8ae69f60684..7522028c7cb 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/AssertEqualsArgumentOrderChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/AssertEqualsArgumentOrderChecker.java @@ -121,11 +121,10 @@ public Double apply(ParameterPair parameterPair) { /** Returns true if this parameter is an enum identifier */ private static boolean isEnumIdentifier(Parameter parameter) { switch (parameter.kind()) { - case IDENTIFIER: - case MEMBER_SELECT: - break; - default: + case IDENTIFIER, MEMBER_SELECT -> {} + default -> { return false; + } } TypeSymbol typeSymbol = parameter.type().tsym; if (typeSymbol != null) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NameInCommentHeuristic.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NameInCommentHeuristic.java index 20cd8764afa..0c44fe54a18 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NameInCommentHeuristic.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NameInCommentHeuristic.java @@ -58,14 +58,13 @@ public boolean isAcceptableChange( private static ImmutableList> findCommentsForArguments( Tree tree, VisitorState state) { - switch (tree.getKind()) { - case METHOD_INVOCATION: - return Comments.findCommentsForArguments((MethodInvocationTree) tree, state); - case NEW_CLASS: - return Comments.findCommentsForArguments((NewClassTree) tree, state); - default: - throw new IllegalArgumentException( - "Only MethodInvocationTree or NewClassTree is supported"); - } + return switch (tree.getKind()) { + case METHOD_INVOCATION -> + Comments.findCommentsForArguments((MethodInvocationTree) tree, state); + case NEW_CLASS -> Comments.findCommentsForArguments((NewClassTree) tree, state); + default -> + throw new IllegalArgumentException( + "Only MethodInvocationTree or NewClassTree is supported"); + }; } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NamedParameterComment.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NamedParameterComment.java index f60a7597b63..b73f5e68257 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NamedParameterComment.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/NamedParameterComment.java @@ -83,8 +83,7 @@ static MatchedComment notAnnotated() { private static boolean isApproximateMatchingComment(ErrorProneComment comment, String formal) { switch (comment.getStyle()) { - case BLOCK: - case LINE: + case BLOCK, LINE -> { // sometimes people use comments around arguments for higher level structuring - such as // dividing two separate blocks of arguments. In these cases we want to avoid concluding // that it's a match. Therefore we also check to make sure that the comment is not really @@ -95,8 +94,10 @@ private static boolean isApproximateMatchingComment(ErrorProneComment comment, S boolean tooLong = commentText.length() > formal.length() + 5 && commentText.length() > 50; boolean tooMuchMarkup = CharMatcher.anyOf("-*!@<>").countIn(commentText) > 5; return textMatches && !tooLong && !tooMuchMarkup; - default: + } + default -> { return false; + } } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Parameter.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Parameter.java index 8ef9a87a7c9..7235a043588 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Parameter.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Parameter.java @@ -164,12 +164,14 @@ private static String getClassName(ClassSymbol s) { @VisibleForTesting static String getArgumentName(ExpressionTree expressionTree) { switch (expressionTree.getKind()) { - case MEMBER_SELECT: + case MEMBER_SELECT -> { return ((MemberSelectTree) expressionTree).getIdentifier().toString(); - case NULL_LITERAL: + } + case NULL_LITERAL -> { // null could match anything pretty well return NAME_NULL; - case IDENTIFIER: + } + case IDENTIFIER -> { IdentifierTree idTree = (IdentifierTree) expressionTree; if (idTree.getName().contentEquals("this")) { // for the 'this' keyword the argument name is the name of the object's class @@ -179,7 +181,8 @@ static String getArgumentName(ExpressionTree expressionTree) { // if we have a variable, just extract its name return idTree.getName().toString(); } - case METHOD_INVOCATION: + } + case METHOD_INVOCATION -> { MethodInvocationTree methodInvocationTree = (MethodInvocationTree) expressionTree; MethodSymbol methodSym = ASTHelpers.getSymbol(methodInvocationTree); String name = methodSym.getSimpleName().toString(); @@ -199,13 +202,16 @@ static String getArgumentName(ExpressionTree expressionTree) { } else { return name; } - case NEW_CLASS: + } + case NEW_CLASS -> { MethodSymbol constructorSym = ASTHelpers.getSymbol((NewClassTree) expressionTree); return constructorSym.owner != null ? getClassName((ClassSymbol) constructorSym.owner) : NAME_NOT_PRESENT; - default: + } + default -> { return NAME_NOT_PRESENT; + } } } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/checkreturnvalue/Api.java b/core/src/main/java/com/google/errorprone/bugpatterns/checkreturnvalue/Api.java index d72eab342f9..a15fcaf3fc1 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/checkreturnvalue/Api.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/checkreturnvalue/Api.java @@ -144,21 +144,22 @@ String owningType() { do { char next = nextLookingFor('#'); switch (next) { - case '#': + case '#' -> { // We've hit the end of the leading type, break out. break token; - case '.': + } + case '.' -> { // OK, separator - break; - case '-': + } + case '-' -> { // OK, used in Kotlin JvmName to prevent Java users. - break; - default: - checkArgument( - isJavaIdentifierPart(next), - "Unable to parse '%s' because '%s' is not a valid identifier", - api, - next); + } + default -> + checkArgument( + isJavaIdentifierPart(next), + "Unable to parse '%s' because '%s' is not a valid identifier", + api, + next); } buffer.append(next); } while (true); @@ -181,26 +182,27 @@ String methodName() { do { char next = nextLookingFor('('); switch (next) { - case '(': + case '(' -> { // We've hit the end of the method name, break out. break token; - case '<': + } + case '<' -> { // Starting a constructor check(!isConstructor, api, "Only one '<' is allowed"); check(buffer.length() == 0, api, "'<' must come directly after '#'"); isConstructor = true; - break; - case '>': + } + case '>' -> { check(isConstructor, api, "'<' must come before '>'"); check(!finishedConstructor, api, "Only one '>' is allowed"); finishedConstructor = true; - break; - default: - checkArgument( - isJavaIdentifierPart(next), - "Unable to parse '%s' because '%s' is not a valid identifier", - api, - next); + } + default -> + checkArgument( + isJavaIdentifierPart(next), + "Unable to parse '%s' because '%s' is not a valid identifier", + api, + next); } buffer.append(next); } while (true); @@ -236,26 +238,22 @@ ImmutableList parameters() { do { char next = nextLookingFor(')'); switch (next) { - case ')': + case ')' -> { if (emptyList) { return ImmutableList.of(); } // We've hit the end of the whole list, bail out. paramBuilder.add(consumeParam(buffer)); break paramList; - case ',': - // We've hit the middle of a parameter, consume it - paramBuilder.add(consumeParam(buffer)); - break; - - case '[': - case ']': - case '.': - // . characters are separators, [ and ] are array characters, they're checked @ the end - buffer.append(next); - break; - - default: + } + case ',' -> + // We've hit the middle of a parameter, consume it + paramBuilder.add(consumeParam(buffer)); + case '[', ']', '.' -> + // . characters are separators, [ and ] are array characters, they're checked @ the + // end + buffer.append(next); + default -> { checkArgument( isJavaIdentifierPart(next), "Unable to parse '%s' because '%s' is not a valid identifier", @@ -263,6 +261,7 @@ ImmutableList parameters() { next); emptyList = false; buffer.append(next); + } } } while (true); return paramBuilder.build(); @@ -284,20 +283,20 @@ private String consumeParam(StringBuilder buffer) { for (int k = 1; k < parameter.length(); k++) { char c = parameter.charAt(k); switch (c) { - case '[': + case '[' -> { check(!parsingArrayStart, api, "multiple consecutive ["); hasArraySpecifiers = true; parsingArrayStart = true; - break; - case ']': + } + case ']' -> { check(parsingArrayStart, api, "unbalanced ] in array type"); parsingArrayStart = false; - break; - default: - check( - !hasArraySpecifiers, - api, - "types with array specifiers should end in those specifiers"); + } + default -> + check( + !hasArraySpecifiers, + api, + "types with array specifiers should end in those specifiers"); } } check(!parsingArrayStart, api, "[ without closing ] at the end of a parameter type"); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/collectionincompatibletype/CollectionIncompatibleType.java b/core/src/main/java/com/google/errorprone/bugpatterns/collectionincompatibletype/CollectionIncompatibleType.java index 370c119b15b..d8878e19dd6 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/collectionincompatibletype/CollectionIncompatibleType.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/collectionincompatibletype/CollectionIncompatibleType.java @@ -115,27 +115,23 @@ public Description match(ExpressionTree tree, VisitorState state) { .setMessage(result.message(sourceType, targetType) + compatibilityReport.extraReason()); switch (fixType) { - case PRINT_TYPES_AS_COMMENT: - description.addFix( - SuggestedFix.prefixWith( - tree, - String.format( - "/* expected: %s, actual: %s */", - ASTHelpers.getUpperBound(result.targetType(), types), result.sourceType()))); - break; - case CAST: - result.buildFix().ifPresent(description::addFix); - break; - case SUPPRESS_WARNINGS: + case PRINT_TYPES_AS_COMMENT -> + description.addFix( + SuggestedFix.prefixWith( + tree, + String.format( + "/* expected: %s, actual: %s */", + ASTHelpers.getUpperBound(result.targetType(), types), result.sourceType()))); + case CAST -> result.buildFix().ifPresent(description::addFix); + case SUPPRESS_WARNINGS -> { SuggestedFix.Builder builder = SuggestedFix.builder(); builder.prefixWith( result.sourceTree(), String.format("/* expected: %s, actual: %s */ ", targetType, sourceType)); addSuppressWarnings(builder, state, "CollectionIncompatibleType"); description.addFix(builder.build()); - break; - case NONE: - break; + } + case NONE -> {} } return description.build(); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerHelpers.java b/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerHelpers.java index 79b8b58ceeb..64cd06d7403 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerHelpers.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerHelpers.java @@ -36,20 +36,15 @@ static char inferFormatSpecifier(Type type, VisitorState state) { if (type == null) { return STRING_FORMAT; } - switch (state.getTypes().unboxedTypeOrType(type).getKind()) { - case INT: - case LONG: - return 'd'; - case FLOAT: - case DOUBLE: - return 'g'; - case BOOLEAN: - // %b is identical to %s in Flogger, but not in String.format, so it might be risky - // to train people to prefer it. (In format() a Boolean "null" becomes "false",) - return STRING_FORMAT; - default: - return STRING_FORMAT; - } + return switch (state.getTypes().unboxedTypeOrType(type).getKind()) { + case INT, LONG -> 'd'; + case FLOAT, DOUBLE -> 'g'; + case BOOLEAN -> + // %b is identical to %s in Flogger, but not in String.format, so it might be risky + // to train people to prefer it. (In format() a Boolean "null" becomes "false",) + STRING_FORMAT; + default -> STRING_FORMAT; + }; } private FloggerHelpers() {} diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/FormatStringValidation.java b/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/FormatStringValidation.java index 73ba43250d0..8463520e909 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/FormatStringValidation.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/FormatStringValidation.java @@ -166,33 +166,19 @@ protected Void defaultAction(Tree tree, Void unused) { Type unboxedType = types.unboxedTypeOrType(types.erasure(type)); if (unboxedType.isPrimitive()) { type = unboxedType; - switch (type.getKind()) { - case BOOLEAN: - return false; - case BYTE: - return (byte) 1; - case SHORT: - return (short) 2; - case INT: - return 3; - case LONG: - return 4L; - case CHAR: - return 'c'; - case FLOAT: - return 5.0f; - case DOUBLE: - return 6.0d; - case VOID: - case NONE: - case NULL: - case ERROR: - return null; - case ARRAY: - return new Object[0]; - default: - throw new AssertionError(type.getKind()); - } + return switch (type.getKind()) { + case BOOLEAN -> false; + case BYTE -> (byte) 1; + case SHORT -> (short) 2; + case INT -> 3; + case LONG -> 4L; + case CHAR -> 'c'; + case FLOAT -> 5.0f; + case DOUBLE -> 6.0d; + case VOID, NONE, NULL, ERROR -> null; + case ARRAY -> new Object[0]; + default -> throw new AssertionError(type.getKind()); + }; } if (isSubtype(types, type, state.getSymtab().stringType)) { return "string"; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/inject/dagger/UseBinds.java b/core/src/main/java/com/google/errorprone/bugpatterns/inject/dagger/UseBinds.java index a48f58ad7d1..0469a9be0d2 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/inject/dagger/UseBinds.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/inject/dagger/UseBinds.java @@ -162,20 +162,19 @@ private static SuggestedFix.Builder convertMethodToBinds( checkState(getSymbol(assignment.getVariable()).getSimpleName().contentEquals("type")); String typeName = getSymbol(assignment.getExpression()).getSimpleName().toString(); switch (typeName) { - case "SET": + case "SET" -> { modifierStringsBuilder.add("@IntoSet"); fix.addImport(INTO_SET_CLASS_NAME); - break; - case "SET_VALUES": + } + case "SET_VALUES" -> { modifierStringsBuilder.add("@ElementsIntoSet"); fix.addImport(ELEMENTS_INTO_SET_CLASS_NAME); - break; - case "MAP": + } + case "MAP" -> { modifierStringsBuilder.add("@IntoMap"); fix.addImport(INTO_MAP_CLASS_NAME); - break; - default: - throw new AssertionError("Unknown type name: " + typeName); + } + default -> throw new AssertionError("Unknown type name: " + typeName); } } } else { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/inlineme/InlinabilityResult.java b/core/src/main/java/com/google/errorprone/bugpatterns/inlineme/InlinabilityResult.java index 842430be464..0b4c931507c 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/inlineme/InlinabilityResult.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/inlineme/InlinabilityResult.java @@ -167,17 +167,16 @@ static InlinabilityResult forMethod(MethodTree tree, VisitorState state) { // The statement is either an ExpressionStatement or a ReturnStatement, given // InlinabilityResult.forMethod switch (statement.getKind()) { - case EXPRESSION_STATEMENT: - body = ((ExpressionStatementTree) statement).getExpression(); - break; - case RETURN: + case EXPRESSION_STATEMENT -> body = ((ExpressionStatementTree) statement).getExpression(); + case RETURN -> { body = ((ReturnTree) statement).getExpression(); if (body == null) { return fromError(InlineValidationErrorReason.EMPTY_VOID); } - break; - default: + } + default -> { return fromError(InlineValidationErrorReason.COMPLEX_STATEMENT); + } } if (methSymbol.isVarArgs() && usesVarargsParamPoorly(body, methSymbol.params().last(), state)) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/InvalidInlineTag.java b/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/InvalidInlineTag.java index 95eed6453f9..91e4390f796 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/InvalidInlineTag.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/InvalidInlineTag.java @@ -235,19 +235,20 @@ private Optional findClosingBrace(String body, int startPos) { for (int pos = startPos; pos < body.length(); ++pos) { char c = body.charAt(pos); switch (c) { - case '(': + case '(' -> { parenDepth++; continue; - case ')': + } + case ')' -> { if (parenDepth == 0) { return Optional.of(pos); } parenDepth--; - break; - case '}': + } + case '}' -> { return Optional.empty(); - default: - // fall out + } + default -> {} } } return Optional.empty(); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/EqualsBrokenForNull.java b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/EqualsBrokenForNull.java index 89a105fd8ee..226c7af7f69 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/EqualsBrokenForNull.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/EqualsBrokenForNull.java @@ -133,17 +133,15 @@ public Void visitLambdaExpression(LambdaExpressionTree node, Void unused) { private @Nullable VarSymbol findVariable(Tree tree) { while (tree != null) { switch (tree.getKind()) { - case TYPE_CAST: - tree = ((TypeCastTree) tree).getExpression(); - break; - case PARENTHESIZED: - tree = ((ParenthesizedTree) tree).getExpression(); - break; - case IDENTIFIER: + case TYPE_CAST -> tree = ((TypeCastTree) tree).getExpression(); + case PARENTHESIZED -> tree = ((ParenthesizedTree) tree).getExpression(); + case IDENTIFIER -> { Symbol symbol = getSymbol(tree); return symbol instanceof VarSymbol ? (VarSymbol) symbol : null; - default: + } + default -> { return null; + } } } return null; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullablePrimitiveArray.java b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullablePrimitiveArray.java index ca64e8070ab..c7ef6303043 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullablePrimitiveArray.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullablePrimitiveArray.java @@ -144,12 +144,10 @@ public Void visitArray(List list, Void unused) { }.visit(value.get(), null); for (String target : targets) { switch (target) { - case "METHOD": - case "FIELD": - case "LOCAL_VARIABLE": - case "PARAMETER": + case "METHOD", "FIELD", "LOCAL_VARIABLE", "PARAMETER" -> { return false; - default: // fall out + } + default -> {} } } return targets.contains("TYPE_USE"); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullableWildcard.java b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullableWildcard.java index 83aa326a6bb..6a5afd35b59 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullableWildcard.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullableWildcard.java @@ -67,7 +67,7 @@ Fix fix(List annotations, WildcardTree tree, VisitorSt AnnotationTree existingAnnotation = getOnlyElement(existingAnnotations); SuggestedFix.Builder fix = SuggestedFix.builder().delete(existingAnnotation); switch (tree.getKind()) { - case EXTENDS_WILDCARD: + case EXTENDS_WILDCARD -> { Tree bound = tree.getBound(); if (bound instanceof AnnotatedTypeTree && NullnessAnnotations.fromAnnotationTrees(((AnnotatedTypeTree) bound).getAnnotations()) @@ -77,15 +77,17 @@ Fix fix(List annotations, WildcardTree tree, VisitorSt return fix.prefixWith( bound, String.format("%s ", state.getSourceForNode(existingAnnotation))) .build(); - case SUPER_WILDCARD: + } + case SUPER_WILDCARD -> { return SuggestedFix.emptyFix(); - case UNBOUNDED_WILDCARD: + } + case UNBOUNDED_WILDCARD -> { return fix.postfixWith( tree, String.format(" extends %s Object", state.getSourceForNode(existingAnnotation))) .build(); - default: - throw new AssertionError(tree.getKind()); + } + default -> throw new AssertionError(tree.getKind()); } } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullnessUtils.java b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullnessUtils.java index 32e5e63663d..cfbd22db344 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullnessUtils.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/NullnessUtils.java @@ -161,18 +161,17 @@ private static SuggestedFix fixByAddingNullableAnnotationToElementOrType( VisitorState state, Tree elementTree, Tree typeTree, @Nullable String suppressionToRemove) { NullableAnnotationToUse nullableAnnotationToUse = pickNullableAnnotation(state); switch (applyOnlyIfAlreadyInScope(state)) { - case TRUE: + case TRUE -> { if (!nullableAnnotationToUse.isAlreadyInScope()) { return emptyFix(); } - break; - case IF_NOT: + } + case IF_NOT -> { if (nullableAnnotationToUse.isAlreadyInScope()) { return emptyFix(); } - break; - default: - break; + } + default -> {} } if (!nullableAnnotationToUse.isTypeUse()) { @@ -209,7 +208,7 @@ private static SuggestedFix fixByAddingKnownTypeUseNullableAnnotation( typeTree = ((ParameterizedTypeTree) typeTree).getType(); } switch (typeTree.getKind()) { - case ARRAY_TYPE: + case ARRAY_TYPE -> { Tree beforeBrackets = typeTree; while (true) { Tree pastAnnotations = @@ -225,8 +224,8 @@ private static SuggestedFix fixByAddingKnownTypeUseNullableAnnotation( // For an explanation of "int @Foo [][] f," etc., see JLS 4.11. return nullableAnnotationToUse.fixPostfixingOnto( beforeBrackets, state, suppressionToRemove); - - case MEMBER_SELECT: + } + case MEMBER_SELECT -> { int lastDot = reverse(state.getOffsetTokensForNode(typeTree)).stream() .filter(t -> t.kind() == DOT) @@ -234,17 +233,17 @@ private static SuggestedFix fixByAddingKnownTypeUseNullableAnnotation( .get() .pos(); return nullableAnnotationToUse.fixPostfixingOnto(lastDot, state, suppressionToRemove); - - case ANNOTATED_TYPE: + } + case ANNOTATED_TYPE -> { return nullableAnnotationToUse.fixPrefixingOnto( ((AnnotatedTypeTree) typeTree).getAnnotations().get(0), state, suppressionToRemove); - - case IDENTIFIER: + } + case IDENTIFIER -> { return nullableAnnotationToUse.fixPrefixingOnto(typeTree, state, suppressionToRemove); - - default: - throw new AssertionError( - "unexpected kind for type tree: " + typeTree.getKind() + " for " + typeTree); + } + default -> + throw new AssertionError( + "unexpected kind for type tree: " + typeTree.getKind() + " for " + typeTree); } // TODO(cpovirk): Remove any @NonNull, etc. annotation that is present? } @@ -376,17 +375,17 @@ private static boolean isTypeUse(String className) { * TODO(b/205115472): Make this tri-state ({type-use, declaration, both}) and avoid using "both" * annotations in any cases in which they would be ambiguous (e.g., arrays/elements). */ - switch (className) { - case "libcore.util.Nullable": - case "org.checkerframework.checker.nullness.compatqual.NullableType": - case "org.checkerframework.checker.nullness.qual.Nullable": - case "org.jspecify.annotations.NonNull": - case "org.jspecify.annotations.Nullable": - return true; - default: - // TODO(cpovirk): Detect type-use-ness from the class symbol if it's available? - return false; - } + return switch (className) { + case "libcore.util.Nullable", + "org.checkerframework.checker.nullness.compatqual.NullableType", + "org.checkerframework.checker.nullness.qual.Nullable", + "org.jspecify.annotations.NonNull", + "org.jspecify.annotations.Nullable" -> + true; + default -> + // TODO(cpovirk): Detect type-use-ness from the class symbol if it's available? + false; + }; } static @Nullable NullCheck getNullCheck(ExpressionTree tree) { @@ -394,14 +393,11 @@ private static boolean isTypeUse(String className) { Polarity polarity; switch (tree.getKind()) { - case EQUAL_TO: - polarity = IS_NULL; - break; - case NOT_EQUAL_TO: - polarity = IS_NOT_NULL; - break; - default: + case EQUAL_TO -> polarity = IS_NULL; + case NOT_EQUAL_TO -> polarity = IS_NOT_NULL; + default -> { return null; + } } BinaryTree equalityTree = (BinaryTree) tree; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/ParameterMissingNullable.java b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/ParameterMissingNullable.java index 2d2925e8149..aefca2e847f 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/ParameterMissingNullable.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/ParameterMissingNullable.java @@ -165,15 +165,16 @@ private static boolean isLoopCondition(TreePath path) { * `param != null && param.somethingElse()`. */ switch (path.getParentPath().getParentPath().getLeaf().getKind()) { - case WHILE_LOOP: - case DO_WHILE_LOOP: + case WHILE_LOOP, DO_WHILE_LOOP -> { return true; - default: + } + default -> {} } switch (path.getParentPath().getLeaf().getKind()) { - case FOR_LOOP: + case FOR_LOOP -> { return true; - default: + } + default -> {} } return false; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ConstantExpressions.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ConstantExpressions.java index b1206cd7eb2..c3f7876fe07 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ConstantExpressions.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ConstantExpressions.java @@ -226,29 +226,21 @@ private static ConstantExpression pureMethod(PureMethodInvocation pureMethodInvo @Override public final String toString() { - switch (kind()) { - case LITERAL: - return literal().toString(); - case CONSTANT_EQUALS: - return constantEquals().toString(); - case PURE_METHOD: - return pureMethod().toString(); - } - throw new AssertionError(); + return switch (kind()) { + case LITERAL -> literal().toString(); + case CONSTANT_EQUALS -> constantEquals().toString(); + case PURE_METHOD -> pureMethod().toString(); + }; } public void accept(ConstantExpressionVisitor visitor) { switch (kind()) { - case LITERAL: - visitor.visitConstant(literal()); - break; - case CONSTANT_EQUALS: + case LITERAL -> visitor.visitConstant(literal()); + case CONSTANT_EQUALS -> { constantEquals().lhs().accept(visitor); constantEquals().rhs().accept(visitor); - break; - case PURE_METHOD: - pureMethod().accept(visitor); - break; + } + case PURE_METHOD -> pureMethod().accept(visitor); } } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/DoubleCheckedLocking.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/DoubleCheckedLocking.java index e82d55fb9b9..f0bdb220c3c 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/DoubleCheckedLocking.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/DoubleCheckedLocking.java @@ -68,14 +68,11 @@ public Description matchIf(IfTree outerIf, VisitorState state) { if (info == null) { return Description.NO_MATCH; } - switch (info.sym().getKind()) { - case FIELD: - return handleField(info.outerIf(), info.sym(), state); - case LOCAL_VARIABLE: - return handleLocal(info, state); - default: - return Description.NO_MATCH; - } + return switch (info.sym().getKind()) { + case FIELD -> handleField(info.outerIf(), info.sym(), state); + case LOCAL_VARIABLE -> handleLocal(info, state); + default -> Description.NO_MATCH; + }; } /** @@ -117,19 +114,14 @@ private Description handleField(IfTree outerIf, VarSymbol sym, VisitorState stat */ private static boolean isImmutable(Type type, VisitorState state) { switch (type.getKind()) { - case BOOLEAN: - case BYTE: - case SHORT: - case INT: - case CHAR: - case FLOAT: + case BOOLEAN, BYTE, SHORT, INT, CHAR, FLOAT -> { return true; - case LONG: - case DOUBLE: + } + case LONG, DOUBLE -> { // double-width primitives aren't written atomically return true; - default: - break; + } + default -> {} } return IMMUTABLE_PRIMITIVES.contains( state.getTypes().erasure(type).tsym.getQualifiedName().toString()); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByBinder.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByBinder.java index 065be87d61a..307b2847f68 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByBinder.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByBinder.java @@ -192,26 +192,23 @@ public GuardedByExpression visitMethodInvocation( "Only nullary methods are allowed."); ExpressionTree methodSelect = node.getMethodSelect(); switch (methodSelect.getKind()) { - case IDENTIFIER: - { - IdentifierTree identifier = (IdentifierTree) methodSelect; - Symbol.MethodSymbol method = - context.resolver.resolveMethod(node, identifier.getName()); - checkGuardedBy(method != null, identifier.toString()); - return bindSelect(computeBase(context, method), method); - } - case MEMBER_SELECT: - { - MemberSelectTree select = (MemberSelectTree) methodSelect; - GuardedByExpression base = visit(select.getExpression(), context); - checkGuardedBy(base != null, select.getExpression().toString()); - Symbol.MethodSymbol method = - context.resolver.resolveMethod(node, base, select.getIdentifier()); - checkGuardedBy(method != null, select.toString()); - return bindSelect(normalizeBase(context, method, base), method); - } - default: - throw new IllegalGuardedBy(methodSelect.getKind().toString()); + case IDENTIFIER -> { + IdentifierTree identifier = (IdentifierTree) methodSelect; + Symbol.MethodSymbol method = + context.resolver.resolveMethod(node, identifier.getName()); + checkGuardedBy(method != null, identifier.toString()); + return bindSelect(computeBase(context, method), method); + } + case MEMBER_SELECT -> { + MemberSelectTree select = (MemberSelectTree) methodSelect; + GuardedByExpression base = visit(select.getExpression(), context); + checkGuardedBy(base != null, select.getExpression().toString()); + Symbol.MethodSymbol method = + context.resolver.resolveMethod(node, base, select.getIdentifier()); + checkGuardedBy(method != null, select.toString()); + return bindSelect(normalizeBase(context, method, base), method); + } + default -> throw new IllegalGuardedBy(methodSelect.getKind().toString()); } } @@ -268,18 +265,16 @@ public GuardedByExpression visitIdentifier(IdentifierTree node, BinderContext co checkGuardedBy(symbol != null, "Could not resolve %s", node); if (symbol instanceof Symbol.VarSymbol varSymbol) { switch (varSymbol.getKind()) { - case LOCAL_VARIABLE: - case PARAMETER: + case LOCAL_VARIABLE, PARAMETER -> { return F.localVariable(varSymbol); - case FIELD: - { - if (symbol.name.contentEquals("this")) { - return F.thisliteral(); - } - return F.select(computeBase(context, varSymbol), varSymbol); + } + case FIELD -> { + if (symbol.name.contentEquals("this")) { + return F.thisliteral(); } - default: - throw new IllegalGuardedBy(varSymbol.getKind().toString()); + return F.select(computeBase(context, varSymbol), varSymbol); + } + default -> throw new IllegalGuardedBy(varSymbol.getKind().toString()); } } else if (symbol instanceof Symbol.MethodSymbol methodSymbol) { return F.select(computeBase(context, symbol), methodSymbol); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByExpression.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByExpression.java index af3f74c2e74..651c08a7e30 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByExpression.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByExpression.java @@ -287,22 +287,11 @@ public static String print(GuardedByExpression exp) { private static void pprint(GuardedByExpression exp, StringBuilder sb) { switch (exp.kind()) { - case CLASS_LITERAL: - sb.append(String.format("%s.class", exp.sym().name)); - break; - case THIS: - sb.append("this"); - break; - case TYPE_LITERAL: - case LOCAL_VARIABLE: - sb.append(exp.sym().name); - break; - case SELECT: - pprintSelect((Select) exp, sb); - break; - case ERROR: - sb.append(((Erroneous) exp).guardString()); - break; + case CLASS_LITERAL -> sb.append(String.format("%s.class", exp.sym().name)); + case THIS -> sb.append("this"); + case TYPE_LITERAL, LOCAL_VARIABLE -> sb.append(exp.sym().name); + case SELECT -> pprintSelect((Select) exp, sb); + case ERROR -> sb.append(((Erroneous) exp).guardString()); } } @@ -341,20 +330,11 @@ public static String print(GuardedByExpression exp) { private static void pprint(GuardedByExpression exp, StringBuilder sb) { switch (exp.kind()) { - case TYPE_LITERAL: - case CLASS_LITERAL: - case LOCAL_VARIABLE: - sb.append(String.format("(%s %s)", exp.kind(), exp.sym())); - break; - case THIS: - sb.append("(THIS)"); - break; - case SELECT: - pprintSelect((Select) exp, sb); - break; - case ERROR: - sb.append("(ERROR)"); - break; + case TYPE_LITERAL, CLASS_LITERAL, LOCAL_VARIABLE -> + sb.append(String.format("(%s %s)", exp.kind(), exp.sym())); + case THIS -> sb.append("(THIS)"); + case SELECT -> pprintSelect((Select) exp, sb); + case ERROR -> sb.append("(ERROR)"); } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/HeldLockAnalyzer.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/HeldLockAnalyzer.java index 26b04ef9326..2347d03886f 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/HeldLockAnalyzer.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/HeldLockAnalyzer.java @@ -504,15 +504,14 @@ private static GuardedByExpression getSelectInstance(GuardedByExpression guard) private static GuardedByExpression helper( GuardedByExpression lockExpression, GuardedByExpression memberAccess) { switch (lockExpression.kind()) { - case SELECT: - { - GuardedByExpression.Select lockSelect = (GuardedByExpression.Select) lockExpression; - return F.select(helper(lockSelect.base(), memberAccess), lockSelect.sym()); - } - case THIS: + case SELECT -> { + GuardedByExpression.Select lockSelect = (GuardedByExpression.Select) lockExpression; + return F.select(helper(lockSelect.base(), memberAccess), lockSelect.sym()); + } + case THIS -> { return memberAccess; - default: - throw new IllegalGuardedBy(lockExpression.toString()); + } + default -> throw new IllegalGuardedBy(lockExpression.toString()); } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableChecker.java index f6220b83d90..be0c52425d1 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableChecker.java @@ -609,12 +609,13 @@ private static ImmutableSet immutableTypeParametersInScope( OUTER: for (Symbol s = sym; s.owner != null; s = s.owner) { switch (s.getKind()) { - case INSTANCE_INIT: + case INSTANCE_INIT -> { continue; - case PACKAGE: + } + case PACKAGE -> { break OUTER; - default: - break; + } + default -> {} } AnnotationInfo annotation = analysis.getImmutableAnnotation(s, state); if (annotation == null) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/StaticGuardedByInstance.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/StaticGuardedByInstance.java index 7f8d144d022..25dbd0eb8f7 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/StaticGuardedByInstance.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/StaticGuardedByInstance.java @@ -105,14 +105,9 @@ public Void visitCompoundAssignment(CompoundAssignmentTree node, Void unused) { @Override public Void visitUnary(UnaryTree node, Void unused) { switch (node.getKind()) { - case PREFIX_DECREMENT: - case PREFIX_INCREMENT: - case POSTFIX_DECREMENT: - case POSTFIX_INCREMENT: - recordWrite(node.getExpression()); - break; - default: - break; + case PREFIX_DECREMENT, PREFIX_INCREMENT, POSTFIX_DECREMENT, POSTFIX_INCREMENT -> + recordWrite(node.getExpression()); + default -> {} } return super.visitUnary(node, null); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeChecker.java index 581397b5e1f..3df20109a25 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeChecker.java @@ -129,10 +129,10 @@ public Description matchTypeParameter(TypeParameterTree tree, VisitorState state return NO_MATCH; } switch (sym.owner.getKind()) { - case METHOD: - case CONSTRUCTOR: + case METHOD, CONSTRUCTOR -> { return NO_MATCH; - default: // fall out + } + default -> {} } ThreadSafeAnalysis analysis = new ThreadSafeAnalysis(this, state, wellKnownThreadSafety); if (analysis.hasThreadSafeTypeParameterAnnotation((TypeVariableSymbol) sym)) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafety.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafety.java index 91025b33995..13130448d70 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafety.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafety.java @@ -548,22 +548,23 @@ public Violation visitTypeVar(TypeVar type, Void s) { @Override public Violation visitType(Type type, Void s) { switch (type.tsym.getKind()) { - case ANNOTATION_TYPE: + case ANNOTATION_TYPE -> { // assume annotations are always immutable // TODO(b/25630189): add enforcement return Violation.absent(); - case ENUM: + } + case ENUM -> { // assume enums are always immutable // TODO(b/25630186): add enforcement return Violation.absent(); - case INTERFACE: - case CLASS: - break; - default: + } + case INTERFACE, CLASS -> {} + default -> { if (type.tsym.getKind().name().equals("RECORD")) { break; } throw new AssertionError(String.format("Unexpected type kind %s", type.tsym.getKind())); + } } if (WellKnownMutability.isAnnotation(state, type)) { // annotation implementations may not have ANNOTATION_TYPE kind, assume they are immutable @@ -722,12 +723,13 @@ public Set threadSafeTypeParametersInScope(Symbol sym) { OUTER: for (Symbol s = sym; s.owner != null; s = s.owner) { switch (s.getKind()) { - case INSTANCE_INIT: + case INSTANCE_INIT -> { continue; - case PACKAGE: + } + case PACKAGE -> { break OUTER; - default: - break; + } + default -> {} } AnnotationInfo annotation = getMarkerOrAcceptedAnnotation(s, state); if (annotation == null) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/time/JavaTimeDefaultTimeZone.java b/core/src/main/java/com/google/errorprone/bugpatterns/time/JavaTimeDefaultTimeZone.java index 8ca453b296c..d5fde507304 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/time/JavaTimeDefaultTimeZone.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/time/JavaTimeDefaultTimeZone.java @@ -83,18 +83,16 @@ private static boolean matches(MethodInvocationTree tree) { } MethodSymbol symbol = ASTHelpers.getSymbol(tree); - switch (symbol.getSimpleName().toString()) { - case "now": - return symbol.isStatic() && NOW_STATIC.contains(symbol.owner.getQualifiedName().toString()); - case "dateNow": - return !symbol.isStatic() - && DATE_NOW_INSTANCE.contains(symbol.owner.getQualifiedName().toString()); - case "systemDefaultZone": - return symbol.isStatic() - && symbol.owner.getQualifiedName().contentEquals("java.time.Clock"); - default: - return false; - } + return switch (symbol.getSimpleName().toString()) { + case "now" -> + symbol.isStatic() && NOW_STATIC.contains(symbol.owner.getQualifiedName().toString()); + case "dateNow" -> + !symbol.isStatic() + && DATE_NOW_INSTANCE.contains(symbol.owner.getQualifiedName().toString()); + case "systemDefaultZone" -> + symbol.isStatic() && symbol.owner.getQualifiedName().contentEquals("java.time.Clock"); + default -> false; + }; } @Override diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/time/NearbyCallers.java b/core/src/main/java/com/google/errorprone/bugpatterns/time/NearbyCallers.java index 73dad8d7629..ff076360890 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/time/NearbyCallers.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/time/NearbyCallers.java @@ -162,15 +162,14 @@ private static Optional> buildProtoGetterChain( private static ImmutableList getNearbyTreesToScan(VisitorState state) { for (Tree parent : state.getPath()) { switch (parent.getKind()) { - case BLOCK: + case BLOCK -> { // if we reach a block tree, then _only_ scan that block return ImmutableList.of(parent); - - case LAMBDA_EXPRESSION: + } + case LAMBDA_EXPRESSION -> { // if we reach a lambda tree, just scan the lambda body itself // TODO(glorioso): for simple expression lambdas, consider looking for use sites and scan // *those* sites, but binding the lambda variable to its use site might be rough :( - // e.g.: // Function NANOS = d -> d.getNano(); // Function SECONDS = d -> d.getSeconds(); @@ -179,8 +178,8 @@ private static ImmutableList getNearbyTreesToScan(VisitorState state) { // // how do we track myDuration through both layers? return ImmutableList.of(((LambdaExpressionTree) parent).getBody()); - - case CLASS: + } + case CLASS -> { // if we get all the way up to the class tree, then _only_ scan the other class-level // fields ImmutableList.Builder treesToScan = ImmutableList.builder(); @@ -193,9 +192,10 @@ private static ImmutableList getNearbyTreesToScan(VisitorState state) { } } return treesToScan.build(); - - default: - // fall out, continue searching up the tree + } + default -> { + // continue searching up the tree + } } } return ImmutableList.of(); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/time/TimeUnitConversionChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/time/TimeUnitConversionChecker.java index 5be09329940..fc71639bc95 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/time/TimeUnitConversionChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/time/TimeUnitConversionChecker.java @@ -125,44 +125,28 @@ private static SuggestedFix replaceTreeWith( } private static long invokeConversion(TimeUnit timeUnit, String methodName, long duration) { - switch (methodName) { - case "toDays": - return timeUnit.toDays(duration); - case "toHours": - return timeUnit.toHours(duration); - case "toMinutes": - return timeUnit.toMinutes(duration); - case "toSeconds": - return timeUnit.toSeconds(duration); - case "toMillis": - return timeUnit.toMillis(duration); - case "toMicros": - return timeUnit.toMicros(duration); - case "toNanos": - return timeUnit.toNanos(duration); - default: - throw new IllegalArgumentException(); - } + return switch (methodName) { + case "toDays" -> timeUnit.toDays(duration); + case "toHours" -> timeUnit.toHours(duration); + case "toMinutes" -> timeUnit.toMinutes(duration); + case "toSeconds" -> timeUnit.toSeconds(duration); + case "toMillis" -> timeUnit.toMillis(duration); + case "toMicros" -> timeUnit.toMicros(duration); + case "toNanos" -> timeUnit.toNanos(duration); + default -> throw new IllegalArgumentException(); + }; } private static TimeUnit methodNameToTimeUnit(String methodName) { - switch (methodName) { - case "toDays": - return TimeUnit.DAYS; - case "toHours": - return TimeUnit.HOURS; - case "toMinutes": - return TimeUnit.MINUTES; - case "toSeconds": - return TimeUnit.SECONDS; - case "toMillis": - return TimeUnit.MILLISECONDS; - case "toMicros": - return TimeUnit.MICROSECONDS; - case "toNanos": - return TimeUnit.NANOSECONDS; - default: - throw new IllegalArgumentException(); - } + return switch (methodName) { + case "toDays" -> TimeUnit.DAYS; + case "toHours" -> TimeUnit.HOURS; + case "toMinutes" -> TimeUnit.MINUTES; + case "toSeconds" -> TimeUnit.SECONDS; + case "toMillis" -> TimeUnit.MILLISECONDS; + case "toMicros" -> TimeUnit.MICROSECONDS; + case "toNanos" -> TimeUnit.NANOSECONDS; + default -> throw new IllegalArgumentException(); + }; } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/time/TimeUnitMismatch.java b/core/src/main/java/com/google/errorprone/bugpatterns/time/TimeUnitMismatch.java index a61708b79a8..5a63720fce0 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/time/TimeUnitMismatch.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/time/TimeUnitMismatch.java @@ -120,19 +120,19 @@ public Description matchBinary(BinaryTree tree, VisitorState state) { return Description.NO_MATCH; } switch (tree.getKind()) { - case PLUS: - case MINUS: - case LESS_THAN: - case GREATER_THAN: - case LESS_THAN_EQUAL: - case GREATER_THAN_EQUAL: - case EQUAL_TO: - case NOT_EQUAL_TO: - case PLUS_ASSIGNMENT: - case MINUS_ASSIGNMENT: - break; - default: + case PLUS, + MINUS, + LESS_THAN, + GREATER_THAN, + LESS_THAN_EQUAL, + GREATER_THAN_EQUAL, + EQUAL_TO, + NOT_EQUAL_TO, + PLUS_ASSIGNMENT, + MINUS_ASSIGNMENT -> {} + default -> { return Description.NO_MATCH; + } } TreeAndTimeUnit lhs = unitSuggestedByTree(tree.getLeftOperand()); @@ -425,44 +425,43 @@ private static SuggestedFix convertTree( */ private static @Nullable String extractArgumentName(ExpressionTree expr) { switch (expr.getKind()) { - case TYPE_CAST: + case TYPE_CAST -> { return extractArgumentName(((TypeCastTree) expr).getExpression()); - case MEMBER_SELECT: - { - // If we have a field or method access, we use the name of the field/method. (We ignore - // the name of the receiver object.) Exception: If the method is named "get" (Optional, - // Flag, etc.), we use the name of the object or class that it's called on. - MemberSelectTree memberSelect = (MemberSelectTree) expr; - String member = memberSelect.getIdentifier().toString(); - return member.equals("get") ? extractArgumentName(memberSelect.getExpression()) : member; - } - case METHOD_INVOCATION: - { - // If we have a 'call expression' we use the name of the method we are calling. Exception: - // If the method is named "get," we use the object or class instead. (See above.) - Symbol sym = getSymbol(expr); - if (sym == null) { - return null; - } - String methodName = sym.getSimpleName().toString(); - return methodName.equals("get") - ? extractArgumentName(((MethodInvocationTree) expr).getMethodSelect()) - : methodName; + } + case MEMBER_SELECT -> { + // If we have a field or method access, we use the name of the field/method. (We ignore + // the name of the receiver object.) Exception: If the method is named "get" (Optional, + // Flag, etc.), we use the name of the object or class that it's called on. + MemberSelectTree memberSelect = (MemberSelectTree) expr; + String member = memberSelect.getIdentifier().toString(); + return member.equals("get") ? extractArgumentName(memberSelect.getExpression()) : member; + } + case METHOD_INVOCATION -> { + // If we have a 'call expression' we use the name of the method we are calling. Exception: + // If the method is named "get," we use the object or class instead. (See above.) + Symbol sym = getSymbol(expr); + if (sym == null) { + return null; } - case IDENTIFIER: - { - IdentifierTree idTree = (IdentifierTree) expr; - if (idTree.getName().contentEquals("this")) { - // for the 'this' keyword the argument name is the name of the object's class - Symbol sym = getSymbol(idTree); - return (sym == null) ? null : enclosingClass(sym).getSimpleName().toString(); - } else { - // if we have a variable, just extract its name - return ((IdentifierTree) expr).getName().toString(); - } + String methodName = sym.getSimpleName().toString(); + return methodName.equals("get") + ? extractArgumentName(((MethodInvocationTree) expr).getMethodSelect()) + : methodName; + } + case IDENTIFIER -> { + IdentifierTree idTree = (IdentifierTree) expr; + if (idTree.getName().contentEquals("this")) { + // for the 'this' keyword the argument name is the name of the object's class + Symbol sym = getSymbol(idTree); + return (sym == null) ? null : enclosingClass(sym).getSimpleName().toString(); + } else { + // if we have a variable, just extract its name + return ((IdentifierTree) expr).getName().toString(); } - default: + } + default -> { return null; + } } } diff --git a/core/src/main/java/com/google/errorprone/refaster/Choice.java b/core/src/main/java/com/google/errorprone/refaster/Choice.java index b385314b3d0..f9badbd5c98 100644 --- a/core/src/main/java/com/google/errorprone/refaster/Choice.java +++ b/core/src/main/java/com/google/errorprone/refaster/Choice.java @@ -155,24 +155,22 @@ public static Choice fromOptional(Optional optional) { } public static Choice from(Collection choices) { - switch (choices.size()) { - case 0: - return none(); - case 1: - return of(Iterables.getOnlyElement(choices)); - default: - return new Choice() { - @Override - protected Iterator iterator() { - return choices.iterator(); - } - - @Override - public String toString() { - return String.format("Choice.from(%s)", choices); - } - }; - } + return switch (choices.size()) { + case 0 -> none(); + case 1 -> of(Iterables.getOnlyElement(choices)); + default -> + new Choice() { + @Override + protected Iterator iterator() { + return choices.iterator(); + } + + @Override + public String toString() { + return String.format("Choice.from(%s)", choices); + } + }; + }; } /** Returns a choice between any of the options from any of the specified choices. */ diff --git a/core/src/main/java/com/google/errorprone/refaster/ControlFlowVisitor.java b/core/src/main/java/com/google/errorprone/refaster/ControlFlowVisitor.java index f855e98c212..1ed34e567df 100644 --- a/core/src/main/java/com/google/errorprone/refaster/ControlFlowVisitor.java +++ b/core/src/main/java/com/google/errorprone/refaster/ControlFlowVisitor.java @@ -63,13 +63,10 @@ public enum Result { NEVER_EXITS { @Override Result or(Result other) { - switch (other) { - case MAY_BREAK_OR_RETURN: - case NEVER_EXITS: - return other; - default: - return MAY_RETURN; - } + return switch (other) { + case MAY_BREAK_OR_RETURN, NEVER_EXITS -> other; + default -> MAY_RETURN; + }; } @Override @@ -96,26 +93,20 @@ Result or(Result other) { @Override Result then(Result other) { - switch (other) { - case MAY_BREAK_OR_RETURN: - case ALWAYS_RETURNS: - return other; - default: - return MAY_RETURN; - } + return switch (other) { + case MAY_BREAK_OR_RETURN, ALWAYS_RETURNS -> other; + default -> MAY_RETURN; + }; } }, ALWAYS_RETURNS { @Override Result or(Result other) { - switch (other) { - case MAY_BREAK_OR_RETURN: - case ALWAYS_RETURNS: - return other; - default: - return MAY_RETURN; - } + return switch (other) { + case MAY_BREAK_OR_RETURN, ALWAYS_RETURNS -> other; + default -> MAY_RETURN; + }; } @Override diff --git a/core/src/main/java/com/google/errorprone/refaster/UInstanceOf.java b/core/src/main/java/com/google/errorprone/refaster/UInstanceOf.java index e3ffa9d41f6..aaddaeb36ae 100644 --- a/core/src/main/java/com/google/errorprone/refaster/UInstanceOf.java +++ b/core/src/main/java/com/google/errorprone/refaster/UInstanceOf.java @@ -49,19 +49,23 @@ public R accept(TreeVisitor visitor, D data) { new Class[] {InstanceOfTree.class}, (unused, method, args) -> { switch (method.getName()) { - case "getPattern": + case "getPattern" -> { // TODO(cushon): support refaster template matching on instanceof patterns return null; - case "getExpression": + } + case "getExpression" -> { return getExpression(); - case "getType": + } + case "getType" -> { return getType(); - default: + } + default -> { try { return method.invoke(UInstanceOf.this, args); } catch (IllegalArgumentException e) { throw new LinkageError(method.getName(), e); } + } } }); return visitor.visitInstanceOf(proxy, data); diff --git a/core/src/main/java/com/google/errorprone/refaster/ULiteral.java b/core/src/main/java/com/google/errorprone/refaster/ULiteral.java index b4e3919d448..6650e70fcaf 100644 --- a/core/src/main/java/com/google/errorprone/refaster/ULiteral.java +++ b/core/src/main/java/com/google/errorprone/refaster/ULiteral.java @@ -119,15 +119,13 @@ public R accept(TreeVisitor visitor, D data) { public JCLiteral inline(Inliner inliner) { Object value = this.getValue(); switch (getKind()) { - case CHAR_LITERAL: - // Why do they do it like this? I wish I knew. - value = (int) ((Character) value).charValue(); - break; - case BOOLEAN_LITERAL: - value = ((Boolean) value) ? 1 : 0; - break; - default: + case CHAR_LITERAL -> + // Why do they do it like this? I wish I knew. + value = (int) ((Character) value).charValue(); + case BOOLEAN_LITERAL -> value = ((Boolean) value) ? 1 : 0; + default -> { // do nothing + } } return inliner.maker().Literal(LIT_KIND_TAG.get(getKind()), value); } diff --git a/core/src/main/java/com/google/errorprone/refaster/UPlaceholderStatement.java b/core/src/main/java/com/google/errorprone/refaster/UPlaceholderStatement.java index 54b3248725a..e3cec79da04 100644 --- a/core/src/main/java/com/google/errorprone/refaster/UPlaceholderStatement.java +++ b/core/src/main/java/com/google/errorprone/refaster/UPlaceholderStatement.java @@ -178,14 +178,11 @@ public List inlineStatements(Inliner inliner) throws CouldNotResolv binding.or( exprBinding.transform( (JCExpression expr) -> { - switch (implementationFlow()) { - case NEVER_EXITS: - return List.of(inliner.maker().Exec(expr)); - case ALWAYS_RETURNS: - return List.of(inliner.maker().Return(expr)); - default: - throw new AssertionError(); - } + return switch (implementationFlow()) { + case NEVER_EXITS -> List.of(inliner.maker().Exec(expr)); + case ALWAYS_RETURNS -> List.of(inliner.maker().Return(expr)); + default -> throw new AssertionError(); + }; })); return UPlaceholderExpression.copier(arguments(), inliner).copy(binding.get(), inliner); } catch (UncheckedCouldNotResolveImportException e) { diff --git a/core/src/main/java/com/google/errorprone/refaster/UPrimitiveType.java b/core/src/main/java/com/google/errorprone/refaster/UPrimitiveType.java index 03061c7c47c..9738dcd1df9 100644 --- a/core/src/main/java/com/google/errorprone/refaster/UPrimitiveType.java +++ b/core/src/main/java/com/google/errorprone/refaster/UPrimitiveType.java @@ -67,29 +67,18 @@ public Choice visitType(Type target, Unifier unifier) { @Override public Type inline(Inliner inliner) { Symtab symtab = inliner.symtab(); - switch (getKind()) { - case BYTE: - return symtab.byteType; - case SHORT: - return symtab.shortType; - case INT: - return symtab.intType; - case LONG: - return symtab.longType; - case FLOAT: - return symtab.floatType; - case DOUBLE: - return symtab.doubleType; - case BOOLEAN: - return symtab.booleanType; - case CHAR: - return symtab.charType; - case VOID: - return symtab.voidType; - case NULL: - return symtab.botType; - default: - throw new AssertionError(); - } + return switch (getKind()) { + case BYTE -> symtab.byteType; + case SHORT -> symtab.shortType; + case INT -> symtab.intType; + case LONG -> symtab.longType; + case FLOAT -> symtab.floatType; + case DOUBLE -> symtab.doubleType; + case BOOLEAN -> symtab.booleanType; + case CHAR -> symtab.charType; + case VOID -> symtab.voidType; + case NULL -> symtab.botType; + default -> throw new AssertionError(); + }; } } diff --git a/core/src/main/java/com/google/errorprone/refaster/UTemplater.java b/core/src/main/java/com/google/errorprone/refaster/UTemplater.java index 49a775b686a..3484b107092 100644 --- a/core/src/main/java/com/google/errorprone/refaster/UTemplater.java +++ b/core/src/main/java/com/google/errorprone/refaster/UTemplater.java @@ -622,14 +622,11 @@ public UExpression visitIdentifier(IdentifierTree tree, Void v) { if (sym == null) { return UTypeVarIdent.create(tree.getName()); } - switch (sym.getKind()) { - case TYPE_PARAMETER: - return UTypeVarIdent.create(tree.getName()); - case METHOD: - return method(sym); - default: - return ULocalVarIdent.create(tree.getName()); - } + return switch (sym.getKind()) { + case TYPE_PARAMETER -> UTypeVarIdent.create(tree.getName()); + case METHOD -> method(sym); + default -> ULocalVarIdent.create(tree.getName()); + }; } /** diff --git a/core/src/test/java/com/google/errorprone/fixes/SuggestedFixesTest.java b/core/src/test/java/com/google/errorprone/fixes/SuggestedFixesTest.java index 2fe33640f02..ac337e3d6a7 100644 --- a/core/src/test/java/com/google/errorprone/fixes/SuggestedFixesTest.java +++ b/core/src/test/java/com/google/errorprone/fixes/SuggestedFixesTest.java @@ -133,14 +133,8 @@ private Description editModifiers(Tree tree, VisitorState state) { .map(v -> Verify.verifyNotNull(MODIFIERS_BY_NAME.get(v), v)) .toArray(Modifier[]::new); switch (editModifiers.kind()) { - case ADD: - fix.merge(SuggestedFixes.addModifiers(tree, state, mods).orElse(null)); - break; - case REMOVE: - fix.merge(SuggestedFixes.removeModifiers(tree, state, mods).orElse(null)); - break; - default: - throw new AssertionError(editModifiers.kind()); + case ADD -> fix.merge(SuggestedFixes.addModifiers(tree, state, mods).orElse(null)); + case REMOVE -> fix.merge(SuggestedFixes.removeModifiers(tree, state, mods).orElse(null)); } return describeMatch(tree, fix.build()); } From b5fa4411c2602b7cb073bc9b4f9bc8ddc20e3083 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 15 Nov 2024 10:14:29 -0800 Subject: [PATCH 32/38] Consolidate javadoc plugin version PiperOrigin-RevId: 696925671 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6ff240e40b1..df76790a67c 100644 --- a/pom.xml +++ b/pom.xml @@ -40,7 +40,7 @@ 0.21.0 3.0.5 0.7.4 - 3.3.1 + 3.11.1 3.2.1 1.6.13 3.25.5 @@ -170,7 +170,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.11.1 + ${maven-javadoc-plugin.version} 17 true From c816c8ba4ea0bf402ff81e8e02decc709fd5e403 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 15 Nov 2024 10:28:48 -0800 Subject: [PATCH 33/38] StatementSwitchToExpressionSwitch - remove `// fall out` comments in switches PiperOrigin-RevId: 696930118 --- .../StatementSwitchToExpressionSwitch.java | 2 +- ...StatementSwitchToExpressionSwitchTest.java | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java b/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java index 20ec1b00bac..3509f35a1c5 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java @@ -95,7 +95,7 @@ public final class StatementSwitchToExpressionSwitch extends BugChecker ImmutableSet.of(THROW, EXPRESSION_STATEMENT); private static final ImmutableSet KINDS_RETURN_OR_THROW = ImmutableSet.of(THROW, RETURN); private static final Pattern FALL_THROUGH_PATTERN = - Pattern.compile("\\bfalls?.?through\\b", Pattern.CASE_INSENSITIVE); + Pattern.compile("\\bfalls?.?(through|out)\\b", Pattern.CASE_INSENSITIVE); // Default (negative) result for assignment switch conversion analysis. Note that the value is // immutable. private static final AssignmentSwitchAnalysisResult DEFAULT_ASSIGNMENT_SWITCH_ANALYSIS_RESULT = diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java index 92e3c2bb662..7cac131bb20 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java @@ -4705,4 +4705,42 @@ String f(int x) { "-XepOpt:StatementSwitchToExpressionSwitch:EnableReturnSwitchConversion=true") .doTest(BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH); } + + @Test + public void fallOutComment() { + refactoringHelper + .addInputLines( + "Test.java", + """ + public class Test { + String f(int x) { + switch (x) { + case 0: + return "ZERO"; + default: // fall out + } + return ""; + } + } + """) + .addOutputLines( + "Test.java", + """ + public class Test { + String f(int x) { + switch (x) { + case 0 -> { + return "ZERO"; + } + default -> {} + } + return ""; + } + } + """) + .setArgs( + "-XepOpt:StatementSwitchToExpressionSwitch:EnableDirectConversion=true", + "-XepOpt:StatementSwitchToExpressionSwitch:EnableReturnSwitchConversion=true") + .doTest(BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH); + } } From 0db3360a331ee1f6f882f6e550d854a025337e56 Mon Sep 17 00:00:00 2001 From: Error Prone Team Date: Mon, 18 Nov 2024 00:50:46 -0800 Subject: [PATCH 34/38] UsafeLocaleUsage: update the proposed fix to use `replace(char, char)` The current `replace(CharSequence, CharSequence)` triggers a JavaOptionalSuggestions, so we might as well apply it directly. PiperOrigin-RevId: 697528702 --- .../com/google/errorprone/bugpatterns/UnsafeLocaleUsage.java | 5 ++--- .../google/errorprone/bugpatterns/UnsafeLocaleUsageTest.java | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnsafeLocaleUsage.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnsafeLocaleUsage.java index 1746c86ab6f..442f01bab4e 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnsafeLocaleUsage.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnsafeLocaleUsage.java @@ -84,10 +84,9 @@ public Description matchNewClass(NewClassTree tree, VisitorState state) { String replacementArg = arg instanceof JCLiteral ? String.format( - "\"%s\"", ASTHelpers.constValue(arg, String.class).replace("_", "-")) + "\"%s\"", ASTHelpers.constValue(arg, String.class).replace('_', '-')) : String.format( - "%s.replace(\"_\", \"-\")", - state.getSourceForNode(constructorArguments.get(0))); + "%s.replace('_', '-')", state.getSourceForNode(constructorArguments.get(0))); descriptionBuilder.addFix( SuggestedFix.replace(tree, String.format("Locale.forLanguageTag(%s)", replacementArg))); diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UnsafeLocaleUsageTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UnsafeLocaleUsageTest.java index a690f816147..fbcee7a2c31 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UnsafeLocaleUsageTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UnsafeLocaleUsageTest.java @@ -60,7 +60,7 @@ class Test { static class Inner { private Locale locale; Inner(String a) { - locale = Locale.forLanguageTag(a.replace("_", "-")); + locale = Locale.forLanguageTag(a.replace('_', '-')); } } From 332cbfae1dfdfb67e2810dc705da9b60237086bd Mon Sep 17 00:00:00 2001 From: ghm Date: Mon, 18 Nov 2024 03:49:52 -0800 Subject: [PATCH 35/38] Support record destructuring in ArgumentSelectionDefectChecker. PiperOrigin-RevId: 697569466 --- .../ArgumentSelectionDefectChecker.java | 27 ++++------ .../argumentselectiondefects/Changes.java | 4 +- .../InvocationInfo.java | 3 +- .../argumentselectiondefects/Parameter.java | 51 +++++++++---------- .../ArgumentSelectionDefectCheckerTest.java | 22 -------- 5 files changed, 39 insertions(+), 68 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectChecker.java index ba4e79ef3c4..6c9e5861a70 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectChecker.java @@ -84,8 +84,7 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState return Description.NO_MATCH; } - return visitNewClassOrMethodInvocation( - InvocationInfo.createFromMethodInvocation(tree, symbol, state)); + return visit(InvocationInfo.createFromMethodInvocation(tree, symbol, state)); } @Override @@ -97,28 +96,24 @@ public Description matchNewClass(NewClassTree tree, VisitorState state) { return Description.NO_MATCH; } - return visitNewClassOrMethodInvocation(InvocationInfo.createFromNewClass(tree, symbol, state)); + return visit(InvocationInfo.createFromNewClass(tree, symbol, state)); } - private Description visitNewClassOrMethodInvocation(InvocationInfo invocationInfo) { - + private Description visit(InvocationInfo invocationInfo) { Changes changes = argumentChangeFinder.findChanges(invocationInfo); if (changes.isEmpty()) { return Description.NO_MATCH; } - Description.Builder description = - buildDescription(invocationInfo.tree()).setMessage(changes.describe(invocationInfo)); - - // Fix 1 (semantics-preserving): apply comments with parameter names to potentially-swapped - // arguments of the method - description.addFix(changes.buildCommentArgumentsFix(invocationInfo)); - - // Fix 2: permute the arguments as required - description.addFix(changes.buildPermuteArgumentsFix(invocationInfo)); - - return description.build(); + return buildDescription(invocationInfo.tree()) + .setMessage(changes.describe(invocationInfo)) + // Fix 1 (semantics-preserving): apply comments with parameter names to potentially-swapped + // arguments of the method + .addFix(changes.buildCommentArgumentsFix(invocationInfo)) + // Fix 2: permute the arguments as required + .addFix(changes.buildPermuteArgumentsFix(invocationInfo)) + .build(); } /** diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Changes.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Changes.java index 2ae08e34251..f26f58265d5 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Changes.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Changes.java @@ -21,7 +21,7 @@ import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; import com.google.errorprone.fixes.SuggestedFix; -import com.sun.source.tree.ExpressionTree; +import com.sun.source.tree.Tree; import java.util.stream.Collectors; /** @@ -65,7 +65,7 @@ SuggestedFix buildCommentArgumentsFix(InvocationInfo info) { SuggestedFix.Builder commentArgumentsFixBuilder = SuggestedFix.builder(); for (ParameterPair change : changedPairs()) { int index = change.formal().index(); - ExpressionTree actual = info.actualParameters().get(index); + Tree actual = info.actualParameters().get(index); int startPosition = getStartPosition(actual); String formal = info.formalParameters().get(index).getSimpleName().toString(); commentArgumentsFixBuilder.replace( diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/InvocationInfo.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/InvocationInfo.java index 1c915419d42..85bc1775ee4 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/InvocationInfo.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/InvocationInfo.java @@ -19,7 +19,6 @@ import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; import com.google.errorprone.VisitorState; -import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.NewClassTree; import com.sun.source.tree.Tree; @@ -39,7 +38,7 @@ abstract class InvocationInfo { abstract MethodSymbol symbol(); - abstract ImmutableList actualParameters(); + abstract ImmutableList actualParameters(); abstract ImmutableList formalParameters(); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Parameter.java b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Parameter.java index 7235a043588..12f771bf9f4 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Parameter.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/argumentselectiondefects/Parameter.java @@ -32,6 +32,7 @@ import com.sun.source.tree.MemberSelectTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.NewClassTree; +import com.sun.source.tree.Tree; import com.sun.source.tree.Tree.Kind; import com.sun.source.tree.VariableTree; import com.sun.tools.javac.code.Symbol; @@ -88,14 +89,17 @@ static ImmutableList createListFromVarSymbols(List varSymb .collect(toImmutableList()); } - static ImmutableList createListFromExpressionTrees( - List trees) { + static ImmutableList createListFromExpressionTrees(List trees) { return Streams.mapWithIndex( trees.stream(), (t, i) -> new AutoValue_Parameter( getArgumentName(t), - Optional.ofNullable(ASTHelpers.getResultType(t)).orElse(Type.noType), + Optional.ofNullable( + t instanceof ExpressionTree + ? ASTHelpers.getResultType((ExpressionTree) t) + : ASTHelpers.getType(t)) + .orElse(Type.noType), (int) i, t.toString(), t.getKind(), @@ -162,28 +166,25 @@ private static String getClassName(ClassSymbol s) { * will return the marker for an unknown name. */ @VisibleForTesting - static String getArgumentName(ExpressionTree expressionTree) { - switch (expressionTree.getKind()) { - case MEMBER_SELECT -> { - return ((MemberSelectTree) expressionTree).getIdentifier().toString(); - } - case NULL_LITERAL -> { - // null could match anything pretty well - return NAME_NULL; - } + static String getArgumentName(Tree tree) { + return switch (tree.getKind()) { + case VARIABLE -> ((VariableTree) tree).getName().toString(); + case MEMBER_SELECT -> ((MemberSelectTree) tree).getIdentifier().toString(); + // null could match anything pretty well + case NULL_LITERAL -> NAME_NULL; case IDENTIFIER -> { - IdentifierTree idTree = (IdentifierTree) expressionTree; + IdentifierTree idTree = (IdentifierTree) tree; if (idTree.getName().contentEquals("this")) { // for the 'this' keyword the argument name is the name of the object's class Symbol sym = ASTHelpers.getSymbol(idTree); - return sym != null ? getClassName(ASTHelpers.enclosingClass(sym)) : NAME_NOT_PRESENT; + yield sym != null ? getClassName(ASTHelpers.enclosingClass(sym)) : NAME_NOT_PRESENT; } else { // if we have a variable, just extract its name - return idTree.getName().toString(); + yield idTree.getName().toString(); } } case METHOD_INVOCATION -> { - MethodInvocationTree methodInvocationTree = (MethodInvocationTree) expressionTree; + MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree; MethodSymbol methodSym = ASTHelpers.getSymbol(methodInvocationTree); String name = methodSym.getSimpleName().toString(); ImmutableList terms = NamingConventions.splitToLowercaseTerms(name); @@ -192,26 +193,24 @@ static String getArgumentName(ExpressionTree expressionTree) { if (terms.size() == 1) { ExpressionTree receiver = ASTHelpers.getReceiver(methodInvocationTree); if (receiver == null) { - return getClassName(ASTHelpers.enclosingClass(methodSym)); + yield getClassName(ASTHelpers.enclosingClass(methodSym)); } // recursively try to get a name from the receiver - return getArgumentName(receiver); + yield getArgumentName(receiver); } else { - return name.substring(firstTerm.length()); + yield name.substring(firstTerm.length()); } } else { - return name; + yield name; } } case NEW_CLASS -> { - MethodSymbol constructorSym = ASTHelpers.getSymbol((NewClassTree) expressionTree); - return constructorSym.owner != null + MethodSymbol constructorSym = ASTHelpers.getSymbol((NewClassTree) tree); + yield constructorSym.owner != null ? getClassName((ClassSymbol) constructorSym.owner) : NAME_NOT_PRESENT; } - default -> { - return NAME_NOT_PRESENT; - } - } + default -> NAME_NOT_PRESENT; + }; } } diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectCheckerTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectCheckerTest.java index 6a650688d5c..5fcc032d1b7 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectCheckerTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectCheckerTest.java @@ -399,28 +399,6 @@ Foo test(String first, String second) { } } -record Foo(String first, String second) {} -""") - .doTest(); - } - - @Test - public void recordDeconstruction() { - assume().that(Runtime.version().feature()).isAtLeast(21); - - testHelper - .addSourceLines( - "Test.java", - """ -class Test { - void test(Foo foo) { - switch (foo) { - // TODO(user): We should report a finding here! - case Foo(String second, String first) -> {} - } - } -} - record Foo(String first, String second) {} """) .doTest(); From b222ea8c65c9e357c76223f2113b795a7c6977ba Mon Sep 17 00:00:00 2001 From: ghm Date: Mon, 18 Nov 2024 05:59:31 -0800 Subject: [PATCH 36/38] Handle qualified enum elements in MissingCasesInEnumSwitch. PiperOrigin-RevId: 697598061 --- .../bugpatterns/MissingCasesInEnumSwitch.java | 18 +++++++---- .../MissingCasesInEnumSwitchTest.java | 32 ++++++++++++++++--- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitch.java b/core/src/main/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitch.java index b861bcf3780..7f18b1b7482 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitch.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitch.java @@ -18,6 +18,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; +import static com.google.errorprone.util.ASTHelpers.getSymbol; import static com.google.errorprone.util.ASTHelpers.isSwitchDefault; import com.google.common.collect.ImmutableSet; @@ -27,9 +28,11 @@ import com.google.errorprone.bugpatterns.BugChecker.SwitchTreeMatcher; import com.google.errorprone.matchers.Description; import com.google.errorprone.util.ASTHelpers; -import com.sun.source.tree.IdentifierTree; +import com.sun.source.tree.CaseTree; +import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.SwitchTree; import com.sun.tools.javac.code.Type; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; import javax.lang.model.element.ElementKind; @@ -44,25 +47,26 @@ public class MissingCasesInEnumSwitch extends BugChecker implements SwitchTreeMa @Override public Description matchSwitch(SwitchTree tree, VisitorState state) { - Type switchType = ASTHelpers.getType(tree.getExpression()); + ExpressionTree expression = tree.getExpression(); + List cases = tree.getCases(); + Type switchType = ASTHelpers.getType(expression); if (switchType.asElement().getKind() != ElementKind.ENUM) { return Description.NO_MATCH; } // default case is present - if (tree.getCases().stream().anyMatch(c -> isSwitchDefault(c))) { + if (cases.stream().anyMatch(c -> isSwitchDefault(c))) { return Description.NO_MATCH; } ImmutableSet handled = - tree.getCases().stream() + cases.stream() .flatMap(c -> c.getExpressions().stream()) - .filter(IdentifierTree.class::isInstance) - .map(e -> ((IdentifierTree) e).getName().toString()) + .map(e -> getSymbol(e).getSimpleName().toString()) .collect(toImmutableSet()); Set unhandled = Sets.difference(ASTHelpers.enumValues(switchType.asElement()), handled); if (unhandled.isEmpty()) { return Description.NO_MATCH; } - return buildDescription(tree).setMessage(buildMessage(unhandled)).build(); + return buildDescription(expression).setMessage(buildMessage(unhandled)).build(); } /** diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitchTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitchTest.java index c1e23c5585f..34461b3f7fd 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitchTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/MissingCasesInEnumSwitchTest.java @@ -56,9 +56,36 @@ void m(Case c) { .doTest(); } + @Test + public void exhaustive_allowsQualifying() { + assume().that(Runtime.version().feature()).isAtLeast(21); + compilationHelper + .addSourceLines( + "Test.java", + """ + class Test { + enum Case { + ONE, + TWO, + THREE + } + + void m(Case c) { + switch (c) { + case Case.ONE: + case Case.TWO: + case Case.THREE: + System.err.println("found it!"); + break; + } + } + } + """) + .doTest(); + } + @Test public void exhaustive_multipleCaseExpressions() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Test.java", @@ -209,7 +236,6 @@ void m(Case e) { @Test public void nonExhaustive_arrowStatement() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Test.java", @@ -235,7 +261,6 @@ void m(Case c) { @Test public void nonExhaustive_multi() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Test.java", @@ -261,7 +286,6 @@ void m(Case c) { @Test public void nonExhaustive_multiArrow() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Test.java", From fc5aade955969968c782504995ead5783ca00723 Mon Sep 17 00:00:00 2001 From: ghm Date: Mon, 18 Nov 2024 07:16:40 -0800 Subject: [PATCH 37/38] Remove swathes of assume()s on the current runtime version. EP is targetting 17, so these are all trivially true for all builds. Except one, which was trivially false, so I removed the test. PiperOrigin-RevId: 697616719 --- .../bugpatterns/AnnotateFormatMethodTest.java | 3 - .../bugpatterns/AnnotationPositionTest.java | 3 - .../bugpatterns/CannotMockFinalClassTest.java | 4 - .../bugpatterns/ClassCanBeStaticTest.java | 3 - .../bugpatterns/DefaultCharsetTest.java | 3 - .../bugpatterns/DefaultLocaleTest.java | 4 - .../bugpatterns/FallThroughTest.java | 4 - .../bugpatterns/FieldCanBeStaticTest.java | 4 - .../bugpatterns/MethodCanBeStaticTest.java | 4 - .../bugpatterns/MisformattedTestDataTest.java | 11 --- .../MisleadingEscapedSpaceTest.java | 20 ----- .../bugpatterns/MissingDefaultTest.java | 3 - .../bugpatterns/MissingOverrideTest.java | 6 -- .../MixedMutabilityReturnTypeTest.java | 3 - .../NamedLikeContextualKeywordTest.java | 4 - .../bugpatterns/NullTernaryTest.java | 3 - ...PrivateConstructorForUtilityClassTest.java | 3 - ...StatementSwitchToExpressionSwitchTest.java | 73 ------------------- .../bugpatterns/StreamResourceLeakTest.java | 2 - .../StringFormatWithLiteralTest.java | 4 - .../bugpatterns/SwitchDefaultTest.java | 2 - .../TraditionalSwitchExpressionTest.java | 5 -- .../bugpatterns/UngroupedOverloadsTest.java | 4 - .../UnnecessaryBreakInSwitchTest.java | 8 -- .../UnnecessaryDefaultInEnumSwitchTest.java | 4 - .../UnnecessaryParenthesesTest.java | 3 - .../bugpatterns/UnusedVariableTest.java | 8 -- .../ArgumentSelectionDefectCheckerTest.java | 4 - .../formatstring/FormatStringTest.java | 6 -- .../bugpatterns/javadoc/InvalidParamTest.java | 7 -- .../nullness/FieldMissingNullableTest.java | 3 - .../nullness/ReturnMissingNullableTest.java | 3 - .../threadsafety/ImmutableCheckerTest.java | 6 -- 33 files changed, 227 deletions(-) diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/AnnotateFormatMethodTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/AnnotateFormatMethodTest.java index 79d7bfaa6bc..7c712b79208 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/AnnotateFormatMethodTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/AnnotateFormatMethodTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.CompilationTestHelper; import org.junit.Test; import org.junit.runner.RunWith; @@ -51,7 +49,6 @@ String formatMe(String formatString, Object... args) { @Test public void formatted() { - assume().that(Runtime.version().feature()).isAtLeast(15); compilationHelper .addSourceLines( "AnnotateFormatMethodPositiveCases.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/AnnotationPositionTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/AnnotationPositionTest.java index a9d6637b752..0a0a983634d 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/AnnotationPositionTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/AnnotationPositionTest.java @@ -16,7 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; import static com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH; import com.google.errorprone.BugCheckerRefactoringTestHelper; @@ -418,7 +417,6 @@ interface Test { // TODO(b/168625474): 'sealed' doesn't have a TokenKind @Test public void sealedInterface() { - assume().that(Runtime.version().feature()).isAtLeast(15); refactoringHelper .addInputLines( "Test.java", @@ -623,7 +621,6 @@ void m() { @Test public void recordAnnotation() { - assume().that(Runtime.version().feature()).isAtLeast(16); refactoringHelper .addInputLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/CannotMockFinalClassTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/CannotMockFinalClassTest.java index 3bdd0e3bab2..6393f87c9fb 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/CannotMockFinalClassTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/CannotMockFinalClassTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.CompilationTestHelper; import org.junit.Test; import org.junit.runner.RunWith; @@ -63,8 +61,6 @@ public void method() { @Test public void positiveCase_record() { - assume().that(Runtime.version().feature()).isAtLeast(16); - compilationHelper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/ClassCanBeStaticTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/ClassCanBeStaticTest.java index b8182650abc..0782895a0ed 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/ClassCanBeStaticTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/ClassCanBeStaticTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.CompilationTestHelper; import org.junit.Test; import org.junit.runner.RunWith; @@ -545,7 +543,6 @@ class Inner {} @Test public void nestedInLocal_static() { - assume().that(Runtime.version().feature()).isAtLeast(16); compilationHelper .addSourceLines( "A.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/DefaultCharsetTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/DefaultCharsetTest.java index e4417896582..741e97eb34b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/DefaultCharsetTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/DefaultCharsetTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.BugCheckerRefactoringTestHelper; import com.google.errorprone.BugCheckerRefactoringTestHelper.FixChoosers; import com.google.errorprone.CompilationTestHelper; @@ -588,7 +586,6 @@ void f() throws Exception { @Test public void withVar() { - assume().that(Runtime.version().feature()).isAtLeast(15); refactoringTest() .addInputLines( "in/Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/DefaultLocaleTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/DefaultLocaleTest.java index 08f68cdb2b4..00c91a91b21 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/DefaultLocaleTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/DefaultLocaleTest.java @@ -17,7 +17,6 @@ package com.google.errorprone.bugpatterns; import static com.google.common.base.Predicates.containsPattern; -import static com.google.common.truth.TruthJUnit.assume; import static com.google.errorprone.bugpatterns.DefaultLocale.onlyContainsSpecifiersInAllowList; import static java.util.function.Predicate.not; import static org.junit.Assert.assertFalse; @@ -143,7 +142,6 @@ public void formatMethods_negative() { @Test public void stringFormatted() { - assume().that(Runtime.version().feature()).isAtLeast(15); compilationHelper .addSourceLines( "Test.java", @@ -233,7 +231,6 @@ void f(DateTimeFormatterBuilder dtfb) throws Exception { @Test public void factoryMethodsJdk12plus() { - assume().that(Runtime.version().feature()).isAtLeast(12); compilationHelper .addSourceLines( "Test.java", @@ -311,7 +308,6 @@ public void resourceBundle() { @Test public void resourceBundleJdk9plus() { - assume().that(Runtime.version().feature()).isAtLeast(9); compilationHelper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/FallThroughTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/FallThroughTest.java index ab4e645f498..6efea5a2f1d 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/FallThroughTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/FallThroughTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.CompilationTestHelper; import org.junit.Ignore; import org.junit.Test; @@ -340,7 +338,6 @@ void f(char c, boolean b) { @Test public void arrowSwitch() { - assume().that(Runtime.version().feature()).isAtLeast(14); testHelper .addSourceLines( "Test.java", @@ -366,7 +363,6 @@ void m(Case c) { @Ignore("https://github.com/google/error-prone/issues/2638") @Test public void i2118() { - assume().that(Runtime.version().feature()).isAtLeast(14); testHelper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/FieldCanBeStaticTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/FieldCanBeStaticTest.java index 693d5aea27d..94ea9b0e4db 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/FieldCanBeStaticTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/FieldCanBeStaticTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.BugCheckerRefactoringTestHelper; import com.google.errorprone.CompilationTestHelper; import org.junit.Test; @@ -351,7 +349,6 @@ class L { @Test public void inner_static() { - assume().that(Runtime.version().feature()).isAtLeast(16); compilationHelper .addSourceLines( "Test.java", @@ -394,7 +391,6 @@ class L { @Test public void record() { - assume().that(Runtime.version().feature()).isAtLeast(16); compilationHelper .addSourceLines( "ExampleClass.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/MethodCanBeStaticTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/MethodCanBeStaticTest.java index eca5ca0ebb6..e15ebfd8cdd 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/MethodCanBeStaticTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/MethodCanBeStaticTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.common.collect.ImmutableList; import com.google.errorprone.BugCheckerRefactoringTestHelper; import com.google.errorprone.CompilationTestHelper; @@ -422,7 +420,6 @@ private int incr(int x) { @Test public void innerClass_static() { - assume().that(Runtime.version().feature()).isAtLeast(16); testHelper .addSourceLines( "Test.java", @@ -491,7 +488,6 @@ private void foo() {} @Test public void positiveLocal() { - assume().that(Runtime.version().feature()).isAtLeast(16); testHelper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/MisformattedTestDataTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/MisformattedTestDataTest.java index e11c1542aae..27aceca89d9 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/MisformattedTestDataTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/MisformattedTestDataTest.java @@ -16,7 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; import static com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH; import com.google.errorprone.BugCheckerRefactoringTestHelper; @@ -34,8 +33,6 @@ public final class MisformattedTestDataTest { @Test public void alreadyFormatted_noFinding() { - assume().that(Runtime.version().feature()).isAtLeast(14); - compilationHelper .addSourceLines( "Test.java", @@ -63,8 +60,6 @@ void method() { @Test public void onlyDiffersByFinalNewline_noFinding() { - assume().that(Runtime.version().feature()).isAtLeast(14); - compilationHelper .addSourceLines( "Test.java", @@ -91,8 +86,6 @@ void method() { @Test public void misformatted_suggestsFix() { - assume().that(Runtime.version().feature()).isAtLeast(14); - refactoringHelper .addInputLines( "Test.java", @@ -141,8 +134,6 @@ void method() { @Test public void onlyDiffersByIndentation_notReindented() { - assume().that(Runtime.version().feature()).isAtLeast(14); - refactoringHelper .addInputLines( "Test.java", @@ -171,8 +162,6 @@ void method() { @Test public void escapesSpecialCharacters() { - assume().that(Runtime.version().feature()).isAtLeast(14); - refactoringHelper .addInputLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/MisleadingEscapedSpaceTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/MisleadingEscapedSpaceTest.java index ab2fb40ec07..51e00d75aa6 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/MisleadingEscapedSpaceTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/MisleadingEscapedSpaceTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.CompilationTestHelper; import org.junit.Test; import org.junit.runner.RunWith; @@ -30,8 +28,6 @@ public final class MisleadingEscapedSpaceTest { @Test public void misleadingEscape() { - assume().that(Runtime.version().feature()).isAtLeast(14); - testHelper .addSourceLines( "Test.class", @@ -46,8 +42,6 @@ class Test { @Test public void literalBackslashS() { - assume().that(Runtime.version().feature()).isAtLeast(14); - testHelper .addSourceLines( "Test.class", @@ -61,8 +55,6 @@ class Test { @Test public void asSingleCharacter_misleading() { - assume().that(Runtime.version().feature()).isAtLeast(14); - testHelper .addSourceLines( "Test.class", @@ -77,8 +69,6 @@ class Test { @Test public void withinTextBlock_notAtEndOfLine_misleading() { - assume().that(Runtime.version().feature()).isAtLeast(14); - testHelper .addSourceLines( "Test.class", @@ -100,8 +90,6 @@ class Test { @Test public void atEndOfLine_notMisleading() { - assume().that(Runtime.version().feature()).isAtLeast(14); - testHelper .addSourceLines( "Test.class", @@ -118,8 +106,6 @@ class Test { @Test public void multipleAtEndOfLine_notMisleading() { - assume().that(Runtime.version().feature()).isAtLeast(14); - testHelper .addSourceLines( "Test.class", @@ -135,8 +121,6 @@ class Test { @Test public void withinCommentInBrokenUpString_noFinding() { - assume().that(Runtime.version().feature()).isAtLeast(14); - testHelper .addSourceLines( "Test.class", @@ -150,8 +134,6 @@ class Test { @Test public void atEndOfString_noFinding() { - assume().that(Runtime.version().feature()).isAtLeast(14); - testHelper .addSourceLines( "Test.class", @@ -168,8 +150,6 @@ class Test { @Test public void escapedSpaceAtEndOfString() { - assume().that(Runtime.version().feature()).isAtLeast(14); - testHelper .addSourceLines( "Test.class", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/MissingDefaultTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/MissingDefaultTest.java index 35d1d18ebef..9152bbf4e9d 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/MissingDefaultTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/MissingDefaultTest.java @@ -257,7 +257,6 @@ boolean f(int i) { @Test public void arrowSwitch() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Test.java", @@ -277,7 +276,6 @@ void m(int i) { @Test public void arrowSwitchNegative() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Test.java", @@ -297,7 +295,6 @@ void m(int i) { @Test public void arrowComment() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/MissingOverrideTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/MissingOverrideTest.java index 13ad7ae024c..def5bd116d6 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/MissingOverrideTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/MissingOverrideTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.common.collect.ImmutableList; import com.google.errorprone.CompilationTestHelper; import org.junit.Test; @@ -195,8 +193,6 @@ public interface Test extends Super { @Test public void explicitRecordAccessor() { - assume().that(Runtime.version().feature()).isAtLeast(16); - compilationHelper .addSourceLines( "Baz.java", @@ -219,8 +215,6 @@ public int y() { @Test public void explicitRecordAccessor_doesNotFlagConstructors() { - assume().that(Runtime.version().feature()).isAtLeast(16); - compilationHelper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/MixedMutabilityReturnTypeTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/MixedMutabilityReturnTypeTest.java index 4e4ba6eef98..0f95c72c8ca 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/MixedMutabilityReturnTypeTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/MixedMutabilityReturnTypeTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.BugCheckerRefactoringTestHelper; import com.google.errorprone.BugCheckerRefactoringTestHelper.FixChoosers; import com.google.errorprone.CompilationTestHelper; @@ -555,7 +553,6 @@ List foo(T a) { @Test public void refactoringWithVar() { - assume().that(Runtime.version().feature()).isAtLeast(15); refactoringHelper .addInputLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/NamedLikeContextualKeywordTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/NamedLikeContextualKeywordTest.java index d7dc67e66bc..c72548a59a6 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/NamedLikeContextualKeywordTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/NamedLikeContextualKeywordTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.common.collect.ImmutableList; import com.google.errorprone.CompilationTestHelper; import org.junit.Test; @@ -153,8 +151,6 @@ public module() {} @Test public void yieldInSwitch_noError() { - - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/NullTernaryTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/NullTernaryTest.java index d6cbf215c02..0bcabef72a7 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/NullTernaryTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/NullTernaryTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.CompilationTestHelper; import org.junit.Test; import org.junit.runner.RunWith; @@ -134,7 +132,6 @@ void conditionalInCondition(Object array, String input) { @Test public void expressionSwitch_doesNotCrash() { - assume().that(Runtime.version().feature()).isAtLeast(14); testHelper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/PrivateConstructorForUtilityClassTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/PrivateConstructorForUtilityClassTest.java index 534def20b43..4072e1cb301 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/PrivateConstructorForUtilityClassTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/PrivateConstructorForUtilityClassTest.java @@ -15,8 +15,6 @@ */ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.BugCheckerRefactoringTestHelper; import com.google.errorprone.CompilationTestHelper; import org.junit.Test; @@ -414,7 +412,6 @@ abstract class Test { @Test public void record() { - assume().that(Runtime.version().feature()).isAtLeast(16); CompilationTestHelper.newInstance(PrivateConstructorForUtilityClass.class, getClass()) .addSourceLines( "ExampleUtilityClass.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java index 7cac131bb20..60a6a12efa9 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitchTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.common.collect.ImmutableList; import com.google.errorprone.BugCheckerRefactoringTestHelper; import com.google.errorprone.CompilationTestHelper; @@ -36,8 +34,6 @@ public final class StatementSwitchToExpressionSwitchTest { @Test public void switchByEnum_removesRedundantBreak_error() { - - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -137,8 +133,6 @@ public void foo(Side side) { @Test public void switchByEnumWithCompletionAnalsis_removesRedundantBreak_error() { - - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -232,8 +226,6 @@ public void foo(Side side) { @Test public void switchByEnumCard_combinesCaseComments_error() { - - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -340,8 +332,6 @@ public void foo(Side side) { @Test public void switchByEnumCard2_removesRedundantBreaks_error() { - - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -445,8 +435,6 @@ public void foo(Side side) { @Test public void switchByEnumCard_onlyExpressionsAndThrowAreBraceless_error() { - - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -551,8 +539,6 @@ public void foo(Side side) { @Test public void switchFallsThruToDefault_noError() { - - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -590,7 +576,6 @@ public void foo(Side side) { public void switchFallsThruFromDefault_noError() { // Placing default in the middle of the switch is not recommended, but is valid Java - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -628,9 +613,7 @@ public void foo(Side side) { @Test public void switchWithDefaultInMiddle_error() { - // Placing default in the middle of the switch is not recommended, but is valid Java - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -735,7 +718,6 @@ public void foo(Side side) { @Test public void switchWithLabelledBreak_error() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -841,7 +823,6 @@ public void foo(Side side) { @Test public void switchByEnum_statementSwitchWithMultipleExpressions_error() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -933,7 +914,6 @@ public void foo(Side side) { @Test public void switchByEnumCardWithThrow_error() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -971,7 +951,6 @@ public void foo(Side side) { @Test public void switchInSwitch_error() { // Only the outer "switch" should generate a finding - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -1015,7 +994,6 @@ public void foo(Side side) { @Test public void switchByEnumCardWithReturnNested1_error() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -1113,7 +1091,6 @@ public void foo(Side side) { @Test public void switchByEnumCardWithReturnNested2_error() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -1156,7 +1133,6 @@ public void foo(Side side) { @Test public void switchByEnumWithConditionalControl_noError() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -1194,7 +1170,6 @@ public void foo(Side side) { @Test public void switchByEnumWithLambda_noError() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -1226,7 +1201,6 @@ public void switchByEnumWithLambda_noError() { @Test public void singleCaseConvertible_error() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -1258,7 +1232,6 @@ public void foo(Side side) { @Test public void emptyExpressionSwitchCases_noMatch() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -1277,7 +1250,6 @@ void foo(int value) { @Test public void nonEmptyExpressionSwitchCases_noMatch() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -1298,7 +1270,6 @@ void foo(int value) { @Test public void dynamicWithThrowableDuringInitializationFromMethod_noMatch() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -1321,7 +1292,6 @@ private static Throwable bar() { @Test public void switchByEnum_exampleInDocumentation_error() { // This code appears as an example in the documentation (added surrounding class) - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -1427,7 +1397,6 @@ private void bar() {} public void switchByEnum_caseHasOnlyComments_error() { // When a case is solely comments, we should still try to convert the switch using braceless // syntax - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -1537,7 +1506,6 @@ private void bar() {} @Test public void switchByEnum_accumulatedComments_error() { // Comments should be aggregated across multiple cases - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -1649,7 +1617,6 @@ private void bar() {} public void switchByEnum_surroundingBracesCannotRemove_error() { // Can't remove braces around OBVERSE because break statements are not a member of // KINDS_CONVERTIBLE_WITHOUT_BRACES - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -1741,7 +1708,6 @@ public void foo(Side side) { public void switchByEnum_surroundingBracesEmpty_error() { // Test handling of cases with surrounding braces that are empty. The braces around OBVERSE // can be removed because throw is a member of KINDS_CONVERTIBLE_WITHOUT_BRACES. - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( @@ -1830,7 +1796,6 @@ public void foo(Side side) { @Test public void switchByEnum_afterReturnComments_error() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -1934,7 +1899,6 @@ public int foo(Suit suit) { @Test public void switchByEnum_returnSwitch_error() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -2038,7 +2002,6 @@ public int foo(Side side) { @Test public void switchByEnum_returnSwitchWithShouldNeverHappen_error() { - assume().that(Runtime.version().feature()).isAtLeast(14); // Check correct generated code refactoringHelper @@ -2112,7 +2075,6 @@ public int foo(Side side) { @Test public void switchByEnum_returnSwitchCommentsBeforeFirstCase_errorAndRetained() { - assume().that(Runtime.version().feature()).isAtLeast(14); // Check correct generated code refactoringHelper @@ -2192,7 +2154,6 @@ public int foo(Side side) { @Test public void switchByEnum_switchInReturnSwitchWithShouldNeverHappen_error() { - assume().that(Runtime.version().feature()).isAtLeast(14); // No error because the inner switch is the only fixable one helper .addSourceLines( @@ -2245,7 +2206,6 @@ public int foo(Side side) { @Test public void switchByEnum_exhaustiveWithDefault_error() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -2353,7 +2313,6 @@ public int foo(Side side) { @Test public void switchByEnum_defaultFallThru_noError() { // No error because default doesn't return anything within its block - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -2395,7 +2354,6 @@ public int foo(Side side) { @Test public void switchByEnum_alwaysThrows_noError() { // Every case throws, thus no type for return switch - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -2436,7 +2394,6 @@ public int foo(Side side) { @Test public void switchByEnum_returnSwitchWithShouldNeverHappen_errorAndRemoveShouldNeverHappen() { // The switch has a case for each enum and "should never happen" error handling - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -2585,7 +2542,6 @@ public int foo(Side side) { public void switchByEnum_returnSwitchNoFollowingStatementsInBlock_errorAndNoRemoval() { // The switch is exhaustive but doesn't have any statements immediately following it in the // lowest ancestor statement block - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -2728,7 +2684,6 @@ public int foo(Side side) { public void switchByEnum_groupedComments_errorAndNoRemoval() { // The switch is exhaustive but doesn't have any statements immediately following it in the // lowest ancestor statement block - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -2887,7 +2842,6 @@ public int foo(Side side) { public void switchByEnum_returnSwitchWithShouldNeverHappenInLambda_errorAndRemoveShouldNeverHappen() { // Conversion to return switch within a lambda - assume().that(Runtime.version().feature()).isAtLeast(14); refactoringHelper .addInputLines( @@ -2978,7 +2932,6 @@ public int foo(Side side) { @Test public void switchByEnum_returnSwitchVoid_noError() { // A void cannot be converted to a return switch - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3016,7 +2969,6 @@ public void foo(Side side) { @Test public void switchByEnum_returnLabelledContinue_noError() { // Control jumps outside the switch for HEART - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3057,7 +3009,6 @@ public int foo(Side side) { @Test public void switchByEnum_returnUnlabelledContinue_noError() { // Control jumps outside the switch for HEART - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3098,7 +3049,6 @@ public int foo(Side side) { @Test public void switchByEnum_returnLabelledBreak_noError() { // Control jumps outside the switch for HEART - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3140,7 +3090,6 @@ public int foo(Side side) { @Test public void switchByEnum_returnYield_noError() { // Does not attempt to convert "yield" expressions - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3183,7 +3132,6 @@ public int foo(Side side) { @Test public void switchByEnum_assignmentSwitchToLocalHasDefault_error() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3285,7 +3233,6 @@ public int foo(Side side) { @Test public void switchByEnum_assignmentSwitchMixedReferences_error() { // Must deduce that "x" and "this.x" refer to same thing - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3410,7 +3357,6 @@ public int foo(Side side) { @Test public void switchByEnum_assignmentSwitchMixedReferences_noError() { // Must deduce that "x" and "this.y" refer to different things - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3456,7 +3402,6 @@ public int foo(Side side) { @Test public void switchByEnum_assignmentSwitchTwoAssignments_noError() { // Can't convert multiple assignments, even if redundant - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3501,7 +3446,6 @@ public int foo(Side side) { @Test public void switchByEnum_assignmentSwitchToSingleArray_error() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3618,7 +3562,6 @@ public void switchByEnum_assignmentSwitchToMultipleArray_noError() { // Multiple array dereferences or other non-variable left-hand-side expressions may (in // principle) be convertible to assignment switches, but this feature is not supported at this // time - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3664,7 +3607,6 @@ public int[] foo(Side side) { @Test public void switchByEnum_assignmentSwitchToMultipleDistinct_noError() { // x[5] and x[6] are distinct assignment targets - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3711,7 +3653,6 @@ public int[] foo(Side side) { public void switchByEnum_assignmentSwitchMixedKinds_noError() { // Different assignment types ("=" versus "+="). The check does not attempt to alter the // assignments to make the assignment types match (e.g. does not change to "x = x + 2") - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3755,7 +3696,6 @@ public int foo(Side side) { @Test public void switchByEnum_assignmentLabelledContinue_noError() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3805,7 +3745,6 @@ public int foo(Side side) { @Test public void switchByEnum_assignmentLabelledBreak_noError() { // Can't convert because of "break before" - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3855,7 +3794,6 @@ public int foo(Side side) { @Test public void switchByEnum_assignmentLabelledBreak2_noError() { // Can't convert because of "break before" as the second statement in its block - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3905,7 +3843,6 @@ public int foo(Side side) { @Test public void switchByEnum_assignmentUnlabelledContinue_noError() { - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3955,7 +3892,6 @@ public int foo(Side side) { @Test public void switchByEnum_assignmentYield_noError() { // Does not attempt to convert "yield" expressions - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -3998,7 +3934,6 @@ public void switchByEnum_exhaustiveAssignmentSwitch_error() { // Transformation can change error handling. Here, if the enum is not exhaustive at runtime // (say there is a new JOKER suit), then nothing would happen. But the transformed source, // would throw. - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -4105,7 +4040,6 @@ public int foo(Side side) { @Test public void switchByEnum_exhaustiveCompoundAssignmentSwitch_error() { // Verify compound assignments (here, +=) - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -4206,7 +4140,6 @@ public int foo(Side side) { @Test public void switchByEnum_groupedComments_error() { // Verify compound assignments (here, *=) with grouped comments - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -4333,7 +4266,6 @@ public int foo(Side side) { @Test public void switchByEnum_compoundAssignmentExampleInDocumentation_error() { // This code appears as an example in the documentation (added surrounding class) - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -4435,7 +4367,6 @@ private void updateScore(Suit suit) { @Test public void switchByEnum_exhaustiveAssignmentSwitchCaseList_error() { // Statement switch has cases with multiple values - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -4529,7 +4460,6 @@ public int foo(Side side) { @Test public void switchByEnum_nonExhaustiveAssignmentSwitch_noError() { // No HEART case - assume().that(Runtime.version().feature()).isAtLeast(14); helper .addSourceLines( "Test.java", @@ -4567,7 +4497,6 @@ public int foo(Side side) { @Test public void i4222() { - assume().that(Runtime.version().feature()).isAtLeast(14); refactoringHelper .addInputLines( "Test.java", @@ -4613,7 +4542,6 @@ public static void main(String[] args) { @Test public void unnecessaryBreaks() { - assume().that(Runtime.version().feature()).isAtLeast(14); refactoringHelper .addInputLines( "Test.java", @@ -4653,7 +4581,6 @@ public static void main(String[] args) { @Test public void mixedExpressionsAndYields() { - assume().that(Runtime.version().feature()).isAtLeast(14); refactoringHelper .addInputLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/StreamResourceLeakTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/StreamResourceLeakTest.java index 2dc099bf071..26b24ee28f9 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/StreamResourceLeakTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/StreamResourceLeakTest.java @@ -16,7 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; import static java.lang.String.format; import com.google.errorprone.BugCheckerRefactoringTestHelper; @@ -322,7 +321,6 @@ default DirectoryStream f(Path path) throws IOException { @Test public void record() { - assume().that(Runtime.version().feature()).isAtLeast(16); testHelper .addSourceLines( "ExampleRecord.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/StringFormatWithLiteralTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/StringFormatWithLiteralTest.java index d68f69715d2..031321f3d23 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/StringFormatWithLiteralTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/StringFormatWithLiteralTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.BugCheckerRefactoringTestHelper; import com.google.errorprone.CompilationTestHelper; import org.junit.Test; @@ -229,7 +227,6 @@ String test() { @Test public void refactoringFormattedWithNoArguments() { - assume().that(Runtime.version().feature()).isAtLeast(15); refactoringHelper .addInputLines( "ExampleClass.java", @@ -278,7 +275,6 @@ String test() { @Test public void refactoringFormattedWithIntegerLiteral() { - assume().that(Runtime.version().feature()).isAtLeast(15); refactoringHelper .addInputLines( "ExampleClass.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/SwitchDefaultTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/SwitchDefaultTest.java index 8ab96914511..56a035f211c 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/SwitchDefaultTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/SwitchDefaultTest.java @@ -258,7 +258,6 @@ boolean f(int i) { @Test public void newNotation_validDefault() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Test.java", @@ -284,7 +283,6 @@ public static void switchDefaultCrash(int i) { @Test public void newNotation_changeOrder() { - assume().that(Runtime.version().feature()).isAtLeast(14); testHelper .addInputLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/TraditionalSwitchExpressionTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/TraditionalSwitchExpressionTest.java index e881c1a40b3..3beb7917861 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/TraditionalSwitchExpressionTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/TraditionalSwitchExpressionTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.CompilationTestHelper; import org.junit.Test; import org.junit.runner.RunWith; @@ -31,7 +29,6 @@ public class TraditionalSwitchExpressionTest { @Test public void positive() { - assume().that(Runtime.version().feature()).isAtLeast(14); testHelper .addSourceLines( "Test.java", @@ -69,7 +66,6 @@ void f(int i) { @Test public void negativeArrowStatement() { - assume().that(Runtime.version().feature()).isAtLeast(14); testHelper .addSourceLines( "Test.java", @@ -87,7 +83,6 @@ void f(int i) { @Test public void negativeArrow() { - assume().that(Runtime.version().feature()).isAtLeast(14); testHelper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UngroupedOverloadsTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UngroupedOverloadsTest.java index 862c467df6c..5b1d1a3a377 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UngroupedOverloadsTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UngroupedOverloadsTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.common.collect.ImmutableList; import com.google.errorprone.BugCheckerRefactoringTestHelper; import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode; @@ -851,8 +849,6 @@ private void bar() {} @Test public void recordConstructor() { - assume().that(Runtime.version().feature()).isAtLeast(16); - compilationHelper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryBreakInSwitchTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryBreakInSwitchTest.java index 6417e9dfd96..fe01261403b 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryBreakInSwitchTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryBreakInSwitchTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.CompilationTestHelper; import org.junit.Test; import org.junit.runner.RunWith; @@ -31,7 +29,6 @@ public class UnnecessaryBreakInSwitchTest { @Test public void positive() { - assume().that(Runtime.version().feature()).isAtLeast(14); testHelper .addSourceLines( "Test.java", @@ -72,7 +69,6 @@ void f(int i) { @Test public void negativeEmpty() { - assume().that(Runtime.version().feature()).isAtLeast(14); testHelper .addSourceLines( "Test.java", @@ -91,7 +87,6 @@ void f(int i) { @Test public void negativeNotLast() { - assume().that(Runtime.version().feature()).isAtLeast(14); testHelper .addSourceLines( "Test.java", @@ -115,7 +110,6 @@ void f(int i) { @Test public void negativeLabelledBreak() { - assume().that(Runtime.version().feature()).isAtLeast(14); testHelper .addSourceLines( "Test.java", @@ -138,7 +132,6 @@ void f(int i) { @Test public void negativeLoop() { - assume().that(Runtime.version().feature()).isAtLeast(14); testHelper .addSourceLines( "Test.java", @@ -162,7 +155,6 @@ void f(int i) { @Test public void positiveIf() { - assume().that(Runtime.version().feature()).isAtLeast(14); testHelper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryDefaultInEnumSwitchTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryDefaultInEnumSwitchTest.java index de7cd82e551..6b55cc8444e 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryDefaultInEnumSwitchTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryDefaultInEnumSwitchTest.java @@ -16,7 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; import static com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH; import com.google.errorprone.BugCheckerRefactoringTestHelper; @@ -1059,7 +1058,6 @@ void proto(ProtoEnum e) { @Test public void defaultCaseKindRule() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Test.java", @@ -1085,7 +1083,6 @@ void m(Case c) { @Test public void unrecognizedCaseKindRule() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Test.java", @@ -1112,7 +1109,6 @@ void m(Case c) { @Test public void multipleLabels() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryParenthesesTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryParenthesesTest.java index 0cf2d5b554f..00732c159c6 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryParenthesesTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UnnecessaryParenthesesTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.BugCheckerRefactoringTestHelper; import com.google.errorprone.CompilationTestHelper; import org.junit.Test; @@ -280,7 +278,6 @@ int f(boolean b, Integer x) { @Test public void switchExpression() { - assume().that(Runtime.version().feature()).isAtLeast(12); helper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/UnusedVariableTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/UnusedVariableTest.java index 8c8f369136e..b12e037b5ab 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/UnusedVariableTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/UnusedVariableTest.java @@ -1570,7 +1570,6 @@ public void f(List> lists) { @Test public void simpleRecord() { - assume().that(Runtime.version().feature()).isAtLeast(16); helper .addSourceLines( "SimpleRecord.java", // @@ -1581,7 +1580,6 @@ public void simpleRecord() { @Test public void nestedRecord() { - assume().that(Runtime.version().feature()).isAtLeast(16); helper .addSourceLines( "SimpleClass.java", @@ -1596,7 +1594,6 @@ public record SimpleRecord (Integer foo, Long bar) {} @Test public void recordWithStaticFields() { - assume().that(Runtime.version().feature()).isAtLeast(16); helper .addSourceLines( "SimpleClass.java", @@ -1627,7 +1624,6 @@ public int b() { // methods differently @Test public void nestedPrivateRecord() { - assume().that(Runtime.version().feature()).isAtLeast(16); helper .addSourceLines( "SimpleClass.java", @@ -1642,7 +1638,6 @@ private record SimpleRecord (Integer foo, Long bar) {} @Test public void nestedPrivateRecordCompactCanonicalConstructor() { - assume().that(Runtime.version().feature()).isAtLeast(16); helper .addSourceLines( "SimpleClass.java", @@ -1660,7 +1655,6 @@ public void nestedPrivateRecordCompactCanonicalConstructor() { @Test public void nestedPrivateRecordNormalCanonicalConstructor() { - assume().that(Runtime.version().feature()).isAtLeast(16); helper .addSourceLines( "SimpleClass.java", @@ -1680,7 +1674,6 @@ private SimpleRecord(Integer foo, Long bar) { @Test public void unusedRecordConstructorParameter() { - assume().that(Runtime.version().feature()).isAtLeast(16); helper .addSourceLines( "SimpleRecord.java", @@ -1697,7 +1690,6 @@ private SimpleRecord(int a, int b) { @Test public void unusedInRecord() { - assume().that(Runtime.version().feature()).isAtLeast(16); helper .addSourceLines( "SimpleClass.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectCheckerTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectCheckerTest.java index 5fcc032d1b7..e1115ac5ccd 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectCheckerTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/argumentselectiondefects/ArgumentSelectionDefectCheckerTest.java @@ -15,8 +15,6 @@ */ package com.google.errorprone.bugpatterns.argumentselectiondefects; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.common.collect.ImmutableSet; import com.google.errorprone.BugPattern; import com.google.errorprone.BugPattern.SeverityLevel; @@ -386,8 +384,6 @@ void test(Object first, Object second) { @Test public void records() { - assume().that(Runtime.version().feature()).isAtLeast(16); - testHelper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/formatstring/FormatStringTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/formatstring/FormatStringTest.java index cd574e18c7b..f201e0602f1 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/formatstring/FormatStringTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/formatstring/FormatStringTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns.formatstring; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.errorprone.CompilationTestHelper; import org.junit.Test; import org.junit.runner.RunWith; @@ -368,7 +366,6 @@ void f(Number n) { @Test public void invalidIndex() { - assume().that(Runtime.version().feature()).isAtLeast(16); compilationHelper .addSourceLines( "T.java", @@ -385,7 +382,6 @@ public static void main(String[] args) { @Test public void stringFormattedNegativeCase() { - assume().that(Runtime.version().feature()).isAtLeast(15); compilationHelper .addSourceLines( "Test.java", @@ -401,7 +397,6 @@ void f() { @Test public void stringFormattedPositiveCase() { - assume().that(Runtime.version().feature()).isAtLeast(15); compilationHelper .addSourceLines( "Test.java", @@ -418,7 +413,6 @@ void f() { @Test public void nonConstantStringFormattedNegativeCase() { - assume().that(Runtime.version().feature()).isAtLeast(15); compilationHelper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/javadoc/InvalidParamTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/javadoc/InvalidParamTest.java index fa496abbf17..6c4318d69e3 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/javadoc/InvalidParamTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/javadoc/InvalidParamTest.java @@ -16,7 +16,6 @@ package com.google.errorprone.bugpatterns.javadoc; -import static com.google.common.truth.TruthJUnit.assume; import static com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH; import com.google.errorprone.BugCheckerRefactoringTestHelper; @@ -215,7 +214,6 @@ interface Test { @Test public void negative_record() { - assume().that(Runtime.version().feature()).isAtLeast(16); helper .addSourceLines( "Test.java", @@ -230,7 +228,6 @@ public record Test(String name) {} @Test public void badParameterName_record() { - assume().that(Runtime.version().feature()).isAtLeast(16); helper .addSourceLines( "Test.java", @@ -246,7 +243,6 @@ public record Test(String foo) {} @Test public void multipleConstructors_record() { - assume().that(Runtime.version().feature()).isAtLeast(16); helper .addSourceLines( "Test.java", @@ -274,7 +270,6 @@ public Test(String foo) { @Test public void typeParameter_record() { - assume().that(Runtime.version().feature()).isAtLeast(16); helper .addSourceLines( "Negative.java", @@ -302,7 +297,6 @@ public record Positive(T contents, String bar) {} @Test public void compactConstructor_record() { - assume().that(Runtime.version().feature()).isAtLeast(16); helper .addSourceLines( "Test.java", @@ -319,7 +313,6 @@ public record Test(String name) { @Test public void normalConstructor_record() { - assume().that(Runtime.version().feature()).isAtLeast(16); helper .addSourceLines( "Test.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/nullness/FieldMissingNullableTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/nullness/FieldMissingNullableTest.java index 8d3caefe03e..c6c4e1b5063 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/nullness/FieldMissingNullableTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/nullness/FieldMissingNullableTest.java @@ -16,7 +16,6 @@ package com.google.errorprone.bugpatterns.nullness; -import static com.google.common.truth.TruthJUnit.assume; import static com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH; import com.google.errorprone.BugCheckerRefactoringTestHelper; @@ -193,7 +192,6 @@ public void reset(FieldMissingNullTest other) { @Test public void recordComponent() { - assume().that(Runtime.version().feature()).isAtLeast(16); createAggressiveRefactoringTestHelper() .addInputLines( "com/google/errorprone/bugpatterns/nullness/FieldMissingNullTest.java", @@ -340,7 +338,6 @@ public void reset() { @Test public void negativeCases_alreadyAnnotatedRecordComponent() { - assume().that(Runtime.version().feature()).isAtLeast(16); createAggressiveCompilationTestHelper() .addSourceLines( "com/google/errorprone/bugpatterns/nullness/FieldMissingNullTest.java", diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/nullness/ReturnMissingNullableTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/nullness/ReturnMissingNullableTest.java index f0390d5d47d..3f85ea431d9 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/nullness/ReturnMissingNullableTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/nullness/ReturnMissingNullableTest.java @@ -16,7 +16,6 @@ package com.google.errorprone.bugpatterns.nullness; -import static com.google.common.truth.TruthJUnit.assume; import static com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH; import com.google.errorprone.BugCheckerRefactoringTestHelper; @@ -150,7 +149,6 @@ public String getMessage(int x) { @Test public void switchExpressionTree() { - assume().that(Runtime.version().feature()).isAtLeast(12); createCompilationTestHelper() .addSourceLines( @@ -172,7 +170,6 @@ public String getMessage(int x) { @Test public void switchExpressionTree_negative() { - assume().that(Runtime.version().feature()).isAtLeast(12); createCompilationTestHelper() .addSourceLines( diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableCheckerTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableCheckerTest.java index 7150dd00611..9b86c3a6500 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableCheckerTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableCheckerTest.java @@ -16,8 +16,6 @@ package com.google.errorprone.bugpatterns.threadsafety; -import static com.google.common.truth.TruthJUnit.assume; - import com.google.common.collect.ImmutableList; import com.google.errorprone.CompilationTestHelper; import com.google.errorprone.annotations.CanIgnoreReturnValue; @@ -3453,7 +3451,6 @@ void test(ImmutableFunction f) { @Test public void switchExpressionsResultingInGenericTypes_doesNotThrow() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Kind.java", @@ -3480,7 +3477,6 @@ Supplier> test(Kind kind) { @Test public void switchExpressionsYieldStatement_doesNotThrow() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Test.java", @@ -3502,7 +3498,6 @@ String test(String mode) { @Test public void switchExpressionsMethodReference_doesNotThrow() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Test.java", @@ -3522,7 +3517,6 @@ Supplier test(String mode) { @Test public void switchExpressionsYieldStatementMethodReference_doesNotThrow() { - assume().that(Runtime.version().feature()).isAtLeast(14); compilationHelper .addSourceLines( "Test.java", From ab522c7dcac5e83b84828d5670595e5582d71fb3 Mon Sep 17 00:00:00 2001 From: cushon Date: Tue, 19 Nov 2024 00:38:12 +0000 Subject: [PATCH 38/38] Release Error Prone 2.36.0 --- annotation/pom.xml | 2 +- annotations/pom.xml | 2 +- check_api/pom.xml | 2 +- core/pom.xml | 2 +- docgen/pom.xml | 2 +- docgen_processor/pom.xml | 2 +- pom.xml | 2 +- refaster/pom.xml | 2 +- test_helpers/pom.xml | 2 +- type_annotations/pom.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/annotation/pom.xml b/annotation/pom.xml index fbbba7c5524..14381c18f78 100644 --- a/annotation/pom.xml +++ b/annotation/pom.xml @@ -21,7 +21,7 @@ com.google.errorprone error_prone_parent - 1.0-HEAD-SNAPSHOT + 2.36.0 @BugPattern annotation diff --git a/annotations/pom.xml b/annotations/pom.xml index 62ebfe88a40..6625c06be5e 100644 --- a/annotations/pom.xml +++ b/annotations/pom.xml @@ -21,7 +21,7 @@ com.google.errorprone error_prone_parent - 1.0-HEAD-SNAPSHOT + 2.36.0 error-prone annotations diff --git a/check_api/pom.xml b/check_api/pom.xml index 061e83e0e6b..adda55633fe 100644 --- a/check_api/pom.xml +++ b/check_api/pom.xml @@ -21,7 +21,7 @@ com.google.errorprone error_prone_parent - 1.0-HEAD-SNAPSHOT + 2.36.0 error-prone check api diff --git a/core/pom.xml b/core/pom.xml index b425e327b32..d1f781af323 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -21,7 +21,7 @@ com.google.errorprone error_prone_parent - 1.0-HEAD-SNAPSHOT + 2.36.0 error-prone library diff --git a/docgen/pom.xml b/docgen/pom.xml index 8ee00587502..2edd4fdf071 100644 --- a/docgen/pom.xml +++ b/docgen/pom.xml @@ -21,7 +21,7 @@ com.google.errorprone error_prone_parent - 1.0-HEAD-SNAPSHOT + 2.36.0 Documentation tool for generating Error Prone bugpattern documentation diff --git a/docgen_processor/pom.xml b/docgen_processor/pom.xml index 7d97a4cb4ca..3dba9d619b8 100644 --- a/docgen_processor/pom.xml +++ b/docgen_processor/pom.xml @@ -21,7 +21,7 @@ com.google.errorprone error_prone_parent - 1.0-HEAD-SNAPSHOT + 2.36.0 JSR-269 annotation processor for @BugPattern annotation diff --git a/pom.xml b/pom.xml index df76790a67c..d7ca440579f 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ Error Prone parent POM com.google.errorprone error_prone_parent - 1.0-HEAD-SNAPSHOT + 2.36.0 pom Error Prone is a static analysis tool for Java that catches common programming mistakes at compile-time. diff --git a/refaster/pom.xml b/refaster/pom.xml index 968b0c2bae4..b56b22c21a0 100644 --- a/refaster/pom.xml +++ b/refaster/pom.xml @@ -19,7 +19,7 @@ error_prone_parent com.google.errorprone - 1.0-HEAD-SNAPSHOT + 2.36.0 4.0.0 diff --git a/test_helpers/pom.xml b/test_helpers/pom.xml index 66b12d308c3..d17696848c1 100644 --- a/test_helpers/pom.xml +++ b/test_helpers/pom.xml @@ -21,7 +21,7 @@ com.google.errorprone error_prone_parent - 1.0-HEAD-SNAPSHOT + 2.36.0 error-prone test helpers diff --git a/type_annotations/pom.xml b/type_annotations/pom.xml index e04034cd3e9..07a6ba69d03 100644 --- a/type_annotations/pom.xml +++ b/type_annotations/pom.xml @@ -21,7 +21,7 @@ com.google.errorprone error_prone_parent - 1.0-HEAD-SNAPSHOT + 2.36.0 error-prone type annotations