memory: reduce number of indirections and classes

This commit is contained in:
Alexey Kudravtsev
2014-12-29 13:54:42 +03:00
parent 4890af7606
commit 9ddb565fcf
4 changed files with 312 additions and 490 deletions
@@ -144,9 +144,9 @@ public class MarkupModelImpl extends UserDataHolderBase implements MarkupModelEx
public void changeAttributesInBatch(@NotNull RangeHighlighterEx highlighter,
@NotNull Consumer<RangeHighlighterEx> changeAttributesAction) {
ApplicationManager.getApplication().assertIsDispatchThread();
RangeHighlighterData.ChangeResult changed = ((RangeHighlighterImpl)highlighter).changeAttributesNoEvents(changeAttributesAction);
if (changed != RangeHighlighterData.ChangeResult.NOT_CHANGED) {
fireAttributesChanged(highlighter, changed == RangeHighlighterData.ChangeResult.RENDERERS_CHANGED);
RangeHighlighterImpl.ChangeResult changed = ((RangeHighlighterImpl)highlighter).changeAttributesNoEvents(changeAttributesAction);
if (changed != RangeHighlighterImpl.ChangeResult.NOT_CHANGED) {
fireAttributesChanged(highlighter, changed == RangeHighlighterImpl.ChangeResult.RENDERERS_CHANGED);
}
}
@@ -213,7 +213,7 @@ public class MarkupModelImpl extends UserDataHolderBase implements MarkupModelEx
});
}
public void removeMarkupModelListener(@NotNull MarkupModelListener listener) {
void removeMarkupModelListener(@NotNull MarkupModelListener listener) {
boolean success = myListeners.remove(listener);
LOG.assertTrue(success);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 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.
@@ -32,6 +32,7 @@ import org.jetbrains.annotations.Nullable;
* @author max
*/
class PersistentRangeHighlighterImpl extends RangeHighlighterImpl implements RangeHighlighterEx {
private int myLine; // for PersistentRangeHighlighterImpl only
static PersistentRangeHighlighterImpl create(@NotNull MarkupModel model,
int offset,
int layer,
@@ -51,7 +52,7 @@ class PersistentRangeHighlighterImpl extends RangeHighlighterImpl implements Ran
@Nullable TextAttributes textAttributes) {
super(model, startOffset, model.getDocument().getLineEndOffset(line), layer, target, textAttributes, false, false);
setLine(line);
myLine = line;
}
@Override
@@ -66,33 +67,33 @@ class PersistentRangeHighlighterImpl extends RangeHighlighterImpl implements Ran
if (!wasTranslatedViaDiff) {
super.changedUpdateImpl(e);
if (isValid()) {
setLine(getDocument().getLineNumber(getStartOffset()));
myLine = getDocument().getLineNumber(getStartOffset());
int endLine = getDocument().getLineNumber(getEndOffset());
if (endLine != getLine()) {
setIntervalEnd(getDocument().getLineEndOffset(getLine()));
if (endLine != myLine) {
setIntervalEnd(getDocument().getLineEndOffset(myLine));
}
}
}
if (isValid() && getTargetArea() == HighlighterTargetArea.LINES_IN_RANGE) {
setIntervalStart(DocumentUtil.getFirstNonSpaceCharOffset(getDocument(), getLine()));
setIntervalEnd(getDocument().getLineEndOffset(getLine()));
setIntervalStart(DocumentUtil.getFirstNonSpaceCharOffset(getDocument(), myLine));
setIntervalEnd(getDocument().getLineEndOffset(myLine));
}
}
private boolean translatedViaDiff(DocumentEvent e, DocumentEventImpl event) {
try {
setLine(event.translateLineViaDiff(getLine()));
myLine = event.translateLineViaDiff(myLine);
}
catch (FilesTooBigForDiffException ignored) {
return false;
}
if (getLine() < 0 || getLine() >= getDocument().getLineCount()) {
if (myLine < 0 || myLine >= getDocument().getLineCount()) {
invalidate(e);
}
else {
DocumentEx document = getDocument();
setIntervalStart(document.getLineStartOffset(getLine()));
setIntervalEnd(document.getLineEndOffset(getLine()));
setIntervalStart(document.getLineStartOffset(myLine));
setIntervalEnd(document.getLineEndOffset(myLine));
}
return true;
}
@@ -101,16 +102,7 @@ class PersistentRangeHighlighterImpl extends RangeHighlighterImpl implements Ran
public String toString() {
return "PersistentRangeHighlighter" +
(isGreedyToLeft() ? "[" : "(") +
(isValid() ? "valid" : "invalid") + "," + getStartOffset() + "," + getEndOffset() + " - " + getLine() +
(isValid() ? "valid" : "invalid") + "," + getStartOffset() + "," + getEndOffset() + " - " + myLine +
(isGreedyToRight() ? "]" : ")");
}
// delegates
private int getLine() {
return getData().myLine;
}
private void setLine(int line) {
getData().myLine = line;
}
}
@@ -1,308 +0,0 @@
/*
* 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.
* 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.openapi.editor.impl;
import com.intellij.codeInsight.daemon.GutterMark;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.ex.MarkupModelEx;
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
import com.intellij.openapi.editor.markup.*;
import com.intellij.openapi.util.Comparing;
import com.intellij.util.Consumer;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
/**
* User: cdr
*/
abstract class RangeHighlighterData {
private static final Color NULL_COLOR = new Color(0, 0, 0);
private final MarkupModel myModel;
private TextAttributes myTextAttributes;
private LineMarkerRenderer myLineMarkerRenderer;
private Color myErrorStripeColor;
private Color myLineSeparatorColor;
private SeparatorPlacement mySeparatorPlacement;
private GutterIconRenderer myGutterIconRenderer;
private Object myErrorStripeTooltip;
private MarkupEditorFilter myFilter = MarkupEditorFilter.EMPTY;
private CustomHighlighterRenderer myCustomRenderer;
int myLine; // for PersistentRangeHighlighterImpl only
private LineSeparatorRenderer myLineSeparatorRenderer;
private byte myFlags;
RangeHighlighterData(@NotNull MarkupModel model,
@NotNull HighlighterTargetArea target,
TextAttributes textAttributes) {
myTextAttributes = textAttributes;
setFlag(TARGET_AREA_IS_EXACT_FLAG, target == HighlighterTargetArea.EXACT_RANGE);
myModel = model;
}
private static final int AFTER_END_OF_LINE_FLAG = 0;
private static final int ERROR_STRIPE_IS_THIN_FLAG = 1;
private static final int TARGET_AREA_IS_EXACT_FLAG = 2;
private static final int IN_BATCH_CHANGE_FLAG = 3;
private static final int CHANGED_FLAG = 4;
private static final int RENDERERS_CHANGED_FLAG = 5;
@MagicConstant(intValues = {AFTER_END_OF_LINE_FLAG, ERROR_STRIPE_IS_THIN_FLAG, TARGET_AREA_IS_EXACT_FLAG, IN_BATCH_CHANGE_FLAG, CHANGED_FLAG, RENDERERS_CHANGED_FLAG})
private @interface FlagConstant {}
private boolean isFlagSet(@FlagConstant int flag) {
int state = myFlags >> flag;
return (state & 1) != 0;
}
private void setFlag(@FlagConstant int flag, boolean value) {
assert flag < 8;
int state = value ? 1 : 0;
myFlags = (byte)(myFlags & ~(1 << flag) | state << flag);
}
@NotNull
public abstract RangeHighlighterEx getRangeHighlighter();
public TextAttributes getTextAttributes() {
return myTextAttributes;
}
public void setTextAttributes(TextAttributes textAttributes) {
TextAttributes old = myTextAttributes;
myTextAttributes = textAttributes;
if (!Comparing.equal(old, textAttributes)) {
fireChanged(false);
}
}
@NotNull
HighlighterTargetArea getTargetArea() {
return isFlagSet(TARGET_AREA_IS_EXACT_FLAG) ? HighlighterTargetArea.EXACT_RANGE : HighlighterTargetArea.LINES_IN_RANGE;
}
LineMarkerRenderer getLineMarkerRenderer() {
return myLineMarkerRenderer;
}
void setLineMarkerRenderer(LineMarkerRenderer renderer) {
LineMarkerRenderer old = myLineMarkerRenderer;
myLineMarkerRenderer = renderer;
if (!Comparing.equal(old, renderer)) {
fireChanged(true);
}
}
CustomHighlighterRenderer getCustomRenderer() {
return myCustomRenderer;
}
void setCustomRenderer(CustomHighlighterRenderer renderer) {
CustomHighlighterRenderer old = myCustomRenderer;
myCustomRenderer = renderer;
if (!Comparing.equal(old, renderer)) {
fireChanged(true);
}
}
public GutterIconRenderer getGutterIconRenderer() {
return myGutterIconRenderer;
}
public void setGutterIconRenderer(GutterIconRenderer renderer) {
GutterMark old = myGutterIconRenderer;
myGutterIconRenderer = renderer;
if (!Comparing.equal(old, renderer)) {
fireChanged(true);
}
}
Color getErrorStripeMarkColor() {
if (myErrorStripeColor == NULL_COLOR) return null;
if (myErrorStripeColor != null) return myErrorStripeColor;
if (myTextAttributes != null) return myTextAttributes.getErrorStripeColor();
return null;
}
public void setErrorStripeMarkColor(Color color) {
if (color == null) color = NULL_COLOR;
Color old = myErrorStripeColor;
myErrorStripeColor = color;
if (!Comparing.equal(old, color)) {
fireChanged(false);
}
}
public Object getErrorStripeTooltip() {
return myErrorStripeTooltip;
}
public void setErrorStripeTooltip(Object tooltipObject) {
ApplicationManager.getApplication().assertIsDispatchThread();
Object old = myErrorStripeTooltip;
myErrorStripeTooltip = tooltipObject;
if (!Comparing.equal(old, tooltipObject)) {
fireChanged(false);
}
}
boolean isThinErrorStripeMark() {
return isFlagSet(ERROR_STRIPE_IS_THIN_FLAG);
}
void setThinErrorStripeMark(boolean value) {
ApplicationManager.getApplication().assertIsDispatchThread();
boolean old = isThinErrorStripeMark();
setFlag(ERROR_STRIPE_IS_THIN_FLAG, value);
if (old != value) {
fireChanged(false);
}
}
Color getLineSeparatorColor() {
return myLineSeparatorColor;
}
void setLineSeparatorColor(Color color) {
Color old = myLineSeparatorColor;
myLineSeparatorColor = color;
if (!Comparing.equal(old, color)) {
fireChanged(false);
}
}
SeparatorPlacement getLineSeparatorPlacement() {
return mySeparatorPlacement;
}
void setLineSeparatorPlacement(@Nullable SeparatorPlacement placement) {
SeparatorPlacement old = mySeparatorPlacement;
mySeparatorPlacement = placement;
if (!Comparing.equal(old, placement)) {
fireChanged(false);
}
}
void setEditorFilter(@NotNull MarkupEditorFilter filter) {
myFilter = filter;
fireChanged(false);
}
@NotNull
MarkupEditorFilter getEditorFilter() {
return myFilter;
}
public boolean isAfterEndOfLine() {
return isFlagSet(AFTER_END_OF_LINE_FLAG);
}
void setAfterEndOfLine(boolean afterEndOfLine) {
boolean old = isAfterEndOfLine();
setFlag(AFTER_END_OF_LINE_FLAG, afterEndOfLine);
if (old != afterEndOfLine) {
fireChanged(false);
}
}
private void fireChanged(boolean renderersChanged) {
if (myModel instanceof MarkupModelEx) {
if (isFlagSet(IN_BATCH_CHANGE_FLAG)) {
setFlag(CHANGED_FLAG, true);
if (renderersChanged) {
setFlag(RENDERERS_CHANGED_FLAG, true);
}
}
else {
((MarkupModelEx)myModel).fireAttributesChanged(getRangeHighlighter(), renderersChanged);
}
}
}
int getAffectedAreaStartOffset() {
int startOffset = getRangeHighlighter().getStartOffset();
switch (getTargetArea()) {
case EXACT_RANGE:
return startOffset;
case LINES_IN_RANGE:
Document document = myModel.getDocument();
int textLength = document.getTextLength();
if (startOffset >= textLength) return textLength;
return document.getLineStartOffset(document.getLineNumber(startOffset));
default:
throw new IllegalStateException(getTargetArea().toString());
}
}
int getAffectedAreaEndOffset() {
int endOffset = getRangeHighlighter().getEndOffset();
switch (getTargetArea()) {
case EXACT_RANGE:
return endOffset;
case LINES_IN_RANGE:
Document document = myModel.getDocument();
int textLength = document.getTextLength();
if (endOffset >= textLength) return endOffset;
return Math.min(textLength, document.getLineEndOffset(document.getLineNumber(endOffset)) + 1);
default:
throw new IllegalStateException(getTargetArea().toString());
}
}
enum ChangeResult { NOT_CHANGED, MINOR_CHANGE, RENDERERS_CHANGED }
@NotNull
ChangeResult changeAttributesInBatch(@NotNull Consumer<RangeHighlighterEx> change) {
assert !isFlagSet(IN_BATCH_CHANGE_FLAG);
assert !isFlagSet(CHANGED_FLAG);
setFlag(IN_BATCH_CHANGE_FLAG, true);
setFlag(RENDERERS_CHANGED_FLAG, false);
ChangeResult result;
try {
change.consume(getRangeHighlighter());
}
finally {
setFlag(IN_BATCH_CHANGE_FLAG, false);
boolean changed = isFlagSet(CHANGED_FLAG);
boolean renderersChanged = isFlagSet(RENDERERS_CHANGED_FLAG);
result = changed ? renderersChanged ? ChangeResult.RENDERERS_CHANGED : ChangeResult.MINOR_CHANGE : ChangeResult.NOT_CHANGED;
setFlag(CHANGED_FLAG, false);
setFlag(RENDERERS_CHANGED_FLAG, false);
}
return result;
}
public MarkupModel getMarkupModel() {
return myModel;
}
void setLineSeparatorRenderer(LineSeparatorRenderer renderer) {
LineSeparatorRenderer old = myLineSeparatorRenderer;
myLineSeparatorRenderer = renderer;
if (!Comparing.equal(old, renderer)) {
fireChanged(true);
}
}
LineSeparatorRenderer getLineSeparatorRenderer() {
return myLineSeparatorRenderer;
}
}
@@ -15,12 +15,18 @@
*/
package com.intellij.openapi.editor.impl;
import com.intellij.codeInsight.daemon.GutterMark;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.editor.ex.MarkupModelEx;
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
import com.intellij.openapi.editor.markup.*;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Getter;
import com.intellij.util.BitUtil;
import com.intellij.util.Consumer;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,7 +37,31 @@ import java.awt.*;
* @author max
*/
class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx, Getter<RangeHighlighterEx> {
private final RangeHighlighterData data;
private static final Color NULL_COLOR = new Color(0, 0, 0);
private final MarkupModel myModel;
private TextAttributes myTextAttributes;
private LineMarkerRenderer myLineMarkerRenderer;
private Color myErrorStripeColor;
private Color myLineSeparatorColor;
private SeparatorPlacement mySeparatorPlacement;
private GutterIconRenderer myGutterIconRenderer;
private Object myErrorStripeTooltip;
private MarkupEditorFilter myFilter = MarkupEditorFilter.EMPTY;
private CustomHighlighterRenderer myCustomRenderer;
private LineSeparatorRenderer myLineSeparatorRenderer;
private byte myFlags;
private static final byte AFTER_END_OF_LINE_MASK = 1;
private static final byte ERROR_STRIPE_IS_THIN_MASK = 2;
private static final byte TARGET_AREA_IS_EXACT_MASK = 4;
private static final byte IN_BATCH_CHANGE_MASK = 8;
private static final byte CHANGED_MASK = 16;
private static final byte RENDERERS_CHANGED_MASK = 32;
@MagicConstant(intValues = {AFTER_END_OF_LINE_MASK, ERROR_STRIPE_IS_THIN_MASK, TARGET_AREA_IS_EXACT_MASK, IN_BATCH_CHANGE_MASK, CHANGED_MASK, RENDERERS_CHANGED_MASK})
private @interface FlagConstant {}
RangeHighlighterImpl(@NotNull MarkupModel model,
int start,
@@ -42,33 +72,284 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
boolean greedyToLeft,
boolean greedyToRight) {
super((DocumentEx)model.getDocument(), start, end,false);
data = new RangeHighlighterData(model, target, textAttributes) {
@NotNull
@Override
public RangeHighlighterEx getRangeHighlighter() {
return RangeHighlighterImpl.this;
}
};
myTextAttributes = textAttributes;
setFlag(TARGET_AREA_IS_EXACT_MASK, target == HighlighterTargetArea.EXACT_RANGE);
myModel = model;
registerInTree(start, end, greedyToLeft, greedyToRight, layer);
}
protected RangeHighlighterData getData() {
return data;
private boolean isFlagSet(@FlagConstant byte mask) {
return BitUtil.isSet(myFlags, mask);
}
private void setFlag(@FlagConstant byte mask, boolean value) {
myFlags = BitUtil.set(myFlags, mask, value);
}
@Override
public TextAttributes getTextAttributes() {
return myTextAttributes;
}
@Override
public void setTextAttributes(@NotNull TextAttributes textAttributes) {
TextAttributes old = myTextAttributes;
myTextAttributes = textAttributes;
if (!Comparing.equal(old, textAttributes)) {
fireChanged(false);
}
}
@Override
@NotNull
public HighlighterTargetArea getTargetArea() {
return isFlagSet(TARGET_AREA_IS_EXACT_MASK) ? HighlighterTargetArea.EXACT_RANGE : HighlighterTargetArea.LINES_IN_RANGE;
}
@Override
public LineMarkerRenderer getLineMarkerRenderer() {
return myLineMarkerRenderer;
}
@Override
public void setLineMarkerRenderer(LineMarkerRenderer renderer) {
LineMarkerRenderer old = myLineMarkerRenderer;
myLineMarkerRenderer = renderer;
if (!Comparing.equal(old, renderer)) {
fireChanged(true);
}
}
@Override
public CustomHighlighterRenderer getCustomRenderer() {
return myCustomRenderer;
}
@Override
public void setCustomRenderer(CustomHighlighterRenderer renderer) {
CustomHighlighterRenderer old = myCustomRenderer;
myCustomRenderer = renderer;
if (!Comparing.equal(old, renderer)) {
fireChanged(true);
}
}
@Override
public GutterIconRenderer getGutterIconRenderer() {
return myGutterIconRenderer;
}
@Override
public void setGutterIconRenderer(GutterIconRenderer renderer) {
GutterMark old = myGutterIconRenderer;
myGutterIconRenderer = renderer;
if (!Comparing.equal(old, renderer)) {
fireChanged(true);
}
}
@Override
public Color getErrorStripeMarkColor() {
if (myErrorStripeColor == NULL_COLOR) return null;
if (myErrorStripeColor != null) return myErrorStripeColor;
if (myTextAttributes != null) return myTextAttributes.getErrorStripeColor();
return null;
}
@Override
public void setErrorStripeMarkColor(Color color) {
if (color == null) color = NULL_COLOR;
Color old = myErrorStripeColor;
myErrorStripeColor = color;
if (!Comparing.equal(old, color)) {
fireChanged(false);
}
}
@Override
public Object getErrorStripeTooltip() {
return myErrorStripeTooltip;
}
@Override
public void setErrorStripeTooltip(Object tooltipObject) {
ApplicationManager.getApplication().assertIsDispatchThread();
Object old = myErrorStripeTooltip;
myErrorStripeTooltip = tooltipObject;
if (!Comparing.equal(old, tooltipObject)) {
fireChanged(false);
}
}
@Override
public boolean isThinErrorStripeMark() {
return isFlagSet(ERROR_STRIPE_IS_THIN_MASK);
}
@Override
public void setThinErrorStripeMark(boolean value) {
ApplicationManager.getApplication().assertIsDispatchThread();
boolean old = isThinErrorStripeMark();
setFlag(ERROR_STRIPE_IS_THIN_MASK, value);
if (old != value) {
fireChanged(false);
}
}
@Override
public Color getLineSeparatorColor() {
return myLineSeparatorColor;
}
@Override
public void setLineSeparatorColor(Color color) {
Color old = myLineSeparatorColor;
myLineSeparatorColor = color;
if (!Comparing.equal(old, color)) {
fireChanged(false);
}
}
@Override
public SeparatorPlacement getLineSeparatorPlacement() {
return mySeparatorPlacement;
}
@Override
public void setLineSeparatorPlacement(@Nullable SeparatorPlacement placement) {
SeparatorPlacement old = mySeparatorPlacement;
mySeparatorPlacement = placement;
if (!Comparing.equal(old, placement)) {
fireChanged(false);
}
}
@Override
public void setEditorFilter(@NotNull MarkupEditorFilter filter) {
myFilter = filter;
fireChanged(false);
}
@Override
@NotNull
public MarkupEditorFilter getEditorFilter() {
return myFilter;
}
@Override
public boolean isAfterEndOfLine() {
return isFlagSet(AFTER_END_OF_LINE_MASK);
}
@Override
public void setAfterEndOfLine(boolean afterEndOfLine) {
boolean old = isAfterEndOfLine();
setFlag(AFTER_END_OF_LINE_MASK, afterEndOfLine);
if (old != afterEndOfLine) {
fireChanged(false);
}
}
private void fireChanged(boolean renderersChanged) {
if (myModel instanceof MarkupModelEx) {
if (isFlagSet(IN_BATCH_CHANGE_MASK)) {
setFlag(CHANGED_MASK, true);
if (renderersChanged) {
setFlag(RENDERERS_CHANGED_MASK, true);
}
}
else {
((MarkupModelEx)myModel).fireAttributesChanged(this, renderersChanged);
}
}
}
@Override
public int getAffectedAreaStartOffset() {
int startOffset = getStartOffset();
switch (getTargetArea()) {
case EXACT_RANGE:
return startOffset;
case LINES_IN_RANGE:
Document document = myModel.getDocument();
int textLength = document.getTextLength();
if (startOffset >= textLength) return textLength;
return document.getLineStartOffset(document.getLineNumber(startOffset));
default:
throw new IllegalStateException(getTargetArea().toString());
}
}
@Override
public int getAffectedAreaEndOffset() {
int endOffset = getEndOffset();
switch (getTargetArea()) {
case EXACT_RANGE:
return endOffset;
case LINES_IN_RANGE:
Document document = myModel.getDocument();
int textLength = document.getTextLength();
if (endOffset >= textLength) return endOffset;
return Math.min(textLength, document.getLineEndOffset(document.getLineNumber(endOffset)) + 1);
default:
throw new IllegalStateException(getTargetArea().toString());
}
}
enum ChangeResult { NOT_CHANGED, MINOR_CHANGE, RENDERERS_CHANGED }
@NotNull
ChangeResult changeAttributesNoEvents(@NotNull Consumer<RangeHighlighterEx> change) {
assert !isFlagSet(IN_BATCH_CHANGE_MASK);
assert !isFlagSet(CHANGED_MASK);
setFlag(IN_BATCH_CHANGE_MASK, true);
setFlag(RENDERERS_CHANGED_MASK, false);
ChangeResult result;
try {
change.consume(this);
}
finally {
setFlag(IN_BATCH_CHANGE_MASK, false);
boolean changed = isFlagSet(CHANGED_MASK);
boolean renderersChanged = isFlagSet(RENDERERS_CHANGED_MASK);
result = changed ? renderersChanged ? ChangeResult.RENDERERS_CHANGED : ChangeResult.MINOR_CHANGE : ChangeResult.NOT_CHANGED;
setFlag(CHANGED_MASK, false);
setFlag(RENDERERS_CHANGED_MASK, false);
}
return result;
}
public MarkupModel getMarkupModel() {
return myModel;
}
@Override
public void setLineSeparatorRenderer(LineSeparatorRenderer renderer) {
LineSeparatorRenderer old = myLineSeparatorRenderer;
myLineSeparatorRenderer = renderer;
if (!Comparing.equal(old, renderer)) {
fireChanged(true);
}
}
@Override
public LineSeparatorRenderer getLineSeparatorRenderer() {
return myLineSeparatorRenderer;
}
@Override
protected void registerInTree(int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) {
// we store highlighters in MarkupModel
((MarkupModelEx)data.getMarkupModel()).addRangeHighlighter(this, start, end, greedyToLeft, greedyToRight, layer);
((MarkupModelEx)getMarkupModel()).addRangeHighlighter(this, start, end, greedyToLeft, greedyToRight, layer);
}
@Override
protected boolean unregisterInTree() {
if (!isValid()) return false;
// we store highlighters in MarkupModel
getData().getMarkupModel().removeHighlighter(this);
getMarkupModel().removeHighlighter(this);
return true;
}
@@ -77,157 +358,14 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
return this;
}
// delegates
@Override
public TextAttributes getTextAttributes() {
return getData().getTextAttributes();
}
@Override
public void setTextAttributes(@NotNull TextAttributes textAttributes) {
getData().setTextAttributes(textAttributes);
}
@NotNull
RangeHighlighterData.ChangeResult changeAttributesNoEvents(@NotNull Consumer<RangeHighlighterEx> change) {
return getData().changeAttributesInBatch(change);
}
@Override
public int getLayer() {
RangeHighlighterTree.RHNode node = (RangeHighlighterTree.RHNode)(Object)myNode;
return node == null ? -1 : node.myLayer;
}
@NotNull
@Override
public HighlighterTargetArea getTargetArea() {
return getData().getTargetArea();
}
@Override
public LineMarkerRenderer getLineMarkerRenderer() {
return getData().getLineMarkerRenderer();
}
@Override
public void setLineMarkerRenderer(LineMarkerRenderer renderer) {
getData().setLineMarkerRenderer(renderer);
}
@Override
public CustomHighlighterRenderer getCustomRenderer() {
return getData().getCustomRenderer();
}
@Override
public void setCustomRenderer(CustomHighlighterRenderer renderer) {
getData().setCustomRenderer(renderer);
}
@Override
public GutterIconRenderer getGutterIconRenderer() {
return getData().getGutterIconRenderer();
}
@Override
public void setGutterIconRenderer(GutterIconRenderer renderer) {
getData().setGutterIconRenderer(renderer);
}
@Override
public Color getErrorStripeMarkColor() {
return getData().getErrorStripeMarkColor();
}
@Override
public void setErrorStripeMarkColor(Color color) {
getData().setErrorStripeMarkColor(color);
}
@Override
public Object getErrorStripeTooltip() {
return getData().getErrorStripeTooltip();
}
@Override
public void setErrorStripeTooltip(Object tooltipObject) {
getData().setErrorStripeTooltip(tooltipObject);
}
@Override
public boolean isThinErrorStripeMark() {
return getData().isThinErrorStripeMark();
}
@Override
public void setThinErrorStripeMark(boolean value) {
getData().setThinErrorStripeMark(value);
}
@Override
public Color getLineSeparatorColor() {
return getData().getLineSeparatorColor();
}
@Override
public void setLineSeparatorColor(Color color) {
getData().setLineSeparatorColor(color);
}
@Override
public void setLineSeparatorRenderer(LineSeparatorRenderer renderer) {
getData().setLineSeparatorRenderer(renderer);
}
@Override
public LineSeparatorRenderer getLineSeparatorRenderer() {
return getData().getLineSeparatorRenderer();
}
@Override
public SeparatorPlacement getLineSeparatorPlacement() {
return getData().getLineSeparatorPlacement();
}
@Override
public void setLineSeparatorPlacement(@Nullable SeparatorPlacement placement) {
getData().setLineSeparatorPlacement(placement);
}
@Override
public void setEditorFilter(@NotNull MarkupEditorFilter filter) {
getData().setEditorFilter(filter);
}
@Override
@NotNull
public MarkupEditorFilter getEditorFilter() {
return getData().getEditorFilter();
}
@Override
public boolean isAfterEndOfLine() {
return getData().isAfterEndOfLine();
}
@Override
public void setAfterEndOfLine(boolean value) {
getData().setAfterEndOfLine(value);
}
@Override
public int getAffectedAreaStartOffset() {
return getData().getAffectedAreaStartOffset();
}
@Override
public int getAffectedAreaEndOffset() {
return getData().getAffectedAreaEndOffset();
}
@Override
public String toString() {
return "RangeHighlighter: ("+getStartOffset()+","+getEndOffset()+"); layer:"+getLayer()+"; tooltip: "+getData().getErrorStripeTooltip();
return "RangeHighlighter: ("+getStartOffset()+","+getEndOffset()+"); layer:"+getLayer()+"; tooltip: "+getErrorStripeTooltip();
}
}