Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jface.text/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/internal/text/codemining/CancellationExceptionMonitor.java34
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/internal/text/codemining/CodeMiningAnnotation.java94
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/internal/text/codemining/CodeMiningManager.java323
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/AbstractCodeMining.java144
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/AbstractCodeMiningProvider.java65
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/ICodeMining.java99
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/ICodeMiningProvider.java45
8 files changed, 806 insertions, 0 deletions
diff --git a/org.eclipse.jface.text/META-INF/MANIFEST.MF b/org.eclipse.jface.text/META-INF/MANIFEST.MF
index ca017ba5b68..11a83d1deea 100644
--- a/org.eclipse.jface.text/META-INF/MANIFEST.MF
+++ b/org.eclipse.jface.text/META-INF/MANIFEST.MF
@@ -9,11 +9,13 @@ Export-Package:
org.eclipse.jface.contentassist,
org.eclipse.jface.contentassist.images,
org.eclipse.jface.internal.text;x-internal:=true,
+ org.eclipse.jface.internal.text.codemining;x-internal:=true,
org.eclipse.jface.internal.text.html;x-friends:="org.eclipse.ui.workbench.texteditor, org.eclipse.ui.editors, org.eclipse.jdt.debug.ui, org.eclipse.jdt.ui, org.eclipse.ant.ui, org.eclipse.ltk.ui.refactoring, org.eclipse.pde.ui",
org.eclipse.jface.internal.text.link.contentassist;x-internal:=true,
org.eclipse.jface.internal.text.revisions;x-internal:=true,
org.eclipse.jface.internal.text.source;x-internal:=true,
org.eclipse.jface.text,
+ org.eclipse.jface.text.codemining,
org.eclipse.jface.text.contentassist,
org.eclipse.jface.text.formatter,
org.eclipse.jface.text.hyperlink,
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/codemining/CancellationExceptionMonitor.java b/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/codemining/CancellationExceptionMonitor.java
new file mode 100644
index 00000000000..a4001cf6cf2
--- /dev/null
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/codemining/CancellationExceptionMonitor.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2017 Angelo ZERR.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Angelo Zerr <angelo.zerr@gmail.com> - [CodeMining] Provide CodeMining support with CodeMiningManager - Bug 527720
+ */
+package org.eclipse.jface.internal.text.codemining;
+
+import java.util.concurrent.CancellationException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
+/**
+ * {@link IProgressMonitor} which throws a {@link CancellationException} when
+ * {@link IProgressMonitor#isCanceled()} returns true.
+ *
+ * @since 3.13
+ */
+class CancellationExceptionMonitor extends NullProgressMonitor {
+
+ @Override
+ public boolean isCanceled() {
+ boolean canceled= super.isCanceled();
+ if (canceled) {
+ throw new CancellationException();
+ }
+ return canceled;
+ }
+}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/codemining/CodeMiningAnnotation.java b/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/codemining/CodeMiningAnnotation.java
new file mode 100644
index 00000000000..7b7daad3f58
--- /dev/null
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/codemining/CodeMiningAnnotation.java
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2017 Angelo ZERR.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Angelo Zerr <angelo.zerr@gmail.com> - [CodeMining] Provide CodeMining support with CodeMiningManager - Bug 527720
+ */
+package org.eclipse.jface.internal.text.codemining;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.codemining.ICodeMining;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.inlined.LineHeaderAnnotation;
+
+/**
+ * Code Mining annotation.
+ *
+ * @since 3.13
+ */
+public class CodeMiningAnnotation extends LineHeaderAnnotation {
+
+ private static final String SEPARATOR= " | "; //$NON-NLS-1$
+
+ private final List<ICodeMining> fMinings;
+
+ private ITextViewer fViewer;
+
+ private IProgressMonitor fMonitor;
+
+ public CodeMiningAnnotation(Position position, ISourceViewer viewer) {
+ super(position, viewer.getTextWidget());
+ fMinings= new ArrayList<>();
+ this.fViewer= viewer;
+ }
+
+ public void update(List<ICodeMining> minings, IProgressMonitor monitor) {
+ disposeMinings();
+ fMonitor= monitor;
+ fMinings.addAll(minings);
+ }
+
+ @Override
+ public void markDeleted(boolean deleted) {
+ super.markDeleted(deleted);
+ if (deleted) {
+ disposeMinings();
+ }
+ }
+
+ private void disposeMinings() {
+ fMinings.stream().forEach(ICodeMining::dispose);
+ fMinings.clear();
+ }
+
+ @Override
+ public void draw(GC gc, StyledText textWidget, int offset, int length, Color color, int x, int y) {
+ gc.setForeground(color);
+ gc.setBackground(textWidget.getBackground());
+ List<ICodeMining> minings= new ArrayList<>(fMinings);
+ int nbDraw= 0;
+ int separatorWidth= -1;
+ for (ICodeMining mining : minings) {
+ if (!mining.isResolved()) {
+ // Don't draw mining which is not resolved
+ // then redraw the annotation when mining is ready.
+ mining.resolve(fViewer, fMonitor).thenRun(() -> this.redraw());
+ continue;
+ }
+ if (nbDraw > 0) {
+ gc.drawText(SEPARATOR, x, y);
+ if (separatorWidth == -1) {
+ separatorWidth= gc.stringExtent(SEPARATOR).x;
+ }
+ x+= separatorWidth;
+ }
+ x+= mining.draw(gc, textWidget, color, x, y).x;
+ nbDraw++;
+ }
+ }
+
+}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/codemining/CodeMiningManager.java b/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/codemining/CodeMiningManager.java
new file mode 100644
index 00000000000..dfd406f63c7
--- /dev/null
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/codemining/CodeMiningManager.java
@@ -0,0 +1,323 @@
+/**
+ * Copyright (c) 2017 Angelo ZERR.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Angelo Zerr <angelo.zerr@gmail.com> - [CodeMining] Provide CodeMining support with CodeMiningManager - Bug 527720
+ */
+package org.eclipse.jface.internal.text.codemining;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.IViewportListener;
+import org.eclipse.jface.text.JFaceTextUtil;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.codemining.ICodeMining;
+import org.eclipse.jface.text.codemining.ICodeMiningProvider;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.inlined.AbstractInlinedAnnotation;
+import org.eclipse.jface.text.source.inlined.InlinedAnnotationSupport;
+
+/**
+ * Code Mining manager implementation.
+ *
+ * @since 3.13
+ */
+public class CodeMiningManager implements Runnable {
+
+ /**
+ * The source viewer
+ */
+ private final ISourceViewer fViewer;
+
+ /**
+ * The inlined annotation support used to draw CodeMining in the line spacing.
+ */
+ private final InlinedAnnotationSupport fInlinedAnnotationSupport;
+
+ /**
+ * The list of codemining providers.
+ */
+ private List<ICodeMiningProvider> fCodeMiningProviders;
+
+ /**
+ * The current progress monitor.
+ */
+ private IProgressMonitor fMonitor;
+
+ /**
+ * Tracker of start/end offset of visible lines.
+ */
+ private VisibleLines visibleLines;
+
+ /**
+ * Class to track start/end offset of visible lines.
+ *
+ */
+ class VisibleLines implements IViewportListener {
+
+ private int startOffset;
+
+ private int endOffset;
+
+ public VisibleLines() {
+ fViewer.getTextWidget().getDisplay().asyncExec(() -> {
+ startOffset= getInclusiveTopIndexStartOffset();
+ endOffset= getExclusiveBottomIndexEndOffset();
+ });
+ }
+
+ @Override
+ public void viewportChanged(int verticalOffset) {
+ compute();
+ }
+
+ private void compute() {
+ startOffset= getInclusiveTopIndexStartOffset();
+ endOffset= getExclusiveBottomIndexEndOffset();
+ }
+
+ /**
+ * Returns the document offset of the upper left corner of the source viewer's view port,
+ * possibly including partially visible lines.
+ *
+ * @return the document offset if the upper left corner of the view port
+ */
+ private int getInclusiveTopIndexStartOffset() {
+ if (fViewer != null && fViewer.getTextWidget() != null && !fViewer.getTextWidget().isDisposed()) {
+ int top= JFaceTextUtil.getPartialTopIndex(fViewer);
+ try {
+ IDocument document= fViewer.getDocument();
+ return document.getLineOffset(top);
+ } catch (BadLocationException x) {
+ // Do nothing
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the first invisible document offset of the lower right corner of the source
+ * viewer's view port, possibly including partially visible lines.
+ *
+ * @return the first invisible document offset of the lower right corner of the view port
+ */
+ private int getExclusiveBottomIndexEndOffset() {
+ if (fViewer != null && fViewer.getTextWidget() != null && !fViewer.getTextWidget().isDisposed()) {
+ int bottom= JFaceTextUtil.getPartialBottomIndex(fViewer);
+ try {
+ IDocument document= fViewer.getDocument();
+
+ if (bottom >= document.getNumberOfLines())
+ bottom= document.getNumberOfLines() - 1;
+
+ return document.getLineOffset(bottom) + document.getLineLength(bottom);
+ } catch (BadLocationException x) {
+ // Do nothing
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns true if the given annotation is in visible lines and false otherwise.
+ *
+ * @param ann the codemining annotation
+ * @return true if the given annotation is in visible lines and false otherwise.
+ */
+ public boolean isInVisibleLines(CodeMiningAnnotation ann) {
+ return ann.getPosition().getOffset() >= startOffset && ann.getPosition().getOffset() <= endOffset;
+ }
+ }
+
+
+ /**
+ * Constructor of codemining manager with the given arguments.
+ *
+ * @param viewer the source viewer
+ * @param inlinedAnnotationSupport the inlined annotation support used to draw code minings
+ * @param codeMiningProviders the array of codemining providers, must not be empty
+ */
+ public CodeMiningManager(ISourceViewer viewer, InlinedAnnotationSupport inlinedAnnotationSupport,
+ ICodeMiningProvider[] codeMiningProviders) {
+ Assert.isNotNull(viewer);
+ Assert.isNotNull(inlinedAnnotationSupport);
+ Assert.isNotNull(codeMiningProviders);
+ fViewer= viewer;
+ visibleLines= new VisibleLines();
+ fViewer.addViewportListener(visibleLines);
+ fInlinedAnnotationSupport= inlinedAnnotationSupport;
+ setCodeMiningProviders(codeMiningProviders);
+ }
+
+ /**
+ * Set the codemining providers.
+ *
+ * @param codeMiningProviders the codemining providers.
+ */
+ public void setCodeMiningProviders(ICodeMiningProvider[] codeMiningProviders) {
+ fCodeMiningProviders= Arrays.asList(codeMiningProviders);
+ }
+
+ /**
+ * Uninstalls this codemining manager.
+ */
+ public void uninstall() {
+ cancel();
+ fViewer.removeViewportListener(visibleLines);
+ }
+
+ /**
+ * Collect, resolve and render the code minings of the viewer.
+ */
+ @Override
+ public void run() {
+ if (fViewer == null || fInlinedAnnotationSupport == null || fCodeMiningProviders == null
+ || fCodeMiningProviders.size() == 0 || fViewer.getAnnotationModel() == null) {
+ return;
+ }
+ // Cancel the last progress monitor to cancel last resolve and render of code
+ // minings
+ cancel();
+ // Update the code minings
+ updateCodeMinings();
+ }
+
+ /**
+ * Update the code minings.
+ */
+ private void updateCodeMinings() {
+ // Refresh the code minings by using the new progress monitor.
+ fMonitor= new CancellationExceptionMonitor();
+ IProgressMonitor monitor= fMonitor;
+ // Collect the code minings for the viewer
+ getCodeMinings(fViewer, fCodeMiningProviders, monitor).thenAccept(symbols -> {
+ // check if request was canceled.
+ monitor.isCanceled();
+ // then group code minings by lines position
+ Map<Position, List<ICodeMining>> groups= goupByLines(symbols, fCodeMiningProviders);
+ // resolve and render code minings
+ renderCodeMinings(groups, fViewer, monitor);
+ });
+ }
+
+ /**
+ * Cancel the codemining process.
+ */
+ private void cancel() {
+ // Cancel the last progress monitor.
+ if (fMonitor != null) {
+ fMonitor.setCanceled(true);
+ }
+ }
+
+ /**
+ * Return the list of {@link CompletableFuture} which provides the list of {@link ICodeMining}
+ * for the given <code>viewer</code> by using the given providers.
+ *
+ * @param viewer the text viewer.
+ * @param providers the CodeMining list providers.
+ * @param monitor the progress monitor.
+ * @return the list of {@link CompletableFuture} which provides the list of {@link ICodeMining}
+ * for the given <code>viewer</code> by using the given providers.
+ */
+ private static CompletableFuture<List<? extends ICodeMining>> getCodeMinings(ITextViewer viewer,
+ List<ICodeMiningProvider> providers, IProgressMonitor monitor) {
+ List<CompletableFuture<List<? extends ICodeMining>>> com= providers.stream()
+ .map(provider -> provider.provideCodeMinings(viewer, monitor)).filter(c -> c != null)
+ .collect(Collectors.toList());
+ return CompletableFuture.allOf(com.toArray(new CompletableFuture[com.size()])).thenApply(
+ v -> com.stream().map(CompletableFuture::join).flatMap(l -> l.stream()).collect(Collectors.toList()));
+ }
+
+ /**
+ * Returns a sorted Map which groups the given code minings by same position line
+ *
+ * @param codeMinings list of code minings to group.
+ * @param providers CodeMining providers used to retrieve code minings.
+ * @return a sorted Map which groups the given code minings by same position line.
+ */
+ private static Map<Position, List<ICodeMining>> goupByLines(List<? extends ICodeMining> codeMinings,
+ List<ICodeMiningProvider> providers) {
+ // sort code minings by lineNumber and provider-rank if
+ Collections.sort(codeMinings, (a, b) -> {
+ if (a.getPosition().offset < b.getPosition().offset) {
+ return -1;
+ } else if (a.getPosition().offset > b.getPosition().offset) {
+ return 1;
+ } else if (providers.indexOf(a.getProvider()) < providers.indexOf(b.getProvider())) {
+ return -1;
+ } else if (providers.indexOf(a.getProvider()) > providers.indexOf(b.getProvider())) {
+ return 1;
+ } else {
+ return 0;
+ }
+ });
+ return codeMinings.stream().collect(Collectors.groupingBy(ICodeMining::getPosition, LinkedHashMap::new,
+ Collectors.mapping(Function.identity(), Collectors.toList())));
+ }
+
+ /**
+ * Render the codemining grouped by line position.
+ *
+ * @param groups code minings grouped by lines position
+ * @param viewer the viewer
+ * @param monitor the progress monitor
+ */
+ private void renderCodeMinings(Map<Position, List<ICodeMining>> groups, ISourceViewer viewer,
+ IProgressMonitor monitor) {
+ // check if request was canceled.
+ monitor.isCanceled();
+ IDocument document= viewer != null ? viewer.getDocument() : null;
+ if (document == null) {
+ // this case comes from when editor is closed before codemining rendered is
+ // done.
+ return;
+ }
+ Set<CodeMiningAnnotation> annotationsToRedraw= new HashSet<>();
+ Set<AbstractInlinedAnnotation> currentAnnotations= new HashSet<>();
+ // Loop for grouped code minings
+ groups.entrySet().stream().forEach(g -> {
+ // check if request was canceled.
+ monitor.isCanceled();
+
+ Position pos= new Position(g.getKey().offset, g.getKey().length);
+ List<ICodeMining> minings= g.getValue();
+ // Try to find existing annotation
+ CodeMiningAnnotation ann= fInlinedAnnotationSupport.findExistingAnnotation(pos);
+ if (ann == null) {
+ // The annotation doesn't exists, create it.
+ ann= new CodeMiningAnnotation(pos, viewer);
+ } else if (visibleLines.isInVisibleLines(ann)) {
+ // annotation is in visible lines
+ annotationsToRedraw.add(ann);
+ }
+ ann.update(minings, monitor);
+ currentAnnotations.add(ann);
+ });
+ // check if request was canceled.
+ monitor.isCanceled();
+ fInlinedAnnotationSupport.updateAnnotations(currentAnnotations);
+ // redraw the existing codemining annotations since their content can change
+ annotationsToRedraw.stream().forEach(ann -> ann.redraw());
+ }
+
+}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/AbstractCodeMining.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/AbstractCodeMining.java
new file mode 100644
index 00000000000..74ba30339d8
--- /dev/null
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/AbstractCodeMining.java
@@ -0,0 +1,144 @@
+/**
+ * Copyright (c) 2017 Angelo ZERR.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Angelo Zerr <angelo.zerr@gmail.com> - [CodeMining] Provide CodeMining support with CodeMiningManager - Bug 527720
+ */
+package org.eclipse.jface.text.codemining;
+
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.inlined.Positions;
+
+/**
+ * Abstract class for {@link ICodeMining}.
+ *
+ * @since 3.13
+ */
+public abstract class AbstractCodeMining implements ICodeMining {
+
+ /**
+ * The position where codemining must be drawn
+ */
+ private final Position position;
+
+ /**
+ * The owner codemining provider which creates this mining.
+ */
+ private final ICodeMiningProvider provider;
+
+ /**
+ * The future used to resolve mining.
+ */
+ private CompletableFuture<Void> resolveFuture;
+
+ /**
+ * The label of the resolved codemining.
+ */
+ private String label;
+
+ /**
+ * CodeMining constructor to locate the code mining before the given line number.
+ *
+ * @param beforeLineNumber the line number where codemining must be drawn. Use 0 if you wish to
+ * locate the code mining before the first line number (1).
+ * @param document the document.
+ * @param provider the owner codemining provider which creates this mining.
+ * @throws BadLocationException when line number doesn't exists
+ */
+ public AbstractCodeMining(int beforeLineNumber, IDocument document, ICodeMiningProvider provider)
+ throws BadLocationException {
+ this.position= Positions.of(beforeLineNumber, document, true);
+ this.provider= provider;
+ }
+
+ @Override
+ public Position getPosition() {
+ return position;
+ }
+
+ @Override
+ public ICodeMiningProvider getProvider() {
+ return provider;
+ }
+
+ @Override
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * Set the label mining.
+ *
+ * @param label the label mining.
+ */
+ public void setLabel(String label) {
+ this.label= label;
+ }
+
+ @Override
+ public final CompletableFuture<Void> resolve(ITextViewer viewer, IProgressMonitor monitor) {
+ if (resolveFuture == null) {
+ resolveFuture= doResolve(viewer, monitor);
+ }
+ return resolveFuture;
+ }
+
+ /**
+ * Returns the future which resolved the content of mining and null otherwise. By default, the
+ * resolve do nothing.
+ *
+ * @param viewer the viewer
+ * @param monitor the monitor
+ * @return the future which resolved the content of mining and null otherwise.
+ */
+ protected CompletableFuture<Void> doResolve(ITextViewer viewer, IProgressMonitor monitor) {
+ return CompletableFuture.completedFuture(null);
+ }
+
+ @Override
+ public boolean isResolved() {
+ return (resolveFuture != null && resolveFuture.isDone());
+ }
+
+ @Override
+ public void dispose() {
+ if (resolveFuture != null) {
+ resolveFuture.cancel(true);
+ resolveFuture= null;
+ }
+ }
+
+ /**
+ * Draw the {@link #getLabel()} of mining with gray color. User can override this method to draw
+ * anything.
+ *
+ * @param gc the graphics context
+ * @param textWidget the text widget to draw on
+ * @param color the color of the line
+ * @param x the x position of the annotation
+ * @param y the y position of the annotation
+ * @return the size of the draw of mining.
+ */
+ @Override
+ public Point draw(GC gc, StyledText textWidget, Color color, int x, int y) {
+ String title= getLabel() != null ? getLabel() : "no command"; //$NON-NLS-1$
+ gc.drawText(title, x, y);
+ return gc.stringExtent(title);
+ }
+}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/AbstractCodeMiningProvider.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/AbstractCodeMiningProvider.java
new file mode 100644
index 00000000000..3b50539d1e5
--- /dev/null
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/AbstractCodeMiningProvider.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2017 Angelo ZERR.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Angelo Zerr <angelo.zerr@gmail.com> - [CodeMining] Provide CodeMining support with CodeMiningManager - Bug 527720
+ */
+package org.eclipse.jface.text.codemining;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+
+/**
+ * A codemining provider that can provide adapters through a context that can be set by the creator
+ * of this codemining provider.
+ * <p>
+ * Clients may subclass.
+ * </p>
+ *
+ * @since 3.13
+ */
+public abstract class AbstractCodeMiningProvider implements ICodeMiningProvider {
+
+ /**
+ * The context of this codemining provider.
+ */
+ private IAdaptable context;
+
+ /**
+ * Sets this codemining provider's context which is responsible to provide the adapters.
+ *
+ * @param context the context for this codemining provider
+ * @throws IllegalArgumentException if the context is <code>null</code>
+ * @throws IllegalStateException if this method is called more than once
+ */
+ public final void setContext(IAdaptable context) throws IllegalStateException, IllegalArgumentException {
+ Assert.isLegal(context != null);
+ if (this.context != null)
+ throw new IllegalStateException();
+ this.context= context;
+ }
+
+ @Override
+ public void dispose() {
+ context= null;
+ }
+
+ /**
+ * Returns an object which is an instance of the given class and provides additional context for
+ * this codemining provider.
+ *
+ * @param adapterClass the adapter class to look up
+ * @return an instance that can be cast to the given class, or <code>null</code> if this object
+ * does not have an adapter for the given class
+ */
+ protected final <T> T getAdapter(Class<T> adapterClass) {
+ Assert.isLegal(adapterClass != null);
+ if (context != null)
+ return context.getAdapter(adapterClass);
+ return null;
+ }
+}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/ICodeMining.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/ICodeMining.java
new file mode 100644
index 00000000000..fc990131556
--- /dev/null
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/ICodeMining.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2017 Angelo ZERR.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Angelo Zerr <angelo.zerr@gmail.com> - [CodeMining] Provide CodeMining support with CodeMiningManager - Bug 527720
+ */
+package org.eclipse.jface.text.codemining;
+
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+
+/**
+ * A code mining represents a content (ex: label, icons) that should be shown along with source
+ * text, like the number of references, a way to run tests (with run/debug icons), etc.
+ *
+ * A code mining is unresolved when no content (ex: label, icons) is associated to it. For
+ * performance reasons the creation of a code mining and resolving should be done to two stages.
+ *
+ * @since 3.13
+ */
+public interface ICodeMining {
+
+ /**
+ * Returns the line position where code mining must be displayed in the line spacing area.
+ *
+ * @return the line position where code mining must be displayed in the line spacing area.
+ */
+ Position getPosition();
+
+ /**
+ * Returns the owner provider which has created this mining.
+ *
+ * @return the owner provider which has created this mining.
+ */
+ ICodeMiningProvider getProvider();
+
+ /**
+ * Returns the label may be set early in the class lifecycle, or upon completion of the future
+ * provided by {@link #resolve(ITextViewer, IProgressMonitor)} operation.
+ *
+ * @return the label may be set early in the class lifecycle, or upon completion of the future
+ * provided by {@link #resolve(ITextViewer, IProgressMonitor)} operation.
+ */
+ String getLabel();
+
+ /**
+ * Returns the future to resolve the content of mining, or
+ * {@link CompletableFuture#completedFuture(Object)} if no such resolution is necessary (in
+ * which case {#isResolved()} is expected to return <code>true</code>).
+ *
+ * @param viewer the viewer.
+ * @param monitor the monitor.
+ * @return the future to resolve the content of mining, or
+ * {@link CompletableFuture#completedFuture(Object)} if no such resolution is necessary
+ * (in which case {#isResolved()} is expected to return <code>true</code>).
+ */
+ CompletableFuture<Void> resolve(ITextViewer viewer, IProgressMonitor monitor);
+
+ /**
+ * Returns whether the content mining is resolved. If it is not resolved,
+ * {{@link #resolve(ITextViewer, IProgressMonitor)}} will be invoked later, triggering the
+ * future to resolve content.
+ *
+ * @return whether the content mining is resolved. If it is not resolved,
+ * {{@link #resolve(ITextViewer, IProgressMonitor)}} will be invoked later, triggering
+ * the future to resolve content.
+ */
+ boolean isResolved();
+
+ /**
+ * Draw the code mining.
+ *
+ * @param gc the graphics context
+ * @param textWidget the text widget to draw on
+ * @param color the color of the line
+ * @param x the x position of the annotation
+ * @param y the y position of the annotation
+ * @return the size of the draw of mining.
+ */
+ Point draw(GC gc, StyledText textWidget, Color color, int x, int y);
+
+ /**
+ * Dispose the mining. Typically shuts down or cancels all related asynchronous operations.
+ */
+ void dispose();
+}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/ICodeMiningProvider.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/ICodeMiningProvider.java
new file mode 100644
index 00000000000..7ea3e8d8053
--- /dev/null
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/ICodeMiningProvider.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2017 Angelo ZERR.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Angelo Zerr <angelo.zerr@gmail.com> - [CodeMining] Provide CodeMining support with CodeMiningManager - Bug 527720
+ */
+package org.eclipse.jface.text.codemining;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.eclipse.jface.text.ITextViewer;
+
+/**
+ * A code mining provider adds minings {@link ICodeMining} to source text. The mining will be shown
+ * as dedicated horizontal lines in between the source text.
+ *
+ * @since 3.13
+ */
+public interface ICodeMiningProvider {
+
+ /**
+ * Compute a list of code minings {@link ICodeMining}. This call should return as fast as
+ * possible and if computing the content of {@link ICodeMining} is expensive implementors should
+ * only return code mining objects with the position and implement resolve
+ * {@link ICodeMining#resolve(ITextViewer, IProgressMonitor)}.
+ *
+ * @param viewer the viewer in which the command was invoked.
+ * @param monitor A progress monitor.
+ * @return An array of future of code minings that resolves to such. The lack of a result can be
+ * signaled by returning null, or an empty array.
+ */
+ CompletableFuture<List<? extends ICodeMining>> provideCodeMinings(ITextViewer viewer, IProgressMonitor monitor);
+
+ /**
+ * Dispose code mining provider.
+ */
+ void dispose();
+}

Back to the top