diff --git a/java/java.hints/src/org/netbeans/modules/java/hints/Bundle.properties b/java/java.hints/src/org/netbeans/modules/java/hints/Bundle.properties
index 62288327ac1d..693c631f1b43 100644
--- a/java/java.hints/src/org/netbeans/modules/java/hints/Bundle.properties
+++ b/java/java.hints/src/org/netbeans/modules/java/hints/Bundle.properties
@@ -283,7 +283,9 @@ HINT_SerialVersionUID_Generated=Add generated serialVersionUID
FieldForUnusedParamCustomizer.finalFields.text=Fields are final
ACSD_Final_Fields=Make fields created by this hint final.
-DSC_StaticImport=Convert a static method/field/enum-field reference to use a static import. Feedback to http://www.netbeans.org/issues/show_bug.cgi?id=89258
+DSC_StaticImport=Convert a static method/field/enum-field reference to use a static import.\
+
Math.abs(-1) -> abs(-1)
+
DN_StaticImport=Static imports
ERR_StaticImport=Convert to static import
HINT_StaticImport=Convert {0} to static import
diff --git a/java/java.hints/src/org/netbeans/modules/java/hints/StaticImport.java b/java/java.hints/src/org/netbeans/modules/java/hints/StaticImport.java
index 0628ceeaef46..5e2967337127 100644
--- a/java/java.hints/src/org/netbeans/modules/java/hints/StaticImport.java
+++ b/java/java.hints/src/org/netbeans/modules/java/hints/StaticImport.java
@@ -28,7 +28,6 @@
import com.sun.source.tree.Tree;
import com.sun.source.tree.Tree.Kind;
import com.sun.source.util.TreePath;
-import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
@@ -42,7 +41,6 @@
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Types;
import org.netbeans.api.java.source.CompilationInfo;
-import org.netbeans.api.java.source.ElementUtilities;
import org.netbeans.api.java.source.GeneratorUtilities;
import org.netbeans.api.java.source.TreeMaker;
import org.netbeans.api.java.source.TreePathHandle;
@@ -77,12 +75,13 @@
*
* @author Sam Halliday
* @author markiewb
- * @see RFE 89258
- * @see Static Imports
*/
@Hint(category="rules15", displayName="#DN_StaticImport", description="#DSC_StaticImport", severity=Severity.HINT, enabled=false, suppressWarnings={"", "StaticImport"},
minSourceVersion = "5")
public class StaticImport {
+
+ private static final Set SUPPORTED_TYPES = EnumSet.of(ElementKind.METHOD, ElementKind.ENUM_CONSTANT, ElementKind.FIELD);
@TriggerTreeKind(Kind.MEMBER_SELECT)
public static List run(HintContext ctx) {
@@ -90,23 +89,22 @@ public static List run(HintContext ctx) {
TreePath treePath = ctx.getPath();
Element e = info.getTrees().getElement(treePath);
- EnumSet supportedTypes = EnumSet.of(ElementKind.METHOD, ElementKind.ENUM_CONSTANT, ElementKind.FIELD);
- if (e == null || !e.getModifiers().contains(Modifier.STATIC) || !supportedTypes.contains(e.getKind())) {
+ if (e == null || !e.getModifiers().contains(Modifier.STATIC) || !SUPPORTED_TYPES.contains(e.getKind())) {
return null;
}
if (ElementKind.METHOD == e.getKind()) {
TreePath mitp = treePath.getParentPath();
if (mitp == null || mitp.getLeaf().getKind() != Kind.METHOD_INVOCATION) {
- return null;
- }
+ return null;
+ }
if (((MethodInvocationTree) mitp.getLeaf()).getMethodSelect() != treePath.getLeaf()) {
- return null;
- }
+ return null;
+ }
List extends Tree> typeArgs = ((MethodInvocationTree) mitp.getLeaf()).getTypeArguments();
if (typeArgs != null && !typeArgs.isEmpty()) {
- return null;
- }
+ return null;
+ }
}
Element enclosingEl = e.getEnclosingElement();
if (enclosingEl == null) {
@@ -122,7 +120,7 @@ public static List run(HintContext ctx) {
return null;
}
Element klass = info.getTrees().getElement(cc);
- if (klass == null || klass.getKind() != ElementKind.CLASS) {
+ if (klass == null || !klass.getKind().isDeclaredType()) {
return null;
}
String fqn = null;
@@ -143,7 +141,7 @@ public static List run(HintContext ctx) {
if (ctx.isCanceled()) {
return null;
}
- return Collections.singletonList(ed);
+ return List.of(ed);
}
public static final class FixImpl extends JavaFix {
@@ -189,31 +187,18 @@ protected void performRewrite(TransformationContext ctx) throws Exception {
return;
}
CompilationUnitTree cut = (CompilationUnitTree) copy.resolveRewriteTarget(copy.getCompilationUnit());
- CompilationUnitTree nue = GeneratorUtilities.get(copy).addImports(cut, Collections.singleton(e));
+ CompilationUnitTree nue = GeneratorUtilities.get(copy).addImports(cut, Set.of(e));
copy.rewrite(cut, nue);
}
}
- /**
- * @param info
- * @return true if the source level supports the static import language feature
- */
- private static boolean supportsStaticImports(CompilationInfo info) {
- return info.getSourceVersion().compareTo(SourceVersion.RELEASE_5) >= 0;
- }
-
// returns true if a METHOD is enclosed in element with simple name sn
private static boolean hasMethodWithSimpleName(CompilationInfo info, Element element, final String sn) {
- Iterable extends Element> members =
- info.getElementUtilities().getMembers(element.asType(), new ElementUtilities.ElementAcceptor() {
-
- @Override
- public boolean accept(Element e, TypeMirror type) {
- return e.getKind() == ElementKind.METHOD && e.getSimpleName().toString().equals(sn);
- }
- });
- return members.iterator().hasNext();
+ return info.getElementUtilities().getMembers(
+ element.asType(),
+ (elem, type) -> elem.getKind() == ElementKind.METHOD && elem.getSimpleName().toString().equals(sn)
+ ).iterator().hasNext();
}
/**
@@ -266,7 +251,7 @@ private static boolean hasStaticImportSimpleNameClash(CompilationInfo info, Stri
*/
private static boolean isSubTypeOrInnerOfSubType(CompilationInfo info, Element t1, Element t2) {
boolean isSubtype = info.getTypes().isSubtype(t1.asType(), t2.asType());
- boolean isInnerClass = t1.getEnclosingElement().getKind() == ElementKind.CLASS;
+ boolean isInnerClass = t1.getEnclosingElement().getKind().isDeclaredType();
return isSubtype || (isInnerClass && info.getTypes().isSubtype(t1.getEnclosingElement().asType(), t2.asType()));
}
@@ -278,15 +263,12 @@ private static boolean isSubTypeOrInnerOfSubType(CompilationInfo info, Element t
* methods in klass (which may be an inner or static class).
*/
private static boolean hasMethodNameClash(CompilationInfo info, Element klass, String simpleName) {
- assert klass != null;
- assert klass.getKind() == ElementKind.CLASS;
-
// check the members and inherited members of the klass
if (hasMethodWithSimpleName(info, klass, simpleName)) {
return true;
}
Element klassEnclosing = klass.getEnclosingElement();
- return (klassEnclosing != null && klassEnclosing.getKind() == ElementKind.CLASS && hasMethodWithSimpleName(info, klassEnclosing, simpleName));
+ return klassEnclosing != null && klassEnclosing.getKind().isDeclaredType() && hasMethodWithSimpleName(info, klassEnclosing, simpleName);
}
/**
diff --git a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/StaticImportTest.java b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/StaticImportTest.java
index 07800c5a03ee..44af98fe3387 100644
--- a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/StaticImportTest.java
+++ b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/StaticImportTest.java
@@ -99,6 +99,12 @@ public void testStaticImportHint1() throws Exception {
String golden = "package test; import static java.lang.Math.abs; public class Test { public Test() { abs(1); } }";
performFixTest(test, golden);
}
+
+ public void testStaticImportHint1_InRecord() throws Exception {
+ String test = "package test; public record Test(int n) { public Test { Math.|abs(n); } }";
+ String golden = "package test; import static java.lang.Math.abs; public record Test(int n) { public Test { abs(n); } }";
+ performFixTest(test, golden, 17);
+ }
public void testStaticImportHint2() throws Exception {
String test = "package test; public class Test { public Test() { Test.get|Logger(); } public static void getLogger() { } }";
@@ -161,10 +167,14 @@ public void testIgnoreClass() throws Exception {
performAnalysisTest(test);
}
+ private void performFixTest(String test, String golden) throws Exception {
+ performFixTest(test, golden, 8);
+ }
+
// test is single line source code for test.Test, | in the member select, space before
// golden is the output to test against
// sn is the simple name of the static method
- private void performFixTest(String test, String golden) throws Exception {
+ private void performFixTest(String test, String golden, int level) throws Exception {
int offset = test.indexOf("|");
assertTrue(offset != -1);
int end = test.indexOf("(", offset) - 1;
@@ -172,6 +182,7 @@ private void performFixTest(String test, String golden) throws Exception {
int start = test.lastIndexOf(" ", offset) + 1;
assertTrue(start > 0);
HintTest.create()
+ .sourceLevel(level)
.input(test.replace("|", ""))
.run(StaticImport.class)
.findWarning("0:" + start + "-0:" + end + ":hint:" + NbBundle.getMessage(StaticImport.class, "ERR_StaticImport"))