diff options
Diffstat (limited to 'platform/lang-impl/src/com/intellij/codeInsight')
20 files changed, 189 insertions, 107 deletions
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java index 3b51cc9ad976..dadafc7a7d84 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java @@ -250,7 +250,7 @@ public class FormatChangedTextUtil { } @NotNull - public static List<TextRange> getChangedTextRanges(@NotNull Project project, @NotNull PsiFile file) { + public static List<TextRange> getChangedTextRanges(@NotNull Project project, @NotNull PsiFile file) throws FilesTooBigForDiffException { Change change = ChangeListManager.getInstance(project).getChange(file.getVirtualFile()); if (change == null) { return ContainerUtilRt.emptyList(); @@ -281,7 +281,10 @@ public class FormatChangedTextUtil { } @NotNull - private static List<TextRange> calculateChangedTextRanges(@NotNull Project project, @NotNull PsiFile file, @NotNull String contentFromVcs) { + private static List<TextRange> calculateChangedTextRanges(@NotNull Project project, + @NotNull PsiFile file, + @NotNull String contentFromVcs) throws FilesTooBigForDiffException + { Document documentFromVcs = ((EditorFactoryImpl)EditorFactory.getInstance()).createDocument(contentFromVcs, true, false); Document document = PsiDocumentManager.getInstance(project).getDocument(file); @@ -289,23 +292,16 @@ public class FormatChangedTextUtil { return ContainerUtil.emptyList(); } - try { - List<Range> changedRanges; - - LineStatusTracker tracker = LineStatusTrackerManager.getInstance(project).getLineStatusTracker(document); - if (tracker != null) { - changedRanges = tracker.getRanges(); - } - else { - changedRanges = new RangesBuilder(document, documentFromVcs).getRanges(); - } - - return getChangedTextRanges(document, changedRanges); + List<Range> changedRanges; + LineStatusTracker tracker = LineStatusTrackerManager.getInstance(project).getLineStatusTracker(document); + if (tracker != null) { + changedRanges = tracker.getRanges(); } - catch (FilesTooBigForDiffException e) { - LOG.error("Error while calculating changed ranges for: " + file.getVirtualFile(), e); - return ContainerUtil.emptyList(); + else { + changedRanges = new RangesBuilder(document, documentFromVcs).getRanges(); } + + return getChangedTextRanges(document, changedRanges); } @NotNull diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeProcessor.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeProcessor.java index ff032c22747b..270f2f92f3cf 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeProcessor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeProcessor.java @@ -18,6 +18,10 @@ package com.intellij.codeInsight.actions; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.formatting.FormattingProgressTask; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.application.ApplicationBundle; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; @@ -27,6 +31,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.diff.FilesTooBigForDiffException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -90,6 +95,17 @@ public class ReformatCodeProcessor extends AbstractLayoutCodeProcessor { CodeStyleManager.getInstance(myProject).reformatText(file, ranges); return !FormattingProgressTask.FORMATTING_CANCELLED_FLAG.get(); } + catch (FilesTooBigForDiffException e) { + LOG.info("Error while calculating changed ranges for: " + file.getVirtualFile(), e); + if (!ApplicationManager.getApplication().isUnitTestMode()) { + Notification notification = new Notification(ApplicationBundle.message("reformat.changed.text.file.too.big.notification.groupId"), + ApplicationBundle.message("reformat.changed.text.file.too.big.notification.title"), + ApplicationBundle.message("reformat.changed.text.file.too.big.notification.text", file.getName()), + NotificationType.INFORMATION); + notification.notify(file.getProject()); + } + return false; + } catch (IncorrectOperationException e) { LOG.error(e); return false; @@ -102,7 +118,7 @@ public class ReformatCodeProcessor extends AbstractLayoutCodeProcessor { } @NotNull - private Collection<TextRange> getRangesToFormat(boolean processChangedTextOnly, PsiFile file) { + private Collection<TextRange> getRangesToFormat(boolean processChangedTextOnly, PsiFile file) throws FilesTooBigForDiffException { if (processChangedTextOnly) { return FormatChangedTextUtil.getChangedTextRanges(myProject, file); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 3bdd05f58a40..dd506593d942 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -65,9 +65,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import java.util.concurrent.atomic.AtomicReference; public class CodeCompletionHandlerBase { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.CodeCompletionHandlerBase"); @@ -306,16 +304,24 @@ public class CodeCompletionHandlerBase { CompletionServiceImpl.setCompletionPhase(synchronous ? new CompletionPhase.Synchronous(indicator) : new CompletionPhase.BgCalculation(indicator)); - final AtomicReference<LookupElement[]> data = indicator.startCompletion(initContext); + indicator.startCompletion(initContext); if (!synchronous) { return; } if (freezeSemaphore.waitFor(2000)) { - final LookupElement[] allItems = data.get(); - if (allItems != null && !indicator.isRunning() && !indicator.isCanceled()) { // the completion is really finished, now we may auto-insert or show lookup - completionFinished(initContext.getStartOffset(), initContext.getSelectionEndOffset(), indicator, allItems, hasModifiers); + if (!indicator.isRunning() && !indicator.isCanceled()) { // the completion is really finished, now we may auto-insert or show lookup + try { + indicator.getLookup().refreshUi(true, false); + } + catch (Exception e) { + CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion); + LOG.error(e); + return; + } + + completionFinished(indicator, hasModifiers); return; } } @@ -324,9 +330,9 @@ public class CodeCompletionHandlerBase { indicator.showLookup(); } - private static void checkNotSync(CompletionProgressIndicator indicator, LookupElement[] allItems) { + private static void checkNotSync(CompletionProgressIndicator indicator, List<LookupElement> allItems) { if (CompletionServiceImpl.isPhase(CompletionPhase.Synchronous.class)) { - LOG.error("sync phase survived: " + Arrays.toString(allItems) + "; indicator=" + CompletionServiceImpl.getCompletionPhase().indicator + "; myIndicator=" + indicator); + LOG.error("sync phase survived: " + allItems + "; indicator=" + CompletionServiceImpl.getCompletionPhase().indicator + "; myIndicator=" + indicator); CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion); } } @@ -345,17 +351,16 @@ public class CodeCompletionHandlerBase { private static PsiElement findCompletionPositionLeaf(CompletionContext newContext, int offset, PsiFile fileCopy, PsiFile originalFile) { final PsiElement insertedElement = newContext.file.findElementAt(offset); CompletionAssertions.assertCompletionPositionPsiConsistent(newContext, offset, fileCopy, originalFile, insertedElement); - assert insertedElement != null; return insertedElement; } - private AutoCompletionDecision shouldAutoComplete(final CompletionProgressIndicator indicator, final LookupElement[] items) { + private AutoCompletionDecision shouldAutoComplete(final CompletionProgressIndicator indicator, List<LookupElement> items) { if (!invokedExplicitly) { return AutoCompletionDecision.SHOW_LOOKUP; } final CompletionParameters parameters = indicator.getParameters(); - final LookupElement item = items[0]; - if (items.length == 1) { + final LookupElement item = items.get(0); + if (items.size() == 1) { final AutoCompletionPolicy policy = getAutocompletionPolicy(item); if (policy == AutoCompletionPolicy.NEVER_AUTOCOMPLETE) return AutoCompletionDecision.SHOW_LOOKUP; if (policy == AutoCompletionPolicy.ALWAYS_AUTOCOMPLETE) return AutoCompletionDecision.insertItem(item); @@ -367,11 +372,11 @@ public class CodeCompletionHandlerBase { if (isInsideIdentifier(indicator.getOffsetMap())) { return AutoCompletionDecision.SHOW_LOOKUP; } - if (items.length == 1 && getAutocompletionPolicy(item) == AutoCompletionPolicy.GIVE_CHANCE_TO_OVERWRITE) { + if (items.size() == 1 && getAutocompletionPolicy(item) == AutoCompletionPolicy.GIVE_CHANCE_TO_OVERWRITE) { return AutoCompletionDecision.insertItem(item); } - AutoCompletionContext context = new AutoCompletionContext(parameters, items, indicator.getOffsetMap(), indicator.getLookup()); + AutoCompletionContext context = new AutoCompletionContext(parameters, items.toArray(new LookupElement[items.size()]), indicator.getOffsetMap(), indicator.getLookup()); for (final CompletionContributor contributor : CompletionContributor.forParameters(parameters)) { final AutoCompletionDecision decision = contributor.handleAutoCompletionPossibility(context); if (decision != null) { @@ -401,12 +406,9 @@ public class CodeCompletionHandlerBase { return offsetMap.getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET) != offsetMap.getOffset(CompletionInitializationContext.SELECTION_END_OFFSET); } - - protected void completionFinished(final int offset1, - final int offset2, - final CompletionProgressIndicator indicator, - final LookupElement[] items, boolean hasModifiers) { - if (items.length == 0) { + protected void completionFinished(final CompletionProgressIndicator indicator, boolean hasModifiers) { + final List<LookupElement> items = indicator.getLookup().getItems(); + if (items.isEmpty()) { LookupManager.getInstance(indicator.getProject()).hideActiveLookup(); Caret nextCaret = getNextCaretToProcess(indicator.getEditor()); @@ -424,7 +426,6 @@ public class CodeCompletionHandlerBase { LOG.assertTrue(!indicator.isCanceled(), "canceled"); try { - indicator.getLookup().refreshUi(true, false); final AutoCompletionDecision decision = shouldAutoComplete(indicator, items); if (decision == AutoCompletionDecision.SHOW_LOOKUP) { CompletionServiceImpl.setCompletionPhase(new CompletionPhase.ItemsCalculated(indicator)); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 8ca94d80463c..4f02d6bc5e54 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -81,7 +81,6 @@ import java.beans.PropertyChangeListener; import java.util.List; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.atomic.AtomicReference; /** * @author peter @@ -742,7 +741,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement return false; } - AtomicReference<LookupElement[]> startCompletion(final CompletionInitializationContext initContext) { + void startCompletion(final CompletionInitializationContext initContext) { boolean sync = ApplicationManager.getApplication().isUnitTestMode() && !CompletionAutoPopupHandler.ourTestingAutopopup; final CompletionThreading strategy = sync ? new SyncCompletion() : new AsyncCompletion(); @@ -754,12 +753,11 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement }); final WeighingDelegate weigher = strategy.delegateWeighing(this); - final AtomicReference<LookupElement[]> data = new AtomicReference<LookupElement[]>(null); class CalculateItems implements Runnable { @Override public void run() { try { - data.set(calculateItems(initContext, weigher)); + calculateItems(initContext, weigher); } catch (ProcessCanceledException ignore) { cancel(); // some contributor may just throw PCE; if indicator is not canceled everything will hang @@ -771,7 +769,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } } strategy.startThread(this, new CalculateItems()); - return data; } private LookupElement[] calculateItems(CompletionInitializationContext initContext, WeighingDelegate weigher) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java index 4ac5e686c5bc..0d02b32baed4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java @@ -58,6 +58,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.newvfs.RefreshQueueImpl; import com.intellij.packageDependencies.DependencyValidationManager; +import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiCompiledElement; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; @@ -184,8 +185,9 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements JDOM @Override public void cleanFileLevelHighlights(@NotNull Project project, final int group, PsiFile psiFile) { - if (psiFile == null || !psiFile.getViewProvider().isPhysical()) return; - VirtualFile vFile = psiFile.getViewProvider().getVirtualFile(); + if (psiFile == null) return; + FileViewProvider provider = psiFile.getViewProvider(); + VirtualFile vFile = provider.getVirtualFile(); final FileEditorManager manager = FileEditorManager.getInstance(project); for (FileEditor fileEditor : manager.getEditors(vFile)) { final List<HighlightInfo> infos = fileEditor.getUserData(FILE_LEVEL_HIGHLIGHTS); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java index 44df90322011..24c3d8b4a6fb 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java @@ -34,6 +34,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -95,6 +96,12 @@ public class PassExecutorService implements Disposable { catch (ProcessCanceledException ignored) { } + catch (Error e) { + throw e; + } + catch (RuntimeException e) { + throw e; + } catch (Throwable throwable) { LOG.error(throwable); } @@ -118,6 +125,10 @@ public class PassExecutorService implements Disposable { LOG.assertTrue(!(editor instanceof EditorWindow)); document = editor.getDocument(); } + else { + VirtualFile virtualFile = ((FileEditorManagerEx)FileEditorManager.getInstance(myProject)).getFile(fileEditor); + document = virtualFile == null ? null : FileDocumentManager.getInstance().getDocument(virtualFile); + } int prevId = 0; for (final HighlightingPass pass : passes) { @@ -534,7 +545,7 @@ public class PassExecutorService implements Disposable { return result; } - private void sortById(@NotNull List<TextEditorHighlightingPass> result) { + private static void sortById(@NotNull List<TextEditorHighlightingPass> result) { ContainerUtil.quickSort(result, new Comparator<TextEditorHighlightingPass>() { @Override public int compare(TextEditorHighlightingPass o1, TextEditorHighlightingPass o2) { @@ -548,7 +559,7 @@ public class PassExecutorService implements Disposable { return ConcurrencyUtil.cacheOrGet(threads, Thread.currentThread(), threads.size()); } - public static void log(ProgressIndicator progressIndicator, TextEditorHighlightingPass pass, @NonNls Object... info) { + public static void log(ProgressIndicator progressIndicator, TextEditorHighlightingPass pass, @NonNls @NotNull Object... info) { if (LOG.isDebugEnabled()) { CharSequence docText = pass == null ? "" : StringUtil.first(pass.getDocument().getCharsSequence(), 10, true); synchronized (PassExecutorService.class) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java index 50f69088033b..10515ba07bef 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java @@ -106,7 +106,10 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr @Override public Image get(Object key) { PsiElement element = getElement(); - return element == null ? null : myManager.getElementImage(element, ((URL)key).toExternalForm()); + if (element == null) return null; + URL url = (URL)key; + Image inMemory = myManager.getElementImage(element, url.toExternalForm()); + return inMemory != null ? inMemory : Toolkit.getDefaultToolkit().createImage(url); } }; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java index 63484f890225..319ce54196da 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java @@ -378,6 +378,8 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp final PsiElement originalElement, @Nullable final Runnable closeCallback) { Project project = getProject(element); + if (!project.isOpen()) return; + storeOriginalElement(project, originalElement, element); myPreviouslyFocused = WindowManagerEx.getInstanceEx().getFocusedComponent(project); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocUtil.java index 064bd020183b..18b28e3409f3 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocUtil.java @@ -26,9 +26,9 @@ import com.intellij.psi.PsiElement; import com.intellij.ui.content.Content; import com.intellij.ui.popup.AbstractPopup; import com.intellij.util.Producer; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; - -import javax.swing.*; +import org.jetbrains.annotations.Nullable; /** * @author gregsh @@ -40,33 +40,41 @@ public class QuickDocUtil { ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { @Override public void run() { - final String documentation = docProducer.produce(); - if (StringUtil.isEmpty(documentation)) return; - // modal dialogs with fragment editors fix: can't guess proper modality state here - //noinspection SSBasedInspection - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - DocumentationManager documentationManager = DocumentationManager.getInstance(project); - DocumentationComponent component; - JBPopup hint = documentationManager.getDocInfoHint(); - if (hint != null) { - component = (DocumentationComponent)((AbstractPopup)hint).getComponent(); - } - else if (documentationManager.hasActiveDockedDocWindow()) { - ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.DOCUMENTATION); - Content selectedContent = toolWindow == null ? null : toolWindow.getContentManager().getSelectedContent(); - component = selectedContent == null ? null : (DocumentationComponent)selectedContent.getComponent(); - } - else { - component = null; - } - if (component != null) { - component.replaceText(documentation, element); - } - } - }); + updateQuickDoc(project, element, docProducer.produce()); } }); } + + public static void updateQuickDoc(@NotNull final Project project, @NotNull final PsiElement element, @Nullable final String documentation) { + if (StringUtil.isEmpty(documentation)) return; + // modal dialogs with fragment editors fix: can't guess proper modality state here + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + DocumentationComponent component = getActiveDocComponent(project); + if (component != null) { + component.replaceText(documentation, element); + } + } + }); + } + + @Nullable + public static DocumentationComponent getActiveDocComponent(@NotNull Project project) { + DocumentationManager documentationManager = DocumentationManager.getInstance(project); + DocumentationComponent component; + JBPopup hint = documentationManager.getDocInfoHint(); + if (hint != null) { + component = (DocumentationComponent)((AbstractPopup)hint).getComponent(); + } + else if (documentationManager.hasActiveDockedDocWindow()) { + ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.DOCUMENTATION); + Content selectedContent = toolWindow == null ? null : toolWindow.getContentManager().getSelectedContent(); + component = selectedContent == null ? null : (DocumentationComponent)selectedContent.getComponent(); + } + else { + component = null; + } + return component; + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java index afd7b230621c..376c24289617 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -367,12 +367,17 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { } private static PsiElement[] filterElements(final PsiElement[] targetElements) { - Set<PsiElement> unique = new LinkedHashSet<PsiElement>(Arrays.asList(targetElements)); - for (PsiElement elt : targetElements) { - final PsiFile containingFile = elt.getContainingFile(); - LOG.assertTrue(containingFile != null, elt); - PsiFile psiFile = containingFile.getOriginalFile(); - if (psiFile.getVirtualFile() == null) unique.remove(elt); + final Set<PsiElement> unique = new LinkedHashSet<PsiElement>(Arrays.asList(targetElements)); + for (final PsiElement elt : targetElements) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + final PsiFile containingFile = elt.getContainingFile(); + LOG.assertTrue(containingFile != null, elt); + PsiFile psiFile = containingFile.getOriginalFile(); + if (psiFile.getVirtualFile() == null) unique.remove(elt); + } + }); } // special case for Python (PY-237) // if the definition is the tree parent of the target element, filter out the target element @@ -392,9 +397,9 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { } private static class ImplementationsUpdaterTask extends BackgroundUpdaterTask<ImplementationViewComponent> { - private String myCaption; - private Editor myEditor; - private PsiElement myElement; + private final String myCaption; + private final Editor myEditor; + private final PsiElement myElement; private final boolean myIncludeSelf; private PsiElement[] myElements; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java index 517f23c5a198..b236e1061315 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java @@ -72,7 +72,6 @@ import org.jetbrains.annotations.TestOnly; import javax.swing.*; import java.awt.*; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -97,8 +96,7 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable { @Nullable private final PsiFile myInjectedFile; - private final List<Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer>> myMarkers = - new LinkedList<Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer>>(); + private final List<Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer>> myMarkers = ContainerUtil.newLinkedList(); @Nullable private final RangeMarker myAltFullRange; @@ -199,7 +197,16 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable { } public boolean isValid() { - return myNewVirtualFile.isValid() && (myAltFullRange == null && myInjectedFile.isValid() || myAltFullRange.isValid()); + boolean valid = myNewVirtualFile.isValid() && (myAltFullRange == null && myInjectedFile.isValid() || myAltFullRange.isValid()); + if (valid) { + for (Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer> t : myMarkers) { + if (!t.first.isValid() || !t.second.isValid() || t.third.getElement() == null) { + valid = false; + break; + } + } + } + return valid; } public void navigate(int injectedOffset) { @@ -285,6 +292,7 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable { } else if (e.getDocument() == myNewDocument) { commitToOriginal(); + if (!isValid()) closeEditor(); } else if (e.getDocument() == myOrigDocument) { if (myCommittingToOriginal || myAltFullRange != null && myAltFullRange.isValid()) return; @@ -359,7 +367,6 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable { private void commitToOriginal() { - if (!isValid()) return; VirtualFile origVirtualFile = PsiUtilCore.getVirtualFile(myNewFile.getContext()); myCommittingToOriginal = true; try { @@ -401,7 +408,7 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable { ProperTextRange insideHost = null; StringBuilder sb = new StringBuilder(); for (Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer> entry : map.get(host)) { - RangeMarker origMarker = entry.first; + RangeMarker origMarker = entry.first; // check for validity? int hostOffset = host.getTextRange().getStartOffset(); ProperTextRange localInsideHost = new ProperTextRange(origMarker.getStartOffset() - hostOffset, origMarker.getEndOffset() - hostOffset); RangeMarker rangeMarker = entry.second; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/EditVariableDialog.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/EditVariableDialog.java index e32fab35508b..bab6ade7b935 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/EditVariableDialog.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/EditVariableDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.help.HelpManager; +import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.ui.ToolbarDecorator; import com.intellij.ui.table.JBTable; @@ -107,11 +108,11 @@ class EditVariableDialog extends DialogWrapper { myTable.getSelectionModel().setSelectionInterval(0, 0); } - JComboBox comboField = new JComboBox(); + ComboBox comboField = new ComboBox(); Macro[] macros = MacroFactory.getMacros(); Arrays.sort(macros, new Comparator<Macro> () { @Override - public int compare(Macro m1, Macro m2) { + public int compare(@NotNull Macro m1, @NotNull Macro m2) { return m1.getPresentableName().compareTo(m2.getPresentableName()); } }); @@ -231,11 +232,13 @@ class EditVariableDialog extends DialogWrapper { } } + @NotNull @Override public String getColumnName(int column) { return myNames[column]; } + @NotNull @Override public Class getColumnClass(int c) { if (c <= 2) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java index 9a7a724e2d5d..1c0b72a5a454 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java @@ -19,6 +19,7 @@ package com.intellij.codeInsight.template.impl; import com.intellij.application.options.ExportSchemeAction; import com.intellij.application.options.SchemesToImportPopup; import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; import com.intellij.ide.dnd.*; import com.intellij.ide.dnd.aware.DnDAwareTree; @@ -690,6 +691,17 @@ public class TemplateListPanel extends JPanel implements Disposable { public void updateButton(AnActionEvent e) { e.getPresentation().setEnabled(getTemplate(getSingleSelectedIndex()) != null); } + }).addExtraAction(new AnActionButton("Restore deleted defaults", AllIcons.General.TodoDefault) { + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + TemplateSettings.getInstance().reset(); + reset(); + } + + @Override + public boolean isEnabled() { + return super.isEnabled() && !TemplateSettings.getInstance().getDeletedTemplates().isEmpty(); + } }); if (getSchemesManager().isExportAvailable()) { decorator.addExtraAction(new AnActionButton("Share...", PlatformIcons.EXPORT_ICON) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java index abf28256aaef..cdefbe83a252 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java @@ -158,6 +158,10 @@ public class TemplateSettings implements PersistentStateComponent<Element>, Expo this.key = key; } + @Override + public String toString() { + return getKey()+"@" + getGroupName(); + } } private TemplateKey myLastSelectedTemplate; @@ -185,7 +189,7 @@ public class TemplateSettings implements PersistentStateComponent<Element>, Expo } @Override - public Document writeScheme(@NotNull final TemplateGroup template) throws WriteExternalException { + public Element writeScheme(@NotNull final TemplateGroup template) throws WriteExternalException { Element templateSetElement = new Element(TEMPLATE_SET); templateSetElement.setAttribute(GROUP, template.getName()); @@ -195,7 +199,7 @@ public class TemplateSettings implements PersistentStateComponent<Element>, Expo } } - return new Document(templateSetElement); + return templateSetElement; } @Override @@ -750,4 +754,9 @@ public class TemplateSettings implements PersistentStateComponent<Element>, Expo public List<TemplateKey> getDeletedTemplates() { return myDeletedTemplates; } + + public void reset() { + myDeletedTemplates.clear(); + loadDefaultLiveTemplates(); + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java index 0c838cd05ec5..2e620c2379c9 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java @@ -723,7 +723,10 @@ public class TemplateState implements Disposable { ExpressionContext context = createExpressionContext(start); Result result = isQuick ? expressionNode.calculateQuickResult(context) : expressionNode.calculateResult(context); - if ((result == null || result.equalsToText("", element)) && defaultValue != null) { + if (isQuick && isEmptyResult(result, element) && !oldValue.isEmpty()) { + return; + } + if (isEmptyResult(result, element) && defaultValue != null) { result = defaultValue.calculateResult(context); } if (element != null) { @@ -743,6 +746,10 @@ public class TemplateState implements Disposable { } } + private static boolean isEmptyResult(Result result, PsiElement context) { + return result == null || result.equalsToText("", context); + } + private void replaceString(String newValue, int start, int end, int segmentNumber) { String oldText = myDocument.getCharsSequence().subSequence(start, end).toString(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ElseExpressionPostfixTemplateBase.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ElseExpressionPostfixTemplateBase.java index 1e9c58488f33..4c810dcf4ff3 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ElseExpressionPostfixTemplateBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ElseExpressionPostfixTemplateBase.java @@ -16,6 +16,7 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Conditions; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; @@ -28,7 +29,7 @@ public abstract class ElseExpressionPostfixTemplateBase extends SurroundPostfixT @SuppressWarnings("unchecked") protected ElseExpressionPostfixTemplateBase(@NotNull PostfixTemplatePsiInfo psiInfo) { - super("else", "if (!expr)", psiInfo, Condition.TRUE); + super("else", "if (!expr)", psiInfo, Conditions.<PsiElement>alwaysTrue()); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/IfPostfixTemplateBase.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/IfPostfixTemplateBase.java index 90a21a269fed..b7e402f31f66 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/IfPostfixTemplateBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/IfPostfixTemplateBase.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Conditions; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; @@ -29,6 +30,6 @@ public abstract class IfPostfixTemplateBase extends SurroundPostfixTemplateBase @SuppressWarnings("unchecked") protected IfPostfixTemplateBase(@NotNull PostfixTemplatePsiInfo psiInfo) { - super("if", "if (expr)", psiInfo, Condition.TRUE); + super("if", "if (expr)", psiInfo, Conditions.<PsiElement>alwaysTrue()); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java index 0190fadbcf02..61544faf2c81 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java @@ -32,6 +32,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Conditions; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDocumentManager; @@ -266,15 +267,13 @@ public class PostfixLiveTemplate extends CustomLiveTemplateBase { PsiFile copyFile = copyFile(file, fileContentWithoutKey); Document copyDocument = copyFile.getViewProvider().getDocument(); if (copyDocument == null) { - //noinspection unchecked - return Condition.FALSE; + return Conditions.alwaysFalse(); } copyFile = provider.preCheck(copyFile, editor, newOffset); copyDocument = copyFile.getViewProvider().getDocument(); if (copyDocument == null) { - //noinspection unchecked - return Condition.FALSE; + return Conditions.alwaysFalse(); } final PsiElement context = CustomTemplateCallback.getContext(copyFile, positiveOffset(newOffset)); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StatementWrapPostfixTemplate.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StatementWrapPostfixTemplate.java index 5b5c3624f33b..33b8ba541f66 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StatementWrapPostfixTemplate.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StatementWrapPostfixTemplate.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Conditions; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; @@ -28,7 +29,7 @@ public abstract class StatementWrapPostfixTemplate extends PostfixTemplateWithEx protected StatementWrapPostfixTemplate(@NotNull String name, @NotNull String descr, @NotNull PostfixTemplatePsiInfo psiInfo) { - super(name, descr, psiInfo, Condition.TRUE); + super(name, descr, psiInfo, Conditions.<PsiElement>alwaysTrue()); } protected StatementWrapPostfixTemplate(@NotNull String name, diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/SurroundPostfixTemplateBase.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/SurroundPostfixTemplateBase.java index 29ea4d39ac64..09ca27a3f948 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/SurroundPostfixTemplateBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/SurroundPostfixTemplateBase.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.template.postfix.templates; import com.intellij.lang.surroundWith.Surrounder; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Conditions; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; @@ -35,7 +36,7 @@ public abstract class SurroundPostfixTemplateBase extends StatementWrapPostfixTe protected SurroundPostfixTemplateBase(@NotNull String name, @NotNull String descr, @NotNull PostfixTemplatePsiInfo psiInfo) { - super(name, descr, psiInfo, Condition.TRUE); + super(name, descr, psiInfo, Conditions.<PsiElement>alwaysTrue()); } |