Skip to content

Commit d3c9371

Browse files
travkin79rubenporras
authored andcommitted
Adapt overlay icon calculation for customization by LSP4E clients
- Extract method for determining all overlay icons so that clients can override it to customize overlay icons. - Introduce convenience method for determining a symbol's name. - Forward the symbol object to methods for calculating the symbol's icon and overlay icons so that clients could use additional symbol details for customization, e.g. name and details fields.
1 parent 86e8927 commit d3c9371

5 files changed

Lines changed: 88 additions & 17 deletions

File tree

org.eclipse.lsp4e/src/org/eclipse/lsp4e/callhierarchy/CallHierarchyLabelProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public CallHierarchyLabelProvider(SymbolIconProvider symbolIconProvider) {
3939
public @Nullable Image getImage(final @Nullable Object element) {
4040
if (element instanceof CallHierarchyViewTreeNode treeNode) {
4141
CallHierarchyItem callContainer = treeNode.getCallContainer();
42-
Image res = symbolIconProvider.getImageFor(callContainer.getKind(), callContainer.getTags());
42+
Image res = symbolIconProvider.getImageFor(callContainer.getKind(), callContainer.getTags(), element);
4343
if (res != null) {
4444
return res;
4545
}

org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/typeHierarchy/TypeHierarchyItemLabelProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public String getText(Object element) {
3939
@Override
4040
public @Nullable Image getImage(@Nullable Object element) {
4141
if (element instanceof TypeHierarchyItem item) {
42-
return symbolIconProvider.getImageFor(item.getKind(), item.getTags());
42+
return symbolIconProvider.getImageFor(item.getKind(), item.getTags(), element);
4343
}
4444
return element == null ? null : super.getImage(element);
4545
}

org.eclipse.lsp4e/src/org/eclipse/lsp4e/outline/SymbolsLabelProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ public void dispose() {
170170
}
171171

172172
if (actualElement != null && symbolKind != null) {
173-
return symbolIconProvider.getImageFor(symbolKind, symbolTags, getMaxSeverity(actualElement));
173+
return symbolIconProvider.getImageFor(symbolKind, symbolTags, getMaxSeverity(actualElement), actualElement);
174174
}
175175

176176
return null;

org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/LSPImages.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,8 @@ public static ImageRegistry getImageRegistry() {
292292
*
293293
* @see #getImage(String))
294294
* @see #getImageDescriptor(String)
295-
* @see SymbolIconProvider#getImageFor(SymbolKind, java.util.List)
296-
* @see SymbolIconProvider#getImageFor(SymbolKind, java.util.List, int)
295+
* @see SymbolIconProvider#getImageFor(SymbolKind, java.util.List, Object)
296+
* @see SymbolIconProvider#getImageFor(SymbolKind, java.util.List, int, Object)
297297
*/
298298
public static @Nullable Image imageFromSymbolKind(@Nullable SymbolKind kind) {
299299
if (kind == null) {

org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/SymbolIconProvider.java

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@
2121
import org.eclipse.jface.resource.ImageDescriptor;
2222
import org.eclipse.jface.viewers.LabelProvider;
2323
import org.eclipse.lsp4e.operations.symbols.SymbolsUtil;
24+
import org.eclipse.lsp4e.outline.SymbolsModel.DocumentSymbolWithURI;
25+
import org.eclipse.lsp4j.DocumentSymbol;
26+
import org.eclipse.lsp4j.SymbolInformation;
2427
import org.eclipse.lsp4j.SymbolKind;
2528
import org.eclipse.lsp4j.SymbolTag;
29+
import org.eclipse.lsp4j.WorkspaceSymbol;
2630
import org.eclipse.swt.graphics.Image;
2731
import org.eclipse.ui.ISharedImages;
2832

@@ -33,6 +37,30 @@
3337
*/
3438
public class SymbolIconProvider {
3539

40+
/**
41+
* Returns a symbol's name if the given symbol is an instance of
42+
* {@link DocumentSymbol}, or {@link DocumentSymbolWithURI},
43+
* {@link SymbolInformation}, or {@link WorkspaceSymbol},
44+
* returns <code>null</code> otherwise.
45+
*
46+
* @param symbol the symbol to get the name for
47+
* @return the symbol's name or <code>null</code>.
48+
*/
49+
protected @Nullable String getName(Object symbol) {
50+
String name = null;
51+
if (symbol instanceof SymbolInformation info) {
52+
name = info.getName();
53+
} else if (symbol instanceof WorkspaceSymbol wpSymbol) {
54+
name = wpSymbol.getName();
55+
} else if (symbol instanceof DocumentSymbol docSymbol) {
56+
name = docSymbol.getName();
57+
} else if (symbol instanceof DocumentSymbolWithURI symbolWithURI) {
58+
name = symbolWithURI.symbol.getName();
59+
}
60+
61+
return name;
62+
}
63+
3664
/**
3765
* Returns an overlay icon {@link ImageDescriptor} for the given severity.
3866
*
@@ -154,6 +182,10 @@ protected String getImageKeyFromSymbolKindWithVisibility(SymbolKind kind, List<S
154182
Optional<SymbolTag> visibilityTag = getHighestPrecedenceVisibilitySymbolTag(symbolTags);
155183

156184
if (visibilityTag.isEmpty()) {
185+
if (kind == SymbolKind.Constructor) {
186+
// we'll add a constructor overlay icon instead in #getOverlaysFor(...), this way, the overlays will be customizable
187+
return LSPImages.IMG_METHOD;
188+
}
157189
return LSPImages.imageKeyFromSymbolKind(kind);
158190
}
159191

@@ -189,12 +221,14 @@ protected String getImageKeyFromSymbolKindWithVisibility(SymbolKind kind, List<S
189221
*
190222
* @param symbolKind the kind of symbol
191223
* @param symbolTags the symbol tags
224+
* @param symbol the symbol for which an image should be returned, may be used by subclasses to determine the image to return
192225
* @return a new or cached image for the given symbol kind with overlay icons computed for the given arguments.
193226
*
194-
* @see #getImageFor(SymbolKind, List, int)
227+
* @see #getImageFor(SymbolKind, List, int, Object)
195228
*/
196-
public @Nullable Image getImageFor(@Nullable SymbolKind symbolKind, @Nullable List<SymbolTag> symbolTags) {
197-
return getImageFor(symbolKind, symbolTags, -1);
229+
public @Nullable Image getImageFor(@Nullable SymbolKind symbolKind, @Nullable List<SymbolTag> symbolTags,
230+
Object symbol) {
231+
return getImageFor(symbolKind, symbolTags, -1, symbol);
198232
}
199233

200234
/**
@@ -206,12 +240,13 @@ protected String getImageKeyFromSymbolKindWithVisibility(SymbolKind kind, List<S
206240
* @param symbolKind the kind of symbol
207241
* @param symbolTags the symbol tags
208242
* @param severity one of -1, {@link IMarker#SEVERITY_WARNING}, and {@link IMarker#SEVERITY_ERROR}. -1 indicates no overlay icon.
243+
* @param symbol the symbol for which an image should be returned, may be used by subclasses to determine the image to return
209244
* @return a new or cached image for the given symbol kind with overlay icons computed for the given arguments.
210245
*
211-
* @see #getImageFor(SymbolKind, List)
246+
* @see #getImageFor(SymbolKind, List, Object)
212247
*/
213248
public @Nullable Image getImageFor(final @Nullable SymbolKind symbolKind,
214-
final @Nullable List<SymbolTag> symbolTags, int severity) {
249+
final @Nullable List<SymbolTag> symbolTags, int severity, Object symbol) {
215250

216251
if (symbolKind == null) {
217252
return LSPImages.imageFromSymbolKind(symbolKind);
@@ -221,10 +256,29 @@ protected String getImageKeyFromSymbolKindWithVisibility(SymbolKind kind, List<S
221256

222257
String baseImageKey = getImageKeyFromSymbolKindWithVisibility(symbolKind, finalSymbolTags);
223258

259+
Overlays overlays = getOverlaysFor(symbolKind, finalSymbolTags, severity, symbol);
260+
261+
return LSPImages.getImageWithOverlays(baseImageKey, overlays.topLeft, overlays.topRight,
262+
overlays.bottomLeft, overlays.bottomRight, overlays.underlay);
263+
}
264+
265+
/**
266+
* Determines the overlay icons to be shown for a symbol with the given arguments.
267+
* Sub-classes may override this method to customize the overlay icons.
268+
*
269+
* @param symbolKind the symbol kind, e.g. field, method, constructor, class, property
270+
* @param symbolTags the symbol tags, e.g. visibility tags, deprecation tag, static tag, final tag
271+
* @param severity the severity of the most severe marker associated with the symbol, or -1 if no marker is associated with the symbol
272+
* @param symbol the original symbol, i.e. an instance of {@link DocumentSymbol}, {@link DocumentSymbolWithURI}, {@link SymbolInformation}, or {@link WorkspaceSymbol}
273+
* @return The overlay icons to display for the given symbol
274+
*/
275+
protected Overlays getOverlaysFor(final SymbolKind symbolKind,
276+
final List<SymbolTag> symbolTags, int severity, Object symbol) {
277+
224278
ImageDescriptor severityImageDescriptor = getOverlayForMarkerSeverity(severity);
225-
ImageDescriptor deprecatedImageDescriptor = getUnderlayForDeprecation(SymbolsUtil.isDeprecated(finalSymbolTags));
279+
ImageDescriptor deprecatedImageDescriptor = getUnderlayForDeprecation(SymbolsUtil.isDeprecated(symbolTags));
226280

227-
List<SymbolTag> additionalTags = getAdditionalSymbolTagsSorted(finalSymbolTags);
281+
List<SymbolTag> additionalTags = getAdditionalSymbolTagsSorted(symbolTags);
228282

229283
ImageDescriptor topLeftOverlayDescriptor = null;
230284
ImageDescriptor topRightOverlayDescriptor = null;
@@ -233,8 +287,7 @@ protected String getImageKeyFromSymbolKindWithVisibility(SymbolKind kind, List<S
233287
ImageDescriptor underlayDescriptor = deprecatedImageDescriptor;
234288

235289
// special case for a constructor with visibility tag => we need to add a "C" overlay to show it's a constructor
236-
if (SymbolKind.Constructor == symbolKind
237-
&& !baseImageKey.equals(LSPImages.imageKeyFromSymbolKind(symbolKind))) {
290+
if (SymbolKind.Constructor == symbolKind) {
238291
topRightOverlayDescriptor = LSPImages.getImageDescriptor(LSPImages.IMG_OVR_CONSTRUCTOR);
239292
}
240293

@@ -262,11 +315,29 @@ protected String getImageKeyFromSymbolKindWithVisibility(SymbolKind kind, List<S
262315
// The top left and top right corners remain for additional symbol tags (besides visibility, severity, deprecation)
263316
// In case of constructors we already have a "C" for "constructor" in the upper right corner
264317
// and have use the lower right corner for another additional symbol tag.
265-
bottomRightOverlayDescriptor = getOverlayForVisibility(finalSymbolTags);
318+
bottomRightOverlayDescriptor = getOverlayForVisibility(symbolTags);
266319
}
267320

268-
return LSPImages.getImageWithOverlays(baseImageKey, topLeftOverlayDescriptor, topRightOverlayDescriptor,
269-
bottomLeftOverlayDescriptor, bottomRightOverlayDescriptor, underlayDescriptor);
321+
return new Overlays(topLeftOverlayDescriptor, topRightOverlayDescriptor, bottomLeftOverlayDescriptor,
322+
bottomRightOverlayDescriptor, underlayDescriptor);
323+
}
324+
325+
public static final class Overlays {
326+
public final @Nullable ImageDescriptor topLeft;
327+
public final @Nullable ImageDescriptor topRight;
328+
public final @Nullable ImageDescriptor bottomLeft;
329+
public final @Nullable ImageDescriptor bottomRight;
330+
public final @Nullable ImageDescriptor underlay;
331+
332+
public Overlays(@Nullable ImageDescriptor topLeft, @Nullable ImageDescriptor topRight,
333+
@Nullable ImageDescriptor bottomLeft, @Nullable ImageDescriptor bottomRight,
334+
@Nullable ImageDescriptor underlay) {
335+
this.topLeft = topLeft;
336+
this.topRight = topRight;
337+
this.bottomLeft = bottomLeft;
338+
this.bottomRight = bottomRight;
339+
this.underlay = underlay;
340+
}
270341
}
271342

272343
}

0 commit comments

Comments
 (0)