From db429f9c2152a1fb5ff1c6a9d1a6aefc3858f89e Mon Sep 17 00:00:00 2001 From: BoykoAlex Date: Tue, 11 Dec 2018 16:59:40 -0500 Subject: [PATCH] PT #162167333: Ask JDT server for hover links (Eclipse, VSCode) --- .../ls/jdt/SpringBootJavaHoverProvider.java | 68 +++- .../ls/eclipse/commons/test/JavadocTest.java | 8 +- .../eclipse/commons/STS4LanguageClient.java | 11 +- .../commons/STS4LanguageClientImpl.java | 30 +- .../gradle/GradleProjectClasspath.java | 4 +- .../vscode/commons/jandex/IndexRoutines.java | 2 +- .../commons/jandex/JandexClasspath.java | 4 +- .../vscode/commons/java/ClasspathData.java | 2 +- .../java/DelegatingCachedClasspath.java | 2 +- .../ide/vscode/commons/java/IClasspath.java | 2 +- .../vscode/commons/java/IClasspathUtil.java | 4 +- .../ide/vscode/commons/java/JavaProject.java | 2 +- .../commons/javadoc/JavaDocProviders.java | 2 +- .../commons/javadoc/JdtLsJavadocProvider.java | 6 +- .../languageserver/java/JavadocService.java | 2 +- .../commons/jandex/JandexClasspathTest.java | 2 +- .../languageserver/STS4LanguageClient.java | 15 +- .../{jdt => java}/ls/Classpath.java | 2 +- .../{jdt => java}/ls/ClasspathListener.java | 2 +- .../ls/ClasspathListenerManager.java | 2 +- .../ls/ClasspathListenerParams.java | 2 +- .../ls/JavaDataParams.java} | 27 +- .../java/ls/JavaElementData.java | 37 +++ .../java/ls/JavaTypeResponse.java | 29 ++ .../java/ls/JavadocHoverLinkResponse.java | 29 ++ .../{ => java/ls}/JavadocResponse.java | 2 +- .../languageserver/java/ls/MemberData.java | 34 ++ .../languageserver/java/ls/TypeData.java | 234 ++++++++++++++ .../util/SimpleLanguageServer.java | 4 +- .../maven/java/MavenProjectClasspath.java | 2 +- .../commons/maven/MavenProjectCacheTest.java | 2 +- .../testharness/ClasspathTestUtil.java | 4 +- .../testharness/LanguageServerHarness.java | 23 +- .../META-INF/MANIFEST.MF | 1 + .../ls/commons/classpath/ClasspathUtil.java | 131 ++++---- .../tooling/jdt/ls/commons/java/JavaData.java | 300 ++++++++++++++++++ .../jdt/ls/commons/java/JavaDataParams.java | 24 +- .../jdt/ls/commons/java/JavaElementData.java | 37 +++ .../jdt/ls/commons/java/JavaTypeResponse.java | 29 ++ .../java/JavadocHoverLinkResponse.java | 29 ++ .../jdt/ls/commons/java/MemberData.java | 34 ++ .../tooling/jdt/ls/commons/java/TypeData.java | 234 ++++++++++++++ .../jdt/ls/commons/javadoc/JavadocUtils.java | 29 +- .../ls/commons/resources/ResourceUtils.java | 2 - .../plugin.xml | 12 + .../jdt/ls/extension/JavaTypeHanlder.java | 37 +++ .../ls/extension/JavadocHoverLinkHandler.java | 48 +++ .../boot/app/BootLanguagServerBootApp.java | 5 +- .../boot/app/BootLanguageServerParams.java | 2 +- .../BootJavaLanguageServerComponents.java | 4 + .../boot/java/handlers/RunningAppMatcher.java | 4 +- .../java/links/JavaServerSourceLinks.java | 65 ++++ .../boot/java/links/SourceLinkFactory.java | 10 +- .../ls/JavaProjectsServiceWithFallback.java | 2 +- .../vscode/boot/jdt/ls/JdtLsProjectCache.java | 4 +- .../boot/java/value/test/MockProjects.java | 4 +- .../harness/BootLanguageServerHarness.java | 4 +- .../commons-vscode/src/java-data.ts | 26 ++ .../commons-vscode/src/javadoc.ts | 23 -- .../commons-vscode/src/launch-util.ts | 4 +- 60 files changed, 1496 insertions(+), 209 deletions(-) rename headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/{jdt => java}/ls/Classpath.java (98%) rename headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/{jdt => java}/ls/ClasspathListener.java (94%) rename headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/{jdt => java}/ls/ClasspathListenerManager.java (98%) rename headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/{jdt => java}/ls/ClasspathListenerParams.java (93%) rename headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/{JavadocParams.java => java/ls/JavaDataParams.java} (69%) create mode 100644 headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaElementData.java create mode 100644 headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaTypeResponse.java create mode 100644 headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavadocHoverLinkResponse.java rename headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/{ => java/ls}/JavadocResponse.java (91%) create mode 100644 headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/MemberData.java create mode 100644 headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/TypeData.java create mode 100644 headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaData.java rename eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/JavadocParams.java => headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaDataParams.java (73%) create mode 100644 headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaElementData.java create mode 100644 headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaTypeResponse.java create mode 100644 headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavadocHoverLinkResponse.java create mode 100644 headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/MemberData.java create mode 100644 headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/TypeData.java create mode 100644 headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/src/org/springframework/tooling/jdt/ls/extension/JavaTypeHanlder.java create mode 100644 headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/src/org/springframework/tooling/jdt/ls/extension/JavadocHoverLinkHandler.java create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/JavaServerSourceLinks.java create mode 100644 vscode-extensions/commons-vscode/src/java-data.ts delete mode 100644 vscode-extensions/commons-vscode/src/javadoc.ts diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/jdt/SpringBootJavaHoverProvider.java b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/jdt/SpringBootJavaHoverProvider.java index 4da525cd6..5fdc128f3 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/jdt/SpringBootJavaHoverProvider.java +++ b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/jdt/SpringBootJavaHoverProvider.java @@ -10,43 +10,77 @@ *******************************************************************************/ package org.springframework.tooling.boot.ls.jdt; -import org.eclipse.jdt.ui.text.java.hover.IJavaEditorTextHover; -import org.eclipse.jface.text.IInformationControlCreator; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.internal.ui.text.java.hover.JavadocBrowserInformationControlInput; +import org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover; import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.ITextHoverExtension; import org.eclipse.jface.text.ITextViewer; import org.eclipse.lsp4e.operations.hover.LSBasedHover; -import org.eclipse.ui.IEditorPart; /** * @author Martin Lippert */ @SuppressWarnings("restriction") -public class SpringBootJavaHoverProvider implements IJavaEditorTextHover, ITextHoverExtension { +public class SpringBootJavaHoverProvider extends JavadocHover { private LSBasedHover lsBasedHover; public SpringBootJavaHoverProvider() { + super(); lsBasedHover = new LSBasedHover(); } @Override - public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { - return this.lsBasedHover.getHoverInfo(textViewer, hoverRegion); + public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) { + // Launch javadoc hover computation in async fashion + CompletableFuture javadocHoverFuture = CompletableFuture.supplyAsync( + () -> (JavadocBrowserInformationControlInput) super.getHoverInfo2(textViewer, hoverRegion)); + String content = this.lsBasedHover.getHoverInfo(textViewer, hoverRegion); + if (content != null && !content.isEmpty()) { + IJavaElement javaElement = null; + JavadocBrowserInformationControlInput previous = null; + int leadingImageWidth = 0; + JavadocBrowserInformationControlInput input; + String html = ""; + try { + input = javadocHoverFuture.get(500, TimeUnit.MILLISECONDS); + if (input != null) { + previous = (JavadocBrowserInformationControlInput) input.getPrevious(); + javaElement = input.getElement(); + leadingImageWidth = input.getLeadingImageWidth(); + html = input.getHtml(); + } + } catch (InterruptedException e) { + html = noJavadocMessage("Javadoc unavailable."); + } catch (ExecutionException e) { + html = noJavadocMessage("Javadoc unavailable. Failed to obtain it."); + } catch (TimeoutException e) { + html = noJavadocMessage("Javadoc unavailable. Took too long to obtain it."); + } + content = content + html; + return new JavadocBrowserInformationControlInput(previous, javaElement, content, leadingImageWidth); + } else { + javadocHoverFuture.cancel(true); + } + return null; + } + + private String noJavadocMessage(String message) { + StringBuilder sb = new StringBuilder(); + sb.append("

"); + sb.append(message); + sb.append("

