From 30f58ecbecefc0a3f6df06e5edff0d36605e37c6 Mon Sep 17 00:00:00 2001
From: Tobias Melcher
Date: Mon, 6 Apr 2026 22:31:29 +0200
Subject: [PATCH 1/5] Add SourceViewer#computeStyleRanges() to highlight
external documents
Introduces computeStyleRanges(IDocument, IRegion) on SourceViewer,
which applies the viewer's own presentation reconciler and partitioner
to an external document, returning the resulting SWT StyleRanges for
the given region without affecting the viewer's current document.
---
.../jface/text/source/SourceViewer.java | 81 +++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
index c8965f3f66f..386a8515ea1 100644
--- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
+++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
@@ -24,6 +24,7 @@
import java.util.Stack;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
@@ -46,7 +47,9 @@
import org.eclipse.jface.text.IAutoEditStrategy;
import org.eclipse.jface.text.IBlockTextSelection;
import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IDocumentExtension4;
+import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.IPositionUpdater;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.IRewriteTarget;
@@ -56,8 +59,11 @@
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.ITextViewerLifecycle;
+import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.codemining.ICodeMiningProvider;
import org.eclipse.jface.text.contentassist.IContentAssistant;
@@ -71,6 +77,8 @@
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.information.IInformationPresenter;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.IPresentationReconcilerExtension;
+import org.eclipse.jface.text.presentation.IPresentationRepairer;
import org.eclipse.jface.text.projection.ChildDocument;
import org.eclipse.jface.text.quickassist.IQuickAssistAssistant;
import org.eclipse.jface.text.quickassist.IQuickAssistInvocationContext;
@@ -1393,4 +1401,77 @@ private void uninstallTextViewer() {
lifecycles.clear();
}
+ /**
+ * Computes syntax-highlighting style ranges for a region of an external document using this
+ * viewer's configured presentation reconciler and partitioner.
+ *
+ * This is useful when you want to syntax-color content that is not the document
+ * currently displayed in the viewer — for example, to preview or render a snippet with the same
+ * language rules that are active in this viewer.
+ *
+ *
+ * The viewer's partitioner is temporarily connected to the given document so that its
+ * presentation repairers can compute the correct highlighting. The viewer's own document is not
+ * affected.
+ *
+ *
+ * @param document the external document whose content should be highlighted; must not be
+ * {@code null} and must use the same language/content type as this viewer
+ * @param damage the region within {@code document} for which style ranges are computed; must
+ * not be {@code null}
+ * @return the list of {@link org.eclipse.swt.custom.StyleRange}s covering the given region, as
+ * produced by this viewer's presentation reconciler; never {@code null}, may be empty
+ * if no repairer is registered for the content type
+ * @throws BadLocationException if {@code damage} is outside the bounds of {@code document}
+ * @since 3.31
+ */
+ public List computeStyleRanges(IDocument document, IRegion damage) throws BadLocationException {
+ String partition= IDocumentExtension3.DEFAULT_PARTITIONING;
+ IPresentationReconciler reconciler= fPresentationReconciler;
+ if (reconciler instanceof IPresentationReconcilerExtension ext) {
+ String extPartition= ext.getDocumentPartitioning();
+ if (extPartition != null && !extPartition.isEmpty()) {
+ partition= extPartition;
+ }
+ }
+ IDocument originalDocument= getDocument();
+ IDocumentPartitioner partitioner= originalDocument.getDocumentPartitioner();
+ document.setDocumentPartitioner(partitioner);
+ IDocumentPartitioner originalDocumentPartitioner= null;
+ if (document instanceof IDocumentExtension3 ext
+ && originalDocument instanceof IDocumentExtension3 originalExt) {
+ originalDocumentPartitioner= originalExt.getDocumentPartitioner(partition);
+ if (originalDocumentPartitioner != null) {
+ // set temporarily another document in partitioner so that presentation can be
+ // created for given source
+ originalDocumentPartitioner.disconnect();
+ try {
+ originalDocumentPartitioner.connect(document);
+ } finally {
+ ext.setDocumentPartitioner(partition, originalDocumentPartitioner);
+ }
+ }
+ }
+ TextPresentation presentation= new TextPresentation(damage, 1000);
+ ITypedRegion[] partitioning= TextUtilities.computePartitioning(document, partition, damage.getOffset(),
+ damage.getLength(), false);
+ for (ITypedRegion r : partitioning) {
+ IPresentationRepairer repairer= reconciler.getRepairer(r.getType());
+ if (repairer != null) {
+ repairer.setDocument(document);
+ repairer.createPresentation(presentation, r);
+ repairer.setDocument(originalDocument);
+ }
+ }
+ if (originalDocumentPartitioner != null) {
+ originalDocumentPartitioner.connect(originalDocument);
+ }
+ List result= new ArrayList<>();
+ var it= presentation.getAllStyleRangeIterator();
+ while (it.hasNext()) {
+ StyleRange next= it.next();
+ result.add(next);
+ }
+ return result;
+ }
}
From c47d26af1b3a94bbc04fc4ad7e250adc66a84c70 Mon Sep 17 00:00:00 2001
From: Tobias Melcher
Date: Fri, 17 Apr 2026 19:04:15 +0200
Subject: [PATCH 2/5] Fix exception-safety and Javadoc of
SourceViewer#computeStyleRanges()
---
.../jface/text/source/SourceViewer.java | 77 +++++++++++--------
1 file changed, 44 insertions(+), 33 deletions(-)
diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
index 386a8515ea1..68878f4328e 100644
--- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
+++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
@@ -31,9 +31,12 @@
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.ScrollBar;
+import org.eclipse.core.runtime.Assert;
+
import org.eclipse.jface.internal.text.NonDeletingPositionUpdater;
import org.eclipse.jface.internal.text.StickyHoverManager;
import org.eclipse.jface.internal.text.codemining.CodeMiningManager;
@@ -1412,20 +1415,28 @@ private void uninstallTextViewer() {
*
* The viewer's partitioner is temporarily connected to the given document so that its
* presentation repairers can compute the correct highlighting. The viewer's own document is not
- * affected.
+ * affected. However, if the original document uses a named partitioning (via
+ * {@link IDocumentExtension3}), its partitioner is briefly disconnected from the original
+ * document and reconnected to {@code document} for the duration of the call; it is always
+ * reconnected to the original document before this method returns, even if an exception is
+ * thrown.
+ *
+ *
+ * Note: This method must be called from the SWT UI thread.
*
*
* @param document the external document whose content should be highlighted; must not be
* {@code null} and must use the same language/content type as this viewer
- * @param damage the region within {@code document} for which style ranges are computed; must
+ * @param region the region within {@code document} for which style ranges are computed; must
* not be {@code null}
* @return the list of {@link org.eclipse.swt.custom.StyleRange}s covering the given region, as
* produced by this viewer's presentation reconciler; never {@code null}, may be empty
* if no repairer is registered for the content type
- * @throws BadLocationException if {@code damage} is outside the bounds of {@code document}
+ * @throws BadLocationException if {@code region} is outside the bounds of {@code document}
* @since 3.31
*/
- public List computeStyleRanges(IDocument document, IRegion damage) throws BadLocationException {
+ public List computeStyleRanges(IDocument document, IRegion region) throws BadLocationException {
+ Assert.isTrue(Display.getCurrent() != null, "computeStyleRanges must be called from SWT UI thread"); //$NON-NLS-1$
String partition= IDocumentExtension3.DEFAULT_PARTITIONING;
IPresentationReconciler reconciler= fPresentationReconciler;
if (reconciler instanceof IPresentationReconcilerExtension ext) {
@@ -1435,43 +1446,43 @@ public List computeStyleRanges(IDocument document, IRegion damage) t
}
}
IDocument originalDocument= getDocument();
- IDocumentPartitioner partitioner= originalDocument.getDocumentPartitioner();
- document.setDocumentPartitioner(partitioner);
IDocumentPartitioner originalDocumentPartitioner= null;
- if (document instanceof IDocumentExtension3 ext
+ if (document instanceof IDocumentExtension3
&& originalDocument instanceof IDocumentExtension3 originalExt) {
originalDocumentPartitioner= originalExt.getDocumentPartitioner(partition);
+ }
+ try {
if (originalDocumentPartitioner != null) {
- // set temporarily another document in partitioner so that presentation can be
- // created for given source
+ // Temporarily reconnect the partitioner to the external document so that
+ // presentation repairers compute highlighting against the right content.
+ // The finally block always restores it to the original document.
originalDocumentPartitioner.disconnect();
- try {
- originalDocumentPartitioner.connect(document);
- } finally {
- ext.setDocumentPartitioner(partition, originalDocumentPartitioner);
+ originalDocumentPartitioner.connect(document);
+ ((IDocumentExtension3) document).setDocumentPartitioner(partition, originalDocumentPartitioner);
+ } else {
+ document.setDocumentPartitioner(originalDocument.getDocumentPartitioner());
+ }
+ TextPresentation presentation= new TextPresentation(region, 1000);
+ ITypedRegion[] partitioning= TextUtilities.computePartitioning(document, partition, region.getOffset(),
+ region.getLength(), false);
+ for (ITypedRegion r : partitioning) {
+ IPresentationRepairer repairer= reconciler.getRepairer(r.getType());
+ if (repairer != null) {
+ repairer.setDocument(document);
+ repairer.createPresentation(presentation, r);
+ repairer.setDocument(originalDocument);
}
}
- }
- TextPresentation presentation= new TextPresentation(damage, 1000);
- ITypedRegion[] partitioning= TextUtilities.computePartitioning(document, partition, damage.getOffset(),
- damage.getLength(), false);
- for (ITypedRegion r : partitioning) {
- IPresentationRepairer repairer= reconciler.getRepairer(r.getType());
- if (repairer != null) {
- repairer.setDocument(document);
- repairer.createPresentation(presentation, r);
- repairer.setDocument(originalDocument);
+ List result= new ArrayList<>();
+ var it= presentation.getAllStyleRangeIterator();
+ while (it.hasNext()) {
+ result.add(it.next());
+ }
+ return result;
+ } finally {
+ if (originalDocumentPartitioner != null) {
+ originalDocumentPartitioner.connect(originalDocument);
}
}
- if (originalDocumentPartitioner != null) {
- originalDocumentPartitioner.connect(originalDocument);
- }
- List result= new ArrayList<>();
- var it= presentation.getAllStyleRangeIterator();
- while (it.hasNext()) {
- StyleRange next= it.next();
- result.add(next);
- }
- return result;
}
}
From d6456a7285fbf36ac9cddc350c22acc31d159da7 Mon Sep 17 00:00:00 2001
From: Tobias Melcher
Date: Sat, 18 Apr 2026 19:03:36 +0200
Subject: [PATCH 3/5] add SourceViewerComputeStyleRangesTest
---
.../jface/text/tests/JFaceTextTestSuite.java | 2 +
.../SourceViewerComputeStyleRangesTest.java | 275 ++++++++++++++++++
2 files changed, 277 insertions(+)
create mode 100644 tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/SourceViewerComputeStyleRangesTest.java
diff --git a/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java b/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java
index eaa2a9bdcec..9d8d5dc6f23 100644
--- a/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java
+++ b/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java
@@ -33,6 +33,7 @@
import org.eclipse.jface.text.tests.rules.WordRuleTest;
import org.eclipse.jface.text.tests.source.AnnotationRulerColumnTest;
import org.eclipse.jface.text.tests.source.LineNumberRulerColumnTest;
+import org.eclipse.jface.text.tests.source.SourceViewerComputeStyleRangesTest;
import org.eclipse.jface.text.tests.source.inlined.AnnotationOnTabTest;
import org.eclipse.jface.text.tests.source.inlined.LineContentBoundsDrawingTest;
import org.eclipse.jface.text.tests.templates.persistence.TemplatePersistenceDataTest;
@@ -46,6 +47,7 @@
@SelectClasses({
AnnotationRulerColumnTest.class,
LineNumberRulerColumnTest.class,
+ SourceViewerComputeStyleRangesTest.class,
HTML2TextReaderTest.class,
TextHoverPopupTest.class,
TextPresentationTest.class,
diff --git a/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/SourceViewerComputeStyleRangesTest.java b/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/SourceViewerComputeStyleRangesTest.java
new file mode 100644
index 00000000000..bc0c8510f22
--- /dev/null
+++ b/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/SourceViewerComputeStyleRangesTest.java
@@ -0,0 +1,275 @@
+/*******************************************************************************
+ * Copyright (c) 2026 SAP SE and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.jface.text.tests.source;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.List;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.FastPartitioner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+/**
+ * Tests for {@link SourceViewer#computeStyleRanges(IDocument, org.eclipse.jface.text.IRegion)}.
+ */
+public class SourceViewerComputeStyleRangesTest {
+
+ private static final RGB HIGHLIGHT_RGB= new RGB(0, 0, 255);
+ private static final String NAMED_PARTITIONING= "test_partitioning"; //$NON-NLS-1$
+
+ private Shell shell;
+ private Color highlightColor;
+
+ @BeforeEach
+ public void setUp() {
+ shell= new Shell();
+ highlightColor= new Color(HIGHLIGHT_RGB);
+ }
+
+ @AfterEach
+ public void tearDown() {
+ highlightColor.dispose();
+ shell.dispose();
+ }
+
+ @Test
+ public void testBasicStyleRanges() throws Exception {
+ SourceViewer viewer= createConfiguredViewer();
+ viewer.setDocument(new Document("original content"));
+
+ Document externalDoc= new Document("some 'highlighted' text");
+ List styles= viewer.computeStyleRanges(externalDoc, new Region(0, externalDoc.getLength()));
+
+ assertNotNull(styles);
+ assertFalse(styles.isEmpty(), "Expected style ranges for quoted text");
+ // The SingleLineRule for 'x' should produce a style covering 'highlighted' (offsets 5..17)
+ boolean foundHighlight= styles.stream().anyMatch(
+ sr -> sr.start == 5 && sr.length == 13 && sr.foreground != null
+ && HIGHLIGHT_RGB.equals(sr.foreground.getRGB()));
+ assertTrue(foundHighlight, "Expected a blue highlight style for the quoted region");
+ }
+
+ @Test
+ public void testNoMatchingContent() throws Exception {
+ SourceViewer viewer= createConfiguredViewer();
+ viewer.setDocument(new Document("original content"));
+
+ Document externalDoc= new Document("no special content here");
+ List styles= viewer.computeStyleRanges(externalDoc, new Region(0, externalDoc.getLength()));
+
+ assertNotNull(styles);
+ // All style ranges should have null foreground (default styling) since no rule matches
+ for (StyleRange sr : styles) {
+ assertTrue(sr.foreground == null || !HIGHLIGHT_RGB.equals(sr.foreground.getRGB()),
+ "Expected no highlight color for unmatched content");
+ }
+ }
+
+ @Test
+ public void testRegionSubset() throws Exception {
+ SourceViewer viewer= createConfiguredViewer();
+ viewer.setDocument(new Document("original content"));
+
+ // Put quoted text at position 10..22
+ Document externalDoc= new Document("0123456789'highlighted'rest");
+ // Request styles only for the region starting at offset 10, length 13
+ List styles= viewer.computeStyleRanges(externalDoc, new Region(10, 13));
+
+ assertNotNull(styles);
+ for (StyleRange sr : styles) {
+ assertTrue(sr.start >= 10, "Style range should start at or after region start");
+ assertTrue(sr.start + sr.length <= 23, "Style range should end at or before region end");
+ }
+ boolean foundHighlight= styles.stream().anyMatch(
+ sr -> sr.foreground != null && HIGHLIGHT_RGB.equals(sr.foreground.getRGB()));
+ assertTrue(foundHighlight, "Expected highlight within subset region");
+ }
+
+ @Test
+ public void testOriginalDocumentNotAffected() throws Exception {
+ SourceViewer viewer= createConfiguredViewer();
+ String originalContent= "original content";
+ Document originalDoc= new Document(originalContent);
+ viewer.setDocument(originalDoc);
+ IDocumentPartitioner originalPartitioner= originalDoc.getDocumentPartitioner();
+
+ Document externalDoc= new Document("some 'highlighted' text");
+ viewer.computeStyleRanges(externalDoc, new Region(0, externalDoc.getLength()));
+
+ assertEquals(originalContent, originalDoc.get(), "Original document content must not change");
+ assertEquals(originalPartitioner, originalDoc.getDocumentPartitioner(),
+ "Original document partitioner must be restored");
+ }
+
+ @Test
+ public void testEmptyRegion() throws Exception {
+ SourceViewer viewer= createConfiguredViewer();
+ viewer.setDocument(new Document("original content"));
+
+ Document externalDoc= new Document("some 'highlighted' text");
+ List styles= viewer.computeStyleRanges(externalDoc, new Region(0, 0));
+
+ assertNotNull(styles);
+ assertEquals(1, styles.size());
+ // empty style range
+ assertEquals(0, styles.get(0).start);
+ assertEquals(0, styles.get(0).length);
+ assertNull(styles.get(0).font);
+ }
+
+ @Test
+ public void testMultipleStyleRanges() throws Exception {
+ SourceViewer viewer= createConfiguredViewer();
+ viewer.setDocument(new Document("original content"));
+
+ Document externalDoc= new Document("'first' normal 'second' end");
+ List styles= viewer.computeStyleRanges(externalDoc, new Region(0, externalDoc.getLength()));
+
+ assertNotNull(styles);
+ long highlightCount= styles.stream()
+ .filter(sr -> sr.foreground != null && HIGHLIGHT_RGB.equals(sr.foreground.getRGB()))
+ .count();
+ assertTrue(highlightCount >= 2, "Expected at least 2 highlighted regions, got " + highlightCount);
+ }
+
+ @Test
+ public void testBadLocationExceptionForOutOfBoundsRegion() throws Exception {
+ SourceViewer viewer= createConfiguredViewer();
+ viewer.setDocument(new Document("original content"));
+
+ Document externalDoc= new Document("short");
+ assertThrows(BadLocationException.class,
+ () -> viewer.computeStyleRanges(externalDoc, new Region(0, 100)));
+ }
+
+ @Test
+ public void testExceptionSafetyPartitionerRestored() throws Exception {
+ SourceViewer viewer= createConfiguredViewerWithNamedPartitioning();
+ Document originalDoc= new Document("original content");
+ setupNamedPartitioning(originalDoc);
+ viewer.setDocument(originalDoc);
+ IDocumentPartitioner originalPartitioner= originalDoc
+ .getDocumentPartitioner(NAMED_PARTITIONING);
+ assertNotNull(originalPartitioner, "Original document should have a named partitioner");
+
+ Document externalDoc= new Document("short");
+ setupNamedPartitioning(externalDoc);
+ try {
+ viewer.computeStyleRanges(externalDoc, new Region(0, 100));
+ } catch (BadLocationException expected) {
+ // expected
+ }
+
+ // Verify partitioner was restored to original document
+ IDocumentPartitioner restoredPartitioner= originalDoc
+ .getDocumentPartitioner(NAMED_PARTITIONING);
+ assertNotNull(restoredPartitioner, "Partitioner must be restored to original document after exception");
+ }
+
+ @Test
+ public void testNamedPartitioning() throws Exception {
+ SourceViewer viewer= createConfiguredViewerWithNamedPartitioning();
+ Document originalDoc= new Document("original 'content' here");
+ setupNamedPartitioning(originalDoc);
+ viewer.setDocument(originalDoc);
+
+ Document externalDoc= new Document("external 'styled' text");
+ setupNamedPartitioning(externalDoc);
+ List styles= viewer.computeStyleRanges(externalDoc, new Region(0, externalDoc.getLength()));
+
+ assertNotNull(styles);
+ assertFalse(styles.isEmpty(), "Expected style ranges for quoted text with named partitioning");
+
+ // Verify partitioner is reconnected to original document
+ IDocumentPartitioner restoredPartitioner= originalDoc
+ .getDocumentPartitioner(NAMED_PARTITIONING);
+ assertNotNull(restoredPartitioner, "Partitioner must be restored to original document");
+ }
+
+ private SourceViewer createConfiguredViewer() {
+ SourceViewer viewer= new SourceViewer(shell, null, SWT.NONE);
+ viewer.configure(new SourceViewerConfiguration() {
+ @Override
+ public org.eclipse.jface.text.presentation.IPresentationReconciler getPresentationReconciler(
+ ISourceViewer sourceViewer) {
+ PresentationReconciler reconciler= new PresentationReconciler();
+ DefaultDamagerRepairer dr= new DefaultDamagerRepairer(createScanner());
+ reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ return reconciler;
+ }
+ });
+ return viewer;
+ }
+
+ private SourceViewer createConfiguredViewerWithNamedPartitioning() {
+ SourceViewer viewer= new SourceViewer(shell, null, SWT.NONE);
+ viewer.configure(new SourceViewerConfiguration() {
+ @Override
+ public org.eclipse.jface.text.presentation.IPresentationReconciler getPresentationReconciler(
+ ISourceViewer sourceViewer) {
+ PresentationReconciler reconciler= new PresentationReconciler();
+ reconciler.setDocumentPartitioning(NAMED_PARTITIONING);
+ DefaultDamagerRepairer dr= new DefaultDamagerRepairer(createScanner());
+ reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ return reconciler;
+ }
+ });
+ return viewer;
+ }
+
+ private RuleBasedScanner createScanner() {
+ RuleBasedScanner scanner= new RuleBasedScanner();
+ IRule[] rules= new IRule[1];
+ rules[0]= new SingleLineRule("'", "'", new Token(new TextAttribute(highlightColor))); //$NON-NLS-1$ //$NON-NLS-2$
+ scanner.setRules(rules);
+ return scanner;
+ }
+
+ private void setupNamedPartitioning(Document document) {
+ IPartitionTokenScanner partitionScanner= new RuleBasedPartitionScanner();
+ IDocumentPartitioner partitioner= new FastPartitioner(partitionScanner, new String[] {});
+ document.setDocumentPartitioner(NAMED_PARTITIONING, partitioner);
+ partitioner.connect(document);
+ }
+}
From 392609f14f149dacdd7970ed1488797b99098c76 Mon Sep 17 00:00:00 2001
From: Tobias Melcher
Date: Sun, 19 Apr 2026 15:50:40 +0200
Subject: [PATCH 4/5] Fix partitioner leak and add null guard in
SourceViewer#computeStyleRanges()
---
.../jface/text/source/SourceViewer.java | 22 +++++++---
.../SourceViewerComputeStyleRangesTest.java | 40 +++++++++++++++++--
2 files changed, 52 insertions(+), 10 deletions(-)
diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
index 68878f4328e..7c55fa2c1d0 100644
--- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
+++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
@@ -1437,6 +1437,8 @@ private void uninstallTextViewer() {
*/
public List computeStyleRanges(IDocument document, IRegion region) throws BadLocationException {
Assert.isTrue(Display.getCurrent() != null, "computeStyleRanges must be called from SWT UI thread"); //$NON-NLS-1$
+ IDocument originalDocument= getDocument();
+ Assert.isNotNull(originalDocument, "viewer must have a document before calling computeStyleRanges"); //$NON-NLS-1$
String partition= IDocumentExtension3.DEFAULT_PARTITIONING;
IPresentationReconciler reconciler= fPresentationReconciler;
if (reconciler instanceof IPresentationReconcilerExtension ext) {
@@ -1445,21 +1447,25 @@ public List computeStyleRanges(IDocument document, IRegion region) t
partition= extPartition;
}
}
- IDocument originalDocument= getDocument();
IDocumentPartitioner originalDocumentPartitioner= null;
- if (document instanceof IDocumentExtension3
+ IDocumentExtension3 documentExt= null;
+ if (document instanceof IDocumentExtension3 docExt
&& originalDocument instanceof IDocumentExtension3 originalExt) {
+ documentExt= docExt;
originalDocumentPartitioner= originalExt.getDocumentPartitioner(partition);
}
+ IDocumentPartitioner externalDocPartitioner= null;
try {
- if (originalDocumentPartitioner != null) {
+ if (originalDocumentPartitioner != null && documentExt != null) {
// Temporarily reconnect the partitioner to the external document so that
// presentation repairers compute highlighting against the right content.
- // The finally block always restores it to the original document.
+ // The finally block always restores both documents to their original state.
+ externalDocPartitioner= documentExt.getDocumentPartitioner(partition);
originalDocumentPartitioner.disconnect();
originalDocumentPartitioner.connect(document);
- ((IDocumentExtension3) document).setDocumentPartitioner(partition, originalDocumentPartitioner);
+ documentExt.setDocumentPartitioner(partition, originalDocumentPartitioner);
} else {
+ externalDocPartitioner= document.getDocumentPartitioner();
document.setDocumentPartitioner(originalDocument.getDocumentPartitioner());
}
TextPresentation presentation= new TextPresentation(region, 1000);
@@ -1480,8 +1486,12 @@ public List computeStyleRanges(IDocument document, IRegion region) t
}
return result;
} finally {
- if (originalDocumentPartitioner != null) {
+ if (originalDocumentPartitioner != null && documentExt != null) {
+ originalDocumentPartitioner.disconnect();
originalDocumentPartitioner.connect(originalDocument);
+ documentExt.setDocumentPartitioner(partition, externalDocPartitioner);
+ } else {
+ document.setDocumentPartitioner(externalDocPartitioner);
}
}
}
diff --git a/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/SourceViewerComputeStyleRangesTest.java b/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/SourceViewerComputeStyleRangesTest.java
index bc0c8510f22..b3f66d8d665 100644
--- a/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/SourceViewerComputeStyleRangesTest.java
+++ b/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/SourceViewerComputeStyleRangesTest.java
@@ -129,15 +129,20 @@ public void testOriginalDocumentNotAffected() throws Exception {
SourceViewer viewer= createConfiguredViewer();
String originalContent= "original content";
Document originalDoc= new Document(originalContent);
+ IDocumentPartitioner originalPartitioner= setupPartitioning(originalDoc);
+ assertNotNull(originalPartitioner);
viewer.setDocument(originalDoc);
- IDocumentPartitioner originalPartitioner= originalDoc.getDocumentPartitioner();
Document externalDoc= new Document("some 'highlighted' text");
+ IDocumentPartitioner externalPartitioner= setupPartitioning(externalDoc);
+ assertNotNull(externalPartitioner);
viewer.computeStyleRanges(externalDoc, new Region(0, externalDoc.getLength()));
assertEquals(originalContent, originalDoc.get(), "Original document content must not change");
assertEquals(originalPartitioner, originalDoc.getDocumentPartitioner(),
"Original document partitioner must be restored");
+ assertEquals(externalPartitioner, externalDoc.getDocumentPartitioner(),
+ "External document partitioner must be restored");
}
@Test
@@ -193,6 +198,10 @@ public void testExceptionSafetyPartitionerRestored() throws Exception {
Document externalDoc= new Document("short");
setupNamedPartitioning(externalDoc);
+ IDocumentPartitioner externalPartitioner= externalDoc
+ .getDocumentPartitioner(NAMED_PARTITIONING);
+ assertNotNull(externalPartitioner, "External document should have a named partitioner");
+
try {
viewer.computeStyleRanges(externalDoc, new Region(0, 100));
} catch (BadLocationException expected) {
@@ -203,17 +212,25 @@ public void testExceptionSafetyPartitionerRestored() throws Exception {
IDocumentPartitioner restoredPartitioner= originalDoc
.getDocumentPartitioner(NAMED_PARTITIONING);
assertNotNull(restoredPartitioner, "Partitioner must be restored to original document after exception");
+ assertEquals(originalPartitioner, restoredPartitioner);
+
+ IDocumentPartitioner restoredExternalPartitioner= externalDoc
+ .getDocumentPartitioner(NAMED_PARTITIONING);
+ assertNotNull(restoredExternalPartitioner, "External partitioner must be restored to original document after exception");
+ assertEquals(externalPartitioner, restoredExternalPartitioner);
}
@Test
public void testNamedPartitioning() throws Exception {
SourceViewer viewer= createConfiguredViewerWithNamedPartitioning();
Document originalDoc= new Document("original 'content' here");
- setupNamedPartitioning(originalDoc);
+ IDocumentPartitioner originalPartitioner= setupNamedPartitioning(originalDoc);
+ assertNotNull(originalPartitioner);
viewer.setDocument(originalDoc);
Document externalDoc= new Document("external 'styled' text");
- setupNamedPartitioning(externalDoc);
+ IDocumentPartitioner externalPartitioner= setupNamedPartitioning(externalDoc);
+ assertNotNull(externalPartitioner);
List styles= viewer.computeStyleRanges(externalDoc, new Region(0, externalDoc.getLength()));
assertNotNull(styles);
@@ -223,6 +240,12 @@ public void testNamedPartitioning() throws Exception {
IDocumentPartitioner restoredPartitioner= originalDoc
.getDocumentPartitioner(NAMED_PARTITIONING);
assertNotNull(restoredPartitioner, "Partitioner must be restored to original document");
+ assertEquals(originalPartitioner, restoredPartitioner);
+
+ IDocumentPartitioner restoredExternalPartitioner= externalDoc
+ .getDocumentPartitioner(NAMED_PARTITIONING);
+ assertNotNull(restoredExternalPartitioner, "External partitioner must be restored to external document");
+ assertEquals(externalPartitioner, restoredExternalPartitioner);
}
private SourceViewer createConfiguredViewer() {
@@ -266,10 +289,19 @@ private RuleBasedScanner createScanner() {
return scanner;
}
- private void setupNamedPartitioning(Document document) {
+ private IDocumentPartitioner setupNamedPartitioning(Document document) {
IPartitionTokenScanner partitionScanner= new RuleBasedPartitionScanner();
IDocumentPartitioner partitioner= new FastPartitioner(partitionScanner, new String[] {});
document.setDocumentPartitioner(NAMED_PARTITIONING, partitioner);
partitioner.connect(document);
+ return partitioner;
+ }
+
+ private IDocumentPartitioner setupPartitioning(Document document) {
+ IPartitionTokenScanner partitionScanner= new RuleBasedPartitionScanner();
+ IDocumentPartitioner partitioner= new FastPartitioner(partitionScanner, new String[] {});
+ document.setDocumentPartitioner(partitioner);
+ partitioner.connect(document);
+ return partitioner;
}
}
From 3142c65d0c336148e6cbea8a6d4f24ddac8531cd Mon Sep 17 00:00:00 2001
From: Tobias Melcher
Date: Wed, 22 Apr 2026 15:33:12 +0200
Subject: [PATCH 5/5] Simplify SourceViewer#computeStyleRanges() and fix
finally-block partitioner restore
---
.../jface/text/source/SourceViewer.java | 53 +++++++++--------
.../SourceViewerComputeStyleRangesTest.java | 59 ++++++++++++++-----
2 files changed, 72 insertions(+), 40 deletions(-)
diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
index 7c55fa2c1d0..e63b1b5162c 100644
--- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
+++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
@@ -1426,12 +1426,16 @@ private void uninstallTextViewer() {
*
*
* @param document the external document whose content should be highlighted; must not be
- * {@code null} and must use the same language/content type as this viewer
+ * {@code null} and must use the same language/content type as this viewer; must
+ * implement {@link org.eclipse.jface.text.IDocumentExtension3} — if either
+ * {@code document} or the viewer's current document does not implement
+ * {@code IDocumentExtension3}, an empty list is returned
* @param region the region within {@code document} for which style ranges are computed; must
* not be {@code null}
* @return the list of {@link org.eclipse.swt.custom.StyleRange}s covering the given region, as
* produced by this viewer's presentation reconciler; never {@code null}, may be empty
- * if no repairer is registered for the content type
+ * if no repairer is registered for the content type, or if either document does not
+ * implement {@code IDocumentExtension3}
* @throws BadLocationException if {@code region} is outside the bounds of {@code document}
* @since 3.31
*/
@@ -1439,12 +1443,13 @@ public List computeStyleRanges(IDocument document, IRegion region) t
Assert.isTrue(Display.getCurrent() != null, "computeStyleRanges must be called from SWT UI thread"); //$NON-NLS-1$
IDocument originalDocument= getDocument();
Assert.isNotNull(originalDocument, "viewer must have a document before calling computeStyleRanges"); //$NON-NLS-1$
- String partition= IDocumentExtension3.DEFAULT_PARTITIONING;
+ List result= new ArrayList<>();
+ String partitioning= IDocumentExtension3.DEFAULT_PARTITIONING;
IPresentationReconciler reconciler= fPresentationReconciler;
if (reconciler instanceof IPresentationReconcilerExtension ext) {
- String extPartition= ext.getDocumentPartitioning();
- if (extPartition != null && !extPartition.isEmpty()) {
- partition= extPartition;
+ String extPartitioning= ext.getDocumentPartitioning();
+ if (extPartitioning != null && !extPartitioning.isEmpty()) {
+ partitioning= extPartitioning;
}
}
IDocumentPartitioner originalDocumentPartitioner= null;
@@ -1452,46 +1457,42 @@ public List computeStyleRanges(IDocument document, IRegion region) t
if (document instanceof IDocumentExtension3 docExt
&& originalDocument instanceof IDocumentExtension3 originalExt) {
documentExt= docExt;
- originalDocumentPartitioner= originalExt.getDocumentPartitioner(partition);
+ originalDocumentPartitioner= originalExt.getDocumentPartitioner(partitioning);
+ } else {
+ return result;
}
IDocumentPartitioner externalDocPartitioner= null;
try {
- if (originalDocumentPartitioner != null && documentExt != null) {
- // Temporarily reconnect the partitioner to the external document so that
- // presentation repairers compute highlighting against the right content.
- // The finally block always restores both documents to their original state.
- externalDocPartitioner= documentExt.getDocumentPartitioner(partition);
+ // Temporarily reconnect the partitioner to the external document so that
+ // presentation repairers compute highlighting against the right content.
+ // The finally block always restores both documents to their original state.
+ externalDocPartitioner= documentExt.getDocumentPartitioner(partitioning);
+ if (originalDocumentPartitioner != null) {
originalDocumentPartitioner.disconnect();
originalDocumentPartitioner.connect(document);
- documentExt.setDocumentPartitioner(partition, originalDocumentPartitioner);
- } else {
- externalDocPartitioner= document.getDocumentPartitioner();
- document.setDocumentPartitioner(originalDocument.getDocumentPartitioner());
+ documentExt.setDocumentPartitioner(partitioning, originalDocumentPartitioner);
}
- TextPresentation presentation= new TextPresentation(region, 1000);
- ITypedRegion[] partitioning= TextUtilities.computePartitioning(document, partition, region.getOffset(),
+ TextPresentation presentation= new TextPresentation(region, Math.max(region.getLength() / 10, 16));
+ ITypedRegion[] partitioningRegions= TextUtilities.computePartitioning(document, partitioning, region.getOffset(),
region.getLength(), false);
- for (ITypedRegion r : partitioning) {
- IPresentationRepairer repairer= reconciler.getRepairer(r.getType());
+ for (ITypedRegion partitioningRegion : partitioningRegions) {
+ IPresentationRepairer repairer= reconciler.getRepairer(partitioningRegion.getType());
if (repairer != null) {
repairer.setDocument(document);
- repairer.createPresentation(presentation, r);
+ repairer.createPresentation(presentation, partitioningRegion);
repairer.setDocument(originalDocument);
}
}
- List result= new ArrayList<>();
var it= presentation.getAllStyleRangeIterator();
while (it.hasNext()) {
result.add(it.next());
}
return result;
} finally {
- if (originalDocumentPartitioner != null && documentExt != null) {
+ if (originalDocumentPartitioner != null) {
originalDocumentPartitioner.disconnect();
originalDocumentPartitioner.connect(originalDocument);
- documentExt.setDocumentPartitioner(partition, externalDocPartitioner);
- } else {
- document.setDocumentPartitioner(externalDocPartitioner);
+ documentExt.setDocumentPartitioner(partitioning, externalDocPartitioner);
}
}
}
diff --git a/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/SourceViewerComputeStyleRangesTest.java b/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/SourceViewerComputeStyleRangesTest.java
index b3f66d8d665..be1244d89f4 100644
--- a/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/SourceViewerComputeStyleRangesTest.java
+++ b/tests/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/source/SourceViewerComputeStyleRangesTest.java
@@ -16,6 +16,7 @@
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
import java.util.List;
@@ -32,6 +33,7 @@
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextAttribute;
@@ -74,7 +76,9 @@ public void tearDown() {
@Test
public void testBasicStyleRanges() throws Exception {
SourceViewer viewer= createConfiguredViewer();
- viewer.setDocument(new Document("original content"));
+ var document= new Document("original content");
+ setupDefaultPartitioning(document);
+ viewer.setDocument(document);
Document externalDoc= new Document("some 'highlighted' text");
List styles= viewer.computeStyleRanges(externalDoc, new Region(0, externalDoc.getLength()));
@@ -91,7 +95,9 @@ public void testBasicStyleRanges() throws Exception {
@Test
public void testNoMatchingContent() throws Exception {
SourceViewer viewer= createConfiguredViewer();
- viewer.setDocument(new Document("original content"));
+ var document= new Document("original content");
+ setupDefaultPartitioning(document);
+ viewer.setDocument(document);
Document externalDoc= new Document("no special content here");
List styles= viewer.computeStyleRanges(externalDoc, new Region(0, externalDoc.getLength()));
@@ -107,7 +113,9 @@ public void testNoMatchingContent() throws Exception {
@Test
public void testRegionSubset() throws Exception {
SourceViewer viewer= createConfiguredViewer();
- viewer.setDocument(new Document("original content"));
+ var document= new Document("original content");
+ setupDefaultPartitioning(document);
+ viewer.setDocument(document);
// Put quoted text at position 10..22
Document externalDoc= new Document("0123456789'highlighted'rest");
@@ -129,28 +137,31 @@ public void testOriginalDocumentNotAffected() throws Exception {
SourceViewer viewer= createConfiguredViewer();
String originalContent= "original content";
Document originalDoc= new Document(originalContent);
- IDocumentPartitioner originalPartitioner= setupPartitioning(originalDoc);
+ IDocumentPartitioner originalPartitioner= setupDefaultPartitioning(originalDoc);
assertNotNull(originalPartitioner);
viewer.setDocument(originalDoc);
Document externalDoc= new Document("some 'highlighted' text");
- IDocumentPartitioner externalPartitioner= setupPartitioning(externalDoc);
+ IDocumentPartitioner externalPartitioner= setupDefaultPartitioning(externalDoc);
assertNotNull(externalPartitioner);
viewer.computeStyleRanges(externalDoc, new Region(0, externalDoc.getLength()));
assertEquals(originalContent, originalDoc.get(), "Original document content must not change");
- assertEquals(originalPartitioner, originalDoc.getDocumentPartitioner(),
+ assertEquals(originalPartitioner, originalDoc.getDocumentPartitioner(IDocumentExtension3.DEFAULT_PARTITIONING),
"Original document partitioner must be restored");
- assertEquals(externalPartitioner, externalDoc.getDocumentPartitioner(),
+ assertEquals(externalPartitioner, externalDoc.getDocumentPartitioner(IDocumentExtension3.DEFAULT_PARTITIONING),
"External document partitioner must be restored");
}
@Test
public void testEmptyRegion() throws Exception {
- SourceViewer viewer= createConfiguredViewer();
- viewer.setDocument(new Document("original content"));
+ SourceViewer viewer= createConfiguredViewerWithNamedPartitioning();
+ var document= new Document("original content");
+ setupNamedPartitioning(document);
+ viewer.setDocument(document);
Document externalDoc= new Document("some 'highlighted' text");
+ setupNamedPartitioning(externalDoc);
List styles= viewer.computeStyleRanges(externalDoc, new Region(0, 0));
assertNotNull(styles);
@@ -163,8 +174,10 @@ public void testEmptyRegion() throws Exception {
@Test
public void testMultipleStyleRanges() throws Exception {
- SourceViewer viewer= createConfiguredViewer();
- viewer.setDocument(new Document("original content"));
+ SourceViewer viewer= createConfiguredViewerWithNamedPartitioning();
+ var document= new Document("original content");
+ setupNamedPartitioning(document);
+ viewer.setDocument(document);
Document externalDoc= new Document("'first' normal 'second' end");
List styles= viewer.computeStyleRanges(externalDoc, new Region(0, externalDoc.getLength()));
@@ -179,7 +192,9 @@ public void testMultipleStyleRanges() throws Exception {
@Test
public void testBadLocationExceptionForOutOfBoundsRegion() throws Exception {
SourceViewer viewer= createConfiguredViewer();
- viewer.setDocument(new Document("original content"));
+ var document= new Document("original content");
+ setupDefaultPartitioning(document);
+ viewer.setDocument(document);
Document externalDoc= new Document("short");
assertThrows(BadLocationException.class,
@@ -248,6 +263,22 @@ public void testNamedPartitioning() throws Exception {
assertEquals(externalPartitioner, restoredExternalPartitioner);
}
+ @Test
+ public void testNonDocumentExtension3ReturnsEmpty() throws Exception {
+ SourceViewer viewer= createConfiguredViewer();
+ Document originalDoc= new Document("original content");
+ setupDefaultPartitioning(originalDoc);
+ viewer.setDocument(originalDoc);
+
+ // Create a document that does NOT implement IDocumentExtension3
+ // so that computeStyleRanges takes the early-return path
+ IDocument document= mock(IDocument.class);
+ List styles= viewer.computeStyleRanges(document, new Region(0, document.getLength()));
+
+ assertNotNull(styles);
+ assertTrue(styles.isEmpty(), "Expected empty style ranges for non-IDocumentExtension3 document");
+ }
+
private SourceViewer createConfiguredViewer() {
SourceViewer viewer= new SourceViewer(shell, null, SWT.NONE);
viewer.configure(new SourceViewerConfiguration() {
@@ -297,10 +328,10 @@ private IDocumentPartitioner setupNamedPartitioning(Document document) {
return partitioner;
}
- private IDocumentPartitioner setupPartitioning(Document document) {
+ private IDocumentPartitioner setupDefaultPartitioning(Document document) {
IPartitionTokenScanner partitionScanner= new RuleBasedPartitionScanner();
IDocumentPartitioner partitioner= new FastPartitioner(partitionScanner, new String[] {});
- document.setDocumentPartitioner(partitioner);
+ document.setDocumentPartitioner(IDocumentExtension3.DEFAULT_PARTITIONING, partitioner);
partitioner.connect(document);
return partitioner;
}