Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion bundles/org.eclipse.cdt.lsp.test/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Bundle-SymbolicName: org.eclipse.cdt.lsp.test;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: Eclipse.org
Fragment-Host: org.eclipse.cdt.lsp
Require-Bundle: junit-jupiter-api
Require-Bundle: junit-jupiter-api,
junit-jupiter-params
Automatic-Module-Name: org.eclipse.cdt.lsp.test
Bundle-RequiredExecutionEnvironment: JavaSE-17
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*******************************************************************************
* Copyright (c) 2026 Advantest GmbH and others.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Dietrich Travkin (Solunar GmbH) - initial implementation
*******************************************************************************/
package org.eclipse.cdt.lsp.test.internal.ui.navigator;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.net.URI;
import java.util.List;

import org.eclipse.cdt.lsp.plugin.LspPlugin;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.lsp4e.outline.SymbolsLabelProvider;
import org.eclipse.lsp4e.outline.SymbolsModel.DocumentSymbolWithURI;
import org.eclipse.lsp4e.ui.LSPImages;
import org.eclipse.lsp4j.DocumentSymbol;
import org.eclipse.lsp4j.SymbolKind;
import org.eclipse.lsp4j.SymbolTag;
import org.eclipse.swt.graphics.Image;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

public class CSymbolIconProviderTest {

@ParameterizedTest
@CsvSource({
// @formatter:off
"~SomeType, true",
"SomeType, false",
"SomeType::~SomeType, true",
"SomeType::SomeType, false"
// @formatter:on
})
public void testCustomDestructorOverlayIconUsed(String symbolName, boolean isDestructor) {
Comment thread
travkin79 marked this conversation as resolved.
// GIVEN a document symbol representing a public destructor or constructor
DocumentSymbol documentSymbol = new DocumentSymbol();

// LSP doesn't know destructors, they are modelled as constructors with a ~ in their name
documentSymbol.setKind(SymbolKind.Constructor);

documentSymbol.setName(symbolName);
documentSymbol.setTags(List.of(SymbolTag.Public));
DocumentSymbolWithURI symbol = new DocumentSymbolWithURI(documentSymbol,
URI.create("file:///home/username/some/path/SomeType.cpp"));

// WHEN we get an image with overlay icons from the label provider for our destructor/constructor symbol
SymbolsLabelProvider labelProvider = new SymbolsLabelProvider();
Image actualImage = labelProvider.getImage(symbol);

// THEN we expect the image to represent a public method (base image)
// with a destructor/constructor overlay icon in the top-right corner
ImageDescriptor topRightOverlay;
if (isDestructor) {
topRightOverlay = LspPlugin.getDefault().getImageDescriptor(LspPlugin.IMG_OVR_DESTRUCTOR);
} else {
topRightOverlay = LSPImages.getImageDescriptor(LSPImages.IMG_OVR_CONSTRUCTOR);
}
Image expectedImage = LSPImages.getImageWithOverlays(
// base image for a public method
LSPImages.IMG_METHOD_VIS_PUBLIC,
// no overlay icons except of our destructor overlay in the top right corner
null, topRightOverlay, null, null, null);

assertEquals(expectedImage, actualImage);
}

}
2 changes: 1 addition & 1 deletion bundles/org.eclipse.cdt.lsp/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Bundle-Activator: org.eclipse.cdt.lsp.plugin.LspPlugin
Bundle-Vendor: %Bundle-Vendor
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.lsp4e;bundle-version="0.18.14",
org.eclipse.lsp4e;bundle-version="0.19.11",
org.eclipse.tm4e.ui,
org.eclipse.tm4e.languageconfiguration,
org.eclipse.ui.genericeditor,
Expand Down
118 changes: 118 additions & 0 deletions bundles/org.eclipse.cdt.lsp/icons/ovr16/destr_ovr.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 21 additions & 8 deletions bundles/org.eclipse.cdt.lsp/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@
</extension>
<extension
point="org.eclipse.tm4e.registry.grammars">
<!-- This content type binding is needed because the cpp content type from TM4E (source.cpp)
does not cover C++ standard library header without file extension -->
<!-- This content type binding is needed because the cpp content type from TM4E (source.cpp)
does not cover C++ standard library header without file extension -->
<scopeNameContentTypeBinding
contentTypeId="org.eclipse.cdt.core.cxxHeader"
scopeName="source.cpp">
Expand Down Expand Up @@ -166,7 +166,7 @@
value="org.eclipse.lsp4e.outline.SymbolsModel$DocumentSymbolWithURI">
</instanceof>
</or>
</enablement>
</enablement>
</actionProvider>
<commonSorter
class="org.eclipse.lsp4e.outline.OutlineSorter"
Expand All @@ -185,6 +185,19 @@
</includes>
</viewerContentBinding>
</extension>
<extension
point="org.eclipse.lsp4e.symbolIconsProvider">
<iconProvider
class="org.eclipse.cdt.lsp.internal.ui.navigator.CSymbolIconProvider"
id="org.eclipse.cdt.lsp.symbolIconProvider">
<contentType
contentTypeId="org.eclipse.cdt.core.cxxSource">
</contentType>
<contentType
contentTypeId="org.eclipse.cdt.core.cxxHeader">
</contentType>
</iconProvider>
</extension>
<extension
point="org.eclipse.core.contenttype.contentTypes">
<file-association
Expand Down Expand Up @@ -220,7 +233,7 @@
property="org.eclipse.cdt.lsp.server.enable.hasLanguageServer"
value="true">
</test>
</with>
</with>
</definition>
</extension>
<extension
Expand Down Expand Up @@ -328,7 +341,7 @@
</action>
</viewerContribution>
</extension>

