diff --git a/java/java-impl/resources/META-INF/JavaPlugin.xml b/java/java-impl/resources/META-INF/JavaPlugin.xml
index 063b02659f09..282828791470 100644
--- a/java/java-impl/resources/META-INF/JavaPlugin.xml
+++ b/java/java-impl/resources/META-INF/JavaPlugin.xml
@@ -1195,6 +1195,7 @@
+
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/CheckInitialized.java b/java/java-impl/src/com/intellij/codeInsight/completion/CheckInitialized.java
index e8dec498bbc4..3603e265e900 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/CheckInitialized.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/CheckInitialized.java
@@ -13,6 +13,7 @@ import com.intellij.psi.util.PsiUtil;
import com.intellij.util.JavaPsiConstructorUtil;
import com.intellij.util.containers.ContainerUtil;
import com.siyeh.ig.psiutils.VariableAccessUtils;
+import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -20,16 +21,17 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
-class CheckInitialized implements ElementFilter {
+@ApiStatus.Internal
+public class CheckInitialized implements ElementFilter {
private final Set myNonInitializedFields;
private final boolean myInsideConstructorCall;
- CheckInitialized(@NotNull PsiElement position) {
+ public CheckInitialized(@NotNull PsiElement position) {
myNonInitializedFields = getNonInitializedFields(position);
myInsideConstructorCall = isInsideConstructorCall(position);
}
- static boolean isInsideConstructorCall(@NotNull PsiElement position) {
+ public static boolean isInsideConstructorCall(@NotNull PsiElement position) {
return JavaPsiConstructorUtil.isConstructorCall(PsiTreeUtil.getParentOfType(position, PsiMethodCallExpression.class)) &&
!JavaKeywordCompletion.AFTER_DOT.accepts(position);
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
index ac40998fcd04..b19a44e84cc2 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
@@ -14,6 +14,7 @@ import com.intellij.codeInsight.guess.GuessManager;
import com.intellij.codeInsight.lookup.*;
import com.intellij.java.codeserver.core.JavaPsiModuleUtil;
import com.intellij.lang.java.JavaLanguage;
+import com.intellij.modcompletion.ModCompletionItemProvider;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -85,7 +86,7 @@ public final class JavaCompletionUtil {
public static final Key SUPER_METHOD_PARAMETERS = Key.create("SUPER_METHOD_PARAMETERS");
- public static @Nullable Set getExpectedTypes(@NotNull CompletionParameters parameters) {
+ public static @Nullable Set getExpectedTypes(@NotNull BaseCompletionParameters parameters) {
PsiExpression expr = PsiTreeUtil.getContextOfType(parameters.getPosition(), PsiExpression.class, true);
if (expr != null) {
Set set = new HashSet<>();
@@ -328,48 +329,45 @@ public final class JavaCompletionUtil {
return Collections.emptyList();
}
- private static boolean shouldCast(@NotNull LookupElement item,
- @NotNull PsiTypeLookupItem castTypeItem,
- @Nullable PsiType plainQualifier,
- @NotNull JavaCompletionProcessor processor,
- @NotNull Set extends PsiType> expectedTypes) {
- PsiType castType = castTypeItem.getType();
+ public static boolean shouldCast(@Nullable PsiType plainQualifier,
+ @NotNull JavaCompletionProcessor processor,
+ @NotNull Set extends PsiType> expectedTypes,
+ PsiType castType,
+ @NotNull PsiMember member) {
if (plainQualifier != null) {
- Object o = item.getObject();
- if (o instanceof PsiMethod) {
- if (plainQualifier instanceof PsiClassType && castType instanceof PsiClassType) {
- PsiMethod method = (PsiMethod)o;
- PsiClassType.ClassResolveResult plainResult = ((PsiClassType)plainQualifier).resolveGenerics();
- PsiClass plainClass = plainResult.getElement();
- HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature();
- PsiMethod plainMethod = plainClass == null ? null :
- StreamEx.ofTree(signature, s -> StreamEx.of(s.getSuperSignatures()))
- .map(sig -> MethodSignatureUtil.findMethodBySignature(plainClass, sig, true))
- .filter(Objects::nonNull)
- .findFirst().orElse(null);
- if (plainMethod != null) {
- PsiClassType.ClassResolveResult castResult = ((PsiClassType)castType).resolveGenerics();
- PsiClass castClass = castResult.getElement();
+ if (member instanceof PsiMethod method &&
+ plainQualifier instanceof PsiClassType classQualifier &&
+ castType instanceof PsiClassType classCastType) {
+ PsiClassType.ClassResolveResult plainResult = classQualifier.resolveGenerics();
+ PsiClass plainClass = plainResult.getElement();
+ HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature();
+ PsiMethod plainMethod = plainClass == null ? null :
+ StreamEx.ofTree(signature, s -> StreamEx.of(s.getSuperSignatures()))
+ .map(sig -> MethodSignatureUtil.findMethodBySignature(plainClass, sig, true))
+ .filter(Objects::nonNull)
+ .findFirst().orElse(null);
+ if (plainMethod != null) {
+ PsiClassType.ClassResolveResult castResult = classCastType.resolveGenerics();
+ PsiClass castClass = castResult.getElement();
- if (castClass == null || !castClass.isInheritor(plainClass, true)) {
- return false;
- }
-
- if (!processor.isAccessible(plainMethod)) {
- return true;
- }
-
- PsiSubstitutor castSub = TypeConversionUtil.getSuperClassSubstitutor(plainClass, (PsiClassType)castType);
- PsiType typeAfterCast = toRaw(castSub.substitute(method.getReturnType()));
- PsiType typeDeclared = toRaw(plainResult.getSubstitutor().substitute(plainMethod.getReturnType()));
- return typeAfterCast != null && typeDeclared != null &&
- !typeAfterCast.equals(typeDeclared) &&
- ContainerUtil.exists(expectedTypes, et -> et.isAssignableFrom(typeAfterCast) && !et.isAssignableFrom(typeDeclared));
+ if (castClass == null || !castClass.isInheritor(plainClass, true)) {
+ return false;
}
+
+ if (!processor.isAccessible(plainMethod)) {
+ return true;
+ }
+
+ PsiSubstitutor castSub = TypeConversionUtil.getSuperClassSubstitutor(plainClass, classCastType);
+ PsiType typeAfterCast = toRaw(castSub.substitute(method.getReturnType()));
+ PsiType typeDeclared = toRaw(plainResult.getSubstitutor().substitute(plainMethod.getReturnType()));
+ return typeAfterCast != null && typeDeclared != null &&
+ !typeAfterCast.equals(typeDeclared) &&
+ ContainerUtil.exists(expectedTypes, et -> et.isAssignableFrom(typeAfterCast) && !et.isAssignableFrom(typeDeclared));
}
}
- return containsMember(castType, o, true) && !containsMember(plainQualifier, o, true);
+ return containsMember(castType, member, true) && !containsMember(plainQualifier, member, true);
}
return false;
}
@@ -420,7 +418,12 @@ public final class JavaCompletionUtil {
@Nullable PsiType plainQualifier,
JavaCompletionProcessor processor,
Set extends PsiType> expectedTypes) {
- return ContainerUtil.find(castTypeItems, c -> shouldCast(item, c, plainQualifier, processor, expectedTypes));
+ PsiMember member = ObjectUtils.tryCast(item.getObject(), PsiMember.class);
+ if (member == null) return null;
+ return ContainerUtil.find(castTypeItems, c -> {
+ PsiType castType = c.getType();
+ return shouldCast(plainQualifier, processor, expectedTypes, castType, member);
+ });
}
private static @Nullable PsiType toRaw(@Nullable PsiType type) {
@@ -536,7 +539,7 @@ public final class JavaCompletionUtil {
return Collections.singletonList(JavaLookupElementBuilder.forMethod((PsiMethod)completion, PsiSubstitutor.EMPTY));
}
- if (completion instanceof PsiClass) {
+ if (completion instanceof PsiClass && !ModCompletionItemProvider.modCommandCompletionEnabled()) {
List classItems = JavaClassNameCompletionContributor.createClassLookupItems(
CompletionUtil.getOriginalOrSelf((PsiClass)completion),
JavaClassNameCompletionContributor.AFTER_NEW.accepts(reference),
@@ -548,7 +551,7 @@ public final class JavaCompletionUtil {
PsiSubstitutor substitutor = completionElement.getSubstitutor();
if (substitutor == null) substitutor = PsiSubstitutor.EMPTY;
- if (completion instanceof PsiClass) {
+ if (completion instanceof PsiClass && !ModCompletionItemProvider.modCommandCompletionEnabled()) {
JavaPsiClassReferenceElement classItem =
JavaClassNameCompletionContributor.createClassLookupItem((PsiClass)completion, true).setSubstitutor(substitutor);
return JavaConstructorCallElement.wrap(classItem, reference.getElement());
@@ -563,14 +566,14 @@ public final class JavaCompletionUtil {
item.setForcedQualifier(completionElement.getQualifierText());
return Collections.singletonList(item);
}
- if (completion instanceof PsiVariable) {
+ if (completion instanceof PsiVariable && !ModCompletionItemProvider.modCommandCompletionEnabled()) {
if (completion instanceof PsiEnumConstant enumConstant &&
PsiTreeUtil.isAncestor(enumConstant.getArgumentList(), reference.getElement(), true)) {
return Collections.emptyList();
}
return Collections.singletonList(new VariableLookupItem((PsiVariable)completion).setSubstitutor(substitutor).qualifyIfNeeded(reference, null));
}
- if (completion instanceof PsiPackage) {
+ if (completion instanceof PsiPackage && !ModCompletionItemProvider.modCommandCompletionEnabled()) {
return Collections.singletonList(new PackageLookupItem((PsiPackage)completion, reference.getElement()));
}
@@ -762,9 +765,13 @@ public final class JavaCompletionUtil {
}
}
- static boolean inSomePackage(@NotNull PsiElement context) {
+ /**
+ * @param context element from Java file
+ * @return true if the element is located not in the unnamed package
+ */
+ public static boolean inSomePackage(@NotNull PsiElement context) {
PsiFile contextFile = context.getContainingFile();
- return contextFile instanceof PsiClassOwner && StringUtil.isNotEmpty(((PsiClassOwner)contextFile).getPackageName());
+ return contextFile instanceof PsiClassOwner owner && StringUtil.isNotEmpty(owner.getPackageName());
}
static boolean isSourceLevelAccessible(@NotNull PsiElement context,
@@ -773,7 +780,7 @@ public final class JavaCompletionUtil {
return isSourceLevelAccessible(context, psiClass, pkgContext, psiClass.getContainingClass());
}
- private static boolean isSourceLevelAccessible(PsiElement context,
+ public static boolean isSourceLevelAccessible(PsiElement context,
@NotNull PsiClass psiClass,
boolean pkgContext,
@Nullable PsiClass qualifierClass) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java
index 1d57a266994e..dc8627be44a5 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java
@@ -211,7 +211,12 @@ public class JavaPsiClassReferenceElement extends LookupItem