From db18d6a1fca908ff333b54ec9d209bbb25fcc511 Mon Sep 17 00:00:00 2001 From: Stephan Schroevers Date: Mon, 9 Dec 2024 09:26:56 +0100 Subject: [PATCH] Drop the `JavaKeywords` class (#1442) Instead: - Move its sole used method `#isValidIdentifier` to the `SourceCode` class. - Delegate most of said method's implementation to `javax.lang.model.SourceVersion`. --- .../errorprone/utils/ConflictDetection.java | 4 +- .../picnic/errorprone/utils/JavaKeywords.java | 159 ------------------ .../picnic/errorprone/utils/SourceCode.java | 13 ++ .../errorprone/utils/JavaKeywordsTest.java | 34 ---- .../errorprone/utils/SourceCodeTest.java | 33 ++++ 5 files changed, 47 insertions(+), 196 deletions(-) delete mode 100644 error-prone-utils/src/main/java/tech/picnic/errorprone/utils/JavaKeywords.java delete mode 100644 error-prone-utils/src/test/java/tech/picnic/errorprone/utils/JavaKeywordsTest.java diff --git a/error-prone-utils/src/main/java/tech/picnic/errorprone/utils/ConflictDetection.java b/error-prone-utils/src/main/java/tech/picnic/errorprone/utils/ConflictDetection.java index 8d64c82d07..d3af56d0d5 100644 --- a/error-prone-utils/src/main/java/tech/picnic/errorprone/utils/ConflictDetection.java +++ b/error-prone-utils/src/main/java/tech/picnic/errorprone/utils/ConflictDetection.java @@ -1,7 +1,5 @@ package tech.picnic.errorprone.utils; -import static tech.picnic.errorprone.utils.JavaKeywords.isValidIdentifier; - import com.google.errorprone.VisitorState; import com.google.errorprone.util.ASTHelpers; import com.sun.source.tree.ImportTree; @@ -47,7 +45,7 @@ public static Optional findMethodRenameBlocker( return Optional.of(String.format("`%s` is already statically imported", newName)); } - if (!isValidIdentifier(newName)) { + if (!SourceCode.isValidIdentifier(newName)) { return Optional.of(String.format("`%s` is not a valid identifier", newName)); } diff --git a/error-prone-utils/src/main/java/tech/picnic/errorprone/utils/JavaKeywords.java b/error-prone-utils/src/main/java/tech/picnic/errorprone/utils/JavaKeywords.java deleted file mode 100644 index 6a7aa842ae..0000000000 --- a/error-prone-utils/src/main/java/tech/picnic/errorprone/utils/JavaKeywords.java +++ /dev/null @@ -1,159 +0,0 @@ -package tech.picnic.errorprone.utils; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; - -/** Utility class that can be used to identify reserved keywords of the Java language. */ -// XXX: This class is no longer only about keywords. Consider changing its name and class-level -// documentation. -public final class JavaKeywords { - /** - * Enumeration of boolean and null literals. - * - * @see JDK 17 - * JLS section 3.10.3: Boolean Literals - * @see JDK 17 - * JLS section 3.10.8: The Null Literal - */ - private static final ImmutableSet BOOLEAN_AND_NULL_LITERALS = - ImmutableSet.of("true", "false", "null"); - - /** - * List of all reserved keywords in the Java language. - * - * @see JDK 17 JLS - * section 3.9: Keywords - */ - private static final ImmutableSet RESERVED_KEYWORDS = - ImmutableSet.of( - "_", - "abstract", - "assert", - "boolean", - "break", - "byte", - "case", - "catch", - "char", - "class", - "const", - "continue", - "default", - "do", - "double", - "else", - "enum", - "extends", - "final", - "finally", - "float", - "for", - "goto", - "if", - "implements", - "import", - "instanceof", - "int", - "interface", - "long", - "native", - "new", - "package", - "private", - "protected", - "public", - "return", - "short", - "static", - "strictfp", - "super", - "switch", - "synchronized", - "this", - "throw", - "throws", - "transient", - "try", - "void", - "volatile", - "while"); - - /** - * List of all contextual keywords in the Java language. - * - * @see JDK 17 JLS - * section 3.9: Keywords - */ - private static final ImmutableSet CONTEXTUAL_KEYWORDS = - ImmutableSet.of( - "exports", - "module", - "non-sealed", - "open", - "opens", - "permits", - "provides", - "record", - "requires", - "sealed", - "to", - "transitive", - "uses", - "var", - "with", - "yield"); - - /** List of all keywords in the Java language. */ - private static final ImmutableSet ALL_KEYWORDS = - Sets.union(RESERVED_KEYWORDS, CONTEXTUAL_KEYWORDS).immutableCopy(); - - private JavaKeywords() {} - - /** - * Tells whether the given string is a valid identifier in the Java language. - * - * @param str The string of interest. - * @return {@code true} if the given string is a valid identifier in the Java language. - * @see JDK 17 JLS - * section 3.8: Identifiers - */ - @SuppressWarnings("java:S1067" /* Chaining conjunctions like this does not impact readability. */) - public static boolean isValidIdentifier(String str) { - return !str.isEmpty() - && !isReservedKeyword(str) - && !BOOLEAN_AND_NULL_LITERALS.contains(str) - && Character.isJavaIdentifierStart(str.codePointAt(0)) - && str.codePoints().skip(1).allMatch(Character::isUnicodeIdentifierPart); - } - - /** - * Tells whether the given string is a reserved keyword in the Java language. - * - * @param str The string of interest. - * @return {@code true} if the given string is a reserved keyword in the Java language. - */ - public static boolean isReservedKeyword(String str) { - return RESERVED_KEYWORDS.contains(str); - } - - /** - * Tells whether the given string is a contextual keyword in the Java language. - * - * @param str The string of interest. - * @return {@code true} if the given string is a contextual keyword in the Java language. - */ - public static boolean isContextualKeyword(String str) { - return CONTEXTUAL_KEYWORDS.contains(str); - } - - /** - * Tells whether the given string is a reserved or contextual keyword in the Java language. - * - * @param str The string of interest. - * @return {@code true} if the given string is a reserved or contextual keyword in the Java - * language. - */ - public static boolean isKeyword(String str) { - return ALL_KEYWORDS.contains(str); - } -} diff --git a/error-prone-utils/src/main/java/tech/picnic/errorprone/utils/SourceCode.java b/error-prone-utils/src/main/java/tech/picnic/errorprone/utils/SourceCode.java index 6d29e96120..741a50a644 100644 --- a/error-prone-utils/src/main/java/tech/picnic/errorprone/utils/SourceCode.java +++ b/error-prone-utils/src/main/java/tech/picnic/errorprone/utils/SourceCode.java @@ -17,6 +17,7 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.Position; import java.util.Optional; +import javax.lang.model.SourceVersion; /** * A collection of Error Prone utility methods for dealing with the source code representation of @@ -28,6 +29,18 @@ public final class SourceCode { private SourceCode() {} + /** + * Tells whether the given string is a valid identifier in the Java language. + * + * @param str The string of interest. + * @return {@code true} if the given string is a valid identifier in the Java language. + * @see JDK 17 JLS + * section 3.8: Identifiers + */ + public static boolean isValidIdentifier(String str) { + return str.indexOf('.') < 0 && SourceVersion.isName(str); + } + /** * Returns a string representation of the given {@link Tree}, preferring the original source code * (if available) over its prettified representation. diff --git a/error-prone-utils/src/test/java/tech/picnic/errorprone/utils/JavaKeywordsTest.java b/error-prone-utils/src/test/java/tech/picnic/errorprone/utils/JavaKeywordsTest.java deleted file mode 100644 index 2cdf48fcd6..0000000000 --- a/error-prone-utils/src/test/java/tech/picnic/errorprone/utils/JavaKeywordsTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package tech.picnic.errorprone.utils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.params.provider.Arguments.arguments; - -import java.util.stream.Stream; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -final class JavaKeywordsTest { - private static Stream isValidIdentifierTestCases() { - /* { string, expected } */ - return Stream.of( - arguments("", false), - arguments("public", false), - arguments("true", false), - arguments("false", false), - arguments("null", false), - arguments("0", false), - arguments("\0", false), - arguments("a%\0", false), - arguments("a", true), - arguments("a0", true), - arguments("_a0", true), - arguments("test", true)); - } - - @MethodSource("isValidIdentifierTestCases") - @ParameterizedTest - void isValidIdentifier(String string, boolean expected) { - assertThat(JavaKeywords.isValidIdentifier(string)).isEqualTo(expected); - } -} diff --git a/error-prone-utils/src/test/java/tech/picnic/errorprone/utils/SourceCodeTest.java b/error-prone-utils/src/test/java/tech/picnic/errorprone/utils/SourceCodeTest.java index ed4b73d98b..942c25bd83 100644 --- a/error-prone-utils/src/test/java/tech/picnic/errorprone/utils/SourceCodeTest.java +++ b/error-prone-utils/src/test/java/tech/picnic/errorprone/utils/SourceCodeTest.java @@ -1,6 +1,8 @@ package tech.picnic.errorprone.utils; import static com.google.errorprone.BugPattern.SeverityLevel.ERROR; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.params.provider.Arguments.arguments; import com.google.errorprone.BugCheckerRefactoringTestHelper; import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode; @@ -22,10 +24,41 @@ import com.sun.source.tree.Tree; import com.sun.source.tree.VariableTree; import java.util.Optional; +import java.util.stream.Stream; import javax.lang.model.element.Name; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; final class SourceCodeTest { + private static Stream isValidIdentifierTestCases() { + /* { string, expected } */ + return Stream.of( + arguments("", false), + arguments(".", false), + arguments("a.", false), + arguments(".a", false), + arguments("a.b", false), + arguments("public", false), + arguments("true", false), + arguments("false", false), + arguments("null", false), + arguments("0", false), + arguments("\0", false), + arguments("a%\0", false), + arguments("a", true), + arguments("a0", true), + arguments("_a0", true), + arguments("test", true)); + } + + @MethodSource("isValidIdentifierTestCases") + @ParameterizedTest + void isValidIdentifier(String string, boolean expected) { + assertThat(SourceCode.isValidIdentifier(string)).isEqualTo(expected); + } + @Test void toStringConstantExpression() { BugCheckerRefactoringTestHelper.newInstance(