diff --git a/java/testFramework/src/com/intellij/codeInsight/completion/LightCompletionTestCase.java b/java/testFramework/src/com/intellij/codeInsight/completion/LightCompletionTestCase.java index 20eb56b37d5c..7dba8dd0e162 100644 --- a/java/testFramework/src/com/intellij/codeInsight/completion/LightCompletionTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/completion/LightCompletionTestCase.java @@ -71,7 +71,7 @@ public abstract class LightCompletionTestCase extends LightCodeInsightTestCase { protected void testByCount(int finalCount, @NonNls String... values) { if (myItems == null) { - assertEquals(0, finalCount); + assertEquals(finalCount, 0); return; } int index = 0; diff --git a/platform/lang-api/src/com/intellij/lang/folding/FoldingDescriptor.java b/platform/lang-api/src/com/intellij/lang/folding/FoldingDescriptor.java index 0f3cba885084..87b2333e277d 100644 --- a/platform/lang-api/src/com/intellij/lang/folding/FoldingDescriptor.java +++ b/platform/lang-api/src/com/intellij/lang/folding/FoldingDescriptor.java @@ -118,5 +118,4 @@ public class FoldingDescriptor { } return null; } - } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedCodeFoldingPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedCodeFoldingPass.java new file mode 100755 index 000000000000..a2bc456e2bd2 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedCodeFoldingPass.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2009 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.codeInsight.daemon.impl; + +import com.intellij.codeHighlighting.TextEditorHighlightingPass; +import com.intellij.codeInsight.folding.impl.FoldingUpdate; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.IndexNotReadyException; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; + +class InjectedCodeFoldingPass extends TextEditorHighlightingPass implements DumbAware { + private Runnable myRunnable; + private final Editor myEditor; + private final PsiFile myFile; + + InjectedCodeFoldingPass(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { + super(project, editor.getDocument(), false); + myEditor = editor; + myFile = file; + } + + public void doCollectInformation(ProgressIndicator progress) { + Runnable runnable = FoldingUpdate.updateInjectedFoldRegions(myEditor, myFile); + synchronized (this) { + myRunnable = runnable; + } + } + + public void doApplyInformationToEditor() { + Runnable runnable; + synchronized (this) { + runnable = myRunnable; + } + if (runnable != null){ + try { + runnable.run(); + } + catch (IndexNotReadyException e) { + } + } + } +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedCodeFoldingPassFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedCodeFoldingPassFactory.java new file mode 100755 index 000000000000..dd98f1a1519a --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedCodeFoldingPassFactory.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2009 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.codeInsight.daemon.impl; + +import com.intellij.codeHighlighting.Pass; +import com.intellij.codeHighlighting.TextEditorHighlightingPass; +import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory; +import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar; +import com.intellij.openapi.components.AbstractProjectComponent; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +/** + * @author cdr +*/ +public class InjectedCodeFoldingPassFactory extends AbstractProjectComponent implements TextEditorHighlightingPassFactory { + public InjectedCodeFoldingPassFactory(Project project, TextEditorHighlightingPassRegistrar highlightingPassRegistrar) { + super(project); + highlightingPassRegistrar.registerTextEditorHighlightingPass(this, new int[]{Pass.UPDATE_ALL}, null, false, -1); + } + + @NonNls + @NotNull + public String getComponentName() { + return "InjectedCodeFoldingPassFactory"; + } + + @NotNull + public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull final Editor editor) { + return new InjectedCodeFoldingPass(myProject, editor, file); + } +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java index 25716dc80a1c..5ef9445a3357 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java @@ -36,16 +36,16 @@ import java.util.Comparator; import java.util.List; import java.util.TreeMap; -class FoldingUpdate { +public class FoldingUpdate { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.folding.impl.FoldingUpdate"); private static final Key LAST_UPDATE_STAMP_KEY = Key.create("LAST_UPDATE_STAMP_KEY"); private static final Comparator COMPARE_BY_OFFSET = new Comparator() { - public int compare(PsiElement element, PsiElement element1) { - int startOffsetDiff = element.getTextRange().getStartOffset() - element1.getTextRange().getStartOffset(); - return startOffsetDiff == 0 ? element.getTextRange().getEndOffset() - element1.getTextRange().getEndOffset() : startOffsetDiff; - } - }; + public int compare(PsiElement element, PsiElement element1) { + int startOffsetDiff = element.getTextRange().getStartOffset() - element1.getTextRange().getStartOffset(); + return startOffsetDiff == 0 ? element.getTextRange().getEndOffset() - element1.getTextRange().getEndOffset() : startOffsetDiff; + } + }; private FoldingUpdate() { } @@ -69,14 +69,7 @@ class FoldingUpdate { final TreeMap elementsToFoldMap = new TreeMap(COMPARE_BY_OFFSET); getFoldingsFor(file, document, elementsToFoldMap, quick); - List injectedDocuments = InjectedLanguageUtil.getCachedInjectedDocuments(file); - for (DocumentWindow injectedDocument : injectedDocuments) { - PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(injectedDocument); - if (psiFile == null || !psiFile.isValid() || !injectedDocument.isValid()) continue; - getFoldingsFor(psiFile, injectedDocument, elementsToFoldMap, quick); - } - - final Runnable operation = new UpdateFoldRegionsOperation(editor, elementsToFoldMap, applyDefaultState); + final Runnable operation = new UpdateFoldRegionsOperation(project, editor, elementsToFoldMap, applyDefaultState, false); return new Runnable() { public void run() { editor.getFoldingModel().runBatchFoldingOperationDoNotCollapseCaret(operation); @@ -87,6 +80,39 @@ class FoldingUpdate { }; } + private static final Key LAST_UPDATE_INJECTED_STAMP_KEY = Key.create("LAST_UPDATE_INJECTED_STAMP_KEY"); + @Nullable + public static Runnable updateInjectedFoldRegions(@NotNull final Editor editor, @NotNull PsiFile file) { + if (file instanceof PsiCompiledElement) return null; + ApplicationManager.getApplication().assertReadAccessAllowed(); + + final Project project = file.getProject(); + Document document = editor.getDocument(); + LOG.assertTrue(!PsiDocumentManager.getInstance(project).isUncommited(document)); + + final long timeStamp = document.getModificationStamp(); + Object lastTimeStamp = editor.getUserData(LAST_UPDATE_INJECTED_STAMP_KEY); + if (lastTimeStamp instanceof Long && ((Long)lastTimeStamp).longValue() == timeStamp) return null; + + final TreeMap elementsToFoldMap = new TreeMap(COMPARE_BY_OFFSET); + + List injectedDocuments = InjectedLanguageUtil.getCachedInjectedDocuments(file); + if (injectedDocuments.isEmpty()) return null; + for (DocumentWindow injectedDocument : injectedDocuments) { + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(injectedDocument); + if (psiFile == null || !psiFile.isValid() || !injectedDocument.isValid()) continue; + getFoldingsFor(psiFile, injectedDocument, elementsToFoldMap, false); + } + + final Runnable operation = new UpdateFoldRegionsOperation(project, editor, elementsToFoldMap, false, true); + return new Runnable() { + public void run() { + editor.getFoldingModel().runBatchFoldingOperationDoNotCollapseCaret(operation); + editor.putUserData(LAST_UPDATE_INJECTED_STAMP_KEY, timeStamp); + } + }; + } + private static void getFoldingsFor(PsiFile file, Document document, TreeMap elementsToFoldMap, boolean quick) { final FileViewProvider viewProvider = file.getViewProvider(); for (final Language language : viewProvider.getLanguages()) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/UpdateFoldRegionsOperation.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/UpdateFoldRegionsOperation.java index 939001b8b314..9cbca86e2040 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/UpdateFoldRegionsOperation.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/UpdateFoldRegionsOperation.java @@ -17,34 +17,43 @@ package com.intellij.codeInsight.folding.impl; import com.intellij.lang.folding.FoldingDescriptor; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.FoldRegion; import com.intellij.openapi.editor.FoldingGroup; import com.intellij.openapi.editor.ex.FoldingModelEx; import com.intellij.openapi.editor.impl.FoldRegionImpl; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; -import static com.intellij.util.containers.CollectionFactory.arrayList; -import static com.intellij.util.containers.CollectionFactory.newTroveMap; +import com.intellij.psi.PsiFile; import com.intellij.util.containers.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; +import static com.intellij.util.containers.CollectionFactory.arrayList; +import static com.intellij.util.containers.CollectionFactory.newTroveMap; + /** * @author cdr */ class UpdateFoldRegionsOperation implements Runnable { + private final Project myProject; private final Editor myEditor; private final boolean myApplyDefaultState; private final TreeMap myElementsToFoldMap; + private final boolean myForInjected; - UpdateFoldRegionsOperation(Editor editor, TreeMap elementsToFoldMap, boolean applyDefaultState) { + UpdateFoldRegionsOperation(Project project, Editor editor, TreeMap elementsToFoldMap, boolean applyDefaultState, + boolean forInjected) { + myProject = project; myEditor = editor; myApplyDefaultState = applyDefaultState; myElementsToFoldMap = elementsToFoldMap; + myForInjected = forInjected; } public void run() { @@ -63,14 +72,8 @@ class UpdateFoldRegionsOperation implements Runnable { private static void applyExpandStatus(List newRegions, Map shouldExpand, Map groupExpand) { for (final FoldRegion region : newRegions) { - final Boolean expanded; final FoldingGroup group = region.getGroup(); - if (group != null) { - expanded = groupExpand.get(group); - } - else { - expanded = shouldExpand.get(region); - } + final Boolean expanded = group == null ? shouldExpand.get(region) : groupExpand.get(group); if (expanded != null) { region.setExpanded(expanded.booleanValue()); @@ -121,8 +124,14 @@ class UpdateFoldRegionsOperation implements Runnable { private void removeInvalidRegions(EditorFoldingInfo info, FoldingModelEx foldingModel, HashMap rangeToExpandStatusMap) { List toRemove = arrayList(); + InjectedLanguageManager injectedManager = InjectedLanguageManager.getInstance(myProject); for (FoldRegion region : foldingModel.getAllFoldRegions()) { PsiElement element = info.getPsiElement(region); + if (element != null) { + PsiFile containingFile = element.getContainingFile(); + boolean isInjected = injectedManager.isInjectedFragment(containingFile); + if (isInjected != myForInjected) continue; + } if (element != null && myElementsToFoldMap.containsKey(element)) { final FoldingDescriptor descriptor = myElementsToFoldMap.get(element); TextRange range = descriptor.getRange(); @@ -141,15 +150,13 @@ class UpdateFoldRegionsOperation implements Runnable { myElementsToFoldMap.remove(element); } } + else if (region.isValid() && info.isLightRegion(region)) { + boolean isExpanded = region.isExpanded(); + rangeToExpandStatusMap.put(new TextRange(region.getStartOffset(), region.getEndOffset()), + isExpanded ? Boolean.TRUE : Boolean.FALSE); + } else { - if (region.isValid() && info.isLightRegion(region)) { - boolean isExpanded = region.isExpanded(); - rangeToExpandStatusMap.put(new TextRange(region.getStartOffset(), region.getEndOffset()), - isExpanded ? Boolean.TRUE : Boolean.FALSE); - } - else { - toRemove.add(region); - } + toRemove.add(region); } } diff --git a/platform/platform-resources/src/componentSets/Lang.xml b/platform/platform-resources/src/componentSets/Lang.xml index 3e34154708fd..e36f71acfced 100644 --- a/platform/platform-resources/src/componentSets/Lang.xml +++ b/platform/platform-resources/src/componentSets/Lang.xml @@ -151,6 +151,10 @@ com.intellij.codeInsight.daemon.impl.CodeFoldingPassFactory + + com.intellij.codeInsight.daemon.impl.InjectedCodeFoldingPassFactory + + com.intellij.codeInsight.daemon.impl.LocalInspectionsPassFactory