diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/plugin.xml b/eclipse-language-servers/org.springframework.tooling.boot.ls/plugin.xml index 25b337b19..ec55a31fa 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/plugin.xml +++ b/eclipse-language-servers/org.springframework.tooling.boot.ls/plugin.xml @@ -104,14 +104,6 @@ - - - - @@ -133,29 +125,6 @@ id="org.springframework.ide.eclipse.commands" name="Spring Generic Text Editor"> - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClient.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClient.java index ff271a0ea..d4138a793 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClient.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClient.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. + * Copyright (c) 2017, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,6 +12,7 @@ package org.springframework.tooling.ls.eclipse.commons; import java.util.concurrent.CompletableFuture; +import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.services.LanguageClient; @@ -51,4 +52,7 @@ public interface STS4LanguageClient extends LanguageClient { @JsonRequest("sts/javadocHoverLink") CompletableFuture javadocHoverLink(JavaDataParams params); + @JsonRequest("sts/javaLocation") + CompletableFuture javaLocation(JavaDataParams params); + } diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClientImpl.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClientImpl.java index d69d85794..b19934baf 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClientImpl.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClientImpl.java @@ -23,6 +23,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer; import org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks; import org.eclipse.jface.action.IStatusLineManager; @@ -42,6 +43,7 @@ import org.eclipse.jface.text.source.ISourceViewerExtension5; import org.eclipse.lsp4e.LSPEclipseUtils; import org.eclipse.lsp4e.LanguageClientImpl; import org.eclipse.lsp4j.CodeLens; +import org.eclipse.lsp4j.Location; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; @@ -63,6 +65,7 @@ import org.springframework.tooling.jdt.ls.commons.java.JavaTypeResponse; import org.springframework.tooling.jdt.ls.commons.java.JavadocHoverLinkResponse; import org.springframework.tooling.jdt.ls.commons.javadoc.JavadocResponse; import org.springframework.tooling.jdt.ls.commons.javadoc.JavadocUtils; +import org.springframework.tooling.jdt.ls.commons.resources.ResourceUtils; import org.springframework.tooling.ls.eclipse.commons.javadoc.JavaDoc2MarkdownConverter; import org.springframework.tooling.ls.eclipse.commons.preferences.PreferenceConstants; @@ -367,4 +370,23 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La return CompletableFuture.completedFuture(response); } + @Override + public CompletableFuture javaLocation(JavaDataParams params) { + return CompletableFuture.supplyAsync(() -> { + try { + URI projectUri = params.getProjectUri() == null ? null : URI.create(params.getProjectUri()); + IJavaElement element = JavaData.findElement(projectUri, params.getBindingKey(), JavaDataParams.isLookInOtherProjects(params)); + if (element != null ) { + IJavaProject project = element.getJavaProject() == null ? ResourceUtils.getJavaProject(projectUri) : element.getJavaProject(); + if (project != null) { + return new Location(Utils.eclipseIntroUri(project.getElementName(), params.getBindingKey()).toString(), null); + } + } + } catch (Exception e) { + LanguageServerCommonsActivator.logError(e, "Failed to find java element for key " + params.getBindingKey()); + } + return null; + }); + } + } diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/Utils.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/Utils.java index 1a64a254b..df6cab3a3 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/Utils.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/Utils.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,7 +10,9 @@ *******************************************************************************/ package org.springframework.tooling.ls.eclipse.commons; +import java.io.UnsupportedEncodingException; import java.net.URI; +import java.net.URLEncoder; import java.util.Arrays; import java.util.Objects; import java.util.stream.Stream; @@ -29,6 +31,17 @@ import org.eclipse.ui.PlatformUI; @SuppressWarnings("restriction") public class Utils { + private static final String URL_PREFIX = "http://org.eclipse.ui.intro/execute?command="; + private static final String EQUALS = "="; + private static final String PARAMETERS_SEPARATOR = ","; + private static final String PARAMETERS_START = "("; + private static final String PARAMETERS_END = ")"; + + private static final String JAVA_ELEMENT_COMMAND = "org.springframework.tooling.ls.eclipse.commons.commands.OpenJavaElementInEditor"; + private static final String BINDING_KEY_PARAMETER_ID = "bindingKey"; + private static final String PROJECT_NAME_PARAMETER_ID = "projectName"; + + public static Stream getActiveTextViewers() { return getActiveEditors() .map(editorPart -> editorPart.getAdapter(ITextViewer.class)) @@ -105,4 +118,23 @@ public class Utils { return null; } + public static URI eclipseIntroUri(String projectName, String bindingKey) throws UnsupportedEncodingException { + StringBuilder paramBuilder = new StringBuilder(JAVA_ELEMENT_COMMAND); + paramBuilder.append(PARAMETERS_START); + paramBuilder.append(BINDING_KEY_PARAMETER_ID); + paramBuilder.append(EQUALS); + paramBuilder.append(bindingKey); + if (projectName != null) { + paramBuilder.append(PARAMETERS_SEPARATOR); + paramBuilder.append(PROJECT_NAME_PARAMETER_ID); + paramBuilder.append(EQUALS); + paramBuilder.append(projectName); + } + paramBuilder.append(PARAMETERS_END); + + StringBuilder urlBuilder = new StringBuilder(URL_PREFIX); + urlBuilder.append(URLEncoder.encode(paramBuilder.toString(), "UTF8")); + return URI.create(urlBuilder.toString()); + } + } diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/commands/OpenJavaElementInEditor.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/commands/OpenJavaElementInEditor.java similarity index 81% rename from eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/commands/OpenJavaElementInEditor.java rename to eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/commands/OpenJavaElementInEditor.java index ad6dd2115..85dbd7c0a 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/commands/OpenJavaElementInEditor.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/commands/OpenJavaElementInEditor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,7 +8,7 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.tooling.boot.ls.commands; +package org.springframework.tooling.ls.eclipse.commons.commands; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; @@ -23,17 +23,17 @@ import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.ui.PartInitException; -import org.springframework.tooling.boot.ls.BootLanguageServerPlugin; +import org.springframework.tooling.ls.eclipse.commons.LanguageServerCommonsActivator; import org.springframework.tooling.ls.eclipse.commons.Utils; /** * Command for opening Java type given by its fully qualified name in an editor - * + * * @author Alex Boyko * */ public class OpenJavaElementInEditor extends AbstractHandler { - + private static final String BINDING_KEY = "bindingKey"; private static final String PROJECT_NAME = "projectName"; @@ -41,15 +41,16 @@ public class OpenJavaElementInEditor extends AbstractHandler { public Object execute(ExecutionEvent event) throws ExecutionException { String bindingKey = event.getParameter(BINDING_KEY); String projectName = event.getParameter(PROJECT_NAME); - + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); - + if (project != null && bindingKey != null) { IJavaProject javaProject = JavaCore.create(project); if (javaProject != null) { IJavaElement element = Utils.findElement(javaProject, bindingKey); if (element == null) { - BootLanguageServerPlugin.getDefault().getLog().log(new Status(IStatus.WARNING, BootLanguageServerPlugin.ID, "Cannot find element: " + bindingKey)); + LanguageServerCommonsActivator.getInstance().getLog().log(new Status(IStatus.WARNING, + LanguageServerCommonsActivator.PLUGIN_ID, "Cannot find element: " + bindingKey)); } else { try { JavaUI.openInEditor(element); @@ -58,11 +59,12 @@ public class OpenJavaElementInEditor extends AbstractHandler { } } } else { - BootLanguageServerPlugin.getDefault().getLog().log(new Status(IStatus.WARNING, BootLanguageServerPlugin.ID, "Cannot find project: " + projectName)); + LanguageServerCommonsActivator.getInstance().getLog().log(new Status(IStatus.WARNING, + LanguageServerCommonsActivator.PLUGIN_ID, "Cannot find project: " + projectName)); } } return null; } - + } diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/commands/OpenResourceInEditor.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/commands/OpenResourceInEditor.java similarity index 95% rename from eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/commands/OpenResourceInEditor.java rename to eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/commands/OpenResourceInEditor.java index 6caae89bc..fdb791421 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/commands/OpenResourceInEditor.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/commands/OpenResourceInEditor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,7 +8,7 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.tooling.boot.ls.commands; +package org.springframework.tooling.ls.eclipse.commons.commands; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/STS4LanguageClient.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/STS4LanguageClient.java index c9a9db374..20e7b1768 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/STS4LanguageClient.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/STS4LanguageClient.java @@ -13,6 +13,7 @@ package org.springframework.ide.vscode.commons.languageserver; import java.util.concurrent.CompletableFuture; +import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.services.LanguageClient; @@ -54,4 +55,7 @@ public interface STS4LanguageClient extends LanguageClient { @JsonRequest("sts/javadocHoverLink") CompletableFuture javadocHoverLink(JavaDataParams params); + @JsonRequest("sts/javaLocation") + CompletableFuture javaLocation(JavaDataParams params); + } diff --git a/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java b/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java index f4308d680..80ed39206 100644 --- a/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java +++ b/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2018 Pivotal, Inc. + * Copyright (c) 2016, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -343,6 +343,11 @@ public class LanguageServerHarness { return CompletableFuture.completedFuture(new JavadocHoverLinkResponse(null)); } + @Override + public CompletableFuture javaLocation(JavaDataParams params) { + return CompletableFuture.completedFuture(null); + } + }); } diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons.test/src/org/springframework/tooling/jdt/ls/commons/test/ClasspathListenerHandlerTest.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons.test/src/org/springframework/tooling/jdt/ls/commons/test/ClasspathListenerHandlerTest.java index df8bfe2c1..027755829 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons.test/src/org/springframework/tooling/jdt/ls/commons/test/ClasspathListenerHandlerTest.java +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons.test/src/org/springframework/tooling/jdt/ls/commons/test/ClasspathListenerHandlerTest.java @@ -48,6 +48,7 @@ import org.junit.rules.TemporaryFolder; import org.springframework.tooling.jdt.ls.commons.Logger.TestLogger; import org.springframework.tooling.jdt.ls.commons.classpath.Classpath; import org.springframework.tooling.jdt.ls.commons.classpath.Classpath.CPE; +import org.springframework.tooling.jdt.ls.commons.classpath.ClasspathUtil; import org.springframework.tooling.jdt.ls.commons.test.ClasspathListenerHandlerTest.MockClientCommandExecutor; import org.springframework.tooling.jdt.ls.commons.classpath.ClientCommandExecutor; import org.springframework.tooling.jdt.ls.commons.classpath.ReusableClasspathListenerHandler; @@ -157,6 +158,7 @@ public class ClasspathListenerHandlerTest { @Test public void sourceJar() throws Exception { String projectName = "maven-with-jar-dependency"; + ClasspathUtil.enableDownloadSources(); IProject project = createTestProject(projectName); File loc = project.getLocation().toFile(); diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathUtil.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathUtil.java index 7431f61d5..2d020c93d 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathUtil.java +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathUtil.java @@ -71,8 +71,6 @@ public class ClasspathUtil { public static Classpath resolve(IJavaProject javaProject, Logger logger) throws Exception { //log("resolving classpath " + javaProject.getElementName() +" ..."); - enableDownloadSources(); - List cpEntries = new ArrayList<>(); IClasspathEntry[] entries = javaProject.getResolvedClasspath(true); @@ -98,7 +96,7 @@ public class ClasspathUtil { return createCpes(getSystemLibraryPaths(javaProject), javaProject, entry); } - private static void enableDownloadSources() { + public static void enableDownloadSources() { if (!enabledDownloadSources.getAndSet(true)) { IEclipsePreferences m2eprefs = InstanceScope.INSTANCE.getNode("org.eclipse.m2e.core"); m2eprefs.putBoolean("eclipse.m2.downloadSources", true); diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/META-INF/MANIFEST.MF b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/META-INF/MANIFEST.MF index 009dc59ba..d3d17929f 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/META-INF/MANIFEST.MF +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/META-INF/MANIFEST.MF @@ -11,4 +11,5 @@ Require-Bundle: org.eclipse.jdt.ls.core, org.eclipse.core.resources, org.springframework.tooling.jdt.ls.commons, com.google.guava, - com.google.gson + com.google.gson, + org.eclipse.lsp4j diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/plugin.xml b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/plugin.xml index a6948ff29..84dc867d9 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/plugin.xml +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/plugin.xml @@ -24,6 +24,12 @@ id="sts.java.javadocHoverLink"> + + + + \ No newline at end of file diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/src/org/springframework/tooling/jdt/ls/extension/JavaLocationHandler.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/src/org/springframework/tooling/jdt/ls/extension/JavaLocationHandler.java new file mode 100644 index 000000000..456050f45 --- /dev/null +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/src/org/springframework/tooling/jdt/ls/extension/JavaLocationHandler.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2019 Pivotal, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.tooling.jdt.ls.extension; + +import java.net.URI; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.core.IClassFile; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.ls.core.internal.IDelegateCommandHandler; +import org.eclipse.jdt.ls.core.internal.JDTUtils; +import org.eclipse.lsp4j.Location; +import org.springframework.tooling.jdt.ls.commons.java.JavaData; + +@SuppressWarnings("restriction") +public class JavaLocationHandler implements IDelegateCommandHandler { + + @SuppressWarnings("unchecked") + @Override + public Object executeCommand(String commandId, List arguments, IProgressMonitor monitor) throws Exception { + Location location = null; + Map obj = (Map) arguments.get(0); + String uri = (String) obj.get("projectUri"); + URI projectUri = URI.create(uri); + String bindingKey = (String) obj.get("bindingKey"); + Boolean lookInOtherProjects = (Boolean) obj.get("lookInOtherProjects"); + IJavaElement element = JavaData.findElement(projectUri, bindingKey, lookInOtherProjects); + if (element != null) { + location = JDTUtils.toLocation(element); + if (location == null) { + IClassFile cf = (IClassFile) element.getAncestor(IJavaElement.CLASS_FILE); + if (cf != null) { + location = JDTUtils.toLocation(cf); + } + } + } + return location; + } + +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguagServerBootApp.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguagServerBootApp.java index e895d7f25..19240a66c 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguagServerBootApp.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguagServerBootApp.java @@ -20,9 +20,9 @@ import org.springframework.ide.vscode.boot.common.PropertyCompletionFactory; import org.springframework.ide.vscode.boot.common.RelaxedNameConfig; import org.springframework.ide.vscode.boot.java.links.DefaultJavaElementLocationProvider; import org.springframework.ide.vscode.boot.java.links.EclipseJavaDocumentUriProvider; -import org.springframework.ide.vscode.boot.java.links.EclipseJavaElementLocationProvider; import org.springframework.ide.vscode.boot.java.links.JavaDocumentUriProvider; import org.springframework.ide.vscode.boot.java.links.JavaElementLocationProvider; +import org.springframework.ide.vscode.boot.java.links.JavaServerElementLocationProvider; import org.springframework.ide.vscode.boot.java.links.JdtJavaDocumentUriProvider; import org.springframework.ide.vscode.boot.java.links.SourceLinkFactory; import org.springframework.ide.vscode.boot.java.links.SourceLinks; @@ -111,11 +111,12 @@ public class BootLanguagServerBootApp { } } - @Bean JavaElementLocationProvider javaElementLocationProvider(CompilationUnitCache cuCache, JavaDocumentUriProvider javaDocUriProvider) { + @Bean JavaElementLocationProvider javaElementLocationProvider(SimpleLanguageServer server, CompilationUnitCache cuCache, JavaDocumentUriProvider javaDocUriProvider) { switch (LspClient.currentClient()) { case ECLIPSE: - // LSP4E doesn't support JDT java doc URIs. Only supports file, eclipse intro and http URIs for docs - return new EclipseJavaElementLocationProvider(); + case VSCODE: + case THEIA: + return new JavaServerElementLocationProvider(server); default: return new DefaultJavaElementLocationProvider(cuCache, javaDocUriProvider); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/DefaultJavaElementLocationProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/DefaultJavaElementLocationProvider.java index e661d1a81..4489cb74a 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/DefaultJavaElementLocationProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/DefaultJavaElementLocationProvider.java @@ -60,6 +60,9 @@ public class DefaultJavaElementLocationProvider implements JavaElementLocationPr URI uri = url.get().toURI(); Range r = cuCache.withCompilationUnit(project, uri, (cu) -> { AtomicReference range = new AtomicReference<>(null); + if (cu == null) { + return new Range(new Position(0, 0), new Position(0, 0)); + } cu.accept(new ASTVisitor() { private Range nameRange(SimpleName nameNode) { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseSourceLinks.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseSourceLinks.java index c0c8e4576..7cf8ec8bb 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseSourceLinks.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseSourceLinks.java @@ -37,11 +37,11 @@ public class EclipseSourceLinks implements SourceLinks { private static final String PARAMETERS_START = "("; private static final String PARAMETERS_END = ")"; - private static final String JAVA_ELEMENT_COMMAND = "org.springframework.tooling.boot.ls.OpenJavaElement"; + private static final String JAVA_ELEMENT_COMMAND = "org.springframework.tooling.ls.eclipse.commons.commands.OpenJavaElementInEditor"; private static final String BINDING_KEY_PARAMETER_ID = "bindingKey"; private static final String PROJECT_NAME_PARAMETER_ID = "projectName"; - private static final String RESOURCE_COMMAND = "org.springframework.tooling.boot.ls.OpenResourceInEditor"; + private static final String RESOURCE_COMMAND = "org.springframework.tooling.ls.eclipse.commons.commands.OpenResourceInEditor"; private static final String PATH = "path"; private static final Logger log = LoggerFactory.getLogger(EclipseSourceLinks.class); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/JavaServerElementLocationProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/JavaServerElementLocationProvider.java new file mode 100644 index 000000000..d3789888c --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/JavaServerElementLocationProvider.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2019 Pivotal, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.java.links; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.eclipse.lsp4j.Location; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.java.IMember; +import org.springframework.ide.vscode.commons.languageserver.java.ls.JavaDataParams; +import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; + +public class JavaServerElementLocationProvider implements JavaElementLocationProvider { + + private static final Logger log = LoggerFactory.getLogger(JavaServerElementLocationProvider.class); + + private SimpleLanguageServer server; + + public JavaServerElementLocationProvider(SimpleLanguageServer server) { + this.server = server; + } + + @Override + public Location findLocation(IJavaProject project, IMember member) { + String projectUri = project == null ? null : project.getLocationUri().toString(); + String bindingKey = member.getBindingKey(); + try { + Location location = server.getClient().javaLocation(new JavaDataParams(projectUri, bindingKey, true)).get(500, TimeUnit.MILLISECONDS); + return location; + } catch (InterruptedException | ExecutionException | TimeoutException e) { + log.error("", e); + return null; + } + } + +} diff --git a/vscode-extensions/commons-vscode/src/java-data.ts b/vscode-extensions/commons-vscode/src/java-data.ts index d06f468e5..f378b849a 100644 --- a/vscode-extensions/commons-vscode/src/java-data.ts +++ b/vscode-extensions/commons-vscode/src/java-data.ts @@ -13,6 +13,11 @@ export function registerJavaDataService(client : LanguageClient) : void { await VSCode.commands.executeCommand("java.execute.workspaceCommand", "sts.java.javadocHoverLink", params) ); + const javaLocationRequest = new RequestType("sts/javaLocation"); + client.onRequest(javaLocationRequest, async (params: JavaDataParams) => + await VSCode.commands.executeCommand("java.execute.workspaceCommand", "sts.java.location", params) + ); + const javadocRequest = new RequestType("sts/javadoc"); client.onRequest(javadocRequest, async (params: JavaDataParams) => await VSCode.commands.executeCommand("java.execute.workspaceCommand", "sts.java.javadoc", params)