diff --git a/lsp/org.eclipse.cdt.lsp.core/.project b/lsp/org.eclipse.cdt.lsp.core/.project index 2524436d04a..55e732955e9 100644 --- a/lsp/org.eclipse.cdt.lsp.core/.project +++ b/lsp/org.eclipse.cdt.lsp.core/.project @@ -20,6 +20,11 @@ + + org.eclipse.pde.ds.core.builder + + + org.eclipse.pde.PluginNature diff --git a/lsp/org.eclipse.cdt.lsp.core/.settings/org.eclipse.pde.ds.annotations.prefs b/lsp/org.eclipse.cdt.lsp.core/.settings/org.eclipse.pde.ds.annotations.prefs new file mode 100644 index 00000000000..73a356b6d05 --- /dev/null +++ b/lsp/org.eclipse.cdt.lsp.core/.settings/org.eclipse.pde.ds.annotations.prefs @@ -0,0 +1,8 @@ +classpath=true +dsVersion=V1_3 +eclipse.preferences.version=1 +enabled=true +generateBundleActivationPolicyLazy=true +path=OSGI-INF +validationErrorLevel=error +validationErrorLevel.missingImplicitUnbindMethod=error diff --git a/lsp/org.eclipse.cdt.lsp.core/META-INF/MANIFEST.MF b/lsp/org.eclipse.cdt.lsp.core/META-INF/MANIFEST.MF index c027f2125fd..212c701adca 100644 --- a/lsp/org.eclipse.cdt.lsp.core/META-INF/MANIFEST.MF +++ b/lsp/org.eclipse.cdt.lsp.core/META-INF/MANIFEST.MF @@ -18,6 +18,7 @@ Require-Bundle: com.google.gson;bundle-version="2.8.2", org.eclipse.lsp4j, org.eclipse.lsp4e, org.eclipse.lsp4j.jsonrpc, + org.eclipse.osgi.services;bundle-version="3.9.0";resolution:=optional, org.eclipse.cdt.core, org.eclipse.cdt.ui Import-Package: org.eclipse.ui.editors.text, @@ -31,3 +32,6 @@ Export-Package: org.eclipse.cdt.cquery;x-friends:="org.eclipse.cdt.lsp.ui", org.eclipse.cdt.lsp.internal.text;x-friends:="org.eclipse.cdt.lsp.ui" Bundle-Activator: org.eclipse.cdt.lsp.core.Activator Bundle-ActivationPolicy: lazy +Service-Component: OSGI-INF/org.eclipse.cdt.lsp.internal.core.ContributedLanguageServers.xml, + OSGI-INF/org.eclipse.cdt.internal.clangd.ClangdLanguageServer.xml, + OSGI-INF/org.eclipse.cdt.internal.cquery.CqueryLanguageServer.xml diff --git a/lsp/org.eclipse.cdt.lsp.core/OSGI-INF/org.eclipse.cdt.internal.clangd.ClangdLanguageServer.xml b/lsp/org.eclipse.cdt.lsp.core/OSGI-INF/org.eclipse.cdt.internal.clangd.ClangdLanguageServer.xml new file mode 100644 index 00000000000..d139d35d2e1 --- /dev/null +++ b/lsp/org.eclipse.cdt.lsp.core/OSGI-INF/org.eclipse.cdt.internal.clangd.ClangdLanguageServer.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/lsp/org.eclipse.cdt.lsp.core/OSGI-INF/org.eclipse.cdt.internal.cquery.CqueryLanguageServer.xml b/lsp/org.eclipse.cdt.lsp.core/OSGI-INF/org.eclipse.cdt.internal.cquery.CqueryLanguageServer.xml new file mode 100644 index 00000000000..811c204defc --- /dev/null +++ b/lsp/org.eclipse.cdt.lsp.core/OSGI-INF/org.eclipse.cdt.internal.cquery.CqueryLanguageServer.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/lsp/org.eclipse.cdt.lsp.core/OSGI-INF/org.eclipse.cdt.lsp.internal.core.ContributedLanguageServers.xml b/lsp/org.eclipse.cdt.lsp.core/OSGI-INF/org.eclipse.cdt.lsp.internal.core.ContributedLanguageServers.xml new file mode 100644 index 00000000000..0d782917b90 --- /dev/null +++ b/lsp/org.eclipse.cdt.lsp.core/OSGI-INF/org.eclipse.cdt.lsp.internal.core.ContributedLanguageServers.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/internal/clangd/ClangdLanguageServer.java b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/internal/clangd/ClangdLanguageServer.java index 1587a05aaf8..13248a3b819 100644 --- a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/internal/clangd/ClangdLanguageServer.java +++ b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/internal/clangd/ClangdLanguageServer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Manish Khurana , Nathan Ridge and others. + * Copyright (c) 2018, 2020 Manish Khurana , Nathan Ridge and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -14,9 +14,12 @@ package org.eclipse.cdt.internal.clangd; import java.net.URI; import org.eclipse.cdt.lsp.LanguageServerConfiguration; +import org.osgi.service.component.annotations.Component; +@Component public class ClangdLanguageServer implements LanguageServerConfiguration { + //FIXME: remove this constant, it is not needed outside the class public static final String CLANGD_ID = "clangd"; //$NON-NLS-1$ @Override diff --git a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/internal/cquery/CqueryLanguageServer.java b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/internal/cquery/CqueryLanguageServer.java index fbd26866ec1..4d744eeb70c 100644 --- a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/internal/cquery/CqueryLanguageServer.java +++ b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/internal/cquery/CqueryLanguageServer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Manish Khurana , Nathan Ridge and others. + * Copyright (c) 2018, 2020 Manish Khurana , Nathan Ridge and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -18,11 +18,14 @@ import org.eclipse.cdt.lsp.LanguageServerConfiguration; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; +import org.osgi.service.component.annotations.Component; import com.google.gson.JsonObject; +@Component public class CqueryLanguageServer implements LanguageServerConfiguration { + //FIXME: remove this constant, it is not needed outside the class public static final String CQUERY_ID = "cquery"; //$NON-NLS-1$ @Override diff --git a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/SupportedLanguageServers.java b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/SupportedLanguageServers.java index 392885f5f62..6ab396c2025 100644 --- a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/SupportedLanguageServers.java +++ b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/SupportedLanguageServers.java @@ -24,6 +24,6 @@ public interface SupportedLanguageServers { Collection all(); - LanguageServerConfiguration preferred() throws IllegalStateException; + LanguageServerConfiguration preferred(); } diff --git a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/CPPStreamConnectionProvider.java b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/CPPStreamConnectionProvider.java index 03f1928d085..64f08f82424 100644 --- a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/CPPStreamConnectionProvider.java +++ b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/CPPStreamConnectionProvider.java @@ -25,13 +25,14 @@ import java.util.Arrays; import java.util.List; import org.eclipse.cdt.lsp.LanguageServerConfiguration; -import org.eclipse.cdt.lsp.internal.core.ContributedLanguageServers; +import org.eclipse.cdt.lsp.SupportedLanguageServers; import org.eclipse.cdt.utils.CommandLineUtil; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.ServiceCaller; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.lsp4e.server.ProcessStreamConnectionProvider; @@ -46,8 +47,7 @@ public class CPPStreamConnectionProvider extends ProcessStreamConnectionProvider private final LanguageServerConfiguration configuration; public CPPStreamConnectionProvider() throws UnsupportedOperationException { - //FIXME: should obtain an instance of interface - configuration = new ContributedLanguageServers().preferred(); + configuration = configuration(); File defaultLSLocation = getDefaultLSLocation(configuration.identifier()); if (defaultLSLocation != null) { store.setDefault(PreferenceConstants.P_SERVER_PATH, defaultLSLocation.getAbsolutePath()); @@ -67,6 +67,13 @@ public class CPPStreamConnectionProvider extends ProcessStreamConnectionProvider setCommands(commands); } + private LanguageServerConfiguration configuration() { + final LanguageServerConfiguration[] configs = new LanguageServerConfiguration[1]; + ServiceCaller.callOnce(CPPStreamConnectionProvider.class, SupportedLanguageServers.class, + x -> configs[0] = x.preferred()); + return configs[0]; + } + @Override public void stop() { super.stop(); diff --git a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/PreferenceInitializer.java b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/PreferenceInitializer.java index d1d41b7cce0..9954a5055b3 100644 --- a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/PreferenceInitializer.java +++ b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/PreferenceInitializer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Manish Khurana , Nathan Ridge and others. + * Copyright (c) 2018, 2020 Manish Khurana , Nathan Ridge and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -12,7 +12,8 @@ package org.eclipse.cdt.lsp.core; import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; -import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; /** * Class used to initialize default preference values for C/C++ Preference Page. @@ -21,9 +22,9 @@ public class PreferenceInitializer extends AbstractPreferenceInitializer { @Override public void initializeDefaultPreferences() { - IPreferenceStore store = Activator.getDefault().getPreferenceStore(); - store.setDefault(PreferenceConstants.P_SERVER_CHOICE, "clangd"); //$NON-NLS-1$ - store.setDefault(PreferenceConstants.P_SERVER_OPTIONS, ""); //$NON-NLS-1$ + IEclipsePreferences node = DefaultScope.INSTANCE.getNode(Activator.PLUGIN_ID); + node.put(PreferenceConstants.P_SERVER_CHOICE, "clangd"); //$NON-NLS-1$ + node.put(PreferenceConstants.P_SERVER_OPTIONS, ""); //$NON-NLS-1$ } } diff --git a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/internal/core/ContributedLanguageServers.java b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/internal/core/ContributedLanguageServers.java index baff08ed3bd..611d2c3a6bf 100644 --- a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/internal/core/ContributedLanguageServers.java +++ b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/internal/core/ContributedLanguageServers.java @@ -16,26 +16,27 @@ package org.eclipse.cdt.lsp.internal.core; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; -import java.util.Optional; -import org.eclipse.cdt.internal.clangd.ClangdLanguageServer; -import org.eclipse.cdt.internal.cquery.CqueryLanguageServer; import org.eclipse.cdt.lsp.LanguageServerConfiguration; import org.eclipse.cdt.lsp.SupportedLanguageServers; import org.eclipse.cdt.lsp.core.PreferenceConstants; -import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.IScopeContext; import org.eclipse.core.runtime.preferences.InstanceScope; import org.osgi.framework.FrameworkUtil; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; -//FIXME ok, not really contributed at the moment, but will be +@Component public final class ContributedLanguageServers implements SupportedLanguageServers { + private final LanguageServerConfiguration undefined; private final Map configs; public ContributedLanguageServers() { configs = new LinkedHashMap<>(); - register(new ClangdLanguageServer()); - register(new CqueryLanguageServer()); + undefined = new UndefinedLanguageServer(); } @Override @@ -43,6 +44,7 @@ public final class ContributedLanguageServers implements SupportedLanguageServer return configs.values(); } + @Reference(cardinality = ReferenceCardinality.MULTIPLE) public void register(LanguageServerConfiguration configuration) { configs.put(configuration.identifier(), configuration); } @@ -52,13 +54,13 @@ public final class ContributedLanguageServers implements SupportedLanguageServer } @Override - public LanguageServerConfiguration preferred() throws IllegalStateException { - return Optional.ofNullable(InstanceScope.INSTANCE.getNode(nodeQualifier()))// - .filter(IEclipsePreferences.class::isInstance)// - .map(IEclipsePreferences.class::cast)// - .flatMap(x -> Optional.ofNullable(x.get(nodePath(), null)))// - .map(configs::get)// - .orElseThrow(() -> new IllegalStateException("No preferred server was found")); + public LanguageServerConfiguration preferred() { + return configs.getOrDefault(preferredIdentifier(), undefined); + } + + private String preferredIdentifier() { + return Platform.getPreferencesService().getString(nodeQualifier(), nodePath(), undefined.identifier(), + new IScopeContext[] { InstanceScope.INSTANCE }); } private String nodeQualifier() { diff --git a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/internal/core/UndefinedLanguageServer.java b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/internal/core/UndefinedLanguageServer.java new file mode 100644 index 00000000000..443c902397d --- /dev/null +++ b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/internal/core/UndefinedLanguageServer.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2020 ArSysOp and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Alexander Fedorov (ArSysOp) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.lsp.internal.core; + +import java.net.URI; + +import org.eclipse.cdt.lsp.LanguageServerConfiguration; + +final class UndefinedLanguageServer implements LanguageServerConfiguration { + + @Override + public String identifier() { + return ""; //$NON-NLS-1$ + } + + @Override + public String label() { + return ""; + } + + @Override + public Object options(Object defaults, URI uri) { + return defaults; + } + +}