<extension
point="org.eclipse.ui.genericeditor.hoverProviders">
<hoverProvider
Expand Down Expand Up @@ -360,7 +373,7 @@
<keywordReference id="org.eclipse.cdt.ui.saveactions"/>
<keywordReference id="org.eclipse.cdt.ui.common"/>
<keywordReference id="org.eclipse.cdt.ui.ceditor"/>
</page>
Comment thread
ghentschke marked this conversation as resolved.
</page>
</extension>
<extension
point="org.eclipse.ui.propertyPages">
Expand Down Expand Up @@ -396,7 +409,7 @@
type="org.eclipse.core.resources.IProject">
</adapt>
</enabledWhen>
</page>
</page>
</extension>
<extension
point="org.eclipse.ui.genericeditor.reconcilers">
Expand Down Expand Up @@ -447,6 +460,6 @@
name="%CEditor.name"
parentId="org.eclipse.ui.genericeditor.genericEditorContext">
</context>
</extension>
</extension>
</plugin>

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2026 Advantest GmbH and others.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Dietrich Travkin (Solunar GmbH) - initial implementation
*******************************************************************************/
package org.eclipse.cdt.lsp.internal.ui.navigator;

import java.util.List;

import org.eclipse.cdt.lsp.plugin.LspPlugin;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.lsp4e.ui.SymbolIconProvider;
import org.eclipse.lsp4j.SymbolKind;
import org.eclipse.lsp4j.SymbolTag;

public class CSymbolIconProvider extends SymbolIconProvider {
Comment thread
ghentschke marked this conversation as resolved.

private static ImageDescriptor IMG_DESTRUCTOR_OVERLAY = null;

private ImageDescriptor getDestructorOverlay() {
if (IMG_DESTRUCTOR_OVERLAY == null) {
IMG_DESTRUCTOR_OVERLAY = LspPlugin.getDefault().getImageDescriptor(LspPlugin.IMG_OVR_DESTRUCTOR);
}
return IMG_DESTRUCTOR_OVERLAY;
}

@Override
protected Overlays getOverlaysFor(final SymbolKind symbolKind, final List<SymbolTag> symbolTags, int severity,
Object symbol) {

final var overlays = super.getOverlaysFor(symbolKind, symbolTags, severity, symbol);

if (symbolKind == SymbolKind.Constructor) {
String name = getName(symbol);
// if the symbol's name represents a destructor, e.g. is named MyType::~MyType
if (name != null && name.contains("~")) { //$NON-NLS-1$
// then replace the constructor overlay with a destructor overlay
ImageDescriptor destructorOverlayDescriptor = getDestructorOverlay();
return new Overlays(overlays.topLeft, destructorOverlayDescriptor, overlays.bottomLeft,
overlays.bottomRight, overlays.underlay);
}
}

return overlays;
}

}
Loading
Loading