Skip to content

Commit c47d26a

Browse files
Fix exception-safety and Javadoc of SourceViewer#computeStyleRanges()
1 parent 30f58ec commit c47d26a

1 file changed

Lines changed: 44 additions & 33 deletions

File tree

bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@
3131
import org.eclipse.swt.widgets.Canvas;
3232
import org.eclipse.swt.widgets.Composite;
3333
import org.eclipse.swt.widgets.Control;
34+
import org.eclipse.swt.widgets.Display;
3435
import org.eclipse.swt.widgets.Layout;
3536
import org.eclipse.swt.widgets.ScrollBar;
3637

38+
import org.eclipse.core.runtime.Assert;
39+
3740
import org.eclipse.jface.internal.text.NonDeletingPositionUpdater;
3841
import org.eclipse.jface.internal.text.StickyHoverManager;
3942
import org.eclipse.jface.internal.text.codemining.CodeMiningManager;
@@ -1412,20 +1415,28 @@ private void uninstallTextViewer() {
14121415
* <p>
14131416
* The viewer's partitioner is temporarily connected to the given document so that its
14141417
* presentation repairers can compute the correct highlighting. The viewer's own document is not
1415-
* affected.
1418+
* affected. However, if the original document uses a named partitioning (via
1419+
* {@link IDocumentExtension3}), its partitioner is briefly disconnected from the original
1420+
* document and reconnected to {@code document} for the duration of the call; it is always
1421+
* reconnected to the original document before this method returns, even if an exception is
1422+
* thrown.
1423+
* </p>
1424+
* <p>
1425+
* <strong>Note:</strong> This method must be called from the SWT UI thread.
14161426
* </p>
14171427
*
14181428
* @param document the external document whose content should be highlighted; must not be
14191429
* {@code null} and must use the same language/content type as this viewer
1420-
* @param damage the region within {@code document} for which style ranges are computed; must
1430+
* @param region the region within {@code document} for which style ranges are computed; must
14211431
* not be {@code null}
14221432
* @return the list of {@link org.eclipse.swt.custom.StyleRange}s covering the given region, as
14231433
* produced by this viewer's presentation reconciler; never {@code null}, may be empty
14241434
* if no repairer is registered for the content type
1425-
* @throws BadLocationException if {@code damage} is outside the bounds of {@code document}
1435+
* @throws BadLocationException if {@code region} is outside the bounds of {@code document}
14261436
* @since 3.31
14271437
*/
1428-
public List<StyleRange> computeStyleRanges(IDocument document, IRegion damage) throws BadLocationException {
1438+
public List<StyleRange> computeStyleRanges(IDocument document, IRegion region) throws BadLocationException {
1439+
Assert.isTrue(Display.getCurrent() != null, "computeStyleRanges must be called from SWT UI thread"); //$NON-NLS-1$
14291440
String partition= IDocumentExtension3.DEFAULT_PARTITIONING;
14301441
IPresentationReconciler reconciler= fPresentationReconciler;
14311442
if (reconciler instanceof IPresentationReconcilerExtension ext) {
@@ -1435,43 +1446,43 @@ public List<StyleRange> computeStyleRanges(IDocument document, IRegion damage) t
14351446
}
14361447
}
14371448
IDocument originalDocument= getDocument();
1438-
IDocumentPartitioner partitioner= originalDocument.getDocumentPartitioner();
1439-
document.setDocumentPartitioner(partitioner);
14401449
IDocumentPartitioner originalDocumentPartitioner= null;
1441-
if (document instanceof IDocumentExtension3 ext
1450+
if (document instanceof IDocumentExtension3
14421451
&& originalDocument instanceof IDocumentExtension3 originalExt) {
14431452
originalDocumentPartitioner= originalExt.getDocumentPartitioner(partition);
1453+
}
1454+
try {
14441455
if (originalDocumentPartitioner != null) {
1445-
// set temporarily another document in partitioner so that presentation can be
1446-
// created for given source
1456+
// Temporarily reconnect the partitioner to the external document so that
1457+
// presentation repairers compute highlighting against the right content.
1458+
// The finally block always restores it to the original document.
14471459
originalDocumentPartitioner.disconnect();
1448-
try {
1449-
originalDocumentPartitioner.connect(document);
1450-
} finally {
1451-
ext.setDocumentPartitioner(partition, originalDocumentPartitioner);
1460+
originalDocumentPartitioner.connect(document);
1461+
((IDocumentExtension3) document).setDocumentPartitioner(partition, originalDocumentPartitioner);
1462+
} else {
1463+
document.setDocumentPartitioner(originalDocument.getDocumentPartitioner());
1464+
}
1465+
TextPresentation presentation= new TextPresentation(region, 1000);
1466+
ITypedRegion[] partitioning= TextUtilities.computePartitioning(document, partition, region.getOffset(),
1467+
region.getLength(), false);
1468+
for (ITypedRegion r : partitioning) {
1469+
IPresentationRepairer repairer= reconciler.getRepairer(r.getType());
1470+
if (repairer != null) {
1471+
repairer.setDocument(document);
1472+
repairer.createPresentation(presentation, r);
1473+
repairer.setDocument(originalDocument);
14521474
}
14531475
}
1454-
}
1455-
TextPresentation presentation= new TextPresentation(damage, 1000);
1456-
ITypedRegion[] partitioning= TextUtilities.computePartitioning(document, partition, damage.getOffset(),
1457-
damage.getLength(), false);
1458-
for (ITypedRegion r : partitioning) {
1459-
IPresentationRepairer repairer= reconciler.getRepairer(r.getType());
1460-
if (repairer != null) {
1461-
repairer.setDocument(document);
1462-
repairer.createPresentation(presentation, r);
1463-
repairer.setDocument(originalDocument);
1476+
List<StyleRange> result= new ArrayList<>();
1477+
var it= presentation.getAllStyleRangeIterator();
1478+
while (it.hasNext()) {
1479+
result.add(it.next());
1480+
}
1481+
return result;
1482+
} finally {
1483+
if (originalDocumentPartitioner != null) {
1484+
originalDocumentPartitioner.connect(originalDocument);
14641485
}
14651486
}
1466-
if (originalDocumentPartitioner != null) {
1467-
originalDocumentPartitioner.connect(originalDocument);
1468-
}
1469-
List<StyleRange> result= new ArrayList<>();
1470-
var it= presentation.getAllStyleRangeIterator();
1471-
while (it.hasNext()) {
1472-
StyleRange next= it.next();
1473-
result.add(next);
1474-
}
1475-
return result;
14761487
}
14771488
}

0 commit comments

Comments
 (0)