Skip to content

Commit cc290be

Browse files
committed
Extend code mining demo to reproduce issue #3405
1 parent 0ce1430 commit cc290be

File tree

4 files changed

+189
-9
lines changed

4 files changed

+189
-9
lines changed

examples/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/codemining/CodeMiningDemo.java

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*
1111
* Contributors:
1212
* Angelo Zerr <[email protected]> - [CodeMining] Add CodeMining support in SourceViewer - Bug 527515
13+
* Dietrich Travkin <[email protected]> - Fix code mining redrawing - Issue 3405
1314
*/
1415
package org.eclipse.jface.text.examples.codemining;
1516

@@ -34,7 +35,9 @@
3435
import org.eclipse.jface.text.source.ISourceViewerExtension5;
3536
import org.eclipse.jface.text.source.SourceViewer;
3637
import org.eclipse.swt.SWT;
38+
import org.eclipse.swt.events.SelectionListener;
3739
import org.eclipse.swt.layout.GridLayout;
40+
import org.eclipse.swt.widgets.Button;
3841
import org.eclipse.swt.widgets.Display;
3942
import org.eclipse.swt.widgets.Shell;
4043
import org.eclipse.swt.widgets.Text;
@@ -45,14 +48,22 @@
4548
public class CodeMiningDemo {
4649

4750
private static boolean showWhitespaces = false;
51+
private static AtomicReference<Boolean> useInLineCodeMinings = new AtomicReference<>(false);;
52+
53+
private static String LINE_HEADER = "Line header";
54+
private static String IN_LINE = "In-line";
4855

4956
public static void main(String[] args) throws Exception {
5057

5158
Display display = new Display();
5259
Shell shell = new Shell(display);
53-
shell.setLayout(new GridLayout());
60+
shell.setLayout(new GridLayout(2, false));
5461
shell.setText("Code Mining demo");
5562

63+
Button toggleInLineButton = new Button(shell, SWT.PUSH);
64+
toggleInLineButton.setText(LINE_HEADER);
65+
GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.FILL).grab(false, false).applyTo(toggleInLineButton);
66+
5667
AtomicReference<String> endOfLineString = new AtomicReference<>("End of line");
5768
Text endOfLineText = new Text(shell, SWT.NONE);
5869
endOfLineText.setText(endOfLineString.get());
@@ -70,7 +81,9 @@ public static void main(String[] args) throws Exception {
7081
+ "// Name class with a number N to emulate Nms before resolving the references CodeMining\n"
7182
+ "// Empty lines show a header annotating they're empty.\n"
7283
+ "// The word `echo` is echoed.\n"
73-
+ "// Lines containing `end` get an annotation at their end\n\n"
84+
+ "// Lines containing `end` get an annotation at their end\n"
85+
+ "// Press the toggle button in the upper left corner to switch between\n"
86+
+ "// showing reference titles in-line and showing them in additional lines.\n\n"
7487
+ "class A\n" //
7588
+ "new A\n" //
7689
+ "new A\n\n" //
@@ -79,29 +92,39 @@ public static void main(String[] args) throws Exception {
7992
+ "class 5\n" //
8093
+ "new 5\n" //
8194
+ "new 5\n" //
82-
+ "new 5\n" //
95+
+ "new 5\n\n" //
96+
+ "Text with some references like [REF-X]\n" + "and [REF-Y] in it.\n\n"
8397
+ "multiline \n" //
8498
+ "multiline \n\n" //
8599
+ "suffix \n"),
86100
new AnnotationModel());
87-
GridDataFactory.fillDefaults().grab(true, true).applyTo(sourceViewer.getTextWidget());
101+
GridDataFactory.fillDefaults().span(2, 1).grab(true, true).applyTo(sourceViewer.getTextWidget());
88102
// Add AnnotationPainter (required by CodeMining)
89103
addAnnotationPainter(sourceViewer);
104+
105+
toggleInLineButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
106+
useInLineCodeMinings.set(!useInLineCodeMinings.get());
107+
toggleInLineButton.setText(useInLineCodeMinings.get() ? IN_LINE : LINE_HEADER);
108+
sourceViewer.updateCodeMinings();
109+
}));
110+
90111
// Initialize codemining providers
91-
((ISourceViewerExtension5) sourceViewer).setCodeMiningProviders(new ICodeMiningProvider[] {
112+
sourceViewer.setCodeMiningProviders(new ICodeMiningProvider[] {
92113
new ClassReferenceCodeMiningProvider(), //
93114
new ClassImplementationsCodeMiningProvider(), //
94115
new ToEchoWithHeaderAndInlineCodeMiningProvider("echo"), //
95116
new MultilineCodeMiningProvider(), //
96117
new EmptyLineCodeMiningProvider(), //
97118
new EchoAtEndOfLineCodeMiningProvider(endOfLineString), //
98-
new LineContentCodeMiningAfterPositionProvider() });
119+
new LineContentCodeMiningAfterPositionProvider(), //
120+
new ReferenceCodeMiningProvider(useInLineCodeMinings) });
121+
99122
// Execute codemining in a reconciler
100123
MonoReconciler reconciler = new MonoReconciler(new IReconcilingStrategy() {
101124

102125
@Override
103126
public void setDocument(IDocument document) {
104-
((ISourceViewerExtension5) sourceViewer).updateCodeMinings();
127+
sourceViewer.updateCodeMinings();
105128
}
106129

107130
@Override
@@ -111,14 +134,14 @@ public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
111134

112135
@Override
113136
public void reconcile(IRegion partition) {
114-
((ISourceViewerExtension5) sourceViewer).updateCodeMinings();
137+
sourceViewer.updateCodeMinings();
115138
}
116139
}, false);
117140
reconciler.install(sourceViewer);
118141