"); + return sb.toString(); } @Override public IRegion getHoverRegion(ITextViewer textViewer, int offset) { return this.lsBasedHover.getHoverRegion(textViewer, offset); } - - @Override - public void setEditor(IEditorPart editor) { - } - - @Override - public IInformationControlCreator getHoverControlCreator() { - return this.lsBasedHover.getHoverControlCreator(); - } - + } diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons.test/src/org/springframework/tooling/ls/eclipse/commons/test/JavadocTest.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons.test/src/org/springframework/tooling/ls/eclipse/commons/test/JavadocTest.java index 5ebd7b593..f78718a26 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons.test/src/org/springframework/tooling/ls/eclipse/commons/test/JavadocTest.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons.test/src/org/springframework/tooling/ls/eclipse/commons/test/JavadocTest.java @@ -21,8 +21,8 @@ import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.junit.After; import org.junit.Test; +import org.springframework.tooling.jdt.ls.commons.java.JavaDataParams; import org.springframework.tooling.jdt.ls.commons.javadoc.JavadocResponse; -import org.springframework.tooling.ls.eclipse.commons.JavadocParams; import org.springframework.tooling.ls.eclipse.commons.STS4LanguageClientImpl; public class JavadocTest { @@ -44,7 +44,7 @@ public class JavadocTest { String expectedBindingKey = "Lcom/sample/SampleJavadoc;"; assertEquals(expectedBindingKey, type.getKey()); - JavadocParams params = new JavadocParams(project.getProject().getLocation().toFile().toURI().toString(), expectedBindingKey); + JavaDataParams params = new JavaDataParams(project.getProject().getLocation().toFile().toURI().toString(), expectedBindingKey); JavadocResponse response = client.javadoc(params).get(1, TimeUnit.SECONDS); assertEquals("**Sample class**", response.getContent()); } @@ -61,7 +61,7 @@ public class JavadocTest { String expectedBindingKey = "Lcom/sample/SampleJavadoc;.number"; assertEquals(expectedBindingKey, field.getKey()); - JavadocParams params = new JavadocParams(project.getProject().getLocation().toFile().toURI().toString(), expectedBindingKey); + JavaDataParams params = new JavaDataParams(project.getProject().getLocation().toFile().toURI().toString(), expectedBindingKey); JavadocResponse response = client.javadoc(params).get(1, TimeUnit.SECONDS); assertEquals("**Sample field**", response.getContent()); } @@ -78,7 +78,7 @@ public class JavadocTest { String expectedBindingKey = "Lcom/sample/SampleJavadoc;.getNumber()V"; assertEquals(expectedBindingKey, method.getKey()); - JavadocParams params = new JavadocParams(project.getProject().getLocation().toFile().toURI().toString(), expectedBindingKey); + JavaDataParams params = new JavaDataParams(project.getProject().getLocation().toFile().toURI().toString(), expectedBindingKey); JavadocResponse response = client.javadoc(params).get(1, TimeUnit.SECONDS); assertEquals("**Sample getter**", response.getContent()); } 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 f996da000..ff271a0ea 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 @@ -15,6 +15,9 @@ import java.util.concurrent.CompletableFuture; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.services.LanguageClient; +import org.springframework.tooling.jdt.ls.commons.java.JavaDataParams; +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; /** @@ -40,6 +43,12 @@ public interface STS4LanguageClient extends LanguageClient { CompletableFuture removeClasspathListener(ClasspathListenerParams classpathListenerParams); @JsonRequest("sts/javadoc") - CompletableFuture javadoc(JavadocParams params); + CompletableFuture javadoc(JavaDataParams params); + + @JsonRequest("sts/javaType") + CompletableFuture javaType(JavaDataParams params); + + @JsonRequest("sts/javadocHoverLink") + CompletableFuture javadocHoverLink(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 081ad1b27..73d5773e7 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 @@ -20,6 +20,8 @@ import java.util.concurrent.ConcurrentHashMap; 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.internal.ui.viewsupport.JavaElementLinks; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.BadLocationException; @@ -52,6 +54,10 @@ import org.eclipse.ui.texteditor.AbstractTextEditor; import org.eclipse.ui.texteditor.SourceViewerDecorationSupport; import org.springframework.tooling.jdt.ls.commons.Logger; import org.springframework.tooling.jdt.ls.commons.classpath.ReusableClasspathListenerHandler; +import org.springframework.tooling.jdt.ls.commons.java.JavaData; +import org.springframework.tooling.jdt.ls.commons.java.JavaDataParams; +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.ls.eclipse.commons.javadoc.JavaDoc2MarkdownConverter; @@ -69,6 +75,8 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La () -> new ProjectSorter() ); + private static JavaData JAVA_DATA = new JavaData(Logger.forEclipsePlugin(LanguageServerCommonsActivator::getInstance)); + private static final String ANNOTION_TYPE_ID = "org.springframework.tooling.bootinfo"; private static final String ALT_ANNOTATION_DRAWING_STRATEGY_ID = "boot.hint.strategy"; @@ -277,7 +285,7 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La } @Override - public CompletableFuture javadoc(JavadocParams params) { + public CompletableFuture javadoc(JavaDataParams params) { JavadocResponse response = new JavadocResponse(); try { String content = JavadocUtils.javadoc(JavaDoc2MarkdownConverter::getMarkdownContentReader, @@ -314,4 +322,24 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La return CompletableFuture.completedFuture("ok"); } + @Override + public CompletableFuture javaType(JavaDataParams params) { + JavaTypeResponse response = new JavaTypeResponse(JAVA_DATA.typeData(params.getProjectUri(), params.getBindingKey())); + return CompletableFuture.completedFuture(response); + } + + @Override + public CompletableFuture javadocHoverLink(JavaDataParams params) { + JavadocHoverLinkResponse response = new JavadocHoverLinkResponse(null); + try { + IJavaElement element = JavaData.findElement(URI.create(params.getProjectUri()), params.getBindingKey()); + if (element != null) { + response.setLink(JavaElementLinks.createURI(JavaElementLinks.OPEN_LINK_SCHEME, element)); + } + } catch (Exception e) { + LanguageServerCommonsActivator.logError(e, "Failed to find java element for key " + params.getBindingKey()); + } + return CompletableFuture.completedFuture(response); + } + } diff --git a/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectClasspath.java b/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectClasspath.java index f35616c32..ed35a83c4 100644 --- a/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectClasspath.java +++ b/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectClasspath.java @@ -23,8 +23,8 @@ import org.gradle.tooling.model.eclipse.EclipseProjectDependency; import org.gradle.tooling.model.eclipse.EclipseSourceDirectory; import org.springframework.ide.vscode.commons.java.IClasspath; import org.springframework.ide.vscode.commons.java.JavaUtils; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/IndexRoutines.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/IndexRoutines.java index 497b00940..feabc305a 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/IndexRoutines.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/IndexRoutines.java @@ -34,7 +34,7 @@ import org.jboss.jandex.JarIndexer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.commons.java.IClasspathUtil; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexClasspath.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexClasspath.java index 639b65b32..f00cc0dc7 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexClasspath.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexClasspath.java @@ -32,8 +32,8 @@ import org.springframework.ide.vscode.commons.java.IClasspath; import org.springframework.ide.vscode.commons.java.IClasspathUtil; import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IType; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import org.springframework.ide.vscode.commons.util.CollectorUtil; import org.springframework.ide.vscode.commons.util.FileObserver; diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/ClasspathData.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/ClasspathData.java index 0bc3d028a..6003c308c 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/ClasspathData.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/ClasspathData.java @@ -16,7 +16,7 @@ import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import com.google.common.collect.ImmutableSet; diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/DelegatingCachedClasspath.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/DelegatingCachedClasspath.java index 46b37f55d..3bdc09350 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/DelegatingCachedClasspath.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/DelegatingCachedClasspath.java @@ -13,7 +13,7 @@ package org.springframework.ide.vscode.commons.java; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicReference; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import org.springframework.ide.vscode.commons.util.Assert; import com.google.common.base.Objects; diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspath.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspath.java index e2ffcaf79..82cb9873d 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspath.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspath.java @@ -14,7 +14,7 @@ import java.util.Collection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; /** * Classpath for a Java artifact diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspathUtil.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspathUtil.java index 1506a751e..29e9003fe 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspathUtil.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspathUtil.java @@ -19,8 +19,8 @@ import java.util.stream.Stream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import com.google.common.collect.ImmutableList; diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/JavaProject.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/JavaProject.java index 6173593cf..23d4bc3c5 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/JavaProject.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/JavaProject.java @@ -16,7 +16,7 @@ import java.net.URI; import org.springframework.ide.vscode.commons.jandex.JandexClasspath; import org.springframework.ide.vscode.commons.jandex.JandexIndex.JavadocProviderFactory; import org.springframework.ide.vscode.commons.languageserver.java.JavadocService; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import org.springframework.ide.vscode.commons.util.FileObserver; import reactor.core.Disposable; diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/JavaDocProviders.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/JavaDocProviders.java index 4787b3733..f7edd5b90 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/JavaDocProviders.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/JavaDocProviders.java @@ -13,7 +13,7 @@ package org.springframework.ide.vscode.commons.javadoc; import java.net.URL; import org.springframework.ide.vscode.commons.java.IJavadocProvider; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; public class JavaDocProviders { diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/JdtLsJavadocProvider.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/JdtLsJavadocProvider.java index 35182a080..e7a20c4af 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/JdtLsJavadocProvider.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/javadoc/JdtLsJavadocProvider.java @@ -22,9 +22,9 @@ import org.springframework.ide.vscode.commons.java.IJavaElement; import org.springframework.ide.vscode.commons.java.IJavadocProvider; import org.springframework.ide.vscode.commons.java.IMethod; import org.springframework.ide.vscode.commons.java.IType; -import org.springframework.ide.vscode.commons.languageserver.JavadocParams; -import org.springframework.ide.vscode.commons.languageserver.JavadocResponse; import org.springframework.ide.vscode.commons.languageserver.STS4LanguageClient; +import org.springframework.ide.vscode.commons.languageserver.java.ls.JavaDataParams; +import org.springframework.ide.vscode.commons.languageserver.java.ls.JavadocResponse; import org.springframework.ide.vscode.commons.util.Renderable; import org.springframework.ide.vscode.commons.util.Renderables; @@ -61,7 +61,7 @@ public class JdtLsJavadocProvider implements IJavadocProvider { long start = System.currentTimeMillis(); try { log.info("Fetching javadoc {}", element.getBindingKey()); - JavadocResponse response = client.javadoc(new JavadocParams(projectUri, element.getBindingKey())).get(10, TimeUnit.SECONDS); + JavadocResponse response = client.javadoc(new JavaDataParams(projectUri, element.getBindingKey())).get(10, TimeUnit.SECONDS); log.info("Fetching javadoc {} took {} ms", element.getBindingKey(), System.currentTimeMillis()-start); return produceJavadocFromMd(response); } catch (InterruptedException | ExecutionException | TimeoutException e) { diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavadocService.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavadocService.java index 5ec443158..7798add1b 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavadocService.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavadocService.java @@ -11,7 +11,7 @@ package org.springframework.ide.vscode.commons.languageserver.java; import org.springframework.ide.vscode.commons.java.IJavadocProvider; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; public interface JavadocService { diff --git a/headless-services/commons/commons-java/src/test/java/org/springframework/ide/vscode/commons/jandex/JandexClasspathTest.java b/headless-services/commons/commons-java/src/test/java/org/springframework/ide/vscode/commons/jandex/JandexClasspathTest.java index b56d2e4f4..c35553bef 100644 --- a/headless-services/commons/commons-java/src/test/java/org/springframework/ide/vscode/commons/jandex/JandexClasspathTest.java +++ b/headless-services/commons/commons-java/src/test/java/org/springframework/ide/vscode/commons/jandex/JandexClasspathTest.java @@ -25,7 +25,7 @@ import org.springframework.ide.vscode.commons.java.ClasspathData; import org.springframework.ide.vscode.commons.java.IField; import org.springframework.ide.vscode.commons.java.IMethod; import org.springframework.ide.vscode.commons.java.IType; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import org.springframework.ide.vscode.commons.util.BasicFileObserver; import com.google.common.collect.ImmutableList; 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 4e9b001f3..c9a9db374 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 @@ -16,7 +16,11 @@ import java.util.concurrent.CompletableFuture; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.services.LanguageClient; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.ClasspathListenerParams; +import org.springframework.ide.vscode.commons.languageserver.java.ls.ClasspathListenerParams; +import org.springframework.ide.vscode.commons.languageserver.java.ls.JavaDataParams; +import org.springframework.ide.vscode.commons.languageserver.java.ls.JavaTypeResponse; +import org.springframework.ide.vscode.commons.languageserver.java.ls.JavadocHoverLinkResponse; +import org.springframework.ide.vscode.commons.languageserver.java.ls.JavadocResponse; import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixEdit.CursorMovement; /** @@ -42,5 +46,12 @@ public interface STS4LanguageClient extends LanguageClient { CompletableFuture removeClasspathListener(ClasspathListenerParams classpathListenerParams); @JsonRequest("sts/javadoc") - CompletableFuture javadoc(JavadocParams params); + CompletableFuture javadoc(JavaDataParams params); + + @JsonRequest("sts/javaType") + CompletableFuture javaType(JavaDataParams params); + + @JsonRequest("sts/javadocHoverLink") + CompletableFuture javadocHoverLink(JavaDataParams params); + } diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/jdt/ls/Classpath.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/Classpath.java similarity index 98% rename from headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/jdt/ls/Classpath.java rename to headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/Classpath.java index dcc095e63..4926a0cbf 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/jdt/ls/Classpath.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/Classpath.java @@ -8,7 +8,7 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.ide.vscode.commons.languageserver.jdt.ls; +package org.springframework.ide.vscode.commons.languageserver.java.ls; import java.io.File; import java.net.URL; diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/jdt/ls/ClasspathListener.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/ClasspathListener.java similarity index 94% rename from headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/jdt/ls/ClasspathListener.java rename to headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/ClasspathListener.java index 54ea62e31..3ed9152da 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/jdt/ls/ClasspathListener.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/ClasspathListener.java @@ -8,7 +8,7 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.ide.vscode.commons.languageserver.jdt.ls; +package org.springframework.ide.vscode.commons.languageserver.java.ls; public interface ClasspathListener { diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/jdt/ls/ClasspathListenerManager.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/ClasspathListenerManager.java similarity index 98% rename from headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/jdt/ls/ClasspathListenerManager.java rename to headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/ClasspathListenerManager.java index 97ca03a3d..6f5704f37 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/jdt/ls/ClasspathListenerManager.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/ClasspathListenerManager.java @@ -8,7 +8,7 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.ide.vscode.commons.languageserver.jdt.ls; +package org.springframework.ide.vscode.commons.languageserver.java.ls; import java.util.List; import java.util.UUID; diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/jdt/ls/ClasspathListenerParams.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/ClasspathListenerParams.java similarity index 93% rename from headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/jdt/ls/ClasspathListenerParams.java rename to headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/ClasspathListenerParams.java index 29db176ae..d55121e48 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/jdt/ls/ClasspathListenerParams.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/ClasspathListenerParams.java @@ -8,7 +8,7 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.ide.vscode.commons.languageserver.jdt.ls; +package org.springframework.ide.vscode.commons.languageserver.java.ls; public class ClasspathListenerParams { diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/JavadocParams.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaDataParams.java similarity index 69% rename from headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/JavadocParams.java rename to headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaDataParams.java index 818ded907..d7810b842 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/JavadocParams.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaDataParams.java @@ -8,29 +8,38 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.ide.vscode.commons.languageserver; +package org.springframework.ide.vscode.commons.languageserver.java.ls; -public class JavadocParams { +public class JavaDataParams { private String projectUri; private String bindingKey; - public JavadocParams(String projectUri, String bindingKey) { + public JavaDataParams(String projectUri, String bindingKey) { super(); this.projectUri = projectUri; this.bindingKey = bindingKey; } - public String getProjectUri() { - return projectUri; - } - public void setProjectUri(String projectUri) { - this.projectUri = projectUri; - } + public String getBindingKey() { return bindingKey; } + public void setBindingKey(String bindingKey) { this.bindingKey = bindingKey; } + public String getProjectUri() { + return projectUri; + } + + public void setProjectUri(String project) { + this.projectUri = project; + } + + @Override + public String toString() { + return "JavaDataParams [projectUri=" + projectUri + ", bindingKey=" + bindingKey + "]"; + } + } diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaElementData.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaElementData.java new file mode 100644 index 000000000..70c8d4262 --- /dev/null +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaElementData.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2018 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.commons.languageserver.java.ls; + +public class JavaElementData { + + private String name; + private String handleIdentifier; + + public JavaElementData() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getHandleIdentifier() { + return handleIdentifier; + } + + public void setHandleIdentifier(String handleIdentifier) { + this.handleIdentifier = handleIdentifier; + } + +} diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaTypeResponse.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaTypeResponse.java new file mode 100644 index 000000000..6ab2e5b4e --- /dev/null +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaTypeResponse.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2018 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.commons.languageserver.java.ls; + +public class JavaTypeResponse { + + private TypeData data; + + public JavaTypeResponse(TypeData data) { + this.data = data; + } + + public TypeData getData() { + return data; + } + + public void setData(TypeData data) { + this.data = data; + } + +} diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavadocHoverLinkResponse.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavadocHoverLinkResponse.java new file mode 100644 index 000000000..f74c467f4 --- /dev/null +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavadocHoverLinkResponse.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2018 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.commons.languageserver.java.ls; + +public class JavadocHoverLinkResponse { + + private String link; + + public JavadocHoverLinkResponse(String link) { + this.link = link; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + +} diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/JavadocResponse.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavadocResponse.java similarity index 91% rename from headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/JavadocResponse.java rename to headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavadocResponse.java index 35d494aad..2d83def69 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/JavadocResponse.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavadocResponse.java @@ -8,7 +8,7 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.ide.vscode.commons.languageserver; +package org.springframework.ide.vscode.commons.languageserver.java.ls; public class JavadocResponse { diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/MemberData.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/MemberData.java new file mode 100644 index 000000000..1fe4cc939 --- /dev/null +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/MemberData.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2018 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.commons.languageserver.java.ls; + +public class MemberData extends JavaElementData { + + private String declaringType; + private int flags; + + public String getDeclaringType() { + return declaringType; + } + + public void setDeclaringType(String declaringType) { + this.declaringType = declaringType; + } + + public int getFlags() { + return flags; + } + + public void setFlags(int flags) { + this.flags = flags; + } + +} diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/TypeData.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/TypeData.java new file mode 100644 index 000000000..f94f2d0f7 --- /dev/null +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/TypeData.java @@ -0,0 +1,234 @@ +/******************************************************************************* + * Copyright (c) 2018 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.commons.languageserver.java.ls; + +import java.util.List; +import java.util.Map; + +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; + +public class TypeData extends MemberData { + + private String fqName; + private String bindingKey; + private boolean clazz; + private boolean annotation; + private boolean interfaze; + private boolean enam; + private String superClassName; + private String[] superInterfaceNames; + private List fields; + private List methods; + private List annotations; + + private ClasspathEntryData classpathEntry; + + public String getFqName() { + return fqName; + } + + public void setFqName(String fqName) { + this.fqName = fqName; + } + + public List getFields() { + return fields; + } + + public void setFields(List fields) { + this.fields = fields; + } + + public List getMethods() { + return methods; + } + + public void setMethods(List methods) { + this.methods = methods; + } + + public String getBindingKey() { + return bindingKey; + } + + public void setBindingKey(String bindingKey) { + this.bindingKey = bindingKey; + } + + public ClasspathEntryData getClasspathEntry() { + return classpathEntry; + } + + public void setClasspathEntry(ClasspathEntryData classpathContainer) { + this.classpathEntry = classpathContainer; + } + + public boolean isClass() { + return clazz; + } + + public void setClass(boolean clazz) { + this.clazz = clazz; + } + + public boolean isAnnotation() { + return annotation; + } + + public void setAnnotation(boolean annotation) { + this.annotation = annotation; + } + + public boolean isInterface() { + return interfaze; + } + + public void setInterface(boolean interfaze) { + this.interfaze = interfaze; + } + + public boolean isEnum() { + return enam; + } + + public void setEnum(boolean enam) { + this.enam = enam; + } + + public String getSuperClassName() { + return superClassName; + } + + public void setSuperClassName(String superClassName) { + this.superClassName = superClassName; + } + + public String[] getSuperInterfaceNames() { + return superInterfaceNames; + } + + public void setSuperInterfaceNames(String[] superInterfaceNames) { + this.superInterfaceNames = superInterfaceNames; + } + + public List getAnnotations() { + return annotations; + } + + public void setAnnotations(List annotations) { + this.annotations = annotations; + } + + public static class AnnotationData extends JavaElementData { + + String fqName; + + Map valuePairs; + + public AnnotationData() { + } + + public String getFqName() { + return fqName; + } + + public void setFqName(String fqName) { + this.fqName = fqName; + } + + public Map getValuePairs() { + return valuePairs; + } + + public void setValuePairs(Map valuePairs) { + this.valuePairs = valuePairs; + } + + } + + public static class FieldData extends MemberData { + + private String bindingKey; + private List annotations; + + public String getBindingKey() { + return bindingKey; + } + + public void setBindingKey(String bindingKey) { + this.bindingKey = bindingKey; + } + + public List getAnnotations() { + return annotations; + } + + public void setAnnotations(List annotations) { + this.annotations = annotations; + } + + } + + public static class ClasspathEntryData { + + private String module; + private CPE cpe; + + public String getModule() { + return module; + } + + public void setModule(String module) { + this.module = module; + } + + public CPE getCpe() { + return cpe; + } + + public void setCpe(CPE cpe) { + this.cpe = cpe; + } + + } + + public static class MethodData extends MemberData { + + private String bindingKey; + private boolean constructor; + private List annotations; + + public String getBindingKey() { + return bindingKey; + } + + public void setBindingKey(String bindingKey) { + this.bindingKey = bindingKey; + } + + public boolean isConstructor() { + return constructor; + } + + public void setConstructor(boolean constructor) { + this.constructor = constructor; + } + + public List getAnnotations() { + return annotations; + } + + public void setAnnotations(List annotations) { + this.annotations = annotations; + } + + } +} diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java index f9e60c20e..81635ffab 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java @@ -63,8 +63,8 @@ import org.springframework.ide.vscode.commons.languageserver.completion.IComplet import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter; import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter.CompletionFilter; import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter.LazyCompletionResolver; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.ClasspathListener; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.ClasspathListenerManager; +import org.springframework.ide.vscode.commons.languageserver.java.ls.ClasspathListener; +import org.springframework.ide.vscode.commons.languageserver.java.ls.ClasspathListenerManager; import org.springframework.ide.vscode.commons.languageserver.quickfix.Quickfix; import org.springframework.ide.vscode.commons.languageserver.quickfix.Quickfix.QuickfixData; import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixEdit; diff --git a/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectClasspath.java b/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectClasspath.java index 97380be28..c46bad025 100644 --- a/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectClasspath.java +++ b/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectClasspath.java @@ -25,7 +25,7 @@ import org.apache.maven.project.MavenProject; import org.springframework.ide.vscode.commons.java.ClasspathData; import org.springframework.ide.vscode.commons.java.IClasspath; import org.springframework.ide.vscode.commons.java.JavaUtils; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import org.springframework.ide.vscode.commons.maven.MavenCore; import org.springframework.ide.vscode.commons.maven.MavenException; import org.springframework.ide.vscode.commons.util.Log; diff --git a/headless-services/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/MavenProjectCacheTest.java b/headless-services/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/MavenProjectCacheTest.java index e7c840324..e24932fe1 100644 --- a/headless-services/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/MavenProjectCacheTest.java +++ b/headless-services/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/MavenProjectCacheTest.java @@ -49,7 +49,7 @@ import org.springframework.ide.vscode.commons.languageserver.DiagnosticService; import org.springframework.ide.vscode.commons.languageserver.ProgressService; import org.springframework.ide.vscode.commons.languageserver.Sts4LanguageServer; import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver.Listener; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import org.springframework.ide.vscode.commons.languageserver.util.ShowMessageException; import org.springframework.ide.vscode.commons.languageserver.util.SimpleWorkspaceService; import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject; diff --git a/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/ClasspathTestUtil.java b/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/ClasspathTestUtil.java index 7e006e376..8ca62bf68 100644 --- a/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/ClasspathTestUtil.java +++ b/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/ClasspathTestUtil.java @@ -14,8 +14,8 @@ import java.nio.file.Path; import java.nio.file.Paths; import org.springframework.ide.vscode.commons.java.IJavaProject; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; public class ClasspathTestUtil { 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 f26b4a84d..68032578c 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 @@ -33,7 +33,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Random; -import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -93,18 +92,18 @@ import org.eclipse.lsp4j.WorkspaceEdit; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.services.LanguageClientAware; import org.springframework.ide.vscode.commons.languageserver.HighlightParams; -import org.springframework.ide.vscode.commons.languageserver.JavadocParams; -import org.springframework.ide.vscode.commons.languageserver.JavadocResponse; import org.springframework.ide.vscode.commons.languageserver.ProgressParams; import org.springframework.ide.vscode.commons.languageserver.STS4LanguageClient; import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits; -import org.springframework.ide.vscode.commons.languageserver.config.LanguageServerInitializer; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.ClasspathListenerParams; +import org.springframework.ide.vscode.commons.languageserver.java.ls.ClasspathListenerParams; +import org.springframework.ide.vscode.commons.languageserver.java.ls.JavaDataParams; +import org.springframework.ide.vscode.commons.languageserver.java.ls.JavaTypeResponse; +import org.springframework.ide.vscode.commons.languageserver.java.ls.JavadocHoverLinkResponse; +import org.springframework.ide.vscode.commons.languageserver.java.ls.JavadocResponse; import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixEdit.CursorMovement; import org.springframework.ide.vscode.commons.languageserver.util.LanguageServerTestListener; import org.springframework.ide.vscode.commons.languageserver.util.Settings; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; -import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServerWrapper; import org.springframework.ide.vscode.commons.util.Assert; import org.springframework.ide.vscode.commons.util.ExceptionUtil; import org.springframework.ide.vscode.commons.util.IOUtil; @@ -320,10 +319,20 @@ public class LanguageServerHarness { } @Override - public CompletableFuture javadoc(JavadocParams params) { + public CompletableFuture javadoc(JavaDataParams params) { return CompletableFuture.completedFuture(new JavadocResponse()); } + @Override + public CompletableFuture javaType(JavaDataParams params) { + return CompletableFuture.completedFuture(new JavaTypeResponse(null)); + } + + @Override + public CompletableFuture javadocHoverLink(JavaDataParams params) { + return CompletableFuture.completedFuture(new JavadocHoverLinkResponse(null)); + } + }); } diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/META-INF/MANIFEST.MF b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/META-INF/MANIFEST.MF index 6b38cab0d..b8283fc6e 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/META-INF/MANIFEST.MF +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/META-INF/MANIFEST.MF @@ -14,5 +14,6 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.m2e.core Export-Package: org.springframework.tooling.jdt.ls.commons, org.springframework.tooling.jdt.ls.commons.classpath, + org.springframework.tooling.jdt.ls.commons.java, org.springframework.tooling.jdt.ls.commons.javadoc, org.springframework.tooling.jdt.ls.commons.resources 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 9e87cae12..5f3e5e90c 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 @@ -13,6 +13,7 @@ package org.springframework.tooling.jdt.ls.commons.classpath; import static org.springframework.tooling.jdt.ls.commons.classpath.Classpath.ENTRY_KIND_BINARY; import static org.springframework.tooling.jdt.ls.commons.classpath.Classpath.ENTRY_KIND_SOURCE; +import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -20,13 +21,13 @@ import java.util.List; import java.util.Set; import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.core.JavaProject; import org.springframework.tooling.jdt.ls.commons.Logger; import org.springframework.tooling.jdt.ls.commons.classpath.Classpath.CPE; @@ -70,59 +71,18 @@ public class ClasspathUtil { List cpEntries = new ArrayList<>(); - - IClasspathEntry[] entries = javaProject.getResolvedClasspath(true); Set systemLibs = getSystemLibraryPaths(javaProject); if (entries != null) { for (IClasspathEntry entry : entries) { - String kind = toContentKind(entry); - switch (kind) { - case Classpath.ENTRY_KIND_BINARY: { - String path = entry.getPath().toString(); - CPE cpe = CPE.binary(path); - if (systemLibs.contains(path)) { - cpe.setSystem(true); + try { + CPE cpe = createCpe(systemLibs, javaProject, entry); + if (cpe != null) { + cpEntries.add(cpe); } - IPath sp = entry.getSourceAttachmentPath(); - if (sp!=null) { - cpe.setSourceContainerUrl(sp.toFile().toURI().toURL()); - //TODO: -// IPath srp = entry.getSourceAttachmentRootPath(); -// if (srp!=null) { -// -// } - } - cpEntries.add(cpe); - break; - } - case Classpath.ENTRY_KIND_SOURCE: { - if (entry.getEntryKind()==IClasspathEntry.CPE_PROJECT) { - IPath projectPath = entry.getPath(); - logger.log("project entry "+projectPath); - resolveProjectOutputFolder(projectPath, cpEntries, logger); - } else { - IPath sourcePath = entry.getPath(); - //log("source entry =" + sourcePath); - IPath absoluteSourcePath = resolveWorkspacePath(sourcePath); - //log("absoluteSourcePath =" + absoluteSourcePath); - if (absoluteSourcePath!=null) { - IPath of = entry.getOutputLocation(); - //log("outputFolder =" + of); - IPath absoluteOutFolder; - if (of!=null) { - absoluteOutFolder = resolveWorkspacePath(of); - } else { - absoluteOutFolder = resolveWorkspacePath(javaProject.getOutputLocation()); - } - cpEntries.add(CPE.source(absoluteSourcePath.toFile(), absoluteOutFolder.toFile())); - } - } - break; - } - default: - break; + } catch (Exception e) { + logger.log(e); } } } @@ -131,22 +91,73 @@ public class ClasspathUtil { return classpath; } - private static void resolveProjectOutputFolder(IPath projectPath, List cpEntries, Logger logger) { - try { - if (projectPath.segmentCount()==1) { - IProject p = ResourcesPlugin.getWorkspace().getRoot().getProject(projectPath.segment(0)); - if (p.isAccessible()) { - IJavaProject jp = JavaCore.create(p); - IPath outputFolder = jp.getOutputLocation(); - if (outputFolder!=null) { - outputFolder = resolveWorkspacePath(outputFolder); - cpEntries.add(CPE.binary(outputFolder.toFile().getAbsolutePath())); + public static CPE createCpe(IJavaProject javaProject, IClasspathEntry entry) throws MalformedURLException, JavaModelException { + return createCpe(getSystemLibraryPaths(javaProject), javaProject, entry); + } + + private static CPE createCpe(Set systemLibs, IJavaProject javaProject, IClasspathEntry entry) + throws MalformedURLException, JavaModelException { + String kind = toContentKind(entry); + switch (kind) { + case Classpath.ENTRY_KIND_BINARY: { + String path = entry.getPath().toString(); + CPE cpe = CPE.binary(path); + if (systemLibs.contains(path)) { + cpe.setSystem(true); + } + IPath sp = entry.getSourceAttachmentPath(); + if (sp != null) { + cpe.setSourceContainerUrl(sp.toFile().toURI().toURL()); + // TODO: +// IPath srp = entry.getSourceAttachmentRootPath(); +// if (srp!=null) { +// +// } + } + return cpe; + } + case Classpath.ENTRY_KIND_SOURCE: { + if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) { + IPath projectPath = entry.getPath(); + return resolveProjectOutputFolder(projectPath); + } else { + IPath sourcePath = entry.getPath(); + // log("source entry =" + sourcePath); + IPath absoluteSourcePath = resolveWorkspacePath(sourcePath); + // log("absoluteSourcePath =" + absoluteSourcePath); + if (absoluteSourcePath != null) { + IPath of = entry.getOutputLocation(); + // log("outputFolder =" + of); + IPath absoluteOutFolder; + if (of != null) { + absoluteOutFolder = resolveWorkspacePath(of); + } else { + absoluteOutFolder = resolveWorkspacePath(javaProject.getOutputLocation()); } + return CPE.source(absoluteSourcePath.toFile(), absoluteOutFolder.toFile()); } } - } catch (Exception e) { - logger.log(e); + break; } + default: + break; + } + return null; + } + + private static CPE resolveProjectOutputFolder(IPath projectPath) throws JavaModelException { + if (projectPath.segmentCount() == 1) { + IProject p = ResourcesPlugin.getWorkspace().getRoot().getProject(projectPath.segment(0)); + if (p.isAccessible()) { + IJavaProject jp = JavaCore.create(p); + IPath outputFolder = jp.getOutputLocation(); + if (outputFolder != null) { + outputFolder = resolveWorkspacePath(outputFolder); + return CPE.binary(outputFolder.toFile().getAbsolutePath()); + } + } + } + return null; } private static IPath resolveWorkspacePath(IPath path) { diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaData.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaData.java new file mode 100644 index 000000000..3776b0c9f --- /dev/null +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaData.java @@ -0,0 +1,300 @@ +/******************************************************************************* + * Copyright (c) 2018 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.commons.java; + +import java.net.MalformedURLException; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jdt.core.IAnnotation; +import org.eclipse.jdt.core.IClasspathEntry; +import org.eclipse.jdt.core.IField; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IMember; +import org.eclipse.jdt.core.IMemberValuePair; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.IParent; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.ITypeRoot; +import org.eclipse.jdt.core.JavaModelException; +import org.springframework.tooling.jdt.ls.commons.Logger; +import org.springframework.tooling.jdt.ls.commons.classpath.ClasspathUtil; +import org.springframework.tooling.jdt.ls.commons.java.TypeData.AnnotationData; +import org.springframework.tooling.jdt.ls.commons.java.TypeData.ClasspathEntryData; +import org.springframework.tooling.jdt.ls.commons.java.TypeData.FieldData; +import org.springframework.tooling.jdt.ls.commons.java.TypeData.MethodData; +import org.springframework.tooling.jdt.ls.commons.javadoc.JavadocUtils; +import org.springframework.tooling.jdt.ls.commons.resources.ResourceUtils; + +import com.google.common.collect.ImmutableList; + +public class JavaData { + + private Logger logger; + + public JavaData(Logger logger) { + this.logger = logger; + } + + public TypeData typeData(String projectUri, String bindingKey) { + try { + IJavaElement element = findElement(URI.create(projectUri), bindingKey); + if (element instanceof IType) { + return createTypeData((IType) element); + } + } catch (Exception e) { + logger.log(e); + } + return null; + } + + public static IJavaElement findElement(URI projectUri, String bindingKey) throws Exception { + IJavaProject javaProject = ResourceUtils.getJavaProject(projectUri); + if (javaProject != null) { + return findElement(javaProject, bindingKey); + } + return null; + } + + private static IJavaElement findElement(IJavaProject project, String bindingKey) { + IJavaElement element = null; + // JDT cannot find anonymous inner type from its binding key + // Find its declaring type. If declaring type found then anonymous inner type is present in the binding key + String declaringTypeFromAnonymousInnerType = delcaringTypeOfAnonymousInnerType(bindingKey); + try { + if (declaringTypeFromAnonymousInnerType == null) { + element = project.findElement(bindingKey, null); + } else { + // Look for element inside the enclosing type that JDT can find. Brute force finding algorithm + element = findInnerElement(project.findElement(declaringTypeFromAnonymousInnerType, null), bindingKey); + } + } catch (Throwable t) { + // ignore + } + if (element == null) { + // Try modifying the binding key to search for the alternate binding + try { + String alternateBinding = JavadocUtils.alternateBinding(bindingKey); + if (alternateBinding != null) { + element = project.findElement(alternateBinding, null); + } + } catch (Throwable t) { + // ignore + } + } + return element; + } + + private static IJavaElement findInnerElement(IJavaElement container, String bindingKey) { + if (container instanceof IField) { + if (bindingKey.equals(((IField)container).getKey())) { + return container; + } + } else if (container instanceof IMethod) { + if (bindingKey.equals(((IMethod)container).getKey())) { + return container; + } + } else if (container instanceof IType) { + if (bindingKey.equals(((IType)container).getKey())) { + return container; + } + } + + if (container instanceof IParent) { + try { + for(IJavaElement e : ((IParent)container).getChildren()) { + IJavaElement found = findInnerElement(e, bindingKey); + if (found != null) { + return found; + } + } + } catch (JavaModelException e) { + // ignore + } + } + return null; + } + + private static String delcaringTypeOfAnonymousInnerType(String bindingKey) { + int idx = bindingKey.indexOf('$'); + if (idx >= 0) { + String rest = bindingKey.substring(idx + 1); + if (rest.charAt(rest.length() - 1) == ';') { + rest = rest.substring(0, rest.length() - 1); + } + String[] tokens = rest.split("$"); + for (String token : tokens) { + int dotIdx = token.indexOf('.'); + String typeToken = dotIdx < 0 ? token : token.substring(0, dotIdx); + if (!typeToken.isEmpty()) { + try { + Integer.parseInt(typeToken); + // Succeeded. There is inner anonymous type present. + // Return it's enclosing type binding key which JDT should have no problem finding the element for + int declaringTypeIdx = bindingKey.indexOf('$' + token); + if (declaringTypeIdx < 0) { + // Should not happen. Throw exception? + return null; + } else { + return bindingKey.substring(0, declaringTypeIdx) + ';'; + } + } catch (NumberFormatException e) { + // ignore and continue looping + } + } + } + } + return null; + } + + private void fillJavaElementData(IJavaElement element, JavaElementData data) { + data.setName(element.getElementName()); + data.setHandleIdentifier(element.getHandleIdentifier()); + } + + private FieldData createFieldData(IField field) { + FieldData data = new FieldData(); + fillMemberData(field, data); + data.setBindingKey(field.getKey()); + ImmutableList.Builder annotationsBuilder = ImmutableList.builder(); + try { + for (IAnnotation annotation : field.getAnnotations()) { + annotationsBuilder.add(createAnnotationData(annotation)); + } + } catch (JavaModelException e) { + logger.log(e); + } + data.setAnnotations(annotationsBuilder.build()); + return data; + } + + private void fillMemberData(IMember member, MemberData data) { + fillJavaElementData(member, data); + IType declaringType = member.getDeclaringType(); + if (declaringType != null) { + data.setDeclaringType(declaringType.getKey()); + } + try { + data.setFlags(member.getFlags()); + } catch (JavaModelException e) { + logger.log(e); + } + } + + private MethodData createMethodData(IMethod method) { + MethodData data = new MethodData(); + fillMemberData(method, data); + data.setBindingKey(method.getKey()); + ImmutableList.Builder annotationsBuilder = ImmutableList.builder(); + try { + data.setConstructor(method.isConstructor()); + for (IAnnotation annotation : method.getAnnotations()) { + annotationsBuilder.add(createAnnotationData(annotation)); + } + } catch (JavaModelException e) { + logger.log(e); + } + data.setAnnotations(annotationsBuilder.build()); + return data; + } + + private TypeData createTypeData(IType type) { + TypeData data = new TypeData(); + fillTypeData(type, data); + return data; + } + + private void fillTypeData(IType type, TypeData data) { + fillMemberData(type, data); + + data.setFqName(type.getFullyQualifiedName()); + + data.setBindingKey(type.getKey()); + + ImmutableList.Builder fieldsBuilder = ImmutableList.builder(); + ImmutableList.Builder methodsBuilder = ImmutableList.builder(); + ImmutableList.Builder annotationsBuilder = ImmutableList.builder(); + try { + for (IField field : type.getFields()) { + fieldsBuilder.add(createFieldData(field)); + } + for (IMethod method : type.getMethods()) { + methodsBuilder.add(createMethodData(method)); + } + for (IAnnotation annotation : type.getAnnotations()) { + annotationsBuilder.add(createAnnotationData(annotation)); + } + data.setAnnotation(type.isAnnotation()); + data.setClass(type.isClass()); + data.setEnum(type.isEnum()); + data.setInterface(type.isInterface()); + data.setSuperClassName(type.getSuperclassName()); + data.setSuperInterfaceNames(type.getSuperInterfaceNames()); + } catch (JavaModelException e) { + logger.log(e); + } + data.setFields(fieldsBuilder.build()); + data.setMethods(methodsBuilder.build()); + data.setAnnotations(annotationsBuilder.build()); + + data.setClasspathEntry(createClasspathEntryData(type)); + } + + private ClasspathEntryData createClasspathEntryData(IMember member) { + ClasspathEntryData data = new ClasspathEntryData(); + + IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot) member.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); + if (packageFragmentRoot != null) { + try { + IClasspathEntry entry = packageFragmentRoot.getRawClasspathEntry(); + if (entry != null) { + data.setCpe(ClasspathUtil.createCpe(packageFragmentRoot.getJavaProject(), entry)); + } + } catch (JavaModelException | MalformedURLException e) { + logger.log(e); + } + } + + ITypeRoot typeRoot = member.getTypeRoot(); + try { + if (typeRoot != null && typeRoot.getModule() != null) { + data.setModule(typeRoot.getModule().getElementName()); + } + } catch (JavaModelException e) { + logger.log(e); + } + + return data; + } + + private AnnotationData createAnnotationData(IAnnotation annotation) { + AnnotationData data = new AnnotationData(); + fillAnnotationData(annotation, data); + return data; + } + + private void fillAnnotationData(IAnnotation annotation, AnnotationData data) { + fillJavaElementData(annotation, data); + Map pairs = new HashMap<>(); + try { + for (IMemberValuePair pair : annotation.getMemberValuePairs()) { + pairs.put(pair.getMemberName(), pair.getValue()); + } + } catch (JavaModelException e) { + logger.log(e); + } + data.setValuePairs(pairs); + } + +} diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/JavadocParams.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaDataParams.java similarity index 73% rename from eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/JavadocParams.java rename to headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaDataParams.java index 7f6a737b3..e5ab6380f 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/JavadocParams.java +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaDataParams.java @@ -8,34 +8,38 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.tooling.ls.eclipse.commons; +package org.springframework.tooling.jdt.ls.commons.java; -public class JavadocParams { +public class JavaDataParams { private String projectUri; private String bindingKey; - public JavadocParams(String projectUri, String bindingKey) { + public JavaDataParams(String projectUri, String bindingKey) { super(); this.projectUri = projectUri; this.bindingKey = bindingKey; } - public String getProjectUri() { - return projectUri; - } - public void setProjectUri(String projectUri) { - this.projectUri = projectUri; - } + public String getBindingKey() { return bindingKey; } + public void setBindingKey(String bindingKey) { this.bindingKey = bindingKey; } + public String getProjectUri() { + return projectUri; + } + + public void setProjectUri(String project) { + this.projectUri = project; + } + @Override public String toString() { - return "JavadocParams [projectUri=" + projectUri + ", bindingKey=" + bindingKey + "]"; + return "JavaDataParams [projectUri=" + projectUri + ", bindingKey=" + bindingKey + "]"; } } diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaElementData.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaElementData.java new file mode 100644 index 000000000..6889f12ab --- /dev/null +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaElementData.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2018 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.commons.java; + +public class JavaElementData { + + private String name; + private String handleIdentifier; + + public JavaElementData() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getHandleIdentifier() { + return handleIdentifier; + } + + public void setHandleIdentifier(String handleIdentifier) { + this.handleIdentifier = handleIdentifier; + } + +} diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaTypeResponse.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaTypeResponse.java new file mode 100644 index 000000000..3eed70f83 --- /dev/null +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaTypeResponse.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2018 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.commons.java; + +public class JavaTypeResponse { + + private TypeData data; + + public JavaTypeResponse(TypeData data) { + this.data = data; + } + + public TypeData getData() { + return data; + } + + public void setData(TypeData data) { + this.data = data; + } + +} diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavadocHoverLinkResponse.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavadocHoverLinkResponse.java new file mode 100644 index 000000000..f80fced4a --- /dev/null +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavadocHoverLinkResponse.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2018 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.commons.java; + +public class JavadocHoverLinkResponse { + + private String link; + + public JavadocHoverLinkResponse(String link) { + this.link = link; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + +} diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/MemberData.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/MemberData.java new file mode 100644 index 000000000..2a26cbb41 --- /dev/null +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/MemberData.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2018 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.commons.java; + +public class MemberData extends JavaElementData { + + private String declaringType; + private int flags; + + public String getDeclaringType() { + return declaringType; + } + + public void setDeclaringType(String declaringType) { + this.declaringType = declaringType; + } + + public int getFlags() { + return flags; + } + + public void setFlags(int flags) { + this.flags = flags; + } + +} diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/TypeData.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/TypeData.java new file mode 100644 index 000000000..51e24a714 --- /dev/null +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/TypeData.java @@ -0,0 +1,234 @@ +/******************************************************************************* + * Copyright (c) 2018 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.commons.java; + +import java.util.List; +import java.util.Map; + +import org.springframework.tooling.jdt.ls.commons.classpath.Classpath.CPE; + +public class TypeData extends MemberData { + + private String fqName; + private String bindingKey; + private boolean clazz; + private boolean annotation; + private boolean interfaze; + private boolean enam; + private String superClassName; + private String[] superInterfaceNames; + private List fields; + private List methods; + private List annotations; + + private ClasspathEntryData classpathEntry; + + public String getFqName() { + return fqName; + } + + public void setFqName(String fqName) { + this.fqName = fqName; + } + + public List getFields() { + return fields; + } + + public void setFields(List fields) { + this.fields = fields; + } + + public List getMethods() { + return methods; + } + + public void setMethods(List methods) { + this.methods = methods; + } + + public String getBindingKey() { + return bindingKey; + } + + public void setBindingKey(String bindingKey) { + this.bindingKey = bindingKey; + } + + public ClasspathEntryData getClasspathEntry() { + return classpathEntry; + } + + public void setClasspathEntry(ClasspathEntryData classpathContainer) { + this.classpathEntry = classpathContainer; + } + + public boolean isClass() { + return clazz; + } + + public void setClass(boolean clazz) { + this.clazz = clazz; + } + + public boolean isAnnotation() { + return annotation; + } + + public void setAnnotation(boolean annotation) { + this.annotation = annotation; + } + + public boolean isInterface() { + return interfaze; + } + + public void setInterface(boolean interfaze) { + this.interfaze = interfaze; + } + + public boolean isEnum() { + return enam; + } + + public void setEnum(boolean enam) { + this.enam = enam; + } + + public String getSuperClassName() { + return superClassName; + } + + public void setSuperClassName(String superClassName) { + this.superClassName = superClassName; + } + + public String[] getSuperInterfaceNames() { + return superInterfaceNames; + } + + public void setSuperInterfaceNames(String[] superInterfaceNames) { + this.superInterfaceNames = superInterfaceNames; + } + + public List getAnnotations() { + return annotations; + } + + public void setAnnotations(List annotations) { + this.annotations = annotations; + } + + public static class AnnotationData extends JavaElementData { + + String fqName; + + Map valuePairs; + + public AnnotationData() { + } + + public String getFqName() { + return fqName; + } + + public void setFqName(String fqName) { + this.fqName = fqName; + } + + public Map getValuePairs() { + return valuePairs; + } + + public void setValuePairs(Map valuePairs) { + this.valuePairs = valuePairs; + } + + } + + public static class FieldData extends MemberData { + + private String bindingKey; + private List annotations; + + public String getBindingKey() { + return bindingKey; + } + + public void setBindingKey(String bindingKey) { + this.bindingKey = bindingKey; + } + + public List getAnnotations() { + return annotations; + } + + public void setAnnotations(List annotations) { + this.annotations = annotations; + } + + } + + public static class ClasspathEntryData { + + private String module; + private CPE cpe; + + public String getModule() { + return module; + } + + public void setModule(String module) { + this.module = module; + } + + public CPE getCpe() { + return cpe; + } + + public void setCpe(CPE cpe) { + this.cpe = cpe; + } + + } + + public static class MethodData extends MemberData { + + private String bindingKey; + private boolean constructor; + private List annotations; + + public String getBindingKey() { + return bindingKey; + } + + public void setBindingKey(String bindingKey) { + this.bindingKey = bindingKey; + } + + public boolean isConstructor() { + return constructor; + } + + public void setConstructor(boolean constructor) { + this.constructor = constructor; + } + + public List getAnnotations() { + return annotations; + } + + public void setAnnotations(List annotations) { + this.annotations = annotations; + } + + } +} diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/javadoc/JavadocUtils.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/javadoc/JavadocUtils.java index 966fc35c6..e03ea7f2d 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/javadoc/JavadocUtils.java +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/javadoc/JavadocUtils.java @@ -16,11 +16,10 @@ import java.net.URI; import java.util.function.Function; import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.ITypeParameter; -import org.springframework.tooling.jdt.ls.commons.resources.ResourceUtils; +import org.springframework.tooling.jdt.ls.commons.java.JavaData; import com.google.common.io.CharStreams; @@ -41,8 +40,7 @@ public class JavadocUtils { } public static final String javadoc(Function readerProvider, URI projectUri, String bindingKey) throws Exception { - IJavaProject project = ResourceUtils.getJavaProject(projectUri); - IJavaElement element = findElement(project, bindingKey); + IJavaElement element = JavaData.findElement(projectUri, bindingKey); return computeJavadoc(readerProvider, element); } @@ -72,28 +70,7 @@ public class JavadocUtils { return getString(r); } - public static IJavaElement findElement(IJavaProject project, String bindingKey) { - IJavaElement element = null; - try { - element = project.findElement(bindingKey, null); - } catch (Throwable t) { - // ignore - } - if (element == null) { - // Try modifying the binding key to search for the alternate binding - try { - String alternateBinding = alternateBinding(bindingKey); - if (alternateBinding != null) { - element = project.findElement(alternateBinding, null); - } - } catch (Throwable t) { - // ignore - } - } - return element; - } - - private static String alternateBinding(String bindingKey) { + public static String alternateBinding(String bindingKey) { int idxStartParams = bindingKey.indexOf('('); if (idxStartParams >= 0) { int idxEndParams = bindingKey.indexOf(')', idxStartParams); diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/resources/ResourceUtils.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/resources/ResourceUtils.java index 9bcbd2c6d..c8c394f7c 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/resources/ResourceUtils.java +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/resources/ResourceUtils.java @@ -10,8 +10,6 @@ *******************************************************************************/ package org.springframework.tooling.jdt.ls.commons.resources; -import static org.springframework.tooling.jdt.ls.commons.Logger.*; - import java.io.File; import java.net.URI; import java.util.Arrays; 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 9be3d0c12..a6948ff29 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 @@ -12,6 +12,18 @@ id="sts.java.javadoc"> + + + + + + + + \ 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/JavaTypeHanlder.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/src/org/springframework/tooling/jdt/ls/extension/JavaTypeHanlder.java new file mode 100644 index 000000000..d941c3a47 --- /dev/null +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/src/org/springframework/tooling/jdt/ls/extension/JavaTypeHanlder.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2018 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.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.ls.core.internal.IDelegateCommandHandler; +import org.springframework.tooling.jdt.ls.commons.Logger; +import org.springframework.tooling.jdt.ls.commons.java.JavaData; +import org.springframework.tooling.jdt.ls.commons.java.JavaTypeResponse; + +public class JavaTypeHanlder implements IDelegateCommandHandler { + + private static final Logger logger = Logger.DEFAULT; + + final private JavaData JAVA_DATA = new JavaData(logger); + + @Override + public Object executeCommand(String commandId, List arguments, IProgressMonitor monitor) throws Exception { + Map obj = (Map) arguments.get(0); + String uri = (String) obj.get("projectUri"); + String bindingKey = (String) obj.get("bindingKey"); + return new JavaTypeResponse(JAVA_DATA.typeData(uri, bindingKey)); + } + + +} diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/src/org/springframework/tooling/jdt/ls/extension/JavadocHoverLinkHandler.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/src/org/springframework/tooling/jdt/ls/extension/JavadocHoverLinkHandler.java new file mode 100644 index 000000000..42f2e08ff --- /dev/null +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/src/org/springframework/tooling/jdt/ls/extension/JavadocHoverLinkHandler.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2018 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.IJavaElement; +import org.eclipse.jdt.ls.core.internal.IDelegateCommandHandler; +import org.eclipse.jdt.ls.core.internal.javadoc.JavaElementLinks; +import org.springframework.tooling.jdt.ls.commons.Logger; +import org.springframework.tooling.jdt.ls.commons.java.JavaData; +import org.springframework.tooling.jdt.ls.commons.java.JavadocHoverLinkResponse; + +public class JavadocHoverLinkHandler implements IDelegateCommandHandler { + + private static final Logger logger = Logger.DEFAULT; + + @Override + public Object executeCommand(String commandId, List arguments, IProgressMonitor monitor) throws Exception { + Map obj = (Map) arguments.get(0); + String uri = (String) obj.get("projectUri"); + String bindingKey = (String) obj.get("bindingKey"); + JavadocHoverLinkResponse response = new JavadocHoverLinkResponse(null); + try { + IJavaElement element = JavaData.findElement(URI.create(uri), bindingKey); + if (element != null) { + // Bug in JDT server one '(' not encoded while everything else in the query is + // encoded + response.setLink(JavaElementLinks.createURI(null, element).replace("(", "%28")); + } + } catch (Exception e) { + logger.log(e); + } + return response; + } + +} 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 fda7a6c49..927695d71 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 @@ -32,7 +32,6 @@ import org.springframework.ide.vscode.boot.metadata.ClassReferenceProvider; import org.springframework.ide.vscode.boot.metadata.LoggerNameProvider; import org.springframework.ide.vscode.boot.metadata.ProjectBasedPropertyIndexProvider; import org.springframework.ide.vscode.boot.metadata.PropertyInfo; -import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider; import org.springframework.ide.vscode.boot.metadata.ValueProviderRegistry; import org.springframework.ide.vscode.boot.yaml.completions.ApplicationYamlAssistContext; import org.springframework.ide.vscode.commons.languageserver.util.DocumentEventListenerManager; @@ -94,8 +93,8 @@ public class BootLanguagServerBootApp { } @ConditionalOnMissingClass("org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness") - @Bean SourceLinks sourceLinks(CompilationUnitCache cuCache) { - return SourceLinkFactory.createSourceLinks(cuCache); + @Bean SourceLinks sourceLinks(SimpleLanguageServer server, CompilationUnitCache cuCache) { + return SourceLinkFactory.createSourceLinks(server, cuCache); } @Bean CompilationUnitCache cuCache(BootLanguageServerParams params, SimpleTextDocumentService documents) { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerParams.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerParams.java index 45ae44db2..32491d353 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerParams.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerParams.java @@ -38,7 +38,7 @@ import org.springframework.ide.vscode.commons.languageserver.java.CompositeProje import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.languageserver.java.JavadocService; import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.maven.MavenCore; import org.springframework.ide.vscode.commons.maven.java.MavenProjectCache; diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java index 65a7a4564..d9da12f22 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java @@ -222,6 +222,10 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent server.onShutdown(this::shutdown); } + public SimpleLanguageServer getServer() { + return server; + } + @Override public ICompletionEngine getCompletionEngine() { return createCompletionEngine(projectFinder, propertyIndexProvider, adHocPropertyIndexProvider); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/RunningAppMatcher.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/RunningAppMatcher.java index ecd74d1cc..dea53d05c 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/RunningAppMatcher.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/RunningAppMatcher.java @@ -18,8 +18,8 @@ import java.util.Set; import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp; import org.springframework.ide.vscode.commons.java.IClasspath; import org.springframework.ide.vscode.commons.java.IJavaProject; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import org.springframework.ide.vscode.commons.util.CollectorUtil; /** diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/JavaServerSourceLinks.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/JavaServerSourceLinks.java new file mode 100644 index 000000000..b63e99757 --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/JavaServerSourceLinks.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2018 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.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.languageserver.java.ls.JavaDataParams; +import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; + +public class JavaServerSourceLinks implements SourceLinks { + + private SimpleLanguageServer server; + + public JavaServerSourceLinks(SimpleLanguageServer server) { + this.server = server; + } + + @Override + public Optional sourceLinkUrlForFQName(IJavaProject project, String fqName) { + StringBuilder bindingKey = new StringBuilder(); + bindingKey.append('L'); + bindingKey.append(fqName.replace('.', '/')); + bindingKey.append(';'); + CompletableFuture> link = server.getClient().javadocHoverLink(new JavaDataParams(project.getLocationUri().toString(), bindingKey.toString())) + .thenApply(response -> Optional.ofNullable(response.getLink())); + try { + return link.get(10, TimeUnit.SECONDS); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + log.error("", e); + } + return Optional.empty(); + } + + @Override + public Optional sourceLinkUrlForClasspathResource(IJavaProject project, String path) { + int idx = path.lastIndexOf(CLASS); + if (idx >= 0) { + Path p = Paths.get(path.substring(0, idx)); + return sourceLinkUrlForFQName(project, p.toString().replace(File.separator, ".")); + } + return Optional.empty(); + } + + @Override + public Optional sourceLinkForResourcePath(Path path) { + return Optional.ofNullable(path).map(p -> p.toUri().toString()); + } + +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinkFactory.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinkFactory.java index 0e12db838..074921d43 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinkFactory.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinkFactory.java @@ -17,6 +17,7 @@ import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.languageserver.util.LspClient; +import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; /** * Factory for creating {@link SourceLinks} @@ -50,13 +51,14 @@ public final class SourceLinkFactory { * @param server the boot LS * @return appropriate source links object */ - public static SourceLinks createSourceLinks(CompilationUnitCache cuCache) { + public static SourceLinks createSourceLinks(SimpleLanguageServer server, CompilationUnitCache cuCache) { switch (LspClient.currentClient()) { case VSCODE: + return /*new VSCodeSourceLinks(cuCache);*/new JavaServerSourceLinks(server); case THEIA: return new VSCodeSourceLinks(cuCache); case ECLIPSE: - return new EclipseSourceLinks(); + return /*new EclipseSourceLinks();*/new JavaServerSourceLinks(server); case ATOM: return new AtomSourceLinks(cuCache); default: @@ -68,7 +70,7 @@ public final class SourceLinkFactory { @Deprecated public static SourceLinks createSourceLinks(BootJavaLanguageServerComponents server) { return server == null - ? createSourceLinks((CompilationUnitCache)null) - : createSourceLinks(server.getCompilationUnitCache()); + ? createSourceLinks(null, (CompilationUnitCache)null) + : createSourceLinks(server.getServer(), server.getCompilationUnitCache()); } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JavaProjectsServiceWithFallback.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JavaProjectsServiceWithFallback.java index d373dd993..5689c8485 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JavaProjectsServiceWithFallback.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JavaProjectsServiceWithFallback.java @@ -18,7 +18,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.java.IJavadocProvider; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.util.Assert; diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JdtLsProjectCache.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JdtLsProjectCache.java index 1e65e6d78..2b74615da 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JdtLsProjectCache.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JdtLsProjectCache.java @@ -30,8 +30,8 @@ import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.java.IJavadocProvider; import org.springframework.ide.vscode.commons.java.JavaProject; import org.springframework.ide.vscode.commons.javadoc.JdtLsJavadocProvider; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.ClasspathListener; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.ClasspathListener; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.util.ExceptionUtil; import org.springframework.ide.vscode.commons.util.FileObserver; diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/value/test/MockProjects.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/value/test/MockProjects.java index 9f7473c15..c03d08a2d 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/value/test/MockProjects.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/value/test/MockProjects.java @@ -34,8 +34,8 @@ import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver; import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver.Listener; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import org.springframework.ide.vscode.commons.util.FileObserver; import org.springframework.ide.vscode.commons.util.IOUtil; diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/project/harness/BootLanguageServerHarness.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/project/harness/BootLanguageServerHarness.java index ca0386965..d55266fc4 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/project/harness/BootLanguageServerHarness.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/project/harness/BootLanguageServerHarness.java @@ -19,8 +19,8 @@ import org.springframework.ide.vscode.boot.editor.harness.PropertyIndexHarness; import org.springframework.ide.vscode.commons.java.IClasspath; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.util.text.LanguageId; import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness; diff --git a/vscode-extensions/commons-vscode/src/java-data.ts b/vscode-extensions/commons-vscode/src/java-data.ts new file mode 100644 index 000000000..d06f468e5 --- /dev/null +++ b/vscode-extensions/commons-vscode/src/java-data.ts @@ -0,0 +1,26 @@ +import * as VSCode from "vscode"; +import {LanguageClient, RequestType} from "vscode-languageclient"; + +export function registerJavaDataService(client : LanguageClient) : void { + + const javaTypeRequest = new RequestType("sts/javaType"); + client.onRequest(javaTypeRequest, async (params: JavaDataParams) => + await VSCode.commands.executeCommand("java.execute.workspaceCommand", "sts.java.type", params) + ); + + const javadocHoverLinkRequest = new RequestType("sts/javadocHoverLink"); + client.onRequest(javadocHoverLinkRequest, async (params: JavaDataParams) => + await VSCode.commands.executeCommand("java.execute.workspaceCommand", "sts.java.javadocHoverLink", params) + ); + + const javadocRequest = new RequestType("sts/javadoc"); + client.onRequest(javadocRequest, async (params: JavaDataParams) => + await VSCode.commands.executeCommand("java.execute.workspaceCommand", "sts.java.javadoc", params) + ); + +} + +interface JavaDataParams { + projectUri: string; + bindingKey: string; +} \ No newline at end of file diff --git a/vscode-extensions/commons-vscode/src/javadoc.ts b/vscode-extensions/commons-vscode/src/javadoc.ts deleted file mode 100644 index b4034a069..000000000 --- a/vscode-extensions/commons-vscode/src/javadoc.ts +++ /dev/null @@ -1,23 +0,0 @@ -'use strict'; - - -import * as VSCode from 'vscode'; -import { LanguageClient, RequestType } from 'vscode-languageclient'; - -export function registerJavadocService(client : LanguageClient) : void { - - let addRequest = new RequestType("sts/javadoc"); - client.onRequest(addRequest, async (params: JavadocParams) => - await VSCode.commands.executeCommand("java.execute.workspaceCommand", "sts.java.javadoc", params) - ); - -} - -interface JavadocParams { - projectUri: string; - bindingKey: string; -} - -interface JavadocResponse { - content: string; -} diff --git a/vscode-extensions/commons-vscode/src/launch-util.ts b/vscode-extensions/commons-vscode/src/launch-util.ts index e528e15e9..238d8004d 100644 --- a/vscode-extensions/commons-vscode/src/launch-util.ts +++ b/vscode-extensions/commons-vscode/src/launch-util.ts @@ -16,8 +16,8 @@ import { log } from 'util'; import { tmpdir } from 'os'; import { JVM, findJvm, findJdk } from '@pivotal-tools/jvm-launch-utils'; import { registerClasspathService } from './classpath'; -import { registerJavadocService } from './javadoc'; import {HighlightCodeLensProvider} from "./code-lens-service"; +import {registerJavaDataService} from "./java-data"; let p2c = P2C.createConverter(); @@ -260,7 +260,7 @@ function setupLanguageClient(context: VSCode.ExtensionContext, createServer: Ser return { applied: true}; }); registerClasspathService(client); - registerJavadocService(client); + registerJavaDataService(client); return client; }); }