do not recalc element text ranges

This commit is contained in:
Alexey Kudravtsev
2013-08-05 13:14:49 +04:00
parent af9e786d28
commit bdb101ecbf
4 changed files with 43 additions and 19 deletions
@@ -19,6 +19,7 @@ import com.intellij.lang.Language;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
@@ -41,14 +42,16 @@ public class Divider {
int endOffset,
@NotNull TextRange range,
@NotNull List<PsiElement> inside,
@NotNull List<ProperTextRange> insideRanges,
@NotNull List<PsiElement> outside,
@NotNull List<ProperTextRange> outsideRanges,
boolean includeParents,
@NotNull Condition<PsiFile> filter) {
final FileViewProvider viewProvider = file.getViewProvider();
for (Language language : viewProvider.getLanguages()) {
final PsiFile psiRoot = viewProvider.getPsi(language);
if (filter.value(psiRoot)) {
divideInsideAndOutside(psiRoot, startOffset, endOffset, range, inside, outside, includeParents);
divideInsideAndOutside(psiRoot, startOffset, endOffset, range, inside, insideRanges, outside, outsideRanges, includeParents);
}
}
}
@@ -58,7 +61,9 @@ public class Divider {
int endOffset,
@NotNull TextRange range,
@NotNull List<PsiElement> inside,
@NotNull List<ProperTextRange> insideRanges,
@NotNull List<PsiElement> outside,
@NotNull List<ProperTextRange> outsideRanges,
boolean includeParents) {
final int currentOffset = root.getTextRange().getStartOffset();
final Condition<PsiElement>[] filters = Extensions.getExtensions(CollectHighlightsUtil.EP_NAME);
@@ -102,9 +107,11 @@ public class Divider {
if (startOffset <= start && offset <= endOffset) {
if (range.containsRange(start, offset)) {
inside.add(element);
insideRanges.add(new ProperTextRange(start, offset));
}
else {
outside.add(element);
outsideRanges.add(new ProperTextRange(start, offset));
}
}
@@ -129,8 +136,15 @@ public class Divider {
CollectHighlightsUtil.findCommonParent(root, startOffset, endOffset);
while (parent != null && parent != root) {
parent = parent.getParent();
if (parent != null) outside.add(parent);
if (parent != null) {
outside.add(parent);
TextRange textRange = parent.getTextRange();
outsideRanges.add(ProperTextRange.create(textRange));
}
}
}
assert inside.size() == insideRanges.size();
assert outside.size() == outsideRanges.size();
}
}
@@ -30,6 +30,7 @@ import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.util.Processor;
@@ -103,7 +104,8 @@ public class InspectionEngine {
TextRange range = file.getTextRange();
final LocalInspectionToolSession session = new LocalInspectionToolSession(file, range.getStartOffset(), range.getEndOffset());
Divider.divideInsideAndOutside(file, range.getStartOffset(), range.getEndOffset(), range, elements, Collections.<PsiElement>emptyList(), true, Condition.TRUE);
Divider.divideInsideAndOutside(file, range.getStartOffset(), range.getEndOffset(), range, elements, new ArrayList<ProperTextRange>(),
Collections.<PsiElement>emptyList(), Collections.<ProperTextRange>emptyList(), true, Condition.TRUE);
boolean result = JobLauncher.getInstance().invokeConcurrentlyUnderProgress(tools, indicator, failFastOnAcquireReadAction,
new Processor<LocalInspectionTool>() {
@@ -201,8 +201,10 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
final List<PsiElement> outside = new ArrayList<PsiElement>();
try {
final HighlightVisitor[] filteredVisitors = filterVisitors(highlightVisitors, myFile);
Divider.divideInsideAndOutside(myFile, myStartOffset, myEndOffset, myPriorityRange, inside, outside,
false, FILE_FILTER);
List<ProperTextRange> insideRanges = new ArrayList<ProperTextRange>();
List<ProperTextRange> outsideRanges = new ArrayList<ProperTextRange>();
Divider.divideInsideAndOutside(myFile, myStartOffset, myEndOffset, myPriorityRange, inside, insideRanges, outside,
outsideRanges, false, FILE_FILTER);
setProgressLimit((long)(inside.size()+outside.size()));
@@ -212,7 +214,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
highlightTodos(myFile, myDocument.getCharsSequence(), myStartOffset, myEndOffset, progress, myPriorityRange, gotHighlights, outsideResult);
}
collectHighlights(inside, new Runnable() {
Runnable after1 = new Runnable() {
@Override
public void run() {
// all infos for the "injected fragment for the host which is inside" are indeed inside
@@ -220,12 +222,13 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
Set<HighlightInfo> injectedResult = new THashSet<HighlightInfo>();
final Set<PsiFile> injected = new THashSet<PsiFile>();
getInjectedPsiFiles(inside, outside, progress, injected);
if (!addInjectedPsiHighlights(injected, progress, Collections.synchronizedSet(injectedResult))) throw new ProcessCanceledException();
if (!addInjectedPsiHighlights(injected, progress, Collections.synchronizedSet(injectedResult)))
throw new ProcessCanceledException();
final List<HighlightInfo> injectionsOutside = new ArrayList<HighlightInfo>(gotHighlights.size());
Set<HighlightInfo> result;
synchronized (injectedResult) {
// sync here because all writes happened in another thread
// sync here because all writes happened in another thread
result = injectedResult;
}
for (HighlightInfo info : result) {
@@ -243,7 +246,8 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
}
final ProperTextRange priorityIntersection = myPriorityRange.intersection(new TextRange(myStartOffset, myEndOffset));
if ((!inside.isEmpty() || !gotHighlights.isEmpty()) && priorityIntersection != null) { // do not apply when there were no elements to highlight
if ((!inside.isEmpty() || !gotHighlights.isEmpty()) &&
priorityIntersection != null) { // do not apply when there were no elements to highlight
// clear infos found in visible area to avoid applying them twice
final List<HighlightInfo> toApplyInside = new ArrayList<HighlightInfo>(gotHighlights);
myHighlights.addAll(toApplyInside);
@@ -257,9 +261,9 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
MarkupModel markupModel = DocumentMarkupModel.forDocument(myDocument, myProject, true);
UpdateHighlightersUtil.setHighlightersInRange(myProject, myDocument, priorityIntersection, getColorsScheme(), toApplyInside,
(MarkupModelEx)markupModel, Pass.UPDATE_ALL);
(MarkupModelEx)markupModel, Pass.UPDATE_ALL);
if (myEditor != null) {
new ShowAutoImportPass(myProject, myFile, myEditor).applyInformationToEditor();
new ShowAutoImportPass(myProject, myFile, myEditor).applyInformationToEditor();
}
}
});
@@ -284,7 +288,8 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
}
};
}
}, outside, progress, filteredVisitors, gotHighlights, forceHighlightParents);
};
collectHighlights(inside, insideRanges, after1, outside, outsideRanges, progress, filteredVisitors, gotHighlights, forceHighlightParents);
if (myUpdateAll) {
((DaemonCodeAnalyzerImpl)daemonCodeAnalyzer).getFileStatusMap().setErrorFoundFlag(myDocument, myErrorFound);
@@ -589,8 +594,10 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
}
private void collectHighlights(@NotNull final List<PsiElement> elements1,
@NotNull final List<ProperTextRange> ranges1,
@NotNull final Runnable after1,
@NotNull final List<PsiElement> elements2,
@NotNull final List<ProperTextRange> ranges2,
@NotNull final ProgressIndicator progress,
@NotNull final HighlightVisitor[] visitors,
@NotNull final Set<HighlightInfo> gotHighlights,
@@ -627,6 +634,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
public void run() {
Stack<Pair<TextRange, List<HighlightInfo>>> nested = new Stack<Pair<TextRange, List<HighlightInfo>>>();
boolean failed = false;
List<ProperTextRange> ranges = ranges1;
//noinspection unchecked
for (List<PsiElement> elements : new List[]{elements1, elements2}) {
nested.clear();
@@ -672,7 +680,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
nextLimit = i + chunkSize;
}
TextRange elementRange = element.getTextRange();
TextRange elementRange = ranges.get(i);
List<HighlightInfo> infosForThisRange = holder.size() == 0 ? null : new ArrayList<HighlightInfo>(holder.size());
for (int j = 0; j < holder.size(); j++) {
final HighlightInfo info = holder.get(j);
@@ -716,7 +724,10 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
}
}
advanceProgress(elements.size() - (nextLimit-chunkSize));
if (elements == elements1) after1.run();
if (elements == elements1) {
after1.run();
ranges = ranges2;
}
}
}
};
@@ -47,10 +47,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.Trinity;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.profile.codeInspection.InspectionProjectProfileManagerImpl;
@@ -224,7 +221,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
List<PsiElement> inside = new ArrayList<PsiElement>();
List<PsiElement> outside = new ArrayList<PsiElement>();
Divider.divideInsideAndOutside(myFile, myStartOffset, myEndOffset, myPriorityRange, inside, outside,
Divider.divideInsideAndOutside(myFile, myStartOffset, myEndOffset, myPriorityRange, inside, new ArrayList<ProperTextRange>(), outside, new ArrayList<ProperTextRange>(),
true, FILE_FILTER);
MultiMap<LocalInspectionToolWrapper, String> tools = getToolsForElements(toolWrappers, checkDumbAwareness, inside, outside);