use of com.intellij.openapi.project.IndexNotReadyException in project intellij-community by JetBrains.
the class CtrlMouseHandler method getInfoAt.
@Nullable
private static Info getInfoAt(@NotNull Project project, @NotNull final Editor editor, @NotNull PsiFile file, int offset, @NotNull BrowseMode browseMode) {
PsiElement targetElement = null;
if (browseMode == BrowseMode.TypeDeclaration) {
try {
targetElement = GotoTypeDeclarationAction.findSymbolType(editor, offset);
} catch (IndexNotReadyException e) {
showDumbModeNotification(project);
}
} else if (browseMode == BrowseMode.Declaration) {
final PsiReference ref = TargetElementUtil.findReference(editor, offset);
final List<PsiElement> resolvedElements = ref == null ? Collections.emptyList() : resolve(ref);
final PsiElement resolvedElement = resolvedElements.size() == 1 ? resolvedElements.get(0) : null;
final PsiElement[] targetElements = GotoDeclarationAction.findTargetElementsNoVS(project, editor, offset, false);
final PsiElement elementAtPointer = file.findElementAt(TargetElementUtil.adjustOffset(file, editor.getDocument(), offset));
if (targetElements != null) {
if (targetElements.length == 0) {
return null;
} else if (targetElements.length == 1) {
if (targetElements[0] != resolvedElement && elementAtPointer != null && targetElements[0].isPhysical()) {
return ref != null ? new InfoSingle(ref, targetElements[0]) : new InfoSingle(elementAtPointer, targetElements[0]);
}
} else {
return elementAtPointer != null ? new InfoMultiple(elementAtPointer) : null;
}
}
if (resolvedElements.size() == 1) {
return new InfoSingle(ref, resolvedElements.get(0));
}
if (resolvedElements.size() > 1) {
return elementAtPointer != null ? new InfoMultiple(elementAtPointer, ref) : null;
}
} else if (browseMode == BrowseMode.Implementation) {
final PsiElement element = TargetElementUtil.getInstance().findTargetElement(editor, ImplementationSearcher.getFlags(), offset);
PsiElement[] targetElements = new ImplementationSearcher() {
@Override
@NotNull
protected PsiElement[] searchDefinitions(final PsiElement element, Editor editor) {
final List<PsiElement> found = new ArrayList<>(2);
DefinitionsScopedSearch.search(element, getSearchScope(element, editor)).forEach(psiElement -> {
found.add(psiElement);
return found.size() != 2;
});
return PsiUtilCore.toPsiElementArray(found);
}
}.searchImplementations(editor, element, offset);
if (targetElements == null) {
return null;
}
if (targetElements.length > 1) {
PsiElement elementAtPointer = file.findElementAt(offset);
if (elementAtPointer != null) {
return new InfoMultiple(elementAtPointer);
}
return null;
}
if (targetElements.length == 1) {
Navigatable descriptor = EditSourceUtil.getDescriptor(targetElements[0]);
if (descriptor == null || !descriptor.canNavigate()) {
return null;
}
targetElement = targetElements[0];
}
}
if (targetElement != null && targetElement.isPhysical()) {
PsiElement elementAtPointer = file.findElementAt(offset);
if (elementAtPointer != null) {
return new InfoSingle(elementAtPointer, targetElement);
}
}
final PsiElement element = GotoDeclarationAction.findElementToShowUsagesOf(editor, offset);
if (element instanceof PsiNameIdentifierOwner) {
PsiElement identifier = ((PsiNameIdentifierOwner) element).getNameIdentifier();
if (identifier != null && identifier.isValid()) {
return new Info(identifier) {
@Override
public void showDocInfo(@NotNull DocumentationManager docManager) {
}
@NotNull
@Override
public DocInfo getInfo() {
String name = UsageViewUtil.getType(element) + " '" + UsageViewUtil.getShortName(element) + "'";
return new DocInfo("Show usages of " + name, null, element);
}
@Override
public boolean isValid(@NotNull Document document) {
return element.isValid();
}
@Override
public boolean isNavigatable() {
return true;
}
};
}
}
return null;
}
use of com.intellij.openapi.project.IndexNotReadyException in project intellij-community by JetBrains.
the class CtrlMouseHandler method fulfillDocInfo.
private void fulfillDocInfo(@NotNull final String header, @NotNull final DocumentationProvider provider, @NotNull final PsiElement originalElement, @NotNull final PsiElement anchorElement, @NotNull final Consumer<String> newTextConsumer, @NotNull final LightweightHint hint) {
myDocAlarm.cancelAllRequests();
myDocAlarm.addRequest(() -> {
final Ref<String> fullTextRef = new Ref<>();
final Ref<String> qualifiedNameRef = new Ref<>();
ApplicationManager.getApplication().runReadAction(() -> {
if (anchorElement.isValid() && originalElement.isValid()) {
try {
fullTextRef.set(provider.generateDoc(anchorElement, originalElement));
} catch (IndexNotReadyException e) {
fullTextRef.set("Documentation is not available while indexing is in progress");
}
if (anchorElement instanceof PsiQualifiedNamedElement) {
qualifiedNameRef.set(((PsiQualifiedNamedElement) anchorElement).getQualifiedName());
}
}
});
String fullText = fullTextRef.get();
if (fullText == null) {
return;
}
final String updatedText = DocPreviewUtil.buildPreview(header, qualifiedNameRef.get(), fullText);
final String newHtml = HintUtil.prepareHintText(updatedText, HintUtil.getInformationHint());
UIUtil.invokeLaterIfNeeded(() -> {
// There is a possible case that quick doc control width is changed, e.g. it contained text
// like 'public final class String implements java.io.Serializable, java.lang.Comparable<java.lang.String>' and
// new text replaces fully-qualified class names by hyperlinks with short name.
// That's why we might need to update the control size. We assume that the hint component is located at the
// layered pane, so, the algorithm is to find an ancestor layered pane and apply new size for the target component.
JComponent component = hint.getComponent();
Dimension oldSize = component.getPreferredSize();
newTextConsumer.consume(newHtml);
final int widthIncrease;
if (component instanceof QuickDocInfoPane) {
int buttonWidth = ((QuickDocInfoPane) component).getButtonWidth();
widthIncrease = calculateWidthIncrease(buttonWidth, updatedText);
} else {
widthIncrease = 0;
}
if (oldSize == null) {
return;
}
Dimension newSize = component.getPreferredSize();
if (newSize.width + widthIncrease == oldSize.width) {
return;
}
component.setPreferredSize(new Dimension(newSize.width + widthIncrease, newSize.height));
// We're assuming here that there are two possible hint representation modes: popup and layered pane.
if (hint.isRealPopup()) {
TooltipProvider tooltipProvider = myTooltipProvider;
if (tooltipProvider != null) {
// There is a possible case that 'raw' control was rather wide but the 'rich' one is narrower. That's why we try to
// re-show the hint here. Benefits: there is a possible case that we'll be able to show nice layered pane-based balloon;
// the popup will be re-positioned according to the new width.
hint.hide();
tooltipProvider.showHint(new LightweightHint(component));
} else {
component.setPreferredSize(new Dimension(newSize.width + widthIncrease, oldSize.height));
hint.pack();
}
return;
}
Container topLevelLayeredPaneChild = null;
boolean adjustBounds = false;
for (Container current = component.getParent(); current != null; current = current.getParent()) {
if (current instanceof JLayeredPane) {
adjustBounds = true;
break;
} else {
topLevelLayeredPaneChild = current;
}
}
if (adjustBounds && topLevelLayeredPaneChild != null) {
Rectangle bounds = topLevelLayeredPaneChild.getBounds();
topLevelLayeredPaneChild.setBounds(bounds.x, bounds.y, bounds.width + newSize.width + widthIncrease - oldSize.width, bounds.height);
}
});
}, 0);
}
use of com.intellij.openapi.project.IndexNotReadyException in project intellij-community by JetBrains.
the class LookupManagerImpl method createLookup.
@NotNull
@Override
public LookupImpl createLookup(@NotNull final Editor editor, @NotNull LookupElement[] items, @NotNull final String prefix, @NotNull final LookupArranger arranger) {
hideActiveLookup();
final CodeInsightSettings settings = CodeInsightSettings.getInstance();
final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument());
final LookupImpl lookup = createLookup(editor, arranger, myProject);
final Alarm alarm = new Alarm();
final Runnable request = () -> {
if (myActiveLookup != lookup)
return;
LookupElement currentItem = lookup.getCurrentItem();
if (currentItem != null && currentItem.isValid() && isAutoPopupJavadocSupportedBy(currentItem)) {
final CompletionProcess completion = CompletionService.getCompletionService().getCurrentCompletion();
if (completion != null && !completion.isAutopopupCompletion()) {
try {
DocumentationManager.getInstance(myProject).showJavaDocInfo(editor, psiFile, false);
} catch (IndexNotReadyException ignored) {
}
}
}
};
if (settings.AUTO_POPUP_JAVADOC_INFO) {
alarm.addRequest(request, settings.JAVADOC_INFO_DELAY);
}
ApplicationManager.getApplication().assertIsDispatchThread();
myActiveLookup = lookup;
myActiveLookupEditor = editor;
myActiveLookup.addLookupListener(new LookupAdapter() {
@Override
public void itemSelected(LookupEvent event) {
lookupClosed();
}
@Override
public void lookupCanceled(LookupEvent event) {
lookupClosed();
}
@Override
public void currentItemChanged(LookupEvent event) {
alarm.cancelAllRequests();
if (settings.AUTO_POPUP_JAVADOC_INFO && DocumentationManager.getInstance(myProject).getDocInfoHint() == null) {
alarm.addRequest(request, settings.JAVADOC_INFO_DELAY);
}
}
private void lookupClosed() {
ApplicationManager.getApplication().assertIsDispatchThread();
alarm.cancelAllRequests();
lookup.removeLookupListener(this);
}
});
Disposer.register(lookup, new Disposable() {
@Override
public void dispose() {
myActiveLookup = null;
myActiveLookupEditor = null;
myPropertyChangeSupport.firePropertyChange(PROP_ACTIVE_LOOKUP, lookup, null);
}
});
CamelHumpMatcher matcher = new CamelHumpMatcher(prefix);
if (items.length > 0) {
for (final LookupElement item : items) {
myActiveLookup.addItem(item, matcher);
}
myActiveLookup.refreshUi(true, true);
} else {
// no items -> no doc
alarm.cancelAllRequests();
}
myPropertyChangeSupport.firePropertyChange(PROP_ACTIVE_LOOKUP, null, myActiveLookup);
return lookup;
}
use of com.intellij.openapi.project.IndexNotReadyException in project intellij-community by JetBrains.
the class ShowIntentionActionsHandler method availableFor.
public static boolean availableFor(@NotNull PsiFile psiFile, @NotNull Editor editor, @NotNull IntentionAction action) {
if (!psiFile.isValid())
return false;
int offset = editor.getCaretModel().getOffset();
PsiElement psiElement = psiFile.findElementAt(offset);
boolean inProject = psiFile.getManager().isInProject(psiFile);
try {
Project project = psiFile.getProject();
if (action instanceof SuppressIntentionActionFromFix) {
final ThreeState shouldBeAppliedToInjectionHost = ((SuppressIntentionActionFromFix) action).isShouldBeAppliedToInjectionHost();
if (editor instanceof EditorWindow && shouldBeAppliedToInjectionHost == ThreeState.YES) {
return false;
}
if (!(editor instanceof EditorWindow) && shouldBeAppliedToInjectionHost == ThreeState.NO) {
return false;
}
}
if (action instanceof PsiElementBaseIntentionAction) {
if (!inProject || psiElement == null || !((PsiElementBaseIntentionAction) action).isAvailable(project, editor, psiElement))
return false;
} else if (!action.isAvailable(project, editor, psiFile)) {
return false;
}
} catch (IndexNotReadyException e) {
return false;
}
return true;
}
use of com.intellij.openapi.project.IndexNotReadyException in project intellij-community by JetBrains.
the class ExecutionManagerImpl method doRun.
protected void doRun(@NotNull final ExecutionEnvironment environment, @NotNull final Runnable startRunnable) {
Boolean allowSkipRun = environment.getUserData(EXECUTION_SKIP_RUN);
if (allowSkipRun != null && allowSkipRun) {
environment.getProject().getMessageBus().syncPublisher(EXECUTION_TOPIC).processNotStarted(environment.getExecutor().getId(), environment);
} else {
// important! Do not use DumbService.smartInvokeLater here because it depends on modality state
// and execution of startRunnable could be skipped if modality state check fails
//noinspection SSBasedInspection
SwingUtilities.invokeLater(() -> {
if (!myProject.isDisposed()) {
if (!Registry.is("dumb.aware.run.configurations")) {
DumbService.getInstance(myProject).runWhenSmart(startRunnable);
} else {
try {
DumbService.getInstance(myProject).setAlternativeResolveEnabled(true);
startRunnable.run();
} catch (IndexNotReadyException ignored) {
ExecutionUtil.handleExecutionError(environment, new ExecutionException("cannot start while indexing is in progress."));
} finally {
DumbService.getInstance(myProject).setAlternativeResolveEnabled(false);
}
}
}
});
}
}
Aggregations