clone language annotator for each thread which allows unsynchronized execution and hence more concurrency

This commit is contained in:
Alexey Kudravtsev
2009-11-02 14:12:02 +03:00
parent bb62e8f638
commit 4d0e5c24d8
5 changed files with 41 additions and 35 deletions
@@ -35,8 +35,7 @@ import org.jetbrains.annotations.Nullable;
public final class RegExpAnnotator extends RegExpElementVisitor implements Annotator {
private AnnotationHolder myHolder;
// made this synchronized after running into the assertion below a couple of times.
public synchronized void annotate(PsiElement psiElement, AnnotationHolder holder) {
public void annotate(PsiElement psiElement, AnnotationHolder holder) {
assert myHolder == null : "unsupported concurrent annotator invocation";
try {
myHolder = holder;
@@ -16,6 +16,7 @@
package com.intellij.lang.annotation;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
@@ -35,5 +36,5 @@ public interface Annotator {
* @param psiElement the element to annotate.
* @param holder the container which receives annotations created by the plugin.
*/
void annotate(PsiElement psiElement, AnnotationHolder holder);
void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder holder);
}
@@ -299,11 +299,25 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
final AnnotationHolderImpl annotationHolder,
final HighlightErrorFilter[] errorFilters,
final InjectedLanguageManager injectedLanguageManager) {
Language injectedLanguage = injectedPsi.getLanguage();
runAnnotatorsForInjected(injectedPsi, annotationHolder, errorFilters, injectedLanguageManager, injectedLanguage);
highlightInjectedSyntax(injectedLanguage, injectedPsi, annotationHolder);
}
private static final PerThreadMap<Annotator,Language> cachedAnnotators = new PerThreadMap<Annotator, Language>() {
@NotNull
@Override
public Collection<Annotator> initialValue(@NotNull Language key) {
return LanguageAnnotators.INSTANCE.allForLanguage(key);
}
};
private static void runAnnotatorsForInjected(final PsiFile injectedPsi, final AnnotationHolderImpl annotationHolder,
final HighlightErrorFilter[] errorFilters, final InjectedLanguageManager injectedLanguageManager,
Language injectedLanguage) {
final DocumentWindow documentRange = ((VirtualFileWindow)injectedPsi.getViewProvider().getVirtualFile()).getDocumentWindow();
assert documentRange != null;
assert documentRange.getText().equals(injectedPsi.getText());
Language injectedLanguage = injectedPsi.getLanguage();
final List<Annotator> annotators = LanguageAnnotators.INSTANCE.allForLanguage(injectedLanguage);
final List<Annotator> annotators = cachedAnnotators.get(injectedLanguage);
final AnnotationHolderImpl fixingOffsetsHolder = new AnnotationHolderImpl() {
public boolean add(final Annotation annotation) {
return true; // we are going to hand off the annotation to the annotationHolder anyway
@@ -356,7 +370,6 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
};
injectedPsi.accept(visitor);
highlightInjectedSyntax(injectedLanguage, injectedPsi, annotationHolder);
}
private static void highlightInjectedSyntax(final Language injectedLanguage,
@@ -467,7 +480,6 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
final HighlightInfoHolder holder = createInfoHolder();
holder.setWritable(true);
final ProgressManager progressManager = ProgressManager.getInstance();
setProgressLimit((long)elements.size() * visitorArray.length);
final int chunkSize = Math.max(1, elements.size() / 100); // one percent precision is enough
@@ -117,7 +117,7 @@ public class DefaultHighlightVisitor extends PsiElementVisitor implements Highli
public static HighlightInfo createErrorElementInfo(final PsiErrorElement element) {
TextRange range = element.getTextRange();
if (range.getLength() > 0) {
if (!range.isEmpty()) {
final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, range, element.getErrorDescription());
for(ErrorQuickFixProvider provider: Extensions.getExtensions(ErrorQuickFixProvider.EP_NAME)) {
provider.registerErrorQuickFix(element, highlightInfo);
@@ -132,10 +132,7 @@ public class DefaultHighlightVisitor extends PsiElementVisitor implements Highli
String text = elementAtOffset == null ? null : elementAtOffset.getText();
HighlightInfo info;
if (offset < fileLength && text != null && !StringUtil.startsWithChar(text, '\n') && !StringUtil.startsWithChar(text, '\r')) {
int start = offset;
int end = offset + 1;
info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, start, end, element.getErrorDescription());
info.navigationShift = offset - start;
info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, offset, offset + 1, element.getErrorDescription());
}
else {
int start;
@@ -60,7 +60,7 @@ public class AnnotatorBasedInspection extends GlobalInspectionTool {
@NotNull
@Override
public String getGroupDisplayName() {
return "General";
return GENERAL_GROUP_NAME;
}
@Nls
@@ -76,12 +76,14 @@ public class AnnotatorBasedInspection extends GlobalInspectionTool {
return "Annotator";
}
private static class MyPsiRecursiveElementVisitor extends PsiRecursiveElementVisitor implements PsiLanguageInjectionHost.InjectedPsiVisitor {
private AnnotationHolder myHolder;
private static class MyPsiRecursiveElementVisitor extends PsiRecursiveElementVisitor
implements PsiLanguageInjectionHost.InjectedPsiVisitor {
private final AnnotationHolder myHolder;
private List<Annotator> annotators;
private PsiFile myFile;
public MyPsiRecursiveElementVisitor(final InspectionManager manager, final GlobalInspectionContext globalContext,
public MyPsiRecursiveElementVisitor(final InspectionManager manager,
final GlobalInspectionContext globalContext,
final ProblemDescriptionsProcessor problemDescriptionsProcessor) {
myHolder = new AnnotationHolderImpl() {
@Override
@@ -104,9 +106,13 @@ public class AnnotatorBasedInspection extends GlobalInspectionTool {
return createProblem(elt, message, ProblemHighlightType.INFORMATION, HighlightSeverity.INFORMATION, null);
}
private Annotation createProblem(PsiElement elt, String message, ProblemHighlightType problemHighlightType,
HighlightSeverity severity, TextRange range) {
GlobalInspectionUtil.createProblem(elt, message, problemHighlightType, range, manager, problemDescriptionsProcessor, globalContext);
private Annotation createProblem(PsiElement elt,
String message,
ProblemHighlightType problemHighlightType,
HighlightSeverity severity,
TextRange range) {
GlobalInspectionUtil
.createProblem(elt, message, problemHighlightType, range, manager, problemDescriptionsProcessor, globalContext);
return super.createAnnotation(elt.getTextRange(), severity, message);
}
@@ -133,15 +139,8 @@ public class AnnotatorBasedInspection extends GlobalInspectionTool {
@Override
protected Annotation createAnnotation(TextRange range, HighlightSeverity severity, String message) {
if (severity != HighlightSeverity.INFORMATION) {
GlobalInspectionUtil.createProblem(
myFile,
message,
HighlightInfo.convertSeverityToProblemHighlight(severity),
range,
manager,
problemDescriptionsProcessor,
globalContext
);
GlobalInspectionUtil.createProblem(myFile, message, HighlightInfo.convertSeverityToProblemHighlight(severity), range, manager,
problemDescriptionsProcessor, globalContext);
}
return super.createAnnotation(range, severity, message);
}
@@ -158,12 +157,9 @@ public class AnnotatorBasedInspection extends GlobalInspectionTool {
public void visitElement(PsiElement element) {
super.visitElement(element);
List<Annotator> annotators = this.annotators != null ?
this.annotators:LanguageAnnotators.INSTANCE.allForLanguage(element.getLanguage());
if (!annotators.isEmpty()) {
for(Annotator annotator:annotators) {
annotator.annotate(element, myHolder);
}
List<Annotator> elemAnnos = annotators != null ? annotators : LanguageAnnotators.INSTANCE.allForLanguage(element.getLanguage());
for (Annotator annotator : elemAnnos) {
annotator.annotate(element, myHolder);
}
if (element instanceof PsiLanguageInjectionHost) {
((PsiLanguageInjectionHost)element).processInjectedPsi(this);
@@ -174,7 +170,8 @@ public class AnnotatorBasedInspection extends GlobalInspectionTool {
try {
annotators = LanguageAnnotators.INSTANCE.allForLanguage(injectedPsi.getLanguage());
injectedPsi.acceptChildren(this);
} finally {
}
finally {
annotators = null;
}
}