Skip to content

Commit b8d4167

Browse files
use SourceViewer.computeStyleRanges
1 parent af1f8ef commit b8d4167

1 file changed

Lines changed: 29 additions & 73 deletions

File tree

team/bundles/org.eclipse.compare/compare/org/eclipse/compare/unifieddiff/internal/UnifiedDiffCodeMiningProvider.java

Lines changed: 29 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import static org.eclipse.compare.unifieddiff.internal.UnifiedDiffManager.error;
1717
import static org.eclipse.compare.unifieddiff.internal.UnifiedDiffManager.isOverlay;
1818

19-
import java.lang.reflect.Field;
2019
import java.util.ArrayList;
2120
import java.util.HashMap;
2221
import java.util.Iterator;
@@ -33,23 +32,15 @@
3332
import org.eclipse.jface.text.BadLocationException;
3433
import org.eclipse.jface.text.Document;
3534
import org.eclipse.jface.text.IDocument;
36-
import org.eclipse.jface.text.IDocumentExtension3;
37-
import org.eclipse.jface.text.IDocumentPartitioner;
3835
import org.eclipse.jface.text.IRegion;
3936
import org.eclipse.jface.text.ITextViewer;
40-
import org.eclipse.jface.text.ITypedRegion;
4137
import org.eclipse.jface.text.Position;
4238
import org.eclipse.jface.text.Region;
43-
import org.eclipse.jface.text.TextPresentation;
44-
import org.eclipse.jface.text.TextUtilities;
4539
import org.eclipse.jface.text.codemining.AbstractCodeMiningProvider;
4640
import org.eclipse.jface.text.codemining.DocumentFooterCodeMining;
4741
import org.eclipse.jface.text.codemining.ICodeMining;
4842
import org.eclipse.jface.text.codemining.ICodeMiningProvider;
4943
import org.eclipse.jface.text.codemining.LineHeaderCodeMining;
50-
import org.eclipse.jface.text.presentation.IPresentationReconciler;
51-
import org.eclipse.jface.text.presentation.IPresentationReconcilerExtension;
52-
import org.eclipse.jface.text.presentation.IPresentationRepairer;
5344
import org.eclipse.jface.text.source.Annotation;
5445
import org.eclipse.jface.text.source.IAnnotationModel;
5546
import org.eclipse.jface.text.source.ISourceViewer;
@@ -345,7 +336,7 @@ public Point draw(GC gc, StyledText textWidget, Color color, int x, int y) {
345336
gc.fillRectangle(0, y, textWidget.getBounds().width /* result.x */, result.y);
346337

347338
String label = getLabel();
348-
List<StyleRange> ranges = getStyleRanges(viewer, label);
339+
List<StyleRange> ranges = computeStyleRanges(viewer, label);
349340
HashMap<Font, Map<Integer /* style */, Font>> styledFonts = new HashMap<>();
350341

351342
// draw darker background for detailed diff
@@ -498,7 +489,8 @@ private Point getPositionForOffset(GC gc, int offset, String str, List<StyleRang
498489
Point result = null;
499490
var before = gc.getFont();
500491
try {
501-
for (var range : ranges) {
492+
for (int i = 0; i < ranges.size(); i++) {
493+
var range = ranges.get(i);
502494
if (range.start <= offset) {
503495
int rangeEnd = range.start + range.length;
504496
if (rangeEnd > offset) {
@@ -512,8 +504,12 @@ private Point getPositionForOffset(GC gc, int offset, String str, List<StyleRang
512504
}
513505
int lfIdx = sub.lastIndexOf("\n"); //$NON-NLS-1$
514506
if (lfIdx > 0) {
515-
sub = sub.substring(lfIdx + 1);
516-
result = null;
507+
if (lfIdx == sub.length() - 1 && isLastForCurrentOffset(ranges, i, offset)) {
508+
sub = sub.substring(0, lfIdx);
509+
} else {
510+
sub = sub.substring(lfIdx + 1);
511+
result = null;
512+
}
517513
}
518514
var rangeWithFont = transformFontStyleToFont(before, range, styledFonts);
519515
if (rangeWithFont.font != null) {
@@ -537,6 +533,18 @@ private Point getPositionForOffset(GC gc, int offset, String str, List<StyleRang
537533
return result;
538534
}
539535

536+
private boolean isLastForCurrentOffset(List<StyleRange> ranges, int i, int offset) {
537+
int nextIdx = i + 1;
538+
if (nextIdx >= ranges.size()) {
539+
return false;
540+
}
541+
StyleRange next = ranges.get(nextIdx);
542+
if (next.start >= offset) {
543+
return true;
544+
}
545+
return false;
546+
}
547+
540548
private StyleRange transformFontStyleToFont(Font baseFont, StyleRange styleRange,
541549
HashMap<Font, Map<Integer /* style */, Font>> styledFonts) {
542550
// as per the StyleRange contract, only consider fontStyle if font is not
@@ -556,82 +564,30 @@ private StyleRange transformFontStyleToFont(Font baseFont, StyleRange styleRange
556564
return styleRange;
557565
}
558566

559-
private List<StyleRange> getStyleRanges(ITextViewer v, String source) {
567+
private List<StyleRange> computeStyleRanges(ITextViewer v, String source) {
560568
List<StyleRange> result = new ArrayList<>();
561569
if (!(v instanceof SourceViewer sv)) {
562570
return result;
563571
}
572+
// TODO (tm) should we better cache the presentation and don't calculate it each
573+
// time?
564574
try {
565-
// TODO (tm) API needed to access IPresentationReconciler
566-
Field f = SourceViewer.class.getDeclaredField("fPresentationReconciler"); //$NON-NLS-1$
567-
f.setAccessible(true);
568-
var reconciler = (IPresentationReconciler) f.get(sv);
569-
// TODO (tm) should we better cache the presentation and don't calculate it each
570-
// time?
571-
result = createPresentation(reconciler, sv.getDocument(), source);
572-
} catch (IllegalAccessException | IllegalArgumentException | NoSuchFieldException | SecurityException e) {
573-
error(e);
574-
}
575-
return result;
576-
}
577-
578-
private List<StyleRange> createPresentation(IPresentationReconciler reconciler, IDocument originalDocument,
579-
String source) {
580-
try {
575+
IDocument originalDocument = sv.getDocument();
581576
String prefix = originalDocument.get(0, diff.leftStart);
582577
IDocument document = new Document(prefix + source);
583578
IRegion damage = new Region(prefix.length(), source.length());
584-
String partition = IDocumentExtension3.DEFAULT_PARTITIONING;
585-
if (reconciler instanceof IPresentationReconcilerExtension ext) {
586-
String extPartition = ext.getDocumentPartitioning();
587-
if (extPartition != null && !extPartition.isEmpty()) {
588-
partition = extPartition;
589-
}
590-
}
591-
IDocumentPartitioner partitioner = originalDocument.getDocumentPartitioner();
592-
document.setDocumentPartitioner(partitioner);
593-
IDocumentPartitioner originalDocumentPartitioner = null;
594-
if (document instanceof IDocumentExtension3 ext
595-
&& originalDocument instanceof IDocumentExtension3 originalExt) {
596-
originalDocumentPartitioner = originalExt.getDocumentPartitioner(partition);
597-
if (originalDocumentPartitioner != null) {
598-
// set temporarily another document in partitioner so that presentation can be
599-
// created for given source
600-
originalDocumentPartitioner.disconnect();
601-
originalDocumentPartitioner.connect(document);
602-
ext.setDocumentPartitioner(partition, originalDocumentPartitioner);
603-
}
604-
}
605-
TextPresentation presentation = new TextPresentation(damage, 1000);
606-
607-
ITypedRegion[] partitioning = TextUtilities.computePartitioning(document, partition, damage.getOffset(),
608-
damage.getLength(), false);
609-
for (ITypedRegion r : partitioning) {
610-
IPresentationRepairer repairer = reconciler.getRepairer(r.getType());
611-
if (repairer != null) {
612-
repairer.setDocument(document);
613-
repairer.createPresentation(presentation, r);
614-
repairer.setDocument(originalDocument);
615-
}
616-
}
617-
if (originalDocumentPartitioner != null) {
618-
originalDocumentPartitioner.connect(originalDocument);
619-
}
620-
List<StyleRange> result = new ArrayList<>();
621-
var it = presentation.getAllStyleRangeIterator();
579+
result = sv.computeStyleRanges(document, damage);
622580
int startOffset = prefix.length();
623-
while (it.hasNext()) {
624-
StyleRange next = it.next();
581+
for (StyleRange next : result) {
625582
if (next.start < startOffset) {
626583
throw new IllegalStateException(
627584
"Invalid presentation with style range starting before source offset"); //$NON-NLS-1$
628585
}
629586
next.start -= startOffset;
630-
result.add(next);
631587
}
632588
return result;
633-
} catch (BadLocationException x) {
634-
return null;
589+
} catch (BadLocationException e) {
590+
return result;
635591
}
636592
}
637593

0 commit comments

Comments
 (0)