void (@NotNull final Project project, @NotNull final Editor editor, @NotNull PsiFile file) { ThreadingAssertions.assertEventDispatchThread(); Language language = PsiUtilCore.getLanguageAtOffset(file, editor.getCaretModel().getOffset()); final Set<ExpressionTypeProvider> handlers = getHandlers(project, language, file.getViewProvider().getBaseLanguage()); if (handlers.isEmpty()) return; Map<PsiElement, ExpressionTypeProvider> map = getExpressions(file, editor, handlers); Pass<PsiElement> callback = new Pass<>() { @Override public void pass(@NotNull PsiElement expression) { ExpressionTypeProvider provider = Objects.requireNonNull(map.get(expression)); TextRange range = expression.getTextRange(); editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset()); // noinspection unchecked displayHint(new DisplayedTypeInfo(expression, provider, editor), false); } }; if (map.isEmpty()) { ApplicationManager.getApplication().invokeLater(() -> { String errorHint = Objects.requireNonNull(ContainerUtil.getFirstItem(handlers)).getErrorHint(); Editor hostEditor = InjectedLanguageEditorUtil.getTopLevelEditor(editor); HintManager.getInstance().showErrorHint(hostEditor, errorHint); }); } else if (map.size() == 1) { Map.Entry<PsiElement, ExpressionTypeProvider> entry = map.entrySet().iterator().next(); PsiElement expression = entry.getKey(); ExpressionTypeProvider provider = entry.getValue(); // noinspection unchecked DisplayedTypeInfo typeInfo = new DisplayedTypeInfo(expression, provider, editor); if (typeInfo.isRepeating() && provider.hasAdvancedInformation()) { displayHint(typeInfo, true); } else { callback.accept(expression); } } else { IntroduceTargetChooser.showChooser( editor, new ArrayList<>(map.keySet()), callback, PsiElement::getText ); } }