-
Notifications
You must be signed in to change notification settings - Fork 745
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
StatementSwitchToExpressionSwitch: only trigger on compatible target versions #3646
Changes from 2 commits
2a0bb07
42a036c
3690ab1
7806808
641c9dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* 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. | ||
* 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.google.common.collect.ImmutableMap; | ||
import com.google.common.collect.Maps; | ||
import com.sun.tools.javac.code.Source; | ||
import com.sun.tools.javac.code.Source.Feature; | ||
import com.sun.tools.javac.util.Context; | ||
import java.util.Arrays; | ||
|
||
/** | ||
* JDK source version utilities. | ||
* | ||
* @see RuntimeVersion | ||
*/ | ||
public final class SourceVersion { | ||
private static final ImmutableMap<String, Feature> KNOWN_FEATURES = | ||
Maps.uniqueIndex(Arrays.asList(Feature.values()), Enum::name); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The string-based lookup is necessary because older runtimes won't recognize newer enum values. A bit fragile, but no more fragile than what's usual for Error Prone. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, I didn't consider that when making the suggestion. This looks like a good way to deal with that. One more suggestion would be to keep the current API, but avoid relying on the public static boolean supportsSwitchExpressions(Context context) {
return Source.instance(state.context).compareTo(Source.lookup("14")) >= 0;
} That means we can't use javac's knowledge about which features were used in which versions, but it also avoids depending on the string names of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Works for me; I can see how this reduces the maintenance burden. The |
||
|
||
/** Returns true if the compiler source version level supports switch expressions. */ | ||
public static boolean supportsSwitchExpressions(Context context) { | ||
return supportsFeature("SWITCH_EXPRESSION", context); | ||
} | ||
|
||
/** Returns true if the compiler source version level supports text blocks. */ | ||
public static boolean supportsTextBlocks(Context context) { | ||
return supportsFeature("TEXT_BLOCKS", context); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason for adding this method is twofold:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 There is at least one other use of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't mind adding that to the PR, but I'm not 100% sure what the extra method would have to be called. (My best guess is that this relates to |
||
|
||
/** | ||
* Returns true if the compiler source version level supports the {@link Feature} indicated by the | ||
* specified string. | ||
* | ||
* @apiNote For features explicitly recognized by this class, prefer calling the associated method | ||
* instead. | ||
*/ | ||
public static boolean supportsFeature(String featureString, Context context) { | ||
Feature feature = KNOWN_FEATURES.get(featureString); | ||
return feature != null && feature.allowedInSource(Source.instance(context)); | ||
} | ||
|
||
private SourceVersion() {} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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.SourceVersion; | ||
import com.sun.source.tree.BreakTree; | ||
import com.sun.source.tree.CaseTree; | ||
import com.sun.source.tree.ExpressionTree; | ||
|
@@ -85,8 +86,7 @@ public StatementSwitchToExpressionSwitch(ErrorProneFlags flags) { | |
|
||
@Override | ||
public Description matchSwitch(SwitchTree switchTree, VisitorState state) { | ||
// Expression switches finalized in Java 14 | ||
if (!RuntimeVersion.isAtLeast14()) { | ||
if (!SourceVersion.supportsSwitchExpressions(state.context)) { | ||
Comment on lines
-88
to
+89
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dropped the comment because the code is now self-documenting. |
||
return NO_MATCH; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could also name the class something like
SourceFeature(s)
, though that might perhaps also call for slightly different method names. 🤔