From c7a23da040ec635ae086fdadad3c4031b98f9804 Mon Sep 17 00:00:00 2001 From: Stephan Schroevers Date: Sat, 31 Dec 2022 15:27:07 +0100 Subject: [PATCH] StatementSwitchToExpressionSwitch: only trigger on compatible target versions This change introduces a `TargetVersion` utility class, analogous to the existing `RuntimeVersion` class. The new class tells whether the current compilation process targets a bytecode version that is generally associated with a given (or more recent) JDK version. The new utility class is used to make sure that `StatementSwitchToExpressionSwitch` flags statement switches only if the target version supports expression switches, irrespective of whether the current runtime supports such switch types. Concretely this makes the check compatible with projects that target JDK 11, yet support building with JDK 17. --- .../errorprone/util/RuntimeVersion.java | 9 +- .../google/errorprone/util/TargetVersion.java | 88 +++++++++++++++++++ .../StatementSwitchToExpressionSwitch.java | 3 +- pom.xml | 5 +- 4 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 check_api/src/main/java/com/google/errorprone/util/TargetVersion.java diff --git a/check_api/src/main/java/com/google/errorprone/util/RuntimeVersion.java b/check_api/src/main/java/com/google/errorprone/util/RuntimeVersion.java index f965d3f625c9..05b3c87ef7ba 100644 --- a/check_api/src/main/java/com/google/errorprone/util/RuntimeVersion.java +++ b/check_api/src/main/java/com/google/errorprone/util/RuntimeVersion.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 The Error Prone Authors. + * Copyright 2023 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. @@ -16,9 +16,12 @@ package com.google.errorprone.util; -/** JDK version string utilities. */ +/** + * JDK runtime version utilities. + * + * @see TargetVersion + */ public final class RuntimeVersion { - private static final int FEATURE = Runtime.version().feature(); /** Returns true if the current runtime is JDK 12 or newer. */ diff --git a/check_api/src/main/java/com/google/errorprone/util/TargetVersion.java b/check_api/src/main/java/com/google/errorprone/util/TargetVersion.java new file mode 100644 index 000000000000..45b359e89a99 --- /dev/null +++ b/check_api/src/main/java/com/google/errorprone/util/TargetVersion.java @@ -0,0 +1,88 @@ +/* + * Copyright 2018 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.util; + +import com.sun.tools.javac.jvm.Target; +import com.sun.tools.javac.util.Context; + +/** + * JDK target version utilities. + * + * @see RuntimeVersion + */ +public final class TargetVersion { + /** Returns true if the compiler targets JRE 11 or newer. */ + public static boolean isAtLeast11(Context context) { + return majorVersion(context) >= 55; + } + + /** Returns true if the compiler targets JRE 12 or newer. */ + public static boolean isAtLeast12(Context context) { + return majorVersion(context) >= 56; + } + + /** Returns true if the compiler targets JRE 13 or newer. */ + public static boolean isAtLeast13(Context context) { + return majorVersion(context) >= 57; + } + + /** Returns true if the compiler targets JRE 14 or newer. */ + public static boolean isAtLeast14(Context context) { + return majorVersion(context) >= 58; + } + + /** Returns true if the compiler targets JRE 15 or newer. */ + public static boolean isAtLeast15(Context context) { + return majorVersion(context) >= 59; + } + + /** Returns true if the compiler targets JRE 16 or newer. */ + public static boolean isAtLeast16(Context context) { + return majorVersion(context) >= 60; + } + + /** Returns true if the compiler targets JRE 17 or newer. */ + public static boolean isAtLeast17(Context context) { + return majorVersion(context) >= 61; + } + + /** Returns true if the compiler targets JRE 18 or newer. */ + public static boolean isAtLeast18(Context context) { + return majorVersion(context) >= 62; + } + + /** Returns true if the compiler targets JRE 19 or newer. */ + public static boolean isAtLeast19(Context context) { + return majorVersion(context) >= 63; + } + + /** Returns true if the compiler targets JRE 20 or newer. */ + public static boolean isAtLeast20(Context context) { + return majorVersion(context) >= 64; + } + + /** Returns true if the compiler targets JRE 21 or newer. */ + public static boolean isAtLeast21(Context context) { + return majorVersion(context) >= 65; + } + + private static int majorVersion(Context context) { + return Target.instance(context).majorVersion; + } + + private TargetVersion() {} +} 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 b885de8b2987..4644f8ac5d4f 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/StatementSwitchToExpressionSwitch.java @@ -39,6 +39,7 @@ import com.google.errorprone.matchers.Description; import com.google.errorprone.util.Reachability; import com.google.errorprone.util.RuntimeVersion; +import com.google.errorprone.util.TargetVersion; import com.sun.source.tree.BreakTree; import com.sun.source.tree.CaseTree; import com.sun.source.tree.ExpressionTree; @@ -86,7 +87,7 @@ public StatementSwitchToExpressionSwitch(ErrorProneFlags flags) { @Override public Description matchSwitch(SwitchTree switchTree, VisitorState state) { // Expression switches finalized in Java 14 - if (!RuntimeVersion.isAtLeast14()) { + if (!TargetVersion.isAtLeast14(state.context)) { return NO_MATCH; } diff --git a/pom.xml b/pom.xml index 515f8b7edb67..51a7df5932cb 100644 --- a/pom.xml +++ b/pom.xml @@ -161,10 +161,10 @@ --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.file=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.jvm=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 @@ -213,6 +213,7 @@ -Xmx1g --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.jvm=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