Skip to content

Commit 03354bf

Browse files
committed
[#227] Refactor ClangdConfigurationManager
- Fix bundle activator/Service Component Runtime (SCR) problem: The Bundle Activator's start method must not rely upon SCR having activated any of the bundle's components. However, the components can rely upon the Bundle Activator's start method having been called. That is, there is a happens-before relationship between the Bundle Activator's start method being run and the components being activated. fixes #227
1 parent 0a9ec78 commit 03354bf

File tree

14 files changed

+52
-166
lines changed

14 files changed

+52
-166
lines changed

bundles/org.eclipse.cdt.lsp.clangd/META-INF/MANIFEST.MF

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,10 @@ Require-Bundle: org.eclipse.cdt.lsp;bundle-version="0.0.0",
3030
org.eclipse.ui.ide;bundle-version="0.0.0",
3131
org.eclipse.ui.workbench;bundle-version="0.0.0",
3232
org.eclipse.ui.workbench.texteditor;bundle-version="0.0.0",
33-
org.eclipse.core.variables,
34-
org.eclipse.cdt.cmake.core
33+
org.eclipse.core.variables;bundle-version="0.0.0"
3534
Service-Component: OSGI-INF/org.eclipse.cdt.lsp.clangd.BuiltinClangdOptionsDefaults.xml,
3635
OSGI-INF/org.eclipse.cdt.lsp.clangd.ClangdConfigurationFileManager.xml,
37-
OSGI-INF/org.eclipse.cdt.lsp.clangd.DefaultCProjectChangeMonitor.xml,
3836
OSGI-INF/org.eclipse.cdt.lsp.internal.clangd.ClangdConfigurationAccess.xml,
3937
OSGI-INF/org.eclipse.cdt.lsp.internal.clangd.ClangdFallbackManager.xml,
40-
OSGI-INF/org.eclipse.cdt.lsp.internal.clangd.ClangdMetadataDefaults.xml,
41-
OSGI-INF/org.eclipse.cdt.lsp.internal.clangd.DefaultMacroResolver.xml
38+
OSGI-INF/org.eclipse.cdt.lsp.internal.clangd.ClangdMetadataDefaults.xml
4239
Bundle-Activator: org.eclipse.cdt.lsp.internal.clangd.editor.ClangdPlugin

bundles/org.eclipse.cdt.lsp.clangd/OSGI-INF/org.eclipse.cdt.lsp.clangd.DefaultCProjectChangeMonitor.xml

Lines changed: 0 additions & 10 deletions
This file was deleted.

bundles/org.eclipse.cdt.lsp.clangd/OSGI-INF/org.eclipse.cdt.lsp.internal.clangd.DefaultMacroResolver.xml

Lines changed: 0 additions & 8 deletions
This file was deleted.

bundles/org.eclipse.cdt.lsp.clangd/src/org/eclipse/cdt/lsp/clangd/CProjectChangeMonitor.java

Lines changed: 0 additions & 32 deletions
This file was deleted.

bundles/org.eclipse.cdt.lsp.clangd/src/org/eclipse/cdt/lsp/clangd/ClangdCProjectDescriptionListener.java

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,19 @@
1414
package org.eclipse.cdt.lsp.clangd;
1515

1616
import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
17-
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
18-
import org.eclipse.core.resources.IProject;
1917

2018
/**
21-
* Vendors can implement this interface as OSGi service
19+
* Vendors may implement this interface as OSGi service
2220
* with a service.ranking property > 0 to implement custom behavior
2321
* and to replace the {@link ClangdConfigurationFileManager}
2422
*/
2523
public interface ClangdCProjectDescriptionListener {
26-
String CLANGD_CONFIG_FILE_NAME = ".clangd"; //$NON-NLS-1$
2724

2825
/**
2926
* Called when the configuration of a CDT C/C++ project changes.
3027
* @param event
31-
* @param macroResolver
28+
* @param macroResolver helper class to resolve macros in builder CWD
3229
*/
3330
void handleEvent(CProjectDescriptionEvent event, MacroResolver macroResolver);
3431

35-
/**
36-
* Set the <code>CompilationDatabase</code> entry in the <code>.clangd</code> file which is located in the <code>project</code> root.
37-
* The <code>.clangd</code> file will be created, if it's not existing.
38-
* The <code>CompilationDatabase</code> points to the build folder of the active build configuration
39-
* (in case <code>project</code> is a managed C/C++ project).
40-
*
41-
* In the following example clangd uses the compile_commands.json file in the Debug folder:
42-
* <pre>CompileFlags: {CompilationDatabase: Debug}</pre>
43-
*
44-
* @param project managed C/C++ project
45-
* @param newCProjectDescription new CProject description
46-
* @param macroResolver helper to resolve macros in the CWD path of the builder
47-
*/
48-
void setCompilationDatabasePath(IProject project, ICProjectDescription newCProjectDescription,
49-
MacroResolver macroResolver);
50-
51-
/**
52-
* Enabler for {@link setCompilationDatabasePath}. Can be overriden for customization.
53-
* @param project
54-
* @return true if the database path should be written to .clangd file in the project root.
55-
*/
56-
boolean enableSetCompilationDatabasePath(IProject project);
5732
}

bundles/org.eclipse.cdt.lsp.clangd/src/org/eclipse/cdt/lsp/clangd/ClangdConfigurationFileManager.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
/**
4747
* Default implementation of the {@link ClangdCProjectDescriptionListener}.
48-
* Can be replaced by vendors if needed. This implementation sets the path to
48+
* Can be extended by vendors if needed. This implementation sets the path to
4949
* the compile_commands.json in the .clangd file in the projects root directory.
5050
* This is needed by CDT projects since the compile_commands.json is generated in the build folder.
5151
* When the active build configuration changes in managed build projects, this manager updates the path to the database in
@@ -55,6 +55,7 @@
5555
*/
5656
@Component(property = { "service.ranking:Integer=0" })
5757
public class ClangdConfigurationFileManager implements ClangdCProjectDescriptionListener {
58+
public static final String CLANGD_CONFIG_FILE_NAME = ".clangd"; //$NON-NLS-1$
5859
private static final String COMPILE_FLAGS = "CompileFlags"; //$NON-NLS-1$
5960
private static final String COMPILATTION_DATABASE = "CompilationDatabase"; //$NON-NLS-1$
6061
private static final String SET_COMPILATION_DB = COMPILE_FLAGS + ": {" + COMPILATTION_DATABASE + ": %s}"; //$NON-NLS-1$ //$NON-NLS-2$
@@ -68,7 +69,19 @@ public void handleEvent(CProjectDescriptionEvent event, MacroResolver macroResol
6869
setCompilationDatabasePath(event.getProject(), event.getNewCProjectDescription(), macroResolver);
6970
}
7071

71-
@Override
72+
/**
73+
* Set the <code>CompilationDatabase</code> entry in the <code>.clangd</code> file which is located in the <code>project</code> root.
74+
* The <code>.clangd</code> file will be created, if it's not existing.
75+
* The <code>CompilationDatabase</code> points to the build folder of the active build configuration
76+
* (in case <code>project</code> is a managed C/C++ project).
77+
*
78+
* In the following example clangd uses the compile_commands.json file in the Debug folder:
79+
* <pre>CompileFlags: {CompilationDatabase: Debug}</pre>
80+
*
81+
* @param project managed C/C++ project
82+
* @param newCProjectDescription new CProject description
83+
* @param macroResolver helper to resolve macros in the CWD path of the builder
84+
*/
7285
public void setCompilationDatabasePath(IProject project, ICProjectDescription newCProjectDescription,
7386
MacroResolver macroResolver) {
7487
if (project != null && newCProjectDescription != null) {
@@ -93,7 +106,11 @@ public void setCompilationDatabasePath(IProject project, ICProjectDescription ne
93106
}
94107
}
95108

96-
@Override
109+
/**
110+
* Enabler for {@link setCompilationDatabasePath}. Can be overriden for customization.
111+
* @param project
112+
* @return true if the database path should be written to .clangd file in the project root.
113+
*/
97114
public boolean enableSetCompilationDatabasePath(IProject project) {
98115
return Optional.ofNullable(LspPlugin.getDefault()).map(LspPlugin::getCLanguageServerProvider)
99116
.map(provider -> provider.isEnabledFor(project)).orElse(Boolean.FALSE);

bundles/org.eclipse.cdt.lsp.clangd/src/org/eclipse/cdt/lsp/clangd/MacroResolver.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,19 @@
1313

1414
package org.eclipse.cdt.lsp.clangd;
1515

16+
import org.eclipse.cdt.core.CCorePlugin;
1617
import org.eclipse.cdt.core.cdtvariables.CdtVariableException;
1718
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
1819

19-
public interface MacroResolver {
20+
/**
21+
* Helper class to resolve macros in builder CWD
22+
*/
23+
public class MacroResolver {
2024

2125
public String resolveValue(String value, String nonexistentMacrosValue, String listDelimiter,
22-
ICConfigurationDescription cfg) throws CdtVariableException;
26+
ICConfigurationDescription cfg) throws CdtVariableException {
27+
return CCorePlugin.getDefault().getCdtVariableManager().resolveValue(value, nonexistentMacrosValue,
28+
listDelimiter, cfg);
29+
}
2330

2431
}
Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,44 +11,39 @@
1111
* Gesa Hentschke (Bachmann electronic GmbH) - initial implementation
1212
*******************************************************************************/
1313

14-
package org.eclipse.cdt.lsp.clangd;
14+
package org.eclipse.cdt.lsp.internal.clangd;
1515

1616
import org.eclipse.cdt.core.CCorePlugin;
1717
import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
1818
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener;
19-
import org.osgi.service.component.annotations.Component;
20-
import org.osgi.service.component.annotations.Reference;
19+
import org.eclipse.cdt.lsp.clangd.ClangdCProjectDescriptionListener;
20+
import org.eclipse.cdt.lsp.clangd.MacroResolver;
21+
import org.eclipse.core.runtime.ServiceCaller;
2122

2223
/**
23-
* This default monitor listens to C project description changes. Can be derived by vendors to add own listeners/behavior.
24-
* This can be done by using this class as superclass and add the new class as OSGi service with a service.ranking > 0.
24+
* This monitor listens to C project description changes.
2525
*/
26-
@Component(property = { "service.ranking:Integer=0" })
27-
public class DefaultCProjectChangeMonitor implements CProjectChangeMonitor {
26+
public class CProjectChangeMonitor {
27+
MacroResolver macroResolver = new MacroResolver();
2828

29-
@Reference
30-
MacroResolver macroResolver;
31-
32-
@Reference
33-
private ClangdCProjectDescriptionListener clangdListener;
29+
private final ServiceCaller<ClangdCProjectDescriptionListener> clangdListener = new ServiceCaller<>(getClass(),
30+
ClangdCProjectDescriptionListener.class);
3431

3532
private final ICProjectDescriptionListener listener = new ICProjectDescriptionListener() {
3633

3734
@Override
3835
public void handleEvent(CProjectDescriptionEvent event) {
39-
clangdListener.handleEvent(event, macroResolver);
36+
clangdListener.call(c -> c.handleEvent(event, macroResolver));
4037
}
4138

4239
};
4340

44-
@Override
4541
public CProjectChangeMonitor start() {
4642
CCorePlugin.getDefault().getProjectDescriptionManager().addCProjectDescriptionListener(listener,
4743
CProjectDescriptionEvent.APPLIED);
4844
return this;
4945
}
5046

51-
@Override
5247
public void stop() {
5348
CCorePlugin.getDefault().getProjectDescriptionManager().removeCProjectDescriptionListener(listener);
5449
}

bundles/org.eclipse.cdt.lsp.clangd/src/org/eclipse/cdt/lsp/internal/clangd/DefaultMacroResolver.java

Lines changed: 0 additions & 32 deletions
This file was deleted.

bundles/org.eclipse.cdt.lsp.clangd/src/org/eclipse/cdt/lsp/internal/clangd/editor/ClangdPlugin.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,8 @@
1414

1515
package org.eclipse.cdt.lsp.internal.clangd.editor;
1616

17-
import java.util.Optional;
18-
19-
import org.eclipse.cdt.lsp.clangd.CProjectChangeMonitor;
17+
import org.eclipse.cdt.lsp.internal.clangd.CProjectChangeMonitor;
2018
import org.eclipse.core.resources.IWorkspace;
21-
import org.eclipse.ui.PlatformUI;
2219
import org.eclipse.ui.plugin.AbstractUIPlugin;
2320
import org.osgi.framework.BundleContext;
2421
import org.osgi.util.tracker.ServiceTracker;
@@ -29,7 +26,7 @@
2926
public class ClangdPlugin extends AbstractUIPlugin {
3027
private IWorkspace workspace;
3128
private CompileCommandsMonitor compileCommandsMonitor;
32-
private Optional<CProjectChangeMonitor> cProjectChangeMonitor;
29+
private CProjectChangeMonitor cProjectChangeMonitor;
3330

3431
// The plug-in ID
3532
public static final String PLUGIN_ID = "org.eclipse.cdt.lsp.clangd"; //$NON-NLS-1$
@@ -51,15 +48,14 @@ public void start(BundleContext context) throws Exception {
5148
workspaceTracker.open();
5249
workspace = workspaceTracker.getService();
5350
compileCommandsMonitor = new CompileCommandsMonitor(workspace).start();
54-
cProjectChangeMonitor = Optional.ofNullable(PlatformUI.getWorkbench().getService(CProjectChangeMonitor.class))
55-
.map(m -> m.start());
51+
cProjectChangeMonitor = new CProjectChangeMonitor().start();
5652
}
5753

5854
@Override
5955
public void stop(BundleContext context) throws Exception {
6056
plugin = null;
6157
compileCommandsMonitor.stop();
62-
cProjectChangeMonitor.ifPresent(m -> m.stop());
58+
cProjectChangeMonitor.stop();
6359
super.stop(context);
6460
}
6561

0 commit comments

Comments
 (0)