use of com.intellij.openapi.editor.RangeMarker in project intellij-community by JetBrains.
the class UpdateHighlightersUtil method setHighlightersOutsideRange.
// set highlights inside startOffset,endOffset but outside priorityRange
static void setHighlightersOutsideRange(@NotNull final Project project, @NotNull final Document document, @NotNull final PsiFile psiFile, @NotNull final List<HighlightInfo> infos, @Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used
final int startOffset, final int endOffset, @NotNull final ProperTextRange priorityRange, final int group) {
ApplicationManager.getApplication().assertIsDispatchThread();
final DaemonCodeAnalyzerEx codeAnalyzer = DaemonCodeAnalyzerEx.getInstanceEx(project);
if (startOffset == 0 && endOffset == document.getTextLength()) {
codeAnalyzer.cleanFileLevelHighlights(project, group, psiFile);
}
final MarkupModel markup = DocumentMarkupModel.forDocument(document, project, true);
assertMarkupConsistent(markup, project);
final SeverityRegistrar severityRegistrar = SeverityRegistrar.getSeverityRegistrar(project);
final HighlightersRecycler infosToRemove = new HighlightersRecycler();
ContainerUtil.quickSort(infos, BY_START_OFFSET_NODUPS);
Set<HighlightInfo> infoSet = new THashSet<>(infos);
Processor<HighlightInfo> processor = info -> {
if (info.getGroup() == group) {
RangeHighlighter highlighter = info.getHighlighter();
int hiStart = highlighter.getStartOffset();
int hiEnd = highlighter.getEndOffset();
if (!info.isFromInjection() && hiEnd < document.getTextLength() && (hiEnd <= startOffset || hiStart >= endOffset)) {
return true;
}
boolean toRemove = infoSet.contains(info) || !priorityRange.containsRange(hiStart, hiEnd) && (hiEnd != document.getTextLength() || priorityRange.getEndOffset() != document.getTextLength());
if (toRemove) {
infosToRemove.recycleHighlighter(highlighter);
info.setHighlighter(null);
}
}
return true;
};
DaemonCodeAnalyzerEx.processHighlightsOverlappingOutside(document, project, null, priorityRange.getStartOffset(), priorityRange.getEndOffset(), processor);
final Map<TextRange, RangeMarker> ranges2markersCache = new THashMap<>(10);
final boolean[] changed = { false };
RangeMarkerTree.sweep((RangeMarkerTree.Generator<HighlightInfo>) processor1 -> ContainerUtil.process(infos, processor1), (offset, info, atStart, overlappingIntervals) -> {
if (!atStart)
return true;
// injections are oblivious to restricting range
if (!info.isFromInjection() && info.getEndOffset() < document.getTextLength() && (info.getEndOffset() <= startOffset || info.getStartOffset() >= endOffset))
return true;
if (info.isFileLevelAnnotation()) {
codeAnalyzer.addFileLevelHighlight(project, group, info, psiFile);
changed[0] = true;
return true;
}
if (isWarningCoveredByError(info, overlappingIntervals, severityRegistrar)) {
return true;
}
if (info.getStartOffset() < priorityRange.getStartOffset() || info.getEndOffset() > priorityRange.getEndOffset()) {
createOrReuseHighlighterFor(info, colorsScheme, document, group, psiFile, (MarkupModelEx) markup, infosToRemove, ranges2markersCache, severityRegistrar);
changed[0] = true;
}
return true;
});
for (RangeHighlighter highlighter : infosToRemove.forAllInGarbageBin()) {
highlighter.dispose();
changed[0] = true;
}
if (changed[0]) {
clearWhiteSpaceOptimizationFlag(document);
}
assertMarkupConsistent(markup, project);
}
use of com.intellij.openapi.editor.RangeMarker in project intellij-community by JetBrains.
the class UpdateHighlightersUtil method createOrReuseHighlighterFor.
private static void createOrReuseHighlighterFor(@NotNull final HighlightInfo info, // if null global scheme will be used
@Nullable final EditorColorsScheme colorsScheme, @NotNull final Document document, final int group, @NotNull final PsiFile psiFile, @NotNull MarkupModelEx markup, @Nullable HighlightersRecycler infosToRemove, @NotNull final Map<TextRange, RangeMarker> ranges2markersCache, @NotNull SeverityRegistrar severityRegistrar) {
int infoStartOffset = info.startOffset;
int infoEndOffset = info.endOffset;
final int docLength = document.getTextLength();
if (infoEndOffset > docLength) {
infoEndOffset = docLength;
infoStartOffset = Math.min(infoStartOffset, infoEndOffset);
}
if (infoEndOffset == infoStartOffset && !info.isAfterEndOfLine()) {
// empty highlighter beyond file boundaries
if (infoEndOffset == docLength)
return;
//show something in case of empty highlightinfo
infoEndOffset++;
}
info.setGroup(group);
int layer = getLayer(info, severityRegistrar);
RangeHighlighterEx highlighter = infosToRemove == null ? null : (RangeHighlighterEx) infosToRemove.pickupHighlighterFromGarbageBin(info.startOffset, info.endOffset, layer);
final TextRange finalInfoRange = new TextRange(infoStartOffset, infoEndOffset);
final TextAttributes infoAttributes = info.getTextAttributes(psiFile, colorsScheme);
Consumer<RangeHighlighterEx> changeAttributes = finalHighlighter -> {
if (infoAttributes != null) {
finalHighlighter.setTextAttributes(infoAttributes);
}
info.setHighlighter(finalHighlighter);
finalHighlighter.setAfterEndOfLine(info.isAfterEndOfLine());
Color color = info.getErrorStripeMarkColor(psiFile, colorsScheme);
finalHighlighter.setErrorStripeMarkColor(color);
if (info != finalHighlighter.getErrorStripeTooltip()) {
finalHighlighter.setErrorStripeTooltip(info);
}
GutterMark renderer = info.getGutterIconRenderer();
finalHighlighter.setGutterIconRenderer((GutterIconRenderer) renderer);
ranges2markersCache.put(finalInfoRange, info.getHighlighter());
if (info.quickFixActionRanges != null) {
List<Pair<HighlightInfo.IntentionActionDescriptor, RangeMarker>> list = new ArrayList<>(info.quickFixActionRanges.size());
for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
TextRange textRange = pair.second;
RangeMarker marker = getOrCreate(document, ranges2markersCache, textRange);
list.add(Pair.create(pair.first, marker));
}
info.quickFixActionMarkers = ContainerUtil.createLockFreeCopyOnWriteList(list);
}
ProperTextRange fixRange = info.getFixTextRange();
if (finalInfoRange.equals(fixRange)) {
info.fixMarker = null;
} else {
info.fixMarker = getOrCreate(document, ranges2markersCache, fixRange);
}
};
if (highlighter == null) {
highlighter = markup.addRangeHighlighterAndChangeAttributes(infoStartOffset, infoEndOffset, layer, null, HighlighterTargetArea.EXACT_RANGE, false, changeAttributes);
} else {
markup.changeAttributesInBatch(highlighter, changeAttributes);
}
boolean attributesSet = Comparing.equal(infoAttributes, highlighter.getTextAttributes());
assert attributesSet : "Info: " + infoAttributes + "; colorsScheme: " + (colorsScheme == null ? "[global]" : colorsScheme.getName()) + "; highlighter:" + highlighter.getTextAttributes();
}
use of com.intellij.openapi.editor.RangeMarker in project intellij-community by JetBrains.
the class UpdateHighlightersUtil method setHighlightersInRange.
static void setHighlightersInRange(@NotNull final Project project, @NotNull final Document document, @NotNull final TextRange range, // if null global scheme will be used
@Nullable final EditorColorsScheme colorsScheme, @NotNull final List<HighlightInfo> infos, @NotNull final MarkupModelEx markup, final int group) {
ApplicationManager.getApplication().assertIsDispatchThread();
final SeverityRegistrar severityRegistrar = SeverityRegistrar.getSeverityRegistrar(project);
final HighlightersRecycler infosToRemove = new HighlightersRecycler();
DaemonCodeAnalyzerEx.processHighlights(document, project, null, range.getStartOffset(), range.getEndOffset(), info -> {
if (info.getGroup() == group) {
RangeHighlighter highlighter = info.getHighlighter();
int hiStart = highlighter.getStartOffset();
int hiEnd = highlighter.getEndOffset();
boolean willBeRemoved = hiEnd == document.getTextLength() && range.getEndOffset() == document.getTextLength() || range.containsRange(hiStart, hiEnd);
if (willBeRemoved) {
infosToRemove.recycleHighlighter(highlighter);
info.setHighlighter(null);
}
}
return true;
});
ContainerUtil.quickSort(infos, BY_START_OFFSET_NODUPS);
final Map<TextRange, RangeMarker> ranges2markersCache = new THashMap<>(10);
final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
final DaemonCodeAnalyzerEx codeAnalyzer = DaemonCodeAnalyzerEx.getInstanceEx(project);
final boolean[] changed = { false };
RangeMarkerTree.sweep((RangeMarkerTree.Generator<HighlightInfo>) processor -> ContainerUtil.process(infos, processor), (offset, info, atStart, overlappingIntervals) -> {
if (!atStart) {
return true;
}
if (info.isFileLevelAnnotation() && psiFile != null && psiFile.getViewProvider().isPhysical()) {
codeAnalyzer.addFileLevelHighlight(project, group, info, psiFile);
changed[0] = true;
return true;
}
if (isWarningCoveredByError(info, overlappingIntervals, severityRegistrar)) {
return true;
}
if (info.getStartOffset() >= range.getStartOffset() && info.getEndOffset() <= range.getEndOffset() && psiFile != null) {
createOrReuseHighlighterFor(info, colorsScheme, document, group, psiFile, markup, infosToRemove, ranges2markersCache, severityRegistrar);
changed[0] = true;
}
return true;
});
for (RangeHighlighter highlighter : infosToRemove.forAllInGarbageBin()) {
highlighter.dispose();
changed[0] = true;
}
if (changed[0]) {
clearWhiteSpaceOptimizationFlag(document);
}
assertMarkupConsistent(markup, project);
}
use of com.intellij.openapi.editor.RangeMarker in project intellij-community by JetBrains.
the class CreateMethodFromUsageFix method doCreate.
public static void doCreate(PsiClass targetClass, PsiMethod method, boolean shouldBeAbstract, List<Pair<PsiExpression, PsiType>> arguments, PsiSubstitutor substitutor, ExpectedTypeInfo[] expectedTypes, @Nullable final PsiElement context) {
method = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(method);
if (method == null) {
return;
}
final Project project = targetClass.getProject();
final PsiFile targetFile = targetClass.getContainingFile();
Document document = PsiDocumentManager.getInstance(project).getDocument(targetFile);
if (document == null)
return;
TemplateBuilderImpl builder = new TemplateBuilderImpl(method);
CreateFromUsageUtils.setupMethodParameters(method, builder, context, substitutor, arguments);
final PsiTypeElement returnTypeElement = method.getReturnTypeElement();
if (returnTypeElement != null) {
new GuessTypeParameters(JavaPsiFacade.getInstance(project).getElementFactory()).setupTypeElement(returnTypeElement, expectedTypes, substitutor, builder, context, targetClass);
}
PsiCodeBlock body = method.getBody();
builder.setEndVariableAfter(shouldBeAbstract || body == null ? method : body.getLBrace());
method = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(method);
if (method == null)
return;
RangeMarker rangeMarker = document.createRangeMarker(method.getTextRange());
final Editor newEditor = positionCursor(project, targetFile, method);
if (newEditor == null)
return;
Template template = builder.buildTemplate();
newEditor.getCaretModel().moveToOffset(rangeMarker.getStartOffset());
newEditor.getDocument().deleteString(rangeMarker.getStartOffset(), rangeMarker.getEndOffset());
rangeMarker.dispose();
if (!shouldBeAbstract) {
startTemplate(newEditor, template, project, new TemplateEditingAdapter() {
@Override
public void templateFinished(Template template, boolean brokenOff) {
if (brokenOff)
return;
WriteCommandAction.runWriteCommandAction(project, () -> {
PsiDocumentManager.getInstance(project).commitDocument(newEditor.getDocument());
final int offset = newEditor.getCaretModel().getOffset();
PsiMethod method1 = PsiTreeUtil.findElementOfClassAtOffset(targetFile, offset - 1, PsiMethod.class, false);
if (method1 != null) {
try {
CreateFromUsageUtils.setupMethodBody(method1);
} catch (IncorrectOperationException e) {
LOG.error(e);
}
CreateFromUsageUtils.setupEditor(method1, newEditor);
}
});
}
});
} else {
startTemplate(newEditor, template, project);
}
}
use of com.intellij.openapi.editor.RangeMarker in project intellij-community by JetBrains.
the class GuardBlockTest method testZero.
public void testZero() throws Exception {
myFixture.configureByText("x.txt", "xxxx");
RangeMarker guard = createGuard(0, 0);
guard.setGreedyToLeft(true);
guard.setGreedyToRight(true);
checkUnableToTypeIn(0);
checkCanTypeIn(1);
}
Aggregations