From 35bdacb51fdef79325d0fc894befd87f7847e09d Mon Sep 17 00:00:00 2001 From: Nikita Eshkeev Date: Wed, 7 Apr 2021 00:52:54 +0300 Subject: [PATCH] [java-highlight] IDEA-253796 Trying to call static method on a new-expression should offer a quickfix to remove new Fix notes from the review, it includes: - moving the check if the new expression can be a call to static field/method to HighlightUtil - checking the base class when looking for a static member GitOrigin-RevId: 0a914f8cc76a13ae4249f9f6b752dcbccae8c940 --- .../daemon/impl/analysis/HighlightUtil.java | 19 +++++++++++++------ .../impl/analysis/HighlightVisitorImpl.java | 4 ---- .../afterCallStaticFieldOfParent.java | 15 +++++++++++++++ .../afterCallStaticMethodOfParent.java | 15 +++++++++++++++ .../beforeCallStaticFieldOfParent.java | 14 ++++++++++++++ .../beforeCallStaticMethodOfParent.java | 14 ++++++++++++++ 6 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/highlight/remove_new/afterCallStaticFieldOfParent.java create mode 100644 java/java-tests/testData/codeInsight/highlight/remove_new/afterCallStaticMethodOfParent.java create mode 100644 java/java-tests/testData/codeInsight/highlight/remove_new/beforeCallStaticFieldOfParent.java create mode 100644 java/java-tests/testData/codeInsight/highlight/remove_new/beforeCallStaticMethodOfParent.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 5376d21484bb..12066d68becd 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -3165,6 +3165,14 @@ public final class HighlightUtil { PsiElement resolved = result.getElement(); PsiElement refParent = ref.getParent(); + + if (isCallToStaticMember(refParent)) { + final String text = JavaErrorBundle.message("cannot.resolve.symbol", refName.getText()); + final HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(ref).descriptionAndTooltip(text).create(); + QuickFixAction.registerQuickFixAction(info, new RemoveNewKeywordFix(refParent)); + return info; + } + PsiElement granny; if (refParent instanceof PsiReferenceExpression && (granny = refParent.getParent()) instanceof PsiMethodCallExpression) { PsiReferenceExpression referenceToMethod = ((PsiMethodCallExpression)granny).getMethodExpression(); @@ -3280,7 +3288,7 @@ public final class HighlightUtil { * @return true if the new expression can actually be a call to a class member (field or method), false otherwise. */ @Contract(value = "null -> false", pure = true) - static boolean isCallToStaticMember(@Nullable PsiElement element) { + private static boolean isCallToStaticMember(@Nullable PsiElement element) { if (!(element instanceof PsiNewExpression)) return false; final PsiNewExpression newExpression = (PsiNewExpression)element; @@ -3292,14 +3300,13 @@ public final class HighlightUtil { if (!(qualifier instanceof PsiReference) || memberName == null) return false; final PsiReference psiReference = (PsiReference)qualifier; - final PsiElement maybeClass = psiReference.resolve(); - if (!(maybeClass instanceof PsiClass)) return false; + final PsiClass clazz = tryCast(psiReference.resolve(), PsiClass.class); + if (clazz == null) return false; - final PsiClass clazz = (PsiClass)maybeClass; - final PsiField field = clazz.findFieldByName(memberName.getText(), false); + final PsiField field = clazz.findFieldByName(memberName.getText(), true); if (field != null) return true; - final PsiMethod[] methods = clazz.findMethodsByName(memberName.getText(), false); + final PsiMethod[] methods = clazz.findMethodsByName(memberName.getText(), true); return methods.length != 0; } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 4a618c53a528..5112a030b583 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -1296,10 +1296,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh String text = JavaErrorBundle.message("cannot.resolve.symbol", ((PsiNamedElement)resolved).getName()); final HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(ref).descriptionAndTooltip(text).create(); - if (HighlightUtil.isCallToStaticMember(parent)) { - QuickFixAction.registerQuickFixAction(info, new RemoveNewKeywordFix(parent)); - } - myHolder.add(info); } diff --git a/java/java-tests/testData/codeInsight/highlight/remove_new/afterCallStaticFieldOfParent.java b/java/java-tests/testData/codeInsight/highlight/remove_new/afterCallStaticFieldOfParent.java new file mode 100644 index 000000000000..88c8102b20ee --- /dev/null +++ b/java/java-tests/testData/codeInsight/highlight/remove_new/afterCallStaticFieldOfParent.java @@ -0,0 +1,15 @@ +// "Remove 'new'" "true" + +class A { + public static A field = new A(); +} + +class B extends A { + { + /* + * hello + * world + */ + A a = B.field; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/highlight/remove_new/afterCallStaticMethodOfParent.java b/java/java-tests/testData/codeInsight/highlight/remove_new/afterCallStaticMethodOfParent.java new file mode 100644 index 000000000000..dc6de64b13ea --- /dev/null +++ b/java/java-tests/testData/codeInsight/highlight/remove_new/afterCallStaticMethodOfParent.java @@ -0,0 +1,15 @@ +// "Remove 'new'" "true" + +class A { + public static void process() {} +} + +class B extends A { + { + /* + * hello + * world + */ + B.process(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/highlight/remove_new/beforeCallStaticFieldOfParent.java b/java/java-tests/testData/codeInsight/highlight/remove_new/beforeCallStaticFieldOfParent.java new file mode 100644 index 000000000000..30bc56d02eda --- /dev/null +++ b/java/java-tests/testData/codeInsight/highlight/remove_new/beforeCallStaticFieldOfParent.java @@ -0,0 +1,14 @@ +// "Remove 'new'" "true" + +class A { + public static A field = new A(); +} + +class B extends A { + { + A a = new /* + * hello + * world + */ B.field; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/highlight/remove_new/beforeCallStaticMethodOfParent.java b/java/java-tests/testData/codeInsight/highlight/remove_new/beforeCallStaticMethodOfParent.java new file mode 100644 index 000000000000..fb15b8cd032e --- /dev/null +++ b/java/java-tests/testData/codeInsight/highlight/remove_new/beforeCallStaticMethodOfParent.java @@ -0,0 +1,14 @@ +// "Remove 'new'" "true" + +class A { + public static void process() {} +} + +class B extends A { + { + new /* + * hello + * world + */ B.process(); + } +} \ No newline at end of file