119142
endOfLineText.addModifyListener(event -> {
120143
endOfLineString.set(endOfLineText.getText());
121-
((ISourceViewerExtension5) sourceViewer).updateCodeMinings();
144+
sourceViewer.updateCodeMinings();
122145
});
123146

124147
shell.open();
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025, Advantest Europe GmbH
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Dietrich Travkin <[email protected]> - Fix code mining redrawing - Issue 3405
13+
*
14+
*******************************************************************************/
15+
package org.eclipse.jface.text.examples.codemining;
16+
17+
import java.util.ArrayList;
18+
import java.util.Collections;
19+
import java.util.List;
20+
import java.util.concurrent.CompletableFuture;
21+
import java.util.concurrent.atomic.AtomicReference;
22+
import java.util.regex.Matcher;
23+
import java.util.regex.Pattern;
24+
25+
import org.eclipse.core.runtime.IProgressMonitor;
26+
import org.eclipse.jface.text.BadLocationException;
27+
import org.eclipse.jface.text.IDocument;
28+
import org.eclipse.jface.text.ITextViewer;
29+
import org.eclipse.jface.text.codemining.AbstractCodeMiningProvider;
30+
import org.eclipse.jface.text.codemining.ICodeMining;
31+
32+
public class ReferenceCodeMiningProvider extends AbstractCodeMiningProvider {
33+
34+
private static final String REGEX_REF = "\\[REF-X\\]|\\[REF-Y\\]";
35+
private static final Pattern REGEX_PATTERN = Pattern.compile(REGEX_REF);
36+
37+
private AtomicReference<Boolean> useInLineCodeMinings;
38+
39+
public ReferenceCodeMiningProvider(AtomicReference<Boolean> useInLineCodeMinings) {
40+
this.useInLineCodeMinings = useInLineCodeMinings;
41+
}
42+
43+
@Override
44+
public CompletableFuture<List<? extends ICodeMining>> provideCodeMinings(ITextViewer viewer,
45+
IProgressMonitor monitor) {
46+
return CompletableFuture.supplyAsync(() -> {
47+
IDocument document = viewer.getDocument();
48+
49+
if (document == null) {
50+
return Collections.emptyList();
51+
}
52+
53+
return createCodeMiningsFor(document);
54+
});
55+
}
56+
57+
List<ICodeMining> createCodeMiningsFor(IDocument document) {
58+
String documentContent = document.get();
59+
List<ICodeMining> minings = new ArrayList<>();
60+
61+
Matcher regexMatcher = REGEX_PATTERN.matcher(documentContent);
62+
while (regexMatcher.find()) {
63+
String matchedText = regexMatcher.group();
64+
int startIndex = regexMatcher.start();
65+
66+
String title = matchedText.endsWith("X]") ? "Plugging into Eclipse"
67+
: "Building commercial quality plug-ins";
68+
69+
if (useInLineCodeMinings.get()) {
70+
minings.add(new ReferenceInLineCodeMining(title + ": ", startIndex, document, this));
71+
} else {
72+
try {
73+
int offset = startIndex;
74+
int line = document.getLineOfOffset(offset);
75+
int lineOffset = document.getLineOffset(line);
76+
77+
minings.add(new ReferenceLineHeaderCodeMining(title, line, offset - lineOffset, title.length(),
78+
document, this));
79+
} catch (BadLocationException e) {
80+
e.printStackTrace();
81+
}
82+
}
83+
}
84+
85+
return minings;
86+
}
87+
88+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025, Advantest Europe GmbH
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Dietrich Travkin <[email protected]> - Fix code mining redrawing - Issue 3405
13+
*
14+
*******************************************************************************/
15+
package org.eclipse.jface.text.examples.codemining;
16+
17+
import org.eclipse.jface.text.IDocument;
18+
import org.eclipse.jface.text.Position;
19+
import org.eclipse.jface.text.codemining.ICodeMiningProvider;
20+
import org.eclipse.jface.text.codemining.LineContentCodeMining;
21+
22+
public class ReferenceInLineCodeMining extends LineContentCodeMining {
23+
24+
public ReferenceInLineCodeMining(String label, int positionOffset, IDocument document,
25+
ICodeMiningProvider provider) {
26+
super(new Position(positionOffset, 1), provider);
27+
this.setLabel(label);
28+
}
29+
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025, Advantest Europe GmbH
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Dietrich Travkin <[email protected]> - Fix code mining redrawing - Issue 3405
13+
*
14+
*******************************************************************************/
15+
package org.eclipse.jface.text.examples.codemining;
16+
17+
import org.eclipse.jface.text.BadLocationException;
18+
import org.eclipse.jface.text.IDocument;
19+
import org.eclipse.jface.text.Position;
20+
import org.eclipse.jface.text.codemining.ICodeMiningProvider;
21+
import org.eclipse.jface.text.codemining.LineHeaderCodeMining;
22+
import org.eclipse.jface.text.source.inlined.Positions;
23+
24+
public class ReferenceLineHeaderCodeMining extends LineHeaderCodeMining {
25+
26+
public ReferenceLineHeaderCodeMining(String label, int beforeLineNumber, int columnInLine, int length,
27+
IDocument document, ICodeMiningProvider provider) throws BadLocationException {
28+
super(calculatePosition(beforeLineNumber, columnInLine, document), provider, null);
29+
this.setLabel(label);
30+
}
31+
32+
private static Position calculatePosition(int beforeLineNumber, int columnInLine, IDocument document)
33+
throws BadLocationException {
34+
Position pos = Positions.of(beforeLineNumber, document, true);
35+
pos.setOffset(pos.offset + columnInLine);
36+
return pos;
37+
}
38+
39+
}

0 commit comments

Comments
 (0)