diff --git a/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java b/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java index d7949b719870..d3902809a44c 100644 --- a/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java @@ -25,6 +25,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.patterns.ElementPattern; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; @@ -82,6 +83,21 @@ public class MagicCompletionContributor extends CompletionContributor { return allowedValues; } + @Nullable + private static PsiModifierListOwner resolveExpression(@Nullable PsiExpression expression) { + expression = PsiUtil.skipParenthesizedExprDown(expression); + if (expression instanceof PsiMethodCallExpression) { + return ((PsiMethodCallExpression)expression).resolveMethod(); + } + if (expression instanceof PsiReferenceExpression) { + PsiElement resolved = ((PsiReferenceExpression)expression).resolve(); + if (resolved instanceof PsiModifierListOwner) { + return (PsiModifierListOwner)resolved; + } + } + return null; + } + @NotNull public static List> getMembersWithAllowedValues(@NotNull PsiElement pos) { List> result = ContainerUtil.newArrayList(); @@ -116,21 +132,22 @@ public class MagicCompletionContributor extends CompletionContributor { PsiBinaryExpression exp = PsiTreeUtil.getParentOfType(pos, PsiBinaryExpression.class); if (exp != null && (exp.getOperationTokenType() == JavaTokenType.EQEQ || exp.getOperationTokenType() == JavaTokenType.NE)) { PsiExpression l = exp.getLOperand(); - PsiElement resolved; - if (l instanceof PsiReferenceExpression && (resolved = ((PsiReferenceExpression)l).resolve()) instanceof PsiModifierListOwner) { - result.add(Pair.create((PsiModifierListOwner)resolved, l.getType())); + PsiModifierListOwner resolved = resolveExpression(l); + if (resolved != null) { + result.add(Pair.create(resolved, l.getType())); } PsiExpression r = exp.getROperand(); - if (result.isEmpty() && r instanceof PsiReferenceExpression && (resolved = ((PsiReferenceExpression)r).resolve()) instanceof PsiModifierListOwner) { - result.add(Pair.create((PsiModifierListOwner)resolved, r.getType())); + resolved = resolveExpression(r); + if (r != null && resolved != null) { + result.add(Pair.create(resolved, r.getType())); } } } else if (IN_ASSIGNMENT.accepts(pos)) { PsiAssignmentExpression assignment = PsiTreeUtil.getParentOfType(pos, PsiAssignmentExpression.class); - PsiElement resolved; PsiExpression l = assignment == null ? null : assignment.getLExpression(); - if (assignment != null && PsiTreeUtil.isAncestor(assignment.getRExpression(), pos, false) && l instanceof PsiReferenceExpression && (resolved = ((PsiReferenceExpression)l).resolve()) instanceof PsiModifierListOwner) { + PsiElement resolved = resolveExpression(l); + if (resolved != null && PsiTreeUtil.isAncestor(assignment.getRExpression(), pos, false)) { result.add(Pair.create((PsiModifierListOwner)resolved, l.getType())); } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/MagicConstantCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/MagicConstantCompletionTest.groovy index c7e4ba16bcf4..4181ec97b95a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/MagicConstantCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/MagicConstantCompletionTest.groovy @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.completion +import com.intellij.codeInsight.lookup.LookupManager import com.intellij.psi.PsiClass import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase @@ -48,13 +49,34 @@ class Foo { assert !myFixture.complete(CompletionType.SMART) } - private PsiClass addModifierList() { - myFixture.addClass """ -package org.intellij.lang.annotations; -public @interface MagicConstant { - String[] stringValues() default {}; + public void "test magic constant in equality"() { + addMagicConstant() + + myFixture.configureByText "a.java", """ +class Bar { + static void foo(ModifierList ml) { + if (getConstant() == ) {} + } + + @org.intellij.lang.annotations.MagicConstant(flagsFromClass = Foo.class) + public native int getConstant(); +} + +interface Foo { + int FOO = 1; + int BAR = 2; } """ + myFixture.complete(CompletionType.SMART) + myFixture.assertPreferredCompletionItems 0, 'BAR', 'FOO' + LookupManager.getInstance(project).hideActiveLookup() + + myFixture.complete(CompletionType.BASIC) + myFixture.assertPreferredCompletionItems 0, 'BAR', 'FOO' + } + + private PsiClass addModifierList() { + addMagicConstant() myFixture.addClass """ import org.intellij.lang.annotations.MagicConstant; @@ -70,6 +92,16 @@ interface PsiModifier { interface ModifierList { boolean hasModifierProperty(@PsiModifier.ModifierConstant String m) {} } +""" + } + + private PsiClass addMagicConstant() { + myFixture.addClass """ +package org.intellij.lang.annotations; +public @interface MagicConstant { + String[] stringValues() default {}; + Class flagsFromClass() default void.class; +} """ } }