2121import org .eclipse .jface .resource .ImageDescriptor ;
2222import org .eclipse .jface .viewers .LabelProvider ;
2323import 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 ;
2427import org .eclipse .lsp4j .SymbolKind ;
2528import org .eclipse .lsp4j .SymbolTag ;
29+ import org .eclipse .lsp4j .WorkspaceSymbol ;
2630import org .eclipse .swt .graphics .Image ;
2731import org .eclipse .ui .ISharedImages ;
2832
3337 */
3438public 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