From 5eded877e844326b3e00a8e0dd4c225ab8f03617 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 24 May 2024 17:08:32 -0700 Subject: [PATCH] Add an Error Prone check that reimplements javac sunapi warnings The javac diagnostic can't be configured using `-Xlint:` (https://bugs.openjdk.org/browse/JDK-8148808), and doesn't work when `--system` is configured (https://bugs.openjdk.org/browse/JDK-8332744) PiperOrigin-RevId: 637073596 --- .../google/errorprone/bugpatterns/SunApi.java | 82 +++++++++++++++++++ .../scanner/BuiltInCheckerSuppliers.java | 2 + .../errorprone/bugpatterns/SunApiTest.java | 67 +++++++++++++++ docs/bugpattern/SunApi.md | 7 ++ 4 files changed, 158 insertions(+) create mode 100644 core/src/main/java/com/google/errorprone/bugpatterns/SunApi.java create mode 100644 core/src/test/java/com/google/errorprone/bugpatterns/SunApiTest.java create mode 100644 docs/bugpattern/SunApi.md diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/SunApi.java b/core/src/main/java/com/google/errorprone/bugpatterns/SunApi.java new file mode 100644 index 00000000000..5da9cb11385 --- /dev/null +++ b/core/src/main/java/com/google/errorprone/bugpatterns/SunApi.java @@ -0,0 +1,82 @@ +/* + * 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.BugPattern.SeverityLevel.WARNING; +import static com.google.errorprone.matchers.Description.NO_MATCH; + +import com.google.errorprone.BugPattern; +import com.google.errorprone.VisitorState; +import com.google.errorprone.bugpatterns.BugChecker.IdentifierTreeMatcher; +import com.google.errorprone.bugpatterns.BugChecker.MemberSelectTreeMatcher; +import com.google.errorprone.matchers.Description; +import com.google.errorprone.util.ASTHelpers; +import com.sun.source.tree.IdentifierTree; +import com.sun.source.tree.ImportTree; +import com.sun.source.tree.MemberSelectTree; +import com.sun.source.tree.Tree; +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.code.Symbol.ModuleSymbol; +import com.sun.tools.javac.code.Symbol.PackageSymbol; + +/** A {@link BugChecker}; see the associated {@link BugPattern} annotation for details. */ +@BugPattern( + summary = "Usage of internal proprietary API which may be removed in a future release", + severity = WARNING) +public class SunApi extends BugChecker implements MemberSelectTreeMatcher, IdentifierTreeMatcher { + @Override + public Description matchIdentifier(IdentifierTree tree, VisitorState state) { + return match(tree, state); + } + + @Override + public Description matchMemberSelect(MemberSelectTree tree, VisitorState state) { + return match(tree, state); + } + + private Description match(Tree tree, VisitorState state) { + Symbol sym = ASTHelpers.getSymbol(tree); + if (sym == null) { + return NO_MATCH; + } + if (!inJdkUnsupportedModule(sym) && ((sym.flags() & Flags.PROPRIETARY) == 0)) { + return NO_MATCH; + } + if (state.findEnclosing(ImportTree.class) != null) { + return NO_MATCH; + } + return buildDescription(tree) + .setMessage( + String.format( + "%s is an internal JDK API which may be removed in a future release", + sym.getQualifiedName())) + .build(); + } + + private static boolean inJdkUnsupportedModule(Symbol sym) { + PackageSymbol packageSymbol = ASTHelpers.enclosingPackage(sym); + if (packageSymbol == null) { + return false; + } + ModuleSymbol moduleSymbol = (ModuleSymbol) packageSymbol.getEnclosingElement(); + if (moduleSymbol == null) { + return false; + } + return moduleSymbol.name.contentEquals("jdk.unsupported"); + } +} 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 2f09446b60c..9b4454ba74e 100644 --- a/core/src/main/java/com/google/errorprone/scanner/BuiltInCheckerSuppliers.java +++ b/core/src/main/java/com/google/errorprone/scanner/BuiltInCheckerSuppliers.java @@ -356,6 +356,7 @@ import com.google.errorprone.bugpatterns.StringSplitter; import com.google.errorprone.bugpatterns.StronglyTypeByteString; import com.google.errorprone.bugpatterns.SubstringOfZero; +import com.google.errorprone.bugpatterns.SunApi; import com.google.errorprone.bugpatterns.SuperCallToObjectMethod; import com.google.errorprone.bugpatterns.SuppressWarningsDeprecated; import com.google.errorprone.bugpatterns.SuppressWarningsWithoutExplanation; @@ -1210,6 +1211,7 @@ public static ScannerSupplier warningChecks() { StringFormatWithLiteral.class, StronglyTypeByteString.class, StronglyTypeTime.class, + SunApi.class, SuppressWarningsWithoutExplanation.class, SwitchDefault.class, SymbolToString.class, diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/SunApiTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/SunApiTest.java new file mode 100644 index 00000000000..76272b91142 --- /dev/null +++ b/core/src/test/java/com/google/errorprone/bugpatterns/SunApiTest.java @@ -0,0 +1,67 @@ +/* + * 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 class SunApiTest { + + private final CompilationTestHelper compilationHelper = + CompilationTestHelper.newInstance(SunApi.class, getClass()); + + @Test + public void positive() { + compilationHelper + .addSourceLines( + "Test.java", // + "class Test {", + " // BUG: Diagnostic contains: sun.misc.Unsafe", + " sun.misc.Unsafe u;", + "}") + .doTest(); + } + + @Test + public void positiveSource8() { + compilationHelper + .addSourceLines( + "Test.java", // + "class Test {", + " // BUG: Diagnostic contains: sun.misc.Unsafe", + " sun.misc.Unsafe u;", + "}") + .setArgs("-source", "8", "-target", "8") + .doTest(); + } + + @Test + public void negative() { + compilationHelper + .addSourceLines( + "Test.java", // + "import jdk.internal.misc.Unsafe;", + "class Test {", + " Unsafe u;", + "}") + .addModules("java.base/jdk.internal.misc") + .doTest(); + } +} diff --git a/docs/bugpattern/SunApi.md b/docs/bugpattern/SunApi.md new file mode 100644 index 00000000000..2c3f7ca592c --- /dev/null +++ b/docs/bugpattern/SunApi.md @@ -0,0 +1,7 @@ +Warn on internal, proprietary APIs that may be removed in future JDK versions. + +For `sun.misc.Unsafe`, note that the API will be removed from a future version +of the JDK: +[JEP 471: Deprecate the Memory-Access Methods in sun.misc.Unsafe for Removal](https://openjdk.org/jeps/471). + +This check is a re-implementation of javac's 'sunapi' diagnostic.