diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java index 441fab727d01..42c9f2750d33 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java @@ -21,6 +21,7 @@ import com.intellij.codeInspection.dataFlow.memory.DfaMemoryState; import com.intellij.codeInspection.dataFlow.memory.DfaMemoryStateImpl; import com.intellij.codeInspection.dataFlow.value.DfaValue; import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; @@ -36,6 +37,7 @@ import com.intellij.util.BitUtil; import com.intellij.util.containers.CollectionFactory; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; +import com.intellij.util.indexing.DumbModeAccessType; import com.siyeh.ig.callMatcher.CallMatcher; import com.siyeh.ig.psiutils.ExpressionUtils; import org.jetbrains.annotations.NotNull; @@ -295,7 +297,8 @@ public final class GuessManagerImpl extends GuessManager { PsiManager manager = PsiManager.getInstance(myProject); PsiElementProcessor.CollectElementsWithLimit processor = new PsiElementProcessor.CollectElementsWithLimit<>(5); - ClassInheritorsSearch.search(refClass).forEach(new PsiElementProcessorAdapter<>(processor)); + DumbModeAccessType.RELIABLE_DATA_ONLY.ignoreDumbMode( + () -> ClassInheritorsSearch.search(refClass).forEach(new PsiElementProcessorAdapter<>(processor))); if (processor.isOverflow()) return; for (PsiClass derivedClass : processor.getCollection()) { @@ -425,27 +428,33 @@ public final class GuessManagerImpl extends GuessManager { PsiExpression place = PsiUtil.skipParenthesizedExprDown(expr); if (place == null) return Collections.emptyList(); - List result = null; - if (!ControlFlowAnalyzer.inlinerMayInferPreciseType(place)) { - GuessTypeVisitor visitor = tryGuessingTypeWithoutDfa(place, honorAssignments); - if (!visitor.isDfaNeeded()) { - result = visitor.mySpecificType == null ? - Collections.emptyList() : Collections.singletonList(DfaPsiUtil.tryGenerify(expr, visitor.mySpecificType)); + DumbService dumbService = DumbService.getInstance(myProject); + PsiType type = dumbService.computeWithAlternativeResolveEnabled(() -> { + if (!ControlFlowAnalyzer.inlinerMayInferPreciseType(place)) { + GuessTypeVisitor visitor = tryGuessingTypeWithoutDfa(place, honorAssignments); + if (!visitor.isDfaNeeded()) return visitor.mySpecificType; } + return getTypeFromDataflow(expr, honorAssignments); + }); + return dumbService.computeWithAlternativeResolveEnabled(() -> postFilter(expr, type)); + } + + @NotNull + private static List flattenAndGenerify(@NotNull PsiExpression expr, PsiType psiType) { + if (psiType instanceof PsiIntersectionType intersection) { + return ContainerUtil.mapNotNull(intersection.getConjuncts(), type -> DfaPsiUtil.tryGenerify(expr, type)); } - if (result == null) { - PsiType psiType = getTypeFromDataflow(expr, honorAssignments); - if (psiType instanceof PsiIntersectionType intersection) { - result = ContainerUtil.mapNotNull(intersection.getConjuncts(), type -> DfaPsiUtil.tryGenerify(expr, type)); - } - else if (psiType != null) { - result = Collections.singletonList(DfaPsiUtil.tryGenerify(expr, psiType)); - } - else { - result = Collections.emptyList(); - } + else if (psiType != null) { + return Collections.singletonList(DfaPsiUtil.tryGenerify(expr, psiType)); } - result = ContainerUtil.filter(result, t -> { + else { + return Collections.emptyList(); + } + } + + @NotNull + private static List postFilter(@NotNull PsiExpression expr, PsiType type) { + List result = ContainerUtil.filter(flattenAndGenerify(expr, type), t -> { PsiClass typeClass = PsiUtil.resolveClassInType(t); return typeClass == null || PsiUtil.isAccessible(typeClass, expr, null); }); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullabilityUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullabilityUtil.java index fa2d5c681fb8..5d76d38369c4 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullabilityUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullabilityUtil.java @@ -5,6 +5,7 @@ import com.intellij.codeInsight.JavaPsiEquivalenceUtil; import com.intellij.codeInsight.Nullability; import com.intellij.codeInsight.daemon.ImplicitUsageProvider; import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.Pair; import com.intellij.psi.*; import com.intellij.psi.augment.PsiAugmentProvider; @@ -89,6 +90,7 @@ public final class NullabilityUtil { expression.getType() instanceof PsiPrimitiveType) { return Nullability.NOT_NULL; } + boolean dumb = DumbService.isDumb(expression.getProject()); if (expression instanceof PsiConditionalExpression) { PsiExpression thenExpression = ((PsiConditionalExpression)expression).getThenExpression(); PsiExpression elseExpression = ((PsiConditionalExpression)expression).getElseExpression(); @@ -104,7 +106,7 @@ public final class NullabilityUtil { if (ref != null && JavaPsiEquivalenceUtil.areExpressionsEquivalent(ref, thenExpression)) { return getExpressionNullability(elseExpression, useDataflow); } - if (useDataflow) { + if (useDataflow && !dumb) { return DfaNullability.toNullability(DfaNullability.fromDfType(CommonDataflow.getDfType(expression))); } Nullability left = getExpressionNullability(thenExpression, false); @@ -121,7 +123,7 @@ public final class NullabilityUtil { } return Nullability.NOT_NULL; } - if (useDataflow) { + if (useDataflow && !dumb) { return DfaNullability.toNullability(DfaNullability.fromDfType(CommonDataflow.getDfType(expression))); } if (expression instanceof PsiReferenceExpression ref) { @@ -129,6 +131,7 @@ public final class NullabilityUtil { if (target instanceof PsiPatternVariable) { return Nullability.NOT_NULL; // currently all pattern variables are not-null } + if (dumb) return Nullability.UNKNOWN; if (target instanceof PsiLocalVariable || target instanceof PsiParameter) { PsiElement block = PsiUtil.getVariableCodeBlock((PsiVariable)target, null); // Do not trust the declared nullability of local variable/parameter if it's reassigned as nullability designates @@ -138,6 +141,7 @@ public final class NullabilityUtil { return DfaPsiUtil.getElementNullabilityIgnoringParameterInference(expression.getType(), (PsiModifierListOwner)target); } if (expression instanceof PsiMethodCallExpression || expression instanceof PsiTemplateExpression) { + if (dumb) return Nullability.UNKNOWN; PsiMethod method = ((PsiCall)expression).resolveMethod(); return method != null ? DfaPsiUtil.getElementNullability(expression.getType(), method) : Nullability.UNKNOWN; } diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/AbstractJavaInplaceIntroducer.java b/java/java-impl-refactorings/src/com/intellij/refactoring/AbstractJavaInplaceIntroducer.java index 2e4066428506..d9f7e58c0459 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/AbstractJavaInplaceIntroducer.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/AbstractJavaInplaceIntroducer.java @@ -7,6 +7,7 @@ import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.NlsContexts; @@ -53,7 +54,8 @@ public abstract class AbstractJavaInplaceIntroducer extends AbstractInplaceIntro final String propertyName = variable != null ? JavaCodeStyleManager.getInstance(myProject).variableNameToPropertyName(variable.getName(), VariableKind.LOCAL_VARIABLE) : null; - mySuggestedNameInfo = suggestNames(defaultType, propertyName); + mySuggestedNameInfo = + DumbService.getInstance(myProject).computeWithAlternativeResolveEnabled(() -> suggestNames(defaultType, propertyName)); final String[] names = mySuggestedNameInfo.names; if (propertyName != null && names.length > 1) { final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(myProject); @@ -92,7 +94,7 @@ public abstract class AbstractJavaInplaceIntroducer extends AbstractInplaceIntro @Override protected void restoreState(@NotNull PsiVariable psiField) { final SmartTypePointer typePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(getType()); - super.restoreState(psiField); + DumbService.getInstance(myProject).withAlternativeResolveEnabled(() -> super.restoreState(psiField)); for (PsiExpression occurrence : myOccurrences) { if (!occurrence.isValid()) return; } diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/AbstractInplaceIntroduceFieldPopup.java b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/AbstractInplaceIntroduceFieldPopup.java index b84d700f2b84..69a834fea000 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/AbstractInplaceIntroduceFieldPopup.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/AbstractInplaceIntroduceFieldPopup.java @@ -4,6 +4,7 @@ package com.intellij.refactoring.introduceField; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.NlsContexts; import com.intellij.openapi.vfs.VirtualFile; @@ -112,20 +113,23 @@ public abstract class AbstractInplaceIntroduceFieldPopup extends AbstractJavaInp } protected void performIntroduce(BaseExpressionToFieldHandler.Settings settings) { - WriteCommandAction.writeCommandAction(myProject).withName(getCommandName()).withGroupId(getCommandName()).run(() -> { - if (getLocalVariable() != null) { - final LocalToFieldHandler.IntroduceFieldRunnable fieldRunnable = - new LocalToFieldHandler.IntroduceFieldRunnable(false, (PsiLocalVariable)getLocalVariable(), getParentClass(), settings, myOccurrences); - fieldRunnable.run(); - updateVariable(fieldRunnable.getField()); - } - else { - final BaseExpressionToFieldHandler.ConvertToFieldRunnable convertToFieldRunnable = - new BaseExpressionToFieldHandler.ConvertToFieldRunnable(myExpr, settings, settings.getForcedType(), myOccurrences, - getAnchorElementIfAll(), getAnchorElement(), myEditor, getParentClass()); - convertToFieldRunnable.run(); - updateVariable(convertToFieldRunnable.getField()); - } - }); + WriteCommandAction.writeCommandAction(myProject).withName(getCommandName()).withGroupId(getCommandName()).run( + () -> DumbService.getInstance(myProject).runWithAlternativeResolveEnabled(() -> { + if (getLocalVariable() != null) { + final LocalToFieldHandler.IntroduceFieldRunnable fieldRunnable = + new LocalToFieldHandler.IntroduceFieldRunnable(false, (PsiLocalVariable)getLocalVariable(), getParentClass(), settings, + myOccurrences); + fieldRunnable.run(); + updateVariable(fieldRunnable.getField()); + } + else { + final BaseExpressionToFieldHandler.ConvertToFieldRunnable convertToFieldRunnable = + new BaseExpressionToFieldHandler.ConvertToFieldRunnable(myExpr, settings, settings.getForcedType(), myOccurrences, + getAnchorElementIfAll(), getAnchorElement(), myEditor, + getParentClass()); + convertToFieldRunnable.run(); + updateVariable(convertToFieldRunnable.getField()); + } + })); } } diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java index 8f06937dfbf3..f8c8aec90f6f 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java @@ -2,8 +2,8 @@ package com.intellij.refactoring.introduceField; import com.intellij.openapi.application.WriteAction; -import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.codeStyle.SuggestedNameInfo; @@ -72,7 +72,7 @@ public class InplaceIntroduceFieldPopup extends AbstractInplaceIntroduceFieldPop protected PsiField createFieldToStartTemplateOn(final String[] names, final PsiType defaultType) { final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); - final PsiField field = WriteAction.compute(() -> { + final PsiField field = WriteAction.compute(() -> DumbService.getInstance(myProject).computeWithAlternativeResolveEnabled(() -> { PsiField field1 = elementFactory.createField(chooseName(names, getParentClass().getLanguage()), defaultType); PsiUtil.setModifierProperty(field1, PsiModifier.FINAL, myIntroduceFieldPanel.isDeclareFinal()); PsiUtil.setModifierProperty(field1, PsiModifier.STATIC, myStatic); @@ -86,7 +86,7 @@ public class InplaceIntroduceFieldPopup extends AbstractInplaceIntroduceFieldPop } updateVariable(field1); return field1; - }); + })); PsiDocumentManager.getInstance(myProject).doPostponedOperationsAndUnblockDocument(myEditor.getDocument()); return field; } diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java index 59419c3e3184..920575faf6c3 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java @@ -5,6 +5,7 @@ import com.intellij.codeInsight.TestFrameworks; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ReadAction; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.ui.ComboBox; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; @@ -149,7 +150,7 @@ public class IntroduceFieldPopupPanel extends IntroduceFieldCentralPanel { myInitialisersPlaceModel.addElement(BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD); myInitialisersPlaceModel.addElement(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION); myInitialisersPlaceModel.addElement(BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR); - if (TestFrameworks.getInstance().isTestClass(myParentClass)) { + if (!DumbService.isDumb(myParentClass.getProject()) && TestFrameworks.getInstance().isTestClass(myParentClass)) { myInitialisersPlaceModel.addElement(BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD); } initializeInitializerPlace(myInitializerExpression, IntroduceFieldDialog.ourLastInitializerPlace); diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java index 587e7a63ec62..dfe70e88fd8f 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -22,6 +22,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.SelectionModel; import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; @@ -324,7 +325,9 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { } - final PsiType originalType = CommonJavaRefactoringUtil.getTypeByExpressionWithExpectedType(expr); + DumbService dumbService = DumbService.getInstance(project); + final PsiType originalType = + dumbService.computeWithAlternativeResolveEnabled(() -> CommonJavaRefactoringUtil.getTypeByExpressionWithExpectedType(expr)); if (originalType == null || LambdaUtil.notInferredType(originalType)) { String message = RefactoringBundle.getCannotRefactorMessage(JavaRefactoringBundle.message("unknown.expression.type")); showErrorMessage(project, editor, message); @@ -401,7 +404,8 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { } else { SlowOperations.allowSlowOperations( - () -> inplaceIntroduce(project, editor, choice, targetContainer, occurrenceManager, originalType, dialogIntroduce)); + () -> dumbService.runWithAlternativeResolveEnabled( + () -> inplaceIntroduce(project, editor, choice, targetContainer, occurrenceManager, originalType, dialogIntroduce))); } } @@ -915,7 +919,8 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { if (parent == null) return null; PsiType type = expression.getType(); PsiLambdaExpression lambda = PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class, true, PsiStatement.class); - ChainCallExtractor extractor = ChainCallExtractor.findExtractor(lambda, expression, type); + ChainCallExtractor extractor = DumbService.getInstance(expression.getProject()) + .computeWithAlternativeResolveEnabled(() -> ChainCallExtractor.findExtractor(lambda, expression, type)); if (extractor == null) return null; PsiParameter parameter = lambda.getParameterList().getParameters()[0]; if (!ReferencesSearch.search(parameter).forEach((Processor)ref -> diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java index 8e16449b4ee5..f3938143314b 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java @@ -17,6 +17,7 @@ import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.editor.impl.EditorImpl; import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.NlsContexts; import com.intellij.openapi.util.Pair; @@ -333,7 +334,7 @@ public class JavaVariableInplaceIntroducer extends AbstractJavaInplaceIntroducer } } if (psiVariable != null && psiVariable.isValid()) { - createCastInVariableDeclaration(project, psiVariable); + DumbService.getInstance(project).runWithAlternativeResolveEnabled(() -> createCastInVariableDeclaration(project, psiVariable)); } } diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java index 6e5257bf2f83..0a22633fc5ef 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java @@ -11,6 +11,7 @@ import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.VisualPosition; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.Disposer; @@ -132,7 +133,7 @@ public final class ReassignVariableUtil { scope instanceof PsiClassInitializer) break; scope = scope.getParent(); } - if (scope == null) return proc; + if (scope == null || DumbService.isDumb(scope.getProject())) return proc; PsiScopesUtil.treeWalkUp(proc, declaration, scope); return proc; } diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/VariableExtractor.java b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/VariableExtractor.java index cdd5910b1b3e..fbacd0904731 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/VariableExtractor.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/introduceVariable/VariableExtractor.java @@ -15,6 +15,7 @@ import com.intellij.openapi.diagnostic.RuntimeExceptionWithAttachments; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.LogicalPosition; import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.psi.*; @@ -296,18 +297,20 @@ final class VariableExtractor { if (type == null) { throw new IncorrectOperationException("Unexpected empty type pointer"); } - - PsiDeclarationStatement probe = JavaPsiFacade.getElementFactory(expression.getProject()) - .createVariableDeclarationStatement("x", TypeUtils.getObjectType(expression), null, expression); - Project project = expression.getProject(); - NullabilityAnnotationInfo nullabilityAnnotationInfo = - NullableNotNullManager.getInstance(project).findExplicitNullability((PsiLocalVariable)probe.getDeclaredElements()[0]); - NullabilityAnnotationInfo info = DfaPsiUtil.getTypeNullabilityInfo(type); - if (info != null && nullabilityAnnotationInfo != null && info.getNullability() != nullabilityAnnotationInfo.getNullability() && - // The type nullability could be inherited from hierarchy. E.g. if the type is type parameter T, - // which is defined as . In this case we should not add @NotNull explicitly - ArrayUtil.contains(info.getAnnotation(), type.getAnnotations())) { - return type.annotate(TypeAnnotationProvider.Static.create(new PsiAnnotation[]{info.getAnnotation()})); + if (!DumbService.isDumb(expression.getProject())) { + // NullableNotNullManager doesn't work well in dumb mode + PsiDeclarationStatement probe = JavaPsiFacade.getElementFactory(expression.getProject()) + .createVariableDeclarationStatement("x", TypeUtils.getObjectType(expression), null, expression); + Project project = expression.getProject(); + NullabilityAnnotationInfo nullabilityAnnotationInfo = + NullableNotNullManager.getInstance(project).findExplicitNullability((PsiLocalVariable)probe.getDeclaredElements()[0]); + NullabilityAnnotationInfo info = DfaPsiUtil.getTypeNullabilityInfo(type); + if (info != null && nullabilityAnnotationInfo != null && info.getNullability() != nullabilityAnnotationInfo.getNullability() && + // The type nullability could be inherited from hierarchy. E.g. if the type is type parameter T, + // which is defined as . In this case we should not add @NotNull explicitly + ArrayUtil.contains(info.getAnnotation(), type.getAnnotations())) { + return type.annotate(TypeAnnotationProvider.Static.create(new PsiAnnotation[]{info.getAnnotation()})); + } } return type.annotate(TypeAnnotationProvider.EMPTY); } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java index c804e972113a..0f5ae7bef2cd 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java @@ -11,6 +11,7 @@ import com.intellij.codeInsight.lookup.PsiTypeLookupItem; import com.intellij.codeInspection.dataFlow.DfaPsiUtil; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorModificationUtilEx; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; @@ -84,7 +85,8 @@ class JavaClassNameInsertHandler implements InsertHandler PsiTypeLookupItem.addImportForItem(context, finalPsiClass)); if (!context.getOffsetMap().containsOffset(refEnd)) { return; } @@ -214,7 +216,8 @@ class JavaClassNameInsertHandler implements InsertHandler isArrayTypeExpected((PsiExpression)prevElement.getParent())); } return false; 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 e0b1bd1dd500..b15c6d24f5de 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -43,10 +43,7 @@ import com.intellij.psi.scope.util.PsiScopesUtil; import com.intellij.psi.util.*; import com.intellij.psi.util.proximity.ReferenceListWeigher; import com.intellij.ui.JBColor; -import com.intellij.util.IncorrectOperationException; -import com.intellij.util.ObjectUtils; -import com.intellij.util.PairFunction; -import com.intellij.util.ThreeState; +import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.JBIterable; import com.siyeh.ig.psiutils.SideEffectChecker; @@ -660,7 +657,7 @@ public final class JavaCompletionUtil { Document document = FileDocumentManager.getInstance().getDocument(file.getViewProvider().getVirtualFile()); PsiReference reference = file.findReferenceAt(startOffset); - if (reference != null && manager.areElementsEquivalent(psiClass, reference.resolve())) { + if (reference != null && manager.areElementsEquivalent(psiClass, resolve(project, reference))) { return endOffset; } @@ -744,13 +741,20 @@ public final class JavaCompletionUtil { return newEndOffset; } + @Nullable + private static PsiElement resolve(Project project, PsiReference reference) { + return DumbService.getInstance(project).computeWithAlternativeResolveEnabled(reference::resolve); + } + @Nullable static PsiElement resolveReference(PsiReference psiReference) { - if (psiReference instanceof PsiPolyVariantReference) { - ResolveResult[] results = ((PsiPolyVariantReference)psiReference).multiResolve(true); - if (results.length == 1) return results[0].getElement(); - } - return psiReference.resolve(); + return DumbService.getInstance(psiReference.getElement().getProject()).computeWithAlternativeResolveEnabled(() -> { + if (psiReference instanceof PsiPolyVariantReference) { + ResolveResult[] results = ((PsiPolyVariantReference)psiReference).multiResolve(true); + if (results.length == 1) return results[0].getElement(); + } + return psiReference.resolve(); + }); } @Nullable diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithTryCatchSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithTryCatchSurrounder.java index 486b85311466..3b2399084215 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithTryCatchSurrounder.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithTryCatchSurrounder.java @@ -4,6 +4,7 @@ package com.intellij.codeInsight.generation.surroundWith; import com.intellij.codeInsight.ExceptionUtil; import com.intellij.java.JavaBundle; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.TextRange; @@ -14,6 +15,7 @@ import com.intellij.psi.codeStyle.VariableKind; import com.intellij.util.IncorrectOperationException; import com.siyeh.ig.psiutils.VariableNameGenerator; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collections; @@ -41,15 +43,63 @@ public class JavaWithTryCatchSurrounder extends JavaStatementsSurrounder { } @Nullable - public TextRange doSurround(Project project, PsiElement container, PsiElement[] statements) { + public TextRange doSurround(Project project, PsiElement container, PsiElement[] origStatements) { PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project); - statements = SurroundWithUtil.moveDeclarationsOut(container, statements, true); + PsiElement[] statements = SurroundWithUtil.moveDeclarationsOut(container, origStatements, true); if (statements.length == 0) { return null; } + return DumbService.getInstance(project).computeWithAlternativeResolveEnabled(() -> { + List exceptions = getExceptionTypes(container, statements, factory); + + @NonNls StringBuilder buffer = new StringBuilder(); + buffer.append("try{\n}"); + for (PsiClassType ignored : exceptions) { + buffer.append("catch(Exception e){\n}"); + } + if (myGenerateFinally) { + buffer.append("finally{\n}"); + } + String text = buffer.toString(); + PsiTryStatement tryStatement = (PsiTryStatement)factory.createStatementFromText(text, null); + tryStatement = (PsiTryStatement)CodeStyleManager.getInstance(project).reformat(tryStatement); + + tryStatement = (PsiTryStatement)addAfter(tryStatement, container, statements); + + PsiCodeBlock tryBlock = tryStatement.getTryBlock(); + SurroundWithUtil.indentCommentIfNecessary(tryBlock, statements); + addRangeWithinContainer(tryBlock, container, statements, true); + + PsiCatchSection[] catchSections = tryStatement.getCatchSections(); + + for (int i = 0; i < exceptions.size(); i++) { + PsiClassType exception = exceptions.get(i); + PsiClass target = exception.resolve(); + if (target instanceof PsiTypeParameter) { + PsiClassType[] extendsListTypes = target.getExtendsListTypes(); + if (extendsListTypes.length > 0) { + exception = extendsListTypes[0]; + } + } + String name = + new VariableNameGenerator(tryBlock, VariableKind.PARAMETER).byName("e", "ex", "exc").byType(exception).generate(false); + PsiCatchSection catchSection = factory.createCatchSection(exception, name, tryBlock); + catchSection = (PsiCatchSection)catchSections[i].replace(catchSection); + codeStyleManager.shortenClassReferences(catchSection); + } + + container.deleteChildRange(statements[0], statements[statements.length - 1]); + + PsiCodeBlock firstCatch = tryStatement.getCatchBlocks()[0]; + return SurroundWithUtil.getRangeToSelect(firstCatch); + }); + } + + @NotNull + private static List getExceptionTypes(PsiElement container, PsiElement[] statements, PsiElementFactory factory) { List exceptions = ExceptionUtil.getUnhandledExceptions(statements); if (exceptions.isEmpty()) { exceptions = ExceptionUtil.getThrownExceptions(statements); @@ -57,45 +107,6 @@ public class JavaWithTryCatchSurrounder extends JavaStatementsSurrounder { exceptions = Collections.singletonList(factory.createTypeByFQClassName("java.lang.Exception", container.getResolveScope())); } } - - @NonNls StringBuilder buffer = new StringBuilder(); - buffer.append("try{\n}"); - for (PsiClassType ignored : exceptions) { - buffer.append("catch(Exception e){\n}"); - } - if (myGenerateFinally) { - buffer.append("finally{\n}"); - } - String text = buffer.toString(); - PsiTryStatement tryStatement = (PsiTryStatement)factory.createStatementFromText(text, null); - tryStatement = (PsiTryStatement)CodeStyleManager.getInstance(project).reformat(tryStatement); - - tryStatement = (PsiTryStatement)addAfter(tryStatement, container, statements); - - PsiCodeBlock tryBlock = tryStatement.getTryBlock(); - SurroundWithUtil.indentCommentIfNecessary(tryBlock, statements); - addRangeWithinContainer(tryBlock, container, statements, true); - - PsiCatchSection[] catchSections = tryStatement.getCatchSections(); - - for (int i = 0; i < exceptions.size(); i++) { - PsiClassType exception = exceptions.get(i); - PsiClass target = exception.resolve(); - if (target instanceof PsiTypeParameter) { - PsiClassType[] extendsListTypes = target.getExtendsListTypes(); - if (extendsListTypes.length > 0) { - exception = extendsListTypes[0]; - } - } - String name = new VariableNameGenerator(tryBlock, VariableKind.PARAMETER).byName("e", "ex", "exc").byType(exception).generate(false); - PsiCatchSection catchSection = factory.createCatchSection(exception, name, tryBlock); - catchSection = (PsiCatchSection)catchSections[i].replace(catchSection); - codeStyleManager.shortenClassReferences(catchSection); - } - - container.deleteChildRange(statements[0], statements[statements.length - 1]); - - PsiCodeBlock firstCatch = tryStatement.getCatchBlocks()[0]; - return SurroundWithUtil.getRangeToSelect(firstCatch); + return exceptions; } } \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java index c4ca01c28452..49752c90e41e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java +++ b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java @@ -7,6 +7,8 @@ import com.intellij.diagnostic.CoreAttachmentFactory; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ClassConditionKey; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; @@ -216,14 +218,17 @@ public final class PsiTypeLookupItem extends LookupItem implements Typed int bracketsCount, boolean diamond, InsertHandler importFixer) { - if (type instanceof PsiClassType) { - PsiClassType.ClassResolveResult classResolveResult = ((PsiClassType)type).resolveGenerics(); + if (type instanceof PsiClassType classType) { + PsiClassType.ClassResolveResult classResolveResult = classType.resolveGenerics(); final PsiClass psiClass = classResolveResult.getElement(); if (psiClass != null) { String name = psiClass.getName(); if (name != null) { - PsiClass resolved = JavaPsiFacade.getInstance(psiClass.getProject()).getResolveHelper().resolveReferencedClass(name, context); + Project project = psiClass.getProject(); + DumbService service = DumbService.getInstance(project); + PsiResolveHelper helper = JavaPsiFacade.getInstance(project).getResolveHelper(); + PsiClass resolved = service.computeWithAlternativeResolveEnabled(() -> helper.resolveReferencedClass(name, context)); String[] allStrings; if (!psiClass.getManager().areElementsEquivalent(resolved, psiClass)) { // inner class name should be shown qualified if it's not accessible by single name diff --git a/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java b/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java index 196ddec79f58..e0dbb5518e10 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/macro/SuggestVariableNameMacro.java @@ -5,6 +5,8 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInsight.lookup.LookupFocusDegree; import com.intellij.codeInsight.template.*; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -54,11 +56,13 @@ public final class SuggestVariableNameMacro extends Macro { } private static String[] getNames (final ExpressionContext context) { - String[] names = ExpressionUtil.getNames(context); + Project project = context.getProject(); + DumbService dumbService = DumbService.getInstance(project); + String[] names = dumbService.computeWithAlternativeResolveEnabled(() -> ExpressionUtil.getNames(context)); if (names == null || names.length == 0) return names; - PsiFile file = PsiDocumentManager.getInstance(context.getProject()).getPsiFile(context.getEditor().getDocument()); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); PsiElement e = file.findElementAt(context.getStartOffset()); - PsiVariable[] vars = MacroUtil.getVariablesVisibleAt(e, ""); + PsiVariable[] vars = dumbService.computeWithAlternativeResolveEnabled(() -> MacroUtil.getVariablesVisibleAt(e, "")); LinkedList namesList = new LinkedList<>(Arrays.asList(names)); for (PsiVariable var : vars) { if (e.equals(var.getNameIdentifier())) continue; diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ArgumentPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ArgumentPostfixTemplate.java index c653ea4e526d..1f317c5c7e22 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ArgumentPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ArgumentPostfixTemplate.java @@ -4,13 +4,14 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.template.Template; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import java.util.Collections; -public class ArgumentPostfixTemplate extends JavaEditablePostfixTemplate { +public class ArgumentPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public ArgumentPostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { super("arg", "$CALL$($EXPR$$END$)", diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/AssertStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/AssertStatementPostfixTemplate.java index 69361fdf9b0a..3270b5e378a3 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/AssertStatementPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/AssertStatementPostfixTemplate.java @@ -3,12 +3,13 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import org.jetbrains.annotations.NotNull; import java.util.Collections; -public class AssertStatementPostfixTemplate extends JavaEditablePostfixTemplate { +public class AssertStatementPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public AssertStatementPostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { super("assert", "assert $EXPR$;$END$", "assert expr", Collections.singleton(new JavaPostfixTemplateExpressionCondition.JavaPostfixTemplateBooleanExpressionCondition()), diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/CastExpressionPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/CastExpressionPostfixTemplate.java index 87e34fe1a061..718d74c22a43 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/CastExpressionPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/CastExpressionPostfixTemplate.java @@ -17,13 +17,14 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.generation.surroundWith.JavaWithCastSurrounder; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.DumbAware; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.IS_NON_VOID; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorAllExpressionsWithCurrentOffset; -public class CastExpressionPostfixTemplate extends PostfixTemplateWithExpressionSelector { +public class CastExpressionPostfixTemplate extends PostfixTemplateWithExpressionSelector implements DumbAware { public CastExpressionPostfixTemplate() { super("cast", "((SomeType) expr)", selectorAllExpressionsWithCurrentOffset(IS_NON_VOID)); } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/CastVarPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/CastVarPostfixTemplate.java index 891442125302..1e0b1d6a8064 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/CastVarPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/CastVarPostfixTemplate.java @@ -11,6 +11,8 @@ import com.intellij.codeInsight.template.Template; import com.intellij.codeInsight.template.impl.ConstantNode; import com.intellij.codeInsight.template.impl.MacroCallNode; import com.intellij.codeInsight.template.macro.SuggestVariableNameMacro; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.DumbService; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiFile; @@ -27,7 +29,7 @@ import java.util.Set; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.IS_NON_VOID; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorTopmost; -public class CastVarPostfixTemplate extends StringBasedPostfixTemplate { +public class CastVarPostfixTemplate extends StringBasedPostfixTemplate implements DumbAware { private static final String TYPE_VAR = "typeVar"; private static final @NonNls String VAR_NAME = "varName"; @@ -60,14 +62,21 @@ public class CastVarPostfixTemplate extends StringBasedPostfixTemplate { } private static void fill(@NotNull Template template, PsiType @NotNull [] suggestedTypes, @NotNull PsiElement context) { - Set itemSet = new LinkedHashSet<>(); - for (PsiType type : suggestedTypes) { - itemSet.add(PsiTypeLookupItem.createLookupItem(type, null)); - } + Set itemSet = + DumbService.getInstance(context.getProject()).computeWithAlternativeResolveEnabled(() -> createLookupItems(suggestedTypes)); final Result result = suggestedTypes.length > 0 ? new PsiTypeResult(suggestedTypes[0], context.getProject()) : null; Expression expr = new ConstantNode(result).withLookupItems(itemSet.size() > 1 ? itemSet : Collections.emptyList()); template.addVariable(TYPE_VAR, expr, expr, true); } + + @NotNull + private static Set createLookupItems(PsiType @NotNull [] suggestedTypes) { + Set itemSet = new LinkedHashSet<>(); + for (PsiType type : suggestedTypes) { + itemSet.add(PsiTypeLookupItem.createLookupItem(type, null)); + } + return itemSet; + } } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ElseStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ElseStatementPostfixTemplate.java index 7e41c2e5b1cb..df7c1b8c32dc 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ElseStatementPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ElseStatementPostfixTemplate.java @@ -17,13 +17,14 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.generation.surroundWith.JavaWithIfExpressionSurrounder; import com.intellij.lang.surroundWith.Surrounder; +import com.intellij.openapi.project.DumbAware; import org.jetbrains.annotations.NotNull; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.IS_BOOLEAN; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.JAVA_PSI_INFO; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorTopmost; -public class ElseStatementPostfixTemplate extends ElseExpressionPostfixTemplateBase { +public class ElseStatementPostfixTemplate extends ElseExpressionPostfixTemplateBase implements DumbAware { public ElseStatementPostfixTemplate() { super(JAVA_PSI_INFO, selectorTopmost(IS_BOOLEAN)); } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForIndexedPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForIndexedPostfixTemplate.java index 9e4e7ec3c8d0..7cbe72efe048 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForIndexedPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForIndexedPostfixTemplate.java @@ -7,6 +7,7 @@ import com.intellij.codeInsight.template.impl.TextExpression; import com.intellij.codeInsight.template.macro.SuggestVariableNameMacro; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.CommonClassNames; import com.intellij.psi.PsiElement; @@ -18,7 +19,7 @@ import org.jetbrains.annotations.Nullable; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.*; -public abstract class ForIndexedPostfixTemplate extends JavaEditablePostfixTemplate { +public abstract class ForIndexedPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { protected ForIndexedPostfixTemplate(@NotNull String templateName, @NotNull String templateText, @NotNull String example, @NotNull JavaPostfixTemplateProvider provider) { super(templateName, templateText, example, diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForeachPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForeachPostfixTemplate.java index 34e3b5090d3b..4cd00a166826 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForeachPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ForeachPostfixTemplate.java @@ -9,6 +9,7 @@ import com.intellij.codeInsight.template.macro.IterableComponentTypeMacro; import com.intellij.codeInsight.template.macro.SuggestVariableNameMacro; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.CommonClassNames; import com.intellij.psi.PsiElement; @@ -16,7 +17,7 @@ import com.intellij.psi.codeStyle.JavaFileCodeStyleFacade; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; -public class ForeachPostfixTemplate extends JavaEditablePostfixTemplate { +public class ForeachPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public ForeachPostfixTemplate(@NotNull String templateName, @NotNull JavaPostfixTemplateProvider provider) { super(templateName, "for ($FINAL$$TYPE$ $NAME$ : $EXPR$) {\n $END$\n}", "for (T item : expr)", ContainerUtil.newHashSet(new JavaPostfixTemplateExpressionCondition.JavaPostfixTemplateArrayExpressionCondition(), diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/FormatPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/FormatPostfixTemplate.java index e9282a7c5ef9..d4e6a7e44e4a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/FormatPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/FormatPostfixTemplate.java @@ -3,13 +3,14 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.CommonClassNames; import org.jetbrains.annotations.NotNull; import java.util.Collections; -public class FormatPostfixTemplate extends JavaEditablePostfixTemplate { +public class FormatPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public FormatPostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { super("format", "String.format($EXPR$, $END$)", diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IfStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IfStatementPostfixTemplate.java index 8eb0e1d6b676..25513e639dc0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IfStatementPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IfStatementPostfixTemplate.java @@ -17,17 +17,15 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.generation.surroundWith.JavaWithIfExpressionSurrounder; import com.intellij.lang.surroundWith.Surrounder; +import com.intellij.openapi.project.DumbAware; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiExpression; -import com.intellij.psi.PsiParenthesizedExpression; import com.intellij.util.CommonJavaRefactoringUtil; import org.jetbrains.annotations.NotNull; -import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.IS_BOOLEAN; -import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.JAVA_PSI_INFO; -import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorTopmost; +import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.*; -public class IfStatementPostfixTemplate extends IfPostfixTemplateBase { +public class IfStatementPostfixTemplate extends IfPostfixTemplateBase implements DumbAware { public IfStatementPostfixTemplate() { super(JAVA_PSI_INFO, selectorTopmost(IS_BOOLEAN)); } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/InstanceofExpressionPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/InstanceofExpressionPostfixTemplate.java index ba3cba02e820..6263fcec9854 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/InstanceofExpressionPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/InstanceofExpressionPostfixTemplate.java @@ -25,9 +25,11 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.introduceField.ElementToWorkOn; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -36,7 +38,7 @@ import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; -public class InstanceofExpressionPostfixTemplate extends PostfixTemplate { +public class InstanceofExpressionPostfixTemplate extends PostfixTemplate implements DumbAware { public InstanceofExpressionPostfixTemplate() { this("instanceof"); @@ -48,7 +50,7 @@ public class InstanceofExpressionPostfixTemplate extends PostfixTemplate { @Override public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) { - if (context instanceof PsiJavaToken && ((PsiJavaToken)context).getTokenType().equals(JavaTokenType.STRING_LITERAL)) { + if (PsiUtil.isJavaToken(context, JavaTokenType.STRING_LITERAL)) { // Do not suggest inside String literals as it could be confusing if literal is interpreted as the reference return false; } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceFieldPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceFieldPostfixTemplate.java index 808dafc2d3b7..d26930bf40eb 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceFieldPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceFieldPostfixTemplate.java @@ -4,6 +4,7 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.lang.LanguageRefactoringSupport; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.DumbAware; import com.intellij.psi.PsiElement; import com.intellij.refactoring.introduceField.JavaIntroduceFieldHandlerBase; import org.jetbrains.annotations.NotNull; @@ -11,7 +12,7 @@ import org.jetbrains.annotations.NotNull; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.IS_NON_VOID; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorAllExpressionsWithCurrentOffset; -public class IntroduceFieldPostfixTemplate extends PostfixTemplateWithExpressionSelector { +public class IntroduceFieldPostfixTemplate extends PostfixTemplateWithExpressionSelector implements DumbAware { public IntroduceFieldPostfixTemplate() { super("field", "myField = expr", selectorAllExpressionsWithCurrentOffset(IS_NON_VOID)); } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceVariablePostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceVariablePostfixTemplate.java index 44449b5e04f8..1f6c8eaaf171 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceVariablePostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IntroduceVariablePostfixTemplate.java @@ -6,6 +6,7 @@ import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; +import com.intellij.openapi.project.DumbAware; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiExpression; import com.intellij.refactoring.introduceVariable.JavaIntroduceVariableHandlerBase; @@ -15,7 +16,7 @@ import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplate import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorAllExpressionsWithCurrentOffset; // todo: support for int[].var (parses as .class access!) -public class IntroduceVariablePostfixTemplate extends PostfixTemplateWithExpressionSelector { +public class IntroduceVariablePostfixTemplate extends PostfixTemplateWithExpressionSelector implements DumbAware { public IntroduceVariablePostfixTemplate() { super("var", "T name = expr", selectorAllExpressionsWithCurrentOffset(IS_NON_VOID)); } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IsNullCheckPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IsNullCheckPostfixTemplate.java index 200514184033..032bf75bbe60 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IsNullCheckPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/IsNullCheckPostfixTemplate.java @@ -17,13 +17,14 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.generation.surroundWith.JavaWithIfExpressionSurrounder; import com.intellij.lang.surroundWith.Surrounder; +import com.intellij.openapi.project.DumbAware; import org.jetbrains.annotations.NotNull; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.IS_NOT_PRIMITIVE; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.JAVA_PSI_INFO; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorTopmost; -public class IsNullCheckPostfixTemplate extends SurroundPostfixTemplateBase { +public class IsNullCheckPostfixTemplate extends SurroundPostfixTemplateBase implements DumbAware { public IsNullCheckPostfixTemplate() { super("null", "if (expr == null)", JAVA_PSI_INFO, selectorTopmost(IS_NOT_PRIMITIVE)); } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/LambdaPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/LambdaPostfixTemplate.java index f0d693b99d7f..ede809b01e36 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/LambdaPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/LambdaPostfixTemplate.java @@ -2,12 +2,13 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import org.jetbrains.annotations.NotNull; import java.util.Collections; -public class LambdaPostfixTemplate extends JavaEditablePostfixTemplate { +public class LambdaPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public LambdaPostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { super("lambda", "() -> $EXPR$", "() -> expr", Collections.emptySet(), LanguageLevel.JDK_1_8, true, provider); diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NewExpressionPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NewExpressionPostfixTemplate.java index c5643181c51e..65f671d010cc 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NewExpressionPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NewExpressionPostfixTemplate.java @@ -7,6 +7,8 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.TextRange; @@ -17,7 +19,7 @@ import org.jetbrains.annotations.Nullable; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorAllExpressionsWithCurrentOffset; -public class NewExpressionPostfixTemplate extends StringBasedPostfixTemplate { +public class NewExpressionPostfixTemplate extends StringBasedPostfixTemplate implements DumbAware { private static final Condition CONSTRUCTOR = expression -> { PsiReferenceExpression ref = expression instanceof PsiMethodCallExpression call ? call.getMethodExpression() : expression instanceof PsiReferenceExpression r ? r : @@ -26,19 +28,21 @@ public class NewExpressionPostfixTemplate extends StringBasedPostfixTemplate { PsiExpression qualifier = ref.getQualifierExpression(); - JavaResolveResult result = ref.advancedResolve(true); - PsiElement element = result.getElement(); + return DumbService.getInstance(ref.getProject()).computeWithAlternativeResolveEnabled(() -> { + JavaResolveResult result = ref.advancedResolve(true); + PsiElement element = result.getElement(); - //todo implement proper support for Foo, Foo.new Bar() - if (qualifier != null && (!(qualifier instanceof PsiReferenceExpression) || element == null)) return false; + //todo implement proper support for Foo, Foo.new Bar() + if (qualifier != null && (!(qualifier instanceof PsiReferenceExpression) || element == null)) return false; - if (element == null) return true; - if (!(element instanceof PsiClass cls)) return false; - PsiMethod[] constructors = cls.getConstructors(); - if (constructors.length == 0) return true; - PsiResolveHelper helper = JavaPsiFacade.getInstance(element.getProject()).getResolveHelper(); - // Check whether there's at least one accessible constructor - return !ContainerUtil.and(constructors, m -> !helper.isAccessible(m, ref, cls)); + if (element == null) return true; + if (!(element instanceof PsiClass cls)) return false; + PsiMethod[] constructors = cls.getConstructors(); + if (constructors.length == 0) return true; + PsiResolveHelper helper = JavaPsiFacade.getInstance(element.getProject()).getResolveHelper(); + // Check whether there's at least one accessible constructor + return !ContainerUtil.and(constructors, m -> !helper.isAccessible(m, ref, cls)); + }); }; protected NewExpressionPostfixTemplate() { diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotExpressionPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotExpressionPostfixTemplate.java index dbb71ce764df..f704ac5c5aa7 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotExpressionPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotExpressionPostfixTemplate.java @@ -15,11 +15,13 @@ */ package com.intellij.codeInsight.template.postfix.templates; +import com.intellij.openapi.project.DumbAware; + import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.IS_BOOLEAN; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.JAVA_PSI_INFO; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorAllExpressionsWithCurrentOffset; -public class NotExpressionPostfixTemplate extends NotPostfixTemplate { +public class NotExpressionPostfixTemplate extends NotPostfixTemplate implements DumbAware { public NotExpressionPostfixTemplate() { super(JAVA_PSI_INFO, selectorAllExpressionsWithCurrentOffset(IS_BOOLEAN)); diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotNullCheckPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotNullCheckPostfixTemplate.java index 487559c43ca5..77ba411ae362 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotNullCheckPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/NotNullCheckPostfixTemplate.java @@ -17,13 +17,14 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.generation.surroundWith.JavaWithIfExpressionSurrounder; import com.intellij.lang.surroundWith.Surrounder; +import com.intellij.openapi.project.DumbAware; import org.jetbrains.annotations.NotNull; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.IS_NOT_PRIMITIVE; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.JAVA_PSI_INFO; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorTopmost; -public class NotNullCheckPostfixTemplate extends SurroundPostfixTemplateBase { +public class NotNullCheckPostfixTemplate extends SurroundPostfixTemplateBase implements DumbAware { public NotNullCheckPostfixTemplate() { this("notnull"); diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ObjectsRequireNonNullPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ObjectsRequireNonNullPostfixTemplate.java index 69ea3dd64b43..69387d4fbc55 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ObjectsRequireNonNullPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ObjectsRequireNonNullPostfixTemplate.java @@ -3,12 +3,13 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import org.jetbrains.annotations.NotNull; import java.util.Collections; -public class ObjectsRequireNonNullPostfixTemplate extends JavaEditablePostfixTemplate { +public class ObjectsRequireNonNullPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public ObjectsRequireNonNullPostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { super("reqnonnull", "java.util.Objects.requireNonNull($EXPR$)", diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/OptionalPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/OptionalPostfixTemplate.java index d10a192d1685..f5355edff928 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/OptionalPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/OptionalPostfixTemplate.java @@ -7,13 +7,14 @@ import com.intellij.codeInsight.template.impl.TextExpression; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; import com.intellij.codeInspection.dataFlow.NullabilityUtil; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; import java.util.Collections; -public class OptionalPostfixTemplate extends JavaEditablePostfixTemplate { +public class OptionalPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public OptionalPostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { super("opt", "java.util.$OPTIONAL_CLASS$.$OPTIONAL_METHOD$($EXPR$)", diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ParenthesizedExpressionPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ParenthesizedExpressionPostfixTemplate.java index 7069afd17b46..fbffa154bf43 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ParenthesizedExpressionPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ParenthesizedExpressionPostfixTemplate.java @@ -15,11 +15,13 @@ */ package com.intellij.codeInsight.template.postfix.templates; +import com.intellij.openapi.project.DumbAware; + import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.IS_NON_VOID; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.JAVA_PSI_INFO; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorAllExpressionsWithCurrentOffset; -public class ParenthesizedExpressionPostfixTemplate extends ParenthesizedPostfixTemplate { +public class ParenthesizedExpressionPostfixTemplate extends ParenthesizedPostfixTemplate implements DumbAware { public ParenthesizedExpressionPostfixTemplate() { super(JAVA_PSI_INFO, selectorAllExpressionsWithCurrentOffset(IS_NON_VOID)); } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ReturnStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ReturnStatementPostfixTemplate.java index 9bf86516a97b..19f08014b2ef 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ReturnStatementPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ReturnStatementPostfixTemplate.java @@ -3,12 +3,13 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import org.jetbrains.annotations.NotNull; import java.util.Collections; -public class ReturnStatementPostfixTemplate extends JavaEditablePostfixTemplate { +public class ReturnStatementPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public ReturnStatementPostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { super("return", "return $EXPR$;$END$", diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SerrPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SerrPostfixTemplate.java index 2421de692d4d..18dcf302112e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SerrPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SerrPostfixTemplate.java @@ -3,12 +3,13 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import org.jetbrains.annotations.NotNull; import java.util.Collections; -public class SerrPostfixTemplate extends JavaEditablePostfixTemplate { +public class SerrPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public SerrPostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { super("serr", "System.err.println($EXPR$);$END$", diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SoufPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SoufPostfixTemplate.java index 4bd7576ceb8e..3258c8422423 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SoufPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SoufPostfixTemplate.java @@ -3,12 +3,13 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import org.jetbrains.annotations.NotNull; import java.util.Collections; -public class SoufPostfixTemplate extends JavaEditablePostfixTemplate { +public class SoufPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public SoufPostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { super("souf", "System.out.printf(\"$END$\", $EXPR$);", diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SoutPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SoutPostfixTemplate.java index 6a0c2c6624d3..56c291d90a9c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SoutPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SoutPostfixTemplate.java @@ -3,12 +3,13 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import org.jetbrains.annotations.NotNull; import java.util.Collections; -public class SoutPostfixTemplate extends JavaEditablePostfixTemplate { +public class SoutPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public SoutPostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { super("sout", "System.out.println($EXPR$);$END$", diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SoutvPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SoutvPostfixTemplate.java index 0538301c1113..909799e5a53d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SoutvPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SoutvPostfixTemplate.java @@ -4,13 +4,14 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.template.Template; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import java.util.Collections; -public class SoutvPostfixTemplate extends JavaEditablePostfixTemplate { +public class SoutvPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public SoutvPostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { super("soutv", "System.out.println(\"$EXPR_COPY$ = \" + $EXPR$);$END$", diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StreamPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StreamPostfixTemplate.java index d356610a5781..4ca50b80e944 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StreamPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/StreamPostfixTemplate.java @@ -16,6 +16,7 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.util.Condition; import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; @@ -23,7 +24,7 @@ import org.jetbrains.annotations.Nullable; import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.selectorAllExpressionsWithCurrentOffset; -public class StreamPostfixTemplate extends StringBasedPostfixTemplate { +public class StreamPostfixTemplate extends StringBasedPostfixTemplate implements DumbAware { private static final Condition IS_SUPPORTED_ARRAY = element -> { if (!(element instanceof PsiExpression)) return false; diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java index 93a1e898877d..3077c65c5006 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SwitchStatementPostfixTemplate.java @@ -20,10 +20,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; -import com.intellij.util.indexing.DumbModeAccessType; -import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -32,48 +29,30 @@ import static com.intellij.openapi.util.Conditions.and; public class SwitchStatementPostfixTemplate extends SurroundPostfixTemplateBase implements DumbAware { - private static final Condition SWITCH_TYPE = expression -> { - if (!(expression instanceof PsiExpression)) return false; + private static final Condition SWITCH_TYPE = e -> { + if (!(e instanceof PsiExpression expression)) return false; - final PsiType type = getType((PsiExpression)expression); + return DumbService.getInstance(expression.getProject()).computeWithAlternativeResolveEnabled(() -> { + final PsiType type = expression.getType(); - if (type == null) return false; - if (PsiTypes.intType().isAssignableFrom(type)) return true; - if (type instanceof PsiClassType) { - if (HighlightingFeature.PATTERNS_IN_SWITCH.isAvailable(expression)) return true; + if (type == null) return false; + if (PsiTypes.intType().isAssignableFrom(type)) return true; + if (type instanceof PsiClassType classType) { + if (HighlightingFeature.PATTERNS_IN_SWITCH.isAvailable(expression)) return true; - final PsiClass psiClass = getClassType(expression.getProject(), (PsiClassType)type); - if (psiClass != null && psiClass.isEnum()) return true; - } + final PsiClass psiClass = classType.resolve(); + if (psiClass != null && psiClass.isEnum()) return true; + } - if (type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { - PsiFile containingFile = expression.getContainingFile(); - if (containingFile instanceof PsiJavaFile) { - LanguageLevel level = ((PsiJavaFile)containingFile).getLanguageLevel(); + if (type.equalsToText(CommonClassNames.JAVA_LANG_STRING) && expression.getContainingFile() instanceof PsiJavaFile javaFile) { + LanguageLevel level = javaFile.getLanguageLevel(); if (level.isAtLeast(LanguageLevel.JDK_1_7)) return true; } - } - return false; + return false; + }); }; - @Contract(pure = true) - private static @Nullable PsiType getType(@NotNull PsiExpression expression) { - if (!DumbService.isDumb(expression.getProject())) { - return expression.getType(); - } - return DumbModeAccessType.RELIABLE_DATA_ONLY.ignoreDumbMode(expression::getType); - } - - @Contract(pure = true) - private static @Nullable PsiClass getClassType(@NotNull Project project, @NotNull PsiClassType type) { - if (!DumbService.isDumb(project)) { - return type.resolve(); - } - - return DumbModeAccessType.RELIABLE_DATA_ONLY.ignoreDumbMode(type::resolve); - } - public SwitchStatementPostfixTemplate() { super("switch", "switch(expr)", JavaPostfixTemplatesUtils.JAVA_PSI_INFO, selectorTopmost(SWITCH_TYPE)); } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SynchronizedStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SynchronizedStatementPostfixTemplate.java index bf2331cf5377..b9a3f0e69f92 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SynchronizedStatementPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/SynchronizedStatementPostfixTemplate.java @@ -3,12 +3,13 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import org.jetbrains.annotations.NotNull; import java.util.Collections; -public class SynchronizedStatementPostfixTemplate extends JavaEditablePostfixTemplate { +public class SynchronizedStatementPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public SynchronizedStatementPostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { super("synchronized", "synchronized ($EXPR$) {\n$END$\n}", diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ThrowExceptionPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ThrowExceptionPostfixTemplate.java index 88ed30a1fe26..8e97fa66db7f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ThrowExceptionPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/ThrowExceptionPostfixTemplate.java @@ -3,13 +3,14 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.CommonClassNames; import org.jetbrains.annotations.NotNull; import java.util.Collections; -public class ThrowExceptionPostfixTemplate extends JavaEditablePostfixTemplate { +public class ThrowExceptionPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public ThrowExceptionPostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { super("throw", "throw $EXPR$;$END$", diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryStatementPostfixTemplate.java index 73fccfcbd438..db4305813272 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryStatementPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryStatementPostfixTemplate.java @@ -4,6 +4,8 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.generation.surroundWith.JavaWithTryCatchSurrounder; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; @@ -11,7 +13,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; -public class TryStatementPostfixTemplate extends PostfixTemplate { +public class TryStatementPostfixTemplate extends PostfixTemplate implements DumbAware { protected TryStatementPostfixTemplate() { super("try", "try { exp } catch(Exception e)"); @@ -25,9 +27,9 @@ public class TryStatementPostfixTemplate extends PostfixTemplate { if (statementParent instanceof PsiDeclarationStatement) return true; - if (statementParent instanceof PsiExpressionStatement) { - PsiExpression expression = ((PsiExpressionStatement)statementParent).getExpression(); - return null != expression.getType(); + if (statementParent instanceof PsiExpressionStatement statement) { + PsiExpression expression = statement.getExpression(); + return DumbService.getInstance(context.getProject()).computeWithAlternativeResolveEnabled(expression::getType) != null; } return false; diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryWithResourcesPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryWithResourcesPostfixTemplate.java index cde59e61c789..1a610af0f111 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryWithResourcesPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/TryWithResourcesPostfixTemplate.java @@ -11,6 +11,8 @@ import com.intellij.codeInsight.template.macro.SuggestVariableNameMacro; import com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.search.ProjectScope; @@ -21,7 +23,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Collection; -public class TryWithResourcesPostfixTemplate extends PostfixTemplate { +public class TryWithResourcesPostfixTemplate extends PostfixTemplate implements DumbAware { protected TryWithResourcesPostfixTemplate() { super("twr", "try(Type f = new Type()) catch (Exception e)"); } @@ -34,15 +36,14 @@ public class TryWithResourcesPostfixTemplate extends PostfixTemplate { if (initializer == null) return false; - final PsiType type = initializer.getType(); - if (!(type instanceof PsiClassType)) return false; - final PsiClass aClass = ((PsiClassType)type).resolve(); - Project project = element.getProject(); - final JavaPsiFacade facade = JavaPsiFacade.getInstance(project); - final PsiClass autoCloseable = facade.findClass(CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE, ProjectScope.getLibrariesScope(project)); - if (!InheritanceUtil.isInheritorOrSelf(aClass, autoCloseable, true)) return false; - - return true; + return DumbService.getInstance(initializer.getProject()).computeWithAlternativeResolveEnabled(() -> { + if (!(initializer.getType() instanceof PsiClassType classType)) return false; + final PsiClass aClass = classType.resolve(); + Project project = element.getProject(); + final JavaPsiFacade facade = JavaPsiFacade.getInstance(project); + final PsiClass autoCloseable = facade.findClass(CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE, ProjectScope.getLibrariesScope(project)); + return InheritanceUtil.isInheritorOrSelf(aClass, autoCloseable, true); + }); } @Override @@ -60,7 +61,9 @@ public class TryWithResourcesPostfixTemplate extends PostfixTemplate { template.addTextSegment("try ("); MacroCallNode name = new MacroCallNode(new SuggestVariableNameMacro()); - template.addVariable("type", new TypeExpression(project, new PsiType[]{expression.getType()}), false); + DumbService dumbService = DumbService.getInstance(project); + PsiType type = dumbService.computeWithAlternativeResolveEnabled(expression::getType); + template.addVariable("type", new TypeExpression(project, new PsiType[]{type}), false); template.addTextSegment(" "); template.addVariable("name", name, name, true); template.addTextSegment(" = "); @@ -69,7 +72,7 @@ public class TryWithResourcesPostfixTemplate extends PostfixTemplate { template.addEndVariable(); template.addTextSegment("\n}"); - Collection unhandled = getUnhandled(expression); + Collection unhandled = dumbService.computeWithAlternativeResolveEnabled(() -> getUnhandled(expression)); for (PsiClassType exception : unhandled) { MacroCallNode variable = new MacroCallNode(new SuggestVariableNameMacro()); template.addTextSegment("catch("); diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/WhileStatementPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/WhileStatementPostfixTemplate.java index 466b0fe3ddca..37c6c8ff5e61 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/WhileStatementPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/WhileStatementPostfixTemplate.java @@ -3,12 +3,13 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; import com.intellij.pom.java.LanguageLevel; import org.jetbrains.annotations.NotNull; import java.util.Collections; -public class WhileStatementPostfixTemplate extends JavaEditablePostfixTemplate { +public class WhileStatementPostfixTemplate extends JavaEditablePostfixTemplate implements DumbAware { public WhileStatementPostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { super("while", "while ($EXPR$) {\n$END$\n}", "while (expr) {}", Collections.singleton(new JavaPostfixTemplateExpressionCondition.JavaPostfixTemplateBooleanExpressionCondition()), diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/editable/JavaEditablePostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/editable/JavaEditablePostfixTemplate.java index af957cf1f598..fbaa354ea3fc 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/editable/JavaEditablePostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/editable/JavaEditablePostfixTemplate.java @@ -69,7 +69,8 @@ public class JavaEditablePostfixTemplate @Override protected List getExpressions(@NotNull PsiElement context, @NotNull Document document, int offset) { - if (DumbService.getInstance(context.getProject()).isDumb()) return Collections.emptyList(); + DumbService dumbService = DumbService.getInstance(context.getProject()); + if (dumbService.isDumb() && !DumbService.isDumbAware(this)) return Collections.emptyList(); if (!PsiUtil.getLanguageLevel(context).isAtLeast(myMinimumLanguageLevel)) { return Collections.emptyList(); } @@ -83,8 +84,9 @@ public class JavaEditablePostfixTemplate } - return ContainerUtil.filter(expressions, Conditions.and(e -> PSI_ERROR_FILTER.value(e) - && e instanceof PsiExpression && e.getTextRange().getEndOffset() == offset, getExpressionCompositeCondition())); + return dumbService.computeWithAlternativeResolveEnabled(() -> ContainerUtil.filter(expressions, Conditions.and( + e -> PSI_ERROR_FILTER.value(e) && e instanceof PsiExpression && e.getTextRange().getEndOffset() == offset, + getExpressionCompositeCondition()))); } @NotNull diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/JavaPostfixTemplatesUtils.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/JavaPostfixTemplatesUtils.java index 44d998495b85..b81582479879 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/JavaPostfixTemplatesUtils.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/util/JavaPostfixTemplatesUtils.java @@ -6,6 +6,7 @@ import com.intellij.codeInsight.template.postfix.templates.PostfixTemplateExpres import com.intellij.codeInsight.template.postfix.templates.PostfixTemplatePsiInfo; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; @@ -91,8 +92,6 @@ public final class JavaPostfixTemplatesUtils { @NotNull @Override public List getExpressions(@NotNull PsiElement context, @NotNull Document document, int offset) { - if (DumbService.getInstance(context.getProject()).isDumb()) return Collections.emptyList(); - List expressions = super.getExpressions(context, document, offset); if (!expressions.isEmpty()) return expressions; @@ -120,30 +119,33 @@ public final class JavaPostfixTemplatesUtils { @NotNull @Override public PsiExpression getNegatedExpression(@NotNull PsiElement element) { - assert element instanceof PsiExpression; - String negatedExpressionText = BoolUtils.getNegatedExpressionText((PsiExpression)element); - return JavaPsiFacade.getElementFactory(element.getProject()).createExpressionFromText(negatedExpressionText, element); + Project project = element.getProject(); + String negatedExpressionText = DumbService.getInstance(project) + .computeWithAlternativeResolveEnabled(() -> BoolUtils.getNegatedExpressionText((PsiExpression)element)); + return JavaPsiFacade.getElementFactory(project).createExpressionFromText(negatedExpressionText, element); } }; - public static final Condition IS_NUMBER = - element -> element instanceof PsiExpression && isNumber(((PsiExpression)element).getType()); + @Nullable + private static PsiType getType(PsiExpression expression) { + return DumbService.getInstance(expression.getProject()).computeWithAlternativeResolveEnabled(expression::getType); + } public static final Condition IS_BOOLEAN = - element -> element instanceof PsiExpression && isBoolean(((PsiExpression)element).getType()); + element -> element instanceof PsiExpression expression && isBoolean(getType(expression)); /** * @deprecated use {@link #isThrowable(PsiType)} */ @Deprecated(forRemoval = true) public static final Condition IS_THROWABLE = - element -> element instanceof PsiExpression && isThrowable(((PsiExpression)element).getType()); + element -> element instanceof PsiExpression expression && isThrowable(getType(expression)); public static final Condition IS_NON_VOID = - element -> element instanceof PsiExpression && isNonVoid(((PsiExpression)element).getType()); + element -> element instanceof PsiExpression expression && isNonVoid(getType(expression)); public static final Condition IS_NOT_PRIMITIVE = - element -> element instanceof PsiExpression && isNotPrimitiveTypeExpression((PsiExpression)element); + element -> element instanceof PsiExpression expression && isNotPrimitiveTypeExpression(expression); /** * @deprecated use {@link #isIterable(PsiType)} / {@link #isArray(PsiType)} @@ -152,7 +154,7 @@ public final class JavaPostfixTemplatesUtils { public static final Condition IS_ITERABLE_OR_ARRAY = element -> { if (!(element instanceof PsiExpression)) return false; - PsiType type = ((PsiExpression)element).getType(); + PsiType type = getType(((PsiExpression)element)); return isArray(type) || isIterable(type); }; @@ -161,7 +163,7 @@ public final class JavaPostfixTemplatesUtils { if (expression == null) { return false; } - PsiType type = expression.getType(); + PsiType type = getType(expression); return type != null && !(type instanceof PsiPrimitiveType); } @@ -182,7 +184,7 @@ public final class JavaPostfixTemplatesUtils { @Contract("null -> false") public static boolean isBoolean(@Nullable PsiType type) { - return type != null && (PsiTypes.booleanType().equals(type) || PsiTypes.booleanType().equals(PsiPrimitiveType.getUnboxedType(type))); + return type != null && (PsiTypes.booleanType().equals(type) || type.equalsToText(CommonClassNames.JAVA_LANG_BOOLEAN)); } @Contract("null -> false") @@ -199,8 +201,10 @@ public final class JavaPostfixTemplatesUtils { return true; } - PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(type); - return PsiTypes.intType().equals(unboxedType) || PsiTypes.byteType().equals(unboxedType) || PsiTypes.longType().equals(unboxedType); + String canonicalText = type.getCanonicalText(); + return CommonClassNames.JAVA_LANG_INTEGER.equals(canonicalText) || + CommonClassNames.JAVA_LANG_LONG.equals(canonicalText) || + CommonClassNames.JAVA_LANG_BYTE.equals(canonicalText); } @NotNull diff --git a/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java b/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java index 3f8798a7a614..9945bc0c4f8f 100644 --- a/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java @@ -9,6 +9,7 @@ import com.intellij.modcommand.ModPsiUpdater; import com.intellij.modcommand.PsiUpdateModCommandQuickFix; import com.intellij.openapi.diagnostic.Attachment; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.NlsSafe; import com.intellij.openapi.util.text.StringUtil; @@ -331,9 +332,9 @@ public final class LambdaCanBeMethodReferenceInspection extends AbstractBaseJava expression instanceof PsiTypeCastExpression) { return false; } - if (expression instanceof PsiReferenceExpression && !(expression.getParent() instanceof PsiCallExpression)) { - PsiElement element = ((PsiReferenceExpression)expression).resolve(); - if (element instanceof PsiField && !((PsiField)element).hasModifierProperty(PsiModifier.FINAL)) { + if (expression instanceof PsiReferenceExpression ref && !(expression.getParent() instanceof PsiCallExpression)) { + PsiElement element = ref.resolve(); + if (element instanceof PsiField field && !field.hasModifierProperty(PsiModifier.FINAL)) { return false; } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeCopyHandler.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeCopyHandler.java index 6adcab9a11bf..786eddbb677d 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeCopyHandler.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeCopyHandler.java @@ -4,6 +4,8 @@ package com.intellij.psi.impl.source.tree; import com.intellij.lang.ASTNode; import com.intellij.lang.Language; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; @@ -35,13 +37,14 @@ public final class JavaTreeCopyHandler implements TreeCopyHandler { elementType == JavaElementType.REFERENCE_EXPRESSION || elementType == JavaElementType.METHOD_REF_EXPRESSION) { PsiJavaCodeReferenceElement ref = SourceTreeToPsiMap.treeToPsiNotNull(element); + Project project = ref.getProject(); PsiClass refClass = element.getCopyableUserData(JavaTreeGenerator.REFERENCED_CLASS_KEY); if (refClass != null) { element.putCopyableUserData(JavaTreeGenerator.REFERENCED_CLASS_KEY, null); PsiManager manager = refClass.getManager(); - JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(refClass.getProject()); - PsiElement refElement = ref.resolve(); + JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project); + PsiElement refElement = DumbService.getInstance(project).computeWithAlternativeResolveEnabled(ref::resolve); try { if (refClass != refElement && !manager.areElementsEquivalent(refClass, refElement)) { if (((CompositeElement)element).findChildByRole(ChildRole.QUALIFIER) == null) { @@ -64,7 +67,7 @@ public final class JavaTreeCopyHandler implements TreeCopyHandler { if (refMember != null) { LOG.assertTrue(ref instanceof PsiReferenceExpression); element.putCopyableUserData(JavaTreeGenerator.REFERENCED_MEMBER_KEY, null); - PsiElement refElement = ref.resolve(); + PsiElement refElement = DumbService.getInstance(project).computeWithAlternativeResolveEnabled(ref::resolve); if (refMember != refElement && !refMember.getManager().areElementsEquivalent(refMember, refElement)) { PsiClass containingClass = refMember.getContainingClass(); if (containingClass != null) { @@ -190,7 +193,8 @@ public final class JavaTreeCopyHandler implements TreeCopyHandler { IElementType originalType = original.getElementType(); if (originalType == JavaElementType.REFERENCE_EXPRESSION) { PsiJavaCodeReferenceElement javaRefElement = SourceTreeToPsiMap.treeToPsiNotNull(original); - JavaResolveResult resolveResult = javaRefElement.advancedResolve(false); + JavaResolveResult resolveResult = DumbService.getInstance(javaRefElement.getProject()).computeWithAlternativeResolveEnabled( + () -> javaRefElement.advancedResolve(false)); PsiElement target = resolveResult.getElement(); if (target instanceof PsiClass && (original.getTreeParent().getElementType() == JavaElementType.REFERENCE_EXPRESSION || @@ -208,7 +212,8 @@ public final class JavaTreeCopyHandler implements TreeCopyHandler { kind = ((PsiJavaCodeReferenceElementImpl)original).getKindEnum(((PsiJavaCodeReferenceElementImpl)original).getContainingFile()); switch (kind) { case CLASS_NAME_KIND, CLASS_OR_PACKAGE_NAME_KIND, CLASS_IN_QUALIFIED_NEW_KIND -> { - PsiElement target = SourceTreeToPsiMap.treeToPsiNotNull(original).resolve(); + PsiJavaCodeReferenceElement element = SourceTreeToPsiMap.treeToPsiNotNull(original); + PsiElement target = DumbService.getInstance(element.getProject()).computeWithAlternativeResolveEnabled(element::resolve); if (target instanceof PsiClass) { ref.putCopyableUserData(JavaTreeGenerator.REFERENCED_CLASS_KEY, (PsiClass)target); } diff --git a/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java b/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java index 7b8f0f914961..905fe21136af 100644 --- a/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java @@ -10,6 +10,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.psi.*; @@ -22,6 +23,7 @@ import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.CommonJavaRefactoringUtil; import com.intellij.util.concurrency.NonUrgentExecutor; +import com.intellij.util.indexing.DumbModeAccessType; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -85,10 +87,10 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { Ref mainTypes = new Ref<>(); Ref allTypes = new Ref<>(); - Runnable calculateTypes = () -> ReadAction.run(() -> { + Runnable calculateTypes = () -> ReadAction.run(() -> DumbService.getInstance(project).runWithAlternativeResolveEnabled(() -> { mainTypes.set(getTypesForMain()); allTypes.set(getTypesForAll(true)); - }); + })); if (ApplicationManager.getApplication().isDispatchThread()) { ProgressManager.getInstance().runProcessWithProgressSynchronously(calculateTypes, JavaBundle.message("progress.title.calculate.applicable.types"), false, project); } @@ -365,9 +367,9 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { public static void typeSelected(@NotNull final PsiType type, @Nullable final PsiType defaultType) { if (defaultType == null) return; - ReadAction.nonBlocking(() -> { + ReadAction.nonBlocking(() -> DumbModeAccessType.RELIABLE_DATA_ONLY.ignoreDumbMode(() -> { return type.isValid() && defaultType.isValid() ? new StatisticsInfo(getStatsKey(defaultType), serialize(type)) : null; - }).finishOnUiThread(ModalityState.nonModal(), stat -> { + })).finishOnUiThread(ModalityState.nonModal(), stat -> { if (stat == null) return; StatisticsManager.getInstance().incUseCount(stat); }).submit(NonUrgentExecutor.getInstance()); diff --git a/java/java-impl/src/com/intellij/util/CommonJavaRefactoringUtil.java b/java/java-impl/src/com/intellij/util/CommonJavaRefactoringUtil.java index b4118b261b93..d388ec991658 100644 --- a/java/java-impl/src/com/intellij/util/CommonJavaRefactoringUtil.java +++ b/java/java-impl/src/com/intellij/util/CommonJavaRefactoringUtil.java @@ -11,6 +11,7 @@ import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.PackageIndex; import com.intellij.openapi.util.Condition; @@ -254,7 +255,8 @@ public final class CommonJavaRefactoringUtil { PsiExpression expression = PsiTreeUtil.getParentOfType(elementAtCaret, PsiExpression.class); while (expression != null) { if (!expressions.contains(expression) && !(expression instanceof PsiParenthesizedExpression) && !(expression instanceof PsiSuperExpression) && - (acceptVoid || !PsiTypes.voidType().equals(expression.getType()))) { + (acceptVoid || !PsiTypes.voidType().equals(DumbService.getInstance(file.getProject()) + .computeWithAlternativeResolveEnabled(expression::getType)))) { if (isExtractable(expression)) { expressions.add(expression); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java index 7200922d489c..95d42c1322c8 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java @@ -1,6 +1,7 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.psi.impl.smartPointers; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; @@ -27,7 +28,7 @@ public final class SmartTypePointerManagerImpl extends SmartTypePointerManager { @Override @NotNull public SmartTypePointer createSmartTypePointer(@NotNull PsiType type) { - final SmartTypePointer pointer = type.accept(new SmartTypeCreatingVisitor()); + final SmartTypePointer pointer = DumbService.getInstance(myProject).computeWithAlternativeResolveEnabled(() -> type.accept(new SmartTypeCreatingVisitor())); return pointer != null ? pointer : NULL_POINTER; } diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/castvar/assigned.java b/java/java-tests/testData/codeInsight/template/postfix/templates/castvar/assigned.java new file mode 100644 index 000000000000..614d74667b86 --- /dev/null +++ b/java/java-tests/testData/codeInsight/template/postfix/templates/castvar/assigned.java @@ -0,0 +1,6 @@ +public class Foo { + void m() { + Object o = "hello"; + o.castvar + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/castvar/assigned_after.java b/java/java-tests/testData/codeInsight/template/postfix/templates/castvar/assigned_after.java new file mode 100644 index 000000000000..c8680daa90fa --- /dev/null +++ b/java/java-tests/testData/codeInsight/template/postfix/templates/castvar/assigned_after.java @@ -0,0 +1,6 @@ +public class Foo { + void m() { + Object o = "hello"; + String s = (String) o; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/var/streamStep.java b/java/java-tests/testData/codeInsight/template/postfix/templates/var/streamStep.java new file mode 100644 index 000000000000..ad6f288b636f --- /dev/null +++ b/java/java-tests/testData/codeInsight/template/postfix/templates/var/streamStep.java @@ -0,0 +1,7 @@ +import java.util.List; + +public class Foo { + void test(List list) { + list.stream().anyMatch(s -> s.trim().var.isEmpty()) + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/var/streamStep2.java b/java/java-tests/testData/codeInsight/template/postfix/templates/var/streamStep2.java new file mode 100644 index 000000000000..ad6f288b636f --- /dev/null +++ b/java/java-tests/testData/codeInsight/template/postfix/templates/var/streamStep2.java @@ -0,0 +1,7 @@ +import java.util.List; + +public class Foo { + void test(List list) { + list.stream().anyMatch(s -> s.trim().var.isEmpty()) + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/var/streamStep2_after.java b/java/java-tests/testData/codeInsight/template/postfix/templates/var/streamStep2_after.java new file mode 100644 index 000000000000..7c09453464b0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/template/postfix/templates/var/streamStep2_after.java @@ -0,0 +1,7 @@ +import java.util.List; + +public class Foo { + void test(List list) { + list.stream().map(String::trim).anyMatch(trim -> trim.isEmpty()) + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/var/streamStep_after.java b/java/java-tests/testData/codeInsight/template/postfix/templates/var/streamStep_after.java new file mode 100644 index 000000000000..560292beee14 --- /dev/null +++ b/java/java-tests/testData/codeInsight/template/postfix/templates/var/streamStep_after.java @@ -0,0 +1,10 @@ +import java.util.List; + +public class Foo { + void test(List list) { + list.stream().anyMatch(s -> { + String trim = s.trim(); + return trim.isEmpty(); + }) + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/JavaCompletionTestSuite.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/JavaCompletionTestSuite.java index f231ec8e1732..93f5b9d7b49a 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/JavaCompletionTestSuite.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/JavaCompletionTestSuite.java @@ -4,11 +4,14 @@ package com.intellij.java.codeInsight.completion; import com.intellij.TestAll; import com.intellij.TestCaseLoader; import com.intellij.java.codeInsight.completion.ml.JavaCompletionFeaturesTest; +import com.intellij.java.codeInsight.template.postfix.templates.*; import com.intellij.testFramework.SkipSlowTestLocally; import com.intellij.testFramework.TestIndexingModeSupporter; import junit.framework.Test; import junit.framework.TestSuite; +import java.util.List; + /** * To run a separate test from this suite with needed IndexingMode in an IDE, comment in {@link #suite()} *
@@ -32,8 +35,10 @@ public class JavaCompletionTestSuite extends TestSuite {
     System.setProperty("intellij.build.test.groups", "JAVA_TESTS");
     TestCaseLoader myTestCaseLoader = new TestCaseLoader(TestCaseLoader.COMMON_TEST_GROUPS_RESOURCE_NAME);
     myTestCaseLoader.fillTestCases("", TestAll.getClassRoots());
-    for (Class aClass : myTestCaseLoader.getClasses()) {
-      if (!aClass.getSimpleName().contains("Completion")) continue;
+    List> classes = myTestCaseLoader.getClasses();
+    for (Class aClass : classes) {
+      if (!aClass.getSimpleName().contains("Completion") && 
+          !PostfixTemplateTestCase.class.isAssignableFrom(aClass)) continue;
       // JavaCompletionFeaturesTest does not depend on indices
       if (JavaCompletionFeaturesTest.class.equals(aClass)) continue;
       // Exclude feature suggester tests
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/Normal8CompletionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/Normal8CompletionTest.java
index 957e8d618124..3eeafc2aab79 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/Normal8CompletionTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/Normal8CompletionTest.java
@@ -417,6 +417,7 @@ public class Normal8CompletionTest extends NormalCompletionTestCase {
     checkResultByFile(getTestName(false) + "_after.java");
   }
 
+  @NeedsIndex.ForStandardLibrary
   public void test_intersection_type_members() {
     myFixture.configureByText("a.java", "import java.util.*; class F { { (true ? new LinkedList<>() : new ArrayList<>()). }}");
     myFixture.completeBasic();
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/SmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/SmartTypeCompletionTest.java
index 4894dac6dcb9..8be1e26beef8 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/SmartTypeCompletionTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/SmartTypeCompletionTest.java
@@ -460,6 +460,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
 
   public void testArrayAccessIndex() { doTest(); }
 
+  @NeedsIndex.ForStandardLibrary(reason = "Need to resolve java.lang.String")
   public void testThrowExceptionConstructor() { doTest('\n'); }
 
   public void testJavadocThrows() { doTest(); }
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/CastVarPostfixTemplateTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/CastVarPostfixTemplateTest.java
index d9e4c38d205f..6e74203da25d 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/CastVarPostfixTemplateTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/CastVarPostfixTemplateTest.java
@@ -2,6 +2,7 @@
 package com.intellij.java.codeInsight.template.postfix.templates;
 
 import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
+import com.intellij.testFramework.NeedsIndex;
 import org.jetbrains.annotations.NotNull;
 
 public class CastVarPostfixTemplateTest extends PostfixTemplateTestCase {
@@ -12,10 +13,16 @@ public class CastVarPostfixTemplateTest extends PostfixTemplateTestCase {
     return "castvar";
   }
 
+  @NeedsIndex.SmartMode(reason = "DFA is necessary for smart-cast")
   public void testSingleExpression() {
     doTest();
   }
 
+  public void testAssigned() {
+    doTest();
+  }
+
+  @NeedsIndex.SmartMode(reason = "DFA is necessary for smart-cast")
   public void testFinalSingleExpression() {
     JavaCodeStyleSettings customSettings = JavaCodeStyleSettings.getInstance(getProject());
     customSettings.GENERATE_FINAL_LOCALS = true;
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/OptionalPostfixTemplateTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/OptionalPostfixTemplateTest.java
index 363ce1aee2b3..e4c35227df53 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/OptionalPostfixTemplateTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/OptionalPostfixTemplateTest.java
@@ -18,6 +18,7 @@ package com.intellij.java.codeInsight.template.postfix.templates;
 import com.intellij.openapi.roots.LanguageLevelProjectExtension;
 import com.intellij.pom.java.LanguageLevel;
 import com.intellij.testFramework.IdeaTestUtil;
+import com.intellij.testFramework.NeedsIndex;
 import org.jetbrains.annotations.NotNull;
 
 public class OptionalPostfixTemplateTest extends PostfixTemplateTestCase {
@@ -87,6 +88,7 @@ public class OptionalPostfixTemplateTest extends PostfixTemplateTestCase {
     doTest();
   }
 
+  @NeedsIndex.SmartMode(reason = "Requires nullability analysis")
   public void testNotNullMethodCall() {
     myFixture.addClass("package org.jetbrains.annotations;" +
                        "public @interface NotNull {}");
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/OriginalElementPostfixTemplateTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/OriginalElementPostfixTemplateTest.java
index a4da78c0744c..641219746a37 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/OriginalElementPostfixTemplateTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/OriginalElementPostfixTemplateTest.java
@@ -11,6 +11,7 @@ import com.intellij.pom.java.LanguageLevel;
 import com.intellij.psi.PsiExpression;
 import com.intellij.psi.PsiMethod;
 import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.testFramework.NeedsIndex;
 import com.intellij.util.LazyKt;
 import kotlin.Lazy;
 import org.jdom.Element;
@@ -54,6 +55,7 @@ public class OriginalElementPostfixTemplateTest extends PostfixTemplateTestCase
     }
   }
 
+  @NeedsIndex.SmartMode(reason = "Not created as DumbAware")
   public void testOriginalElement() {
     doTest();
   }
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/SameKeyPostfixTemplatesTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/SameKeyPostfixTemplatesTest.java
index 2c0c1117d3ff..c3efce92eba4 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/SameKeyPostfixTemplatesTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/SameKeyPostfixTemplatesTest.java
@@ -7,6 +7,7 @@ import com.intellij.codeInsight.template.postfix.templates.PostfixTemplate;
 import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate;
 import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition;
 import com.intellij.pom.java.LanguageLevel;
+import com.intellij.testFramework.NeedsIndex;
 import com.intellij.util.LazyKt;
 import kotlin.Lazy;
 import org.jetbrains.annotations.NotNull;
@@ -34,10 +35,12 @@ public class SameKeyPostfixTemplatesTest extends PostfixTemplateTestCase {
     PostfixTemplateStorage.getInstance().setTemplates(provider, asList(template1, template2));
   }
 
+  @NeedsIndex.SmartMode(reason = "Not created as DumbAware")
   public void testSameKeyInteger() {
     doTest();
   }
 
+  @NeedsIndex.SmartMode(reason = "Not created as DumbAware")
   public void testSameKeyBoolean() {
     doTest();
   }
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/VarPostfixTemplateTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/VarPostfixTemplateTest.java
index acc21a163766..6424aaf729ef 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/VarPostfixTemplateTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/VarPostfixTemplateTest.java
@@ -15,12 +15,22 @@
  */
 package com.intellij.java.codeInsight.template.postfix.templates;
 
+import com.intellij.testFramework.LightProjectDescriptor;
+import com.intellij.ui.ChooserInterceptor;
+import com.intellij.ui.UiInterceptors;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.List;
+
 /**
  * @author ignatov
  */
 public class VarPostfixTemplateTest extends PostfixTemplateTestCase {
+  @Override
+  protected @NotNull LightProjectDescriptor getProjectDescriptor() {
+    return JAVA_LATEST_WITH_LATEST_JDK;
+  }
+
   @NotNull
   @Override
   protected String getSuffix() {
@@ -35,6 +45,18 @@ public class VarPostfixTemplateTest extends PostfixTemplateTestCase {
     doTest();
   }
 
+  public void testStreamStep() {
+    UiInterceptors.register(new ChooserInterceptor(List.of("Create variable inside current lambda", "Extract as 'map' operation"), 
+                                                   "Create variable inside current lambda"));
+    doTest();
+  }
+
+  public void testStreamStep2() {
+    UiInterceptors.register(new ChooserInterceptor(List.of("Create variable inside current lambda", "Extract as 'map' operation"), 
+                                                   "Extract as 'map' operation"));
+    doTest();
+  }
+
   public void testAnonymous() {
     doTest();
   }
diff --git a/java/openapi/src/com/intellij/codeInsight/generation/surroundWith/JavaExpressionSurrounder.java b/java/openapi/src/com/intellij/codeInsight/generation/surroundWith/JavaExpressionSurrounder.java
index 2e59e5c86fb5..2b2c00a3605b 100644
--- a/java/openapi/src/com/intellij/codeInsight/generation/surroundWith/JavaExpressionSurrounder.java
+++ b/java/openapi/src/com/intellij/codeInsight/generation/surroundWith/JavaExpressionSurrounder.java
@@ -4,6 +4,7 @@ package com.intellij.codeInsight.generation.surroundWith;
 import com.intellij.lang.surroundWith.Surrounder;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.project.DumbService;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.PsiElement;
@@ -22,8 +23,8 @@ public abstract class JavaExpressionSurrounder implements Surrounder {
   @Override
   public boolean isApplicable(PsiElement @NotNull [] elements) {
     return elements.length == 1 &&
-           elements[0] instanceof PsiExpression &&
-           isApplicable((PsiExpression)elements[0]);
+           elements[0] instanceof PsiExpression expr &&
+           DumbService.getInstance(expr.getProject()).computeWithAlternativeResolveEnabled(() -> isApplicable(expr));
   }
 
   /**