From 0681baa8769b5c65f5dc01ad1285eec72ab2311d Mon Sep 17 00:00:00 2001 From: BoykoAlex Date: Thu, 17 Jan 2019 19:01:04 -0500 Subject: [PATCH] PT #160596363: Fixes for live hints and navigation for multi-projects Initial work: highlights fixed, source links bean SourceLinks bean uses project finder Project finder all projects. Source entries for dependency projects. Properly support peer projects for fall back Gradle projects Update code minings for e4.9 --- .../commons/STS4LanguageClientImpl.java | 9 ++- .../gradle/GradleProjectClasspath.java | 20 +++-- .../commons/gradle/GradleProjectFinder.java | 16 ++-- .../commons/javadoc/JdtLsJavadocProvider.java | 4 +- .../java/AbstractJavaProjectCache.java | 34 ++++---- .../java/CompositeJavaProjectFinder.java | 27 +++++-- .../java/JavaProjectFinder.java | 33 ++++++-- .../languageserver/java/ls/Classpath.java | 23 +++++- .../java/ls/JavaDataParams.java | 25 +++++- .../maven/java/MavenProjectClasspath.java | 10 ++- .../maven/java/MavenProjectFinder.java | 14 +++- .../jdt/ls/commons/classpath/Classpath.java | 17 +++- .../ls/commons/classpath/ClasspathUtil.java | 77 +++++++++++-------- .../tooling/jdt/ls/commons/java/JavaData.java | 33 +++++--- .../jdt/ls/commons/java/JavaDataParams.java | 22 +++++- .../jdt/ls/commons/javadoc/JavadocUtils.java | 6 +- .../ls/commons/resources/ResourceUtils.java | 23 +++++- .../jdt/ls/extension/JavaTypeHanlder.java | 6 +- .../jdt/ls/extension/JavadocHandler.java | 7 +- .../ls/extension/JavadocHoverLinkHandler.java | 6 +- .../boot/app/BootLanguagServerBootApp.java | 16 ++-- .../app/BootLanguageServerInitializer.java | 4 +- .../boot/app/BootLanguageServerParams.java | 11 ++- .../app/PropertiesJavaDefinitionHandler.java | 8 +- .../autowired/AutowiredHoverProvider.java | 4 +- .../java/handlers/BootJavaHoverProvider.java | 19 ++++- .../boot/java/links/AbstractSourceLinks.java | 35 ++++++--- .../boot/java/links/AtomSourceLinks.java | 7 +- .../boot/java/links/EclipseSourceLinks.java | 37 ++++++--- .../java/links/JavaServerSourceLinks.java | 21 +++-- .../boot/java/links/SourceLinkFactory.java | 22 ++---- .../vscode/boot/java/links/SourceLinks.java | 39 +++++++++- .../boot/java/links/VSCodeSourceLinks.java | 7 +- .../boot/java/livehover/LiveHoverUtils.java | 4 +- .../SpringLiveChangeDetectionWatchdog.java | 20 ++--- .../boot/java/utils/SpringResource.java | 18 +++-- .../ls/JavaProjectsServiceWithFallback.java | 18 ++++- .../vscode/boot/jdt/ls/JdtLsProjectCache.java | 7 +- .../boot/metadata/ClassReferenceProvider.java | 60 ++++++++------- .../boot/metadata/LoggerNameProvider.java | 14 ++-- .../boot/metadata/hints/StsValueHint.java | 17 ++-- .../vscode/boot/metadata/types/TypeUtil.java | 21 ++--- .../boot/metadata/types/TypeUtilProvider.java | 5 +- ...ootPropertiesLanguageServerComponents.java | 15 ++-- .../SpringPropertiesCompletionEngine.java | 9 ++- .../hover/PropertiesHoverInfoProvider.java | 17 ++-- .../SpringPropertiesReconcileEngine.java | 9 ++- .../ApplicationYamlAssistContext.java | 4 +- .../ApplicationYamlReconcileEngine.java | 7 +- .../boot/bootiful/PropertyEditorTestConf.java | 4 +- .../harness/AbstractPropsEditorTest.java | 7 ++ .../editor/harness/PropertyIndexHarness.java | 18 ++++- .../ComponentInjectionsHoverProviderTest.java | 55 ++++++++++++- .../utils/test/VSCodeSourceLinksTest.java | 8 +- .../boot/java/value/test/MockProjects.java | 7 +- .../java/value/test/ValueCompletionTest.java | 20 ++++- .../boot/metadata/LoggerNameProviderTest.java | 4 +- .../vscode/boot/metadata/TypeUtilTest.java | 12 +-- 58 files changed, 710 insertions(+), 312 deletions(-) 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 ae0ebb408..8e1624e50 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 @@ -182,7 +182,8 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La method.setAccessible(true); method.invoke(sourceViewer); } catch (InvocationTargetException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException e) { - LanguageServerCommonsActivator.logError(e, ""); + // don't log the exception + ((ISourceViewerExtension5) sourceViewer).updateCodeMinings(); } } else { ((ISourceViewerExtension5) sourceViewer).updateCodeMinings(); @@ -312,7 +313,7 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La JavadocResponse response = new JavadocResponse(); try { String content = JavadocUtils.javadoc(JavaDoc2MarkdownConverter::getMarkdownContentReader, - URI.create(params.getProjectUri()), params.getBindingKey()); + URI.create(params.getProjectUri()), params.getBindingKey(), JavaDataParams.isLookInOtherProjects(params)); response.setContent(content); } catch (Exception e) { LanguageServerCommonsActivator.logError(e, "Failed getting javadoc for " + params.toString()); @@ -347,7 +348,7 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La @Override public CompletableFuture javaType(JavaDataParams params) { - JavaTypeResponse response = new JavaTypeResponse(JAVA_DATA.typeData(params.getProjectUri(), params.getBindingKey())); + JavaTypeResponse response = new JavaTypeResponse(JAVA_DATA.typeData(params.getProjectUri(), params.getBindingKey(), JavaDataParams.isLookInOtherProjects(params))); return CompletableFuture.completedFuture(response); } @@ -355,7 +356,7 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La public CompletableFuture javadocHoverLink(JavaDataParams params) { JavadocHoverLinkResponse response = new JavadocHoverLinkResponse(null); try { - IJavaElement element = JavaData.findElement(URI.create(params.getProjectUri()), params.getBindingKey()); + IJavaElement element = JavaData.findElement(URI.create(params.getProjectUri()), params.getBindingKey(), JavaDataParams.isLookInOtherProjects(params)); if (element != null) { response.setLink(JavaElementLinks.createURI(JavaElementLinks.OPEN_LINK_SCHEME, element)); } 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 ed35a83c4..5370dca08 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2018 Pivotal, Inc. + * Copyright (c) 2017, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -90,20 +90,26 @@ public class GradleProjectClasspath implements IClasspath { for (EclipseProjectDependency dep : project.getProjectDependencies()) { EclipseProject peer = findPeer(root, dep.getTargetProject().getName()); if (peer!=null) { - entries.add(new CPE(Classpath.ENTRY_KIND_BINARY, - peer.getProjectDirectory().toPath().resolve(peer.getOutputLocation().getPath()).toString() - )); + for (EclipseSourceDirectory sf : peer.getSourceDirectories()) { + entries.add(createSourceCPE(peer, sf)); + } } } for (EclipseSourceDirectory sf : project.getSourceDirectories()) { - File sourceFolder = sf.getDirectory(); - String of = sf.getOutput(); - entries.add(CPE.source(sourceFolder.getAbsoluteFile(), new File(project.getProjectDirectory(), of))); + CPE cpe = createSourceCPE(project, sf); + cpe.setOwn(true); + entries.add(cpe); } return entries.build(); } } + private static CPE createSourceCPE(EclipseProject project, EclipseSourceDirectory sf) { + File sourceFolder = sf.getDirectory(); + String of = sf.getOutput(); + return CPE.source(sourceFolder.getAbsoluteFile(), new File(project.getProjectDirectory(), of)); + } + private EclipseProject findPeer(EclipseProject root, String name) { return root.getChildren().stream().filter(p -> p.getName().equals(name)).findFirst().orElse(null); } diff --git a/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectFinder.java b/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectFinder.java index 2eb8a1024..a1bf7839c 100644 --- a/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectFinder.java +++ b/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectFinder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2018 Pivotal, Inc. + * Copyright (c) 2017, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,6 +14,7 @@ import java.io.File; import java.nio.file.FileSystems; import java.nio.file.PathMatcher; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.Optional; @@ -23,19 +24,19 @@ import org.springframework.ide.vscode.commons.util.FileUtils; /** * Finder for Gradle Projects - * + * * @author Alex Boyko * */ public class GradleProjectFinder extends FileBasedJavaProjectFinder { - + private static List PATH_MATCHERS = Arrays.asList( FileSystems.getDefault().getPathMatcher("glob:**/" + GradleCore.GRADLE_BUILD_FILE), FileSystems.getDefault().getPathMatcher("glob:" + GradleCore.GLOB_GRADLE_FILE) ); - + private GradleProjectCache cache; - + public GradleProjectFinder(GradleProjectCache cache) { super(); this.cache = cache; @@ -50,4 +51,9 @@ public class GradleProjectFinder extends FileBasedJavaProjectFinder { protected Optional findProjectByName(String name) { return cache.projectByName(name); } + + @Override + public Collection all() { + return cache.all(); + } } 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 e7a20c4af..ba9b2b5b2 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -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 JavaDataParams(projectUri, element.getBindingKey())).get(10, TimeUnit.SECONDS); + JavadocResponse response = client.javadoc(new JavaDataParams(projectUri, element.getBindingKey(), false)).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/AbstractJavaProjectCache.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/AbstractJavaProjectCache.java index 723912e12..8a9764d7f 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/AbstractJavaProjectCache.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/AbstractJavaProjectCache.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2018 Pivotal, Inc. + * Copyright (c) 2017, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,6 +10,7 @@ *******************************************************************************/ package org.springframework.ide.vscode.commons.languageserver.java; +import java.util.Collection; import java.util.Optional; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; @@ -21,29 +22,28 @@ import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.languageserver.Sts4LanguageServer; import org.springframework.ide.vscode.commons.util.FileObserver; import org.springframework.ide.vscode.commons.util.ListenerList; -import org.springframework.ide.vscode.commons.util.Log; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; /** * Abstract implementation of java project cache indexed by keys - * + * * @author Alex Boyko * * @param key class * @param

project class */ public abstract class AbstractJavaProjectCache implements JavaProjectCache { - + private static final Logger log = LoggerFactory.getLogger(AbstractJavaProjectCache.class); - + protected Sts4LanguageServer server; private ListenerList listeners = new ListenerList<>(); protected Cache cache = CacheBuilder.newBuilder().build(); - + public AbstractJavaProjectCache(Sts4LanguageServer server) { this.server = server; } @@ -70,16 +70,16 @@ public abstract class AbstractJavaProjectCache implem } } } catch (ExecutionException e) { - Log.log(e); + log.error("", e); return null; } } return null; } - + public Optional projectByName(String name) { ConcurrentMap map = cache.asMap(); - + for (P project : map.values()) { if (project != null && project.getElementName().equals(name)) { return Optional.of(project); @@ -88,11 +88,11 @@ public abstract class AbstractJavaProjectCache implem return Optional.empty(); } - + abstract protected P createProject(K key) throws Exception; - + protected void attachListeners(K key, P project) { - + } @Override @@ -105,17 +105,17 @@ public abstract class AbstractJavaProjectCache implem public void removeListener(Listener listener) { listeners.remove(listener); } - + final protected void notifyProjectCreated(P project) { log.debug("project created {}", project); listeners.forEach(l -> l.created(project)); } - + final protected void notifyProjectChanged(P project) { log.debug("project changed {}", project); listeners.forEach(l -> l.changed(project)); } - + final protected void notifyProjectDeleted(P project) { log.debug("project deleted {}", project); listeners.forEach(l -> l.deleted(project)); @@ -124,4 +124,8 @@ public abstract class AbstractJavaProjectCache implem final protected FileObserver getFileObserver() { return server.getWorkspaceService().getFileObserver(); } + + final public Collection all() { + return cache.asMap().values(); + } } diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/CompositeJavaProjectFinder.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/CompositeJavaProjectFinder.java index 73dc1136c..922957182 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/CompositeJavaProjectFinder.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/CompositeJavaProjectFinder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. + * Copyright (c) 2017, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -19,32 +19,34 @@ import java.util.Optional; import org.eclipse.lsp4j.TextDocumentIdentifier; import org.springframework.ide.vscode.commons.java.IJavaProject; +import com.google.common.collect.ImmutableList; + /** * Composite project manager that acts a single project manager but consists of many project managers - * + * * @author Alex Boyko * */ public class CompositeJavaProjectFinder implements JavaProjectFinder { - + private final List projectFinders; - + public CompositeJavaProjectFinder(Collection projectFinders) { this.projectFinders = new ArrayList<>(projectFinders); } - + public CompositeJavaProjectFinder() { this(Collections.emptyList()); } - + public boolean addJavaProjectFinder(JavaProjectFinder javaProjectFinder) { return projectFinders.add(javaProjectFinder); } - + public boolean removeJavaProjectFinder(JavaProjectFinder javaProjectFinder) { return projectFinders.remove(javaProjectFinder); } - + @Override public Optional find(TextDocumentIdentifier doc) { for (JavaProjectFinder finder : projectFinders) { @@ -56,4 +58,13 @@ public class CompositeJavaProjectFinder implements JavaProjectFinder { return Optional.empty(); } + @Override + public Collection all() { + ImmutableList.Builder builder = ImmutableList.builder(); + for (JavaProjectFinder projectFinder : projectFinders) { + builder.addAll(projectFinder.all()); + } + return builder.build(); + } + } diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectFinder.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectFinder.java index 095302477..18dca4f42 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectFinder.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectFinder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2017 Pivotal, Inc. + * Copyright (c) 2016, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,9 +10,10 @@ *******************************************************************************/ package org.springframework.ide.vscode.commons.languageserver.java; +import java.util.Collection; import java.util.Optional; -import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; +import java.util.stream.Collectors; import org.eclipse.lsp4j.TextDocumentIdentifier; import org.springframework.ide.vscode.commons.java.IJavaProject; @@ -28,13 +29,31 @@ public interface JavaProjectFinder { Optional find(TextDocumentIdentifier doc); + Collection all(); + default JavaProjectFinder filter(Predicate acceptWhen) { - return doc -> this.find(doc).flatMap(jp -> { - if (acceptWhen.test(jp)) { - return Optional.of(jp); + + final JavaProjectFinder delegate = this; + + return new JavaProjectFinder() { + + @Override + public Optional find(TextDocumentIdentifier doc) { + return delegate.find(doc).flatMap(jp -> { + if (acceptWhen.test(jp)) { + return Optional.of(jp); + } + return Optional.empty(); + }); } - return Optional.empty(); - }); + + @Override + public Collection all() { + return delegate.all().stream().filter(acceptWhen).collect(Collectors.toList()); + } + + }; + } } diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/Classpath.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/Classpath.java index 4926a0cbf..0706e7a2d 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/Classpath.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/Classpath.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -57,6 +57,7 @@ public class Classpath { private URL sourceContainerUrl; private URL javadocContainerUrl; private boolean isSystem = false; + private boolean isOwn = false; public String getOutputFolder() { return outputFolder; @@ -127,10 +128,19 @@ public class Classpath { this.isSystem = isSystem; } + public boolean isOwn() { + return isOwn; + } + + public void setOwn(boolean isOwn) { + this.isOwn = isOwn; + } + @Override public int hashCode() { final int prime = 31; int result = 1; + result = prime * result + (isOwn ? 1231 : 1237); result = prime * result + (isSystem ? 1231 : 1237); result = prime * result + ((javadocContainerUrl == null) ? 0 : javadocContainerUrl.hashCode()); result = prime * result + ((kind == null) ? 0 : kind.hashCode()); @@ -149,6 +159,8 @@ public class Classpath { if (getClass() != obj.getClass()) return false; CPE other = (CPE) obj; + if (isOwn != other.isOwn) + return false; if (isSystem != other.isSystem) return false; if (javadocContainerUrl == null) { @@ -181,12 +193,19 @@ public class Classpath { @Override public String toString() { - return "CPE [kind=" + kind + ", path=" + path + ", isSystem=" + isSystem + "]"; + return "CPE [kind=" + kind + ", path=" + path + ", outputFolder=" + outputFolder + ", sourceContainerUrl=" + + sourceContainerUrl + ", javadocContainerUrl=" + javadocContainerUrl + ", isSystem=" + isSystem + + ", isOwn=" + isOwn + "]"; } + } public static boolean isSource(CPE e) { return e!=null && Classpath.ENTRY_KIND_SOURCE.equals(e.getKind()); } + public static boolean isProjectSource(CPE e) { + return isSource(e) && e.isOwn(); + } + } \ No newline at end of file diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaDataParams.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaDataParams.java index d7810b842..2908623c6 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaDataParams.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/ls/JavaDataParams.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,11 +14,13 @@ public class JavaDataParams { private String projectUri; private String bindingKey; + private Boolean lookInOtherProjects; - public JavaDataParams(String projectUri, String bindingKey) { + public JavaDataParams(String projectUri, String bindingKey, Boolean lookInOtherProjects) { super(); this.projectUri = projectUri; this.bindingKey = bindingKey; + this.lookInOtherProjects = lookInOtherProjects; } public String getBindingKey() { @@ -37,9 +39,26 @@ public class JavaDataParams { this.projectUri = project; } + public Boolean getLookInOtherProjects() { + return lookInOtherProjects; + } + @Override public String toString() { - return "JavaDataParams [projectUri=" + projectUri + ", bindingKey=" + bindingKey + "]"; + return "JavaDataParams [projectUri=" + projectUri + ", bindingKey=" + bindingKey + ", lookInOtherProjects=" + + lookInOtherProjects + "]"; + } + + public void setLookInOtherProjects(Boolean lookInOtherProjects) { + this.lookInOtherProjects = lookInOtherProjects; + } + + public static boolean isLookInOtherProjects(JavaDataParams params) { + return isLookInOtherProjects(params.projectUri, params.getLookInOtherProjects()); + } + + public static boolean isLookInOtherProjects(String projectUri, Boolean lookInOtherProjects) { + return projectUri == null ? true : lookInOtherProjects == null ? false : lookInOtherProjects.booleanValue(); } } 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 c46bad025..2332c15e3 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 @@ -122,6 +122,7 @@ public class MavenProjectClasspath implements IClasspath { File sourceFolder = new File(project.getBuild().getSourceDirectory()); File outputFolder = new File(project.getBuild().getOutputDirectory()); CPE cpe = CPE.source(sourceFolder, outputFolder); + cpe.setOwn(true); safe(() -> { String reportingDir = project.getModel().getReporting().getOutputDirectory(); if (reportingDir!=null) { @@ -138,7 +139,9 @@ public class MavenProjectClasspath implements IClasspath { if (targetPath==null) { targetPath = project.getBuild().getOutputDirectory(); } - entries.add(CPE.source(sourceFolder, new File(targetPath))); + CPE cpe = CPE.source(sourceFolder, new File(targetPath)); + cpe.setOwn(true); + entries.add(cpe); } } { //test/resources @@ -148,13 +151,16 @@ public class MavenProjectClasspath implements IClasspath { if (targetPath==null) { targetPath = project.getBuild().getTestOutputDirectory(); } - entries.add(CPE.source(sourceFolder, targetPath==null ? null : new File(targetPath))); + CPE cpe = CPE.source(sourceFolder, targetPath==null ? null : new File(targetPath)); + cpe.setOwn(true); + entries.add(cpe); } } { //test/java File sourceFolder = new File(project.getBuild().getTestSourceDirectory()); File outputFolder = new File(project.getBuild().getTestOutputDirectory()); CPE cpe = CPE.source(sourceFolder, outputFolder); + cpe.setOwn(true); safe(() -> { String reportingDir = project.getModel().getReporting().getOutputDirectory(); if (reportingDir!=null) { diff --git a/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectFinder.java b/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectFinder.java index b662c072e..8e67e1777 100644 --- a/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectFinder.java +++ b/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectFinder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2018 Pivotal, Inc. + * Copyright (c) 2017, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,6 +11,7 @@ package org.springframework.ide.vscode.commons.maven.java; import java.io.File; +import java.util.Collection; import java.util.Optional; import org.springframework.ide.vscode.commons.java.IJavaProject; @@ -20,14 +21,14 @@ import org.springframework.ide.vscode.commons.util.FileUtils; /** * Finds Maven projects. Looks for pom.xml file - * + * * @author Alex Boyko * */ public class MavenProjectFinder extends FileBasedJavaProjectFinder { - + private MavenProjectCache cache; - + public MavenProjectFinder(MavenProjectCache cache) { this.cache = cache; } @@ -45,4 +46,9 @@ public class MavenProjectFinder extends FileBasedJavaProjectFinder { protected Optional findProjectByName(String name) { return cache.projectByName(name); } + + @Override + public Collection all() { + return cache.all(); + } } diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/Classpath.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/Classpath.java index 7537d8585..b146d7e75 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/Classpath.java +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/Classpath.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -59,6 +59,7 @@ public class Classpath { private URL sourceContainerUrl; private URL javadocContainerUrl; private boolean isSystem = false; + private boolean isOwn = false; public String getOutputFolder() { return outputFolder; @@ -128,11 +129,19 @@ public class Classpath { this.isSystem = isSystem; } + public boolean isOwn() { + return isOwn; + } + + public void setOwn(boolean isOwn) { + this.isOwn = isOwn; + } + @Override public String toString() { - return "CPE [kind=" + kind + ", isSystem=" + isSystem + ", path=" + path + ", outputFolder=" + outputFolder - + ", sourceContainerUrl=" + sourceContainerUrl + ", javadocContainerUrl=" + javadocContainerUrl - + "]"; + return "CPE [kind=" + kind + ", path=" + path + ", outputFolder=" + outputFolder + ", sourceContainerUrl=" + + sourceContainerUrl + ", javadocContainerUrl=" + javadocContainerUrl + ", isSystem=" + isSystem + + ", isOwn=" + isOwn + "]"; } } 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 26c278154..7431f61d5 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -81,10 +81,7 @@ public class ClasspathUtil { if (entries != null) { for (IClasspathEntry entry : entries) { try { - CPE cpe = createCpe(systemLibs, javaProject, entry); - if (cpe != null) { - cpEntries.add(cpe); - } + cpEntries.addAll(createCpes(systemLibs, javaProject, entry)); } catch (Exception e) { logger.log(e); } @@ -97,8 +94,8 @@ public class ClasspathUtil { private static AtomicBoolean enabledDownloadSources = new AtomicBoolean(false); - public static CPE createCpe(IJavaProject javaProject, IClasspathEntry entry) throws MalformedURLException, JavaModelException { - return createCpe(getSystemLibraryPaths(javaProject), javaProject, entry); + public static List createCpes(IJavaProject javaProject, IClasspathEntry entry) throws MalformedURLException, JavaModelException { + return createCpes(getSystemLibraryPaths(javaProject), javaProject, entry); } private static void enableDownloadSources() { @@ -108,7 +105,7 @@ public class ClasspathUtil { } } - private static CPE createCpe(Set systemLibs, IJavaProject javaProject, IClasspathEntry entry) + private static List createCpes(Set systemLibs, IJavaProject javaProject, IClasspathEntry entry) throws MalformedURLException, JavaModelException { String kind = toContentKind(entry); switch (kind) { @@ -127,52 +124,64 @@ public class ClasspathUtil { // // } } - return cpe; + return Collections.singletonList(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()); - } + return resolveDependencyProjectCPEs(projectPath); + } else if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { + CPE cpe = createSourceCPE(javaProject, entry); + cpe.setOwn(true); + return cpe == null ? null : Collections.singletonList(cpe); } - break; } default: break; } + return Collections.emptyList(); + } + + private static CPE createSourceCPE(IJavaProject javaProject, IClasspathEntry entry) throws JavaModelException { + 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()); + } return null; } - private static CPE resolveProjectOutputFolder(IPath projectPath) throws JavaModelException { + private static List resolveDependencyProjectCPEs(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()); + IClasspathEntry[] rawClasspath = jp.getRawClasspath(); + ArrayList cpes = new ArrayList<>(rawClasspath.length); + for (IClasspathEntry entry : rawClasspath) { + if (toContentKind(entry) == Classpath.ENTRY_KIND_SOURCE && entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { + CPE cpe = createSourceCPE(jp, entry); + if (cpe != null) { + cpes.add(cpe); + } + } } + return cpes; } } - return null; + return Collections.emptyList(); } - + private static IPath resolveWorkspacePath(IPath path) { if (path.segmentCount()>0) { String projectName = path.segment(0); 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 index 3776b0c9f..dc5caa14c 100644 --- 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -13,8 +13,10 @@ package org.springframework.tooling.jdt.ls.commons.java; import java.net.MalformedURLException; import java.net.URI; import java.util.HashMap; +import java.util.List; import java.util.Map; +import org.eclipse.core.runtime.Assert; import org.eclipse.jdt.core.IAnnotation; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IField; @@ -29,6 +31,7 @@ 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.Classpath.CPE; 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; @@ -47,9 +50,9 @@ public class JavaData { this.logger = logger; } - public TypeData typeData(String projectUri, String bindingKey) { + public TypeData typeData(String projectUri, String bindingKey, boolean lookInOtherProjects) { try { - IJavaElement element = findElement(URI.create(projectUri), bindingKey); + IJavaElement element = findElement(projectUri == null ? null : URI.create(projectUri), bindingKey, lookInOtherProjects); if (element instanceof IType) { return createTypeData((IType) element); } @@ -59,12 +62,20 @@ public class JavaData { return null; } - public static IJavaElement findElement(URI projectUri, String bindingKey) throws Exception { - IJavaProject javaProject = ResourceUtils.getJavaProject(projectUri); - if (javaProject != null) { - return findElement(javaProject, bindingKey); + public static IJavaElement findElement(URI projectUri, String bindingKey, boolean lookInOtherProjects) throws Exception { + IJavaProject javaProject = projectUri == null ? null : ResourceUtils.getJavaProject(projectUri); + IJavaElement element = javaProject == null ? null : findElement(javaProject, bindingKey); + if (lookInOtherProjects && element == null) { + for (IJavaProject jp : ResourceUtils.allJavaProjects()) { + if (jp != javaProject) { + element = findElement(jp, bindingKey); + if (element != null) { + break; + } + } + } } - return null; + return element; } private static IJavaElement findElement(IJavaProject project, String bindingKey) { @@ -259,7 +270,11 @@ public class JavaData { try { IClasspathEntry entry = packageFragmentRoot.getRawClasspathEntry(); if (entry != null) { - data.setCpe(ClasspathUtil.createCpe(packageFragmentRoot.getJavaProject(), entry)); + List cpes = ClasspathUtil.createCpes(packageFragmentRoot.getJavaProject(), entry); + Assert.isTrue(cpes.size() < 2); + if (!cpes.isEmpty()) { + data.setCpe(cpes.get(0)); + } } } catch (JavaModelException | MalformedURLException e) { logger.log(e); diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaDataParams.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaDataParams.java index e5ab6380f..4b62d2832 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaDataParams.java +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/java/JavaDataParams.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,6 +14,7 @@ public class JavaDataParams { private String projectUri; private String bindingKey; + private Boolean lookInOtherProjects; public JavaDataParams(String projectUri, String bindingKey) { super(); @@ -37,9 +38,26 @@ public class JavaDataParams { this.projectUri = project; } + public Boolean getLookInOtherProjects() { + return lookInOtherProjects; + } + @Override public String toString() { - return "JavaDataParams [projectUri=" + projectUri + ", bindingKey=" + bindingKey + "]"; + return "JavaDataParams [projectUri=" + projectUri + ", bindingKey=" + bindingKey + ", lookInOtherProjects=" + + lookInOtherProjects + "]"; + } + + public void setLookInOtherProjects(Boolean lookInOtherProjects) { + this.lookInOtherProjects = lookInOtherProjects; + } + + public static boolean isLookInOtherProjects(JavaDataParams params) { + return isLookInOtherProjects(params.projectUri, params.getLookInOtherProjects()); + } + + public static boolean isLookInOtherProjects(String projectUri, Boolean lookInOtherProjects) { + return projectUri == null ? true : lookInOtherProjects == null ? false : lookInOtherProjects.booleanValue(); } } 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 e03ea7f2d..0bdf9c91a 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -39,8 +39,8 @@ public class JavadocUtils { return null; } - public static final String javadoc(Function readerProvider, URI projectUri, String bindingKey) throws Exception { - IJavaElement element = JavaData.findElement(projectUri, bindingKey); + public static final String javadoc(Function readerProvider, URI projectUri, String bindingKey, boolean lookInOtherProjects) throws Exception { + IJavaElement element = JavaData.findElement(projectUri, bindingKey, lookInOtherProjects); return computeJavadoc(readerProvider, element); } 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 c8c394f7c..5dacd5b8d 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,13 +12,16 @@ package org.springframework.tooling.jdt.ls.commons.resources; import java.io.File; import java.net.URI; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.Optional; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; @@ -56,6 +59,24 @@ public final class ResourceUtils { throw new Exception("Resolve classpath: unable to resolve a Java project from : " + resourceUri); } + + public static Collection allJavaProjects() { + IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); + ArrayList javaProjects = new ArrayList<>(projects.length); + for (IProject project : projects) { + try { + if (project.isAccessible() && project.hasNature(JavaCore.NATURE_ID)) { + IJavaProject javaProject = JavaCore.create(project); + if (javaProject != null) { + javaProjects.add(javaProject); + } + } + } catch (CoreException e) { + // ignore + } + } + return javaProjects; + } /** * Returns the resource URI, IFF it exists. Throws exception if it doesn't exist. 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 index d941c3a47..565b9871b 100644 --- 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -17,6 +17,7 @@ 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.JavaDataParams; import org.springframework.tooling.jdt.ls.commons.java.JavaTypeResponse; public class JavaTypeHanlder implements IDelegateCommandHandler { @@ -30,7 +31,8 @@ public class JavaTypeHanlder implements IDelegateCommandHandler { 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)); + Boolean lookInOtherProjects = (Boolean) obj.get("lookInOtherProjects"); + return new JavaTypeResponse(JAVA_DATA.typeData(uri, bindingKey, JavaDataParams.isLookInOtherProjects(uri, lookInOtherProjects))); } diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/src/org/springframework/tooling/jdt/ls/extension/JavadocHandler.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/src/org/springframework/tooling/jdt/ls/extension/JavadocHandler.java index 347442046..1dca81b5c 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/src/org/springframework/tooling/jdt/ls/extension/JavadocHandler.java +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.extension/src/org/springframework/tooling/jdt/ls/extension/JavadocHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -18,6 +18,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.ls.core.internal.IDelegateCommandHandler; import org.eclipse.jdt.ls.core.internal.javadoc.JavadocContentAccess2; import org.springframework.tooling.jdt.ls.commons.Logger; +import org.springframework.tooling.jdt.ls.commons.java.JavaDataParams; import org.springframework.tooling.jdt.ls.commons.javadoc.JavadocResponse; import org.springframework.tooling.jdt.ls.commons.javadoc.JavadocUtils; @@ -29,7 +30,9 @@ public class JavadocHandler implements IDelegateCommandHandler { String uri = (String) obj.get("projectUri"); URI projectUri = URI.create(uri); String bindingKey = (String) obj.get("bindingKey"); - String content = JavadocUtils.javadoc(JavadocContentAccess2::getMarkdownContentReader, projectUri, bindingKey); + Boolean lookInOtherProjects = (Boolean) obj.get("lookInOtherProjects"); + String content = JavadocUtils.javadoc(JavadocContentAccess2::getMarkdownContentReader, projectUri, bindingKey, + JavaDataParams.isLookInOtherProjects(uri, lookInOtherProjects)); JavadocResponse response = new JavadocResponse(); response.setContent(content); return response; 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 index 42f2e08ff..6d93c6dd0 100644 --- 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -31,9 +31,11 @@ public class JavadocHoverLinkHandler implements IDelegateCommandHandler { Map obj = (Map) arguments.get(0); String uri = (String) obj.get("projectUri"); String bindingKey = (String) obj.get("bindingKey"); + Boolean lookInOtherProjectsObj = (Boolean) obj.get("lookInOtherProjects"); + boolean lookInOtherProjects = uri == null ? true : lookInOtherProjectsObj == null ? false : lookInOtherProjectsObj.booleanValue(); JavadocHoverLinkResponse response = new JavadocHoverLinkResponse(null); try { - IJavaElement element = JavaData.findElement(URI.create(uri), bindingKey); + IJavaElement element = JavaData.findElement(uri == null ? null : URI.create(uri), bindingKey, lookInOtherProjects); if (element != null) { // Bug in JDT server one '(' not encoded while everything else in the query is // encoded 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 927695d71..e895d7f25 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -80,10 +80,10 @@ public class BootLanguagServerBootApp { return new ValueProviderRegistry(); } - @Bean InitializingBean initializeValueProviders(ValueProviderRegistry r, @Qualifier("adHocProperties") ProjectBasedPropertyIndexProvider adHocProperties) { + @Bean InitializingBean initializeValueProviders(ValueProviderRegistry r, @Qualifier("adHocProperties") ProjectBasedPropertyIndexProvider adHocProperties, SourceLinks sourceLinks) { return () -> { - r.def("logger-name", LoggerNameProvider.factory(adHocProperties)); - r.def("class-reference", ClassReferenceProvider.FACTORY); + r.def("logger-name", LoggerNameProvider.factory(adHocProperties, sourceLinks)); + r.def("class-reference", ClassReferenceProvider.factory(sourceLinks)); }; } @@ -93,8 +93,8 @@ public class BootLanguagServerBootApp { } @ConditionalOnMissingClass("org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness") - @Bean SourceLinks sourceLinks(SimpleLanguageServer server, CompilationUnitCache cuCache) { - return SourceLinkFactory.createSourceLinks(server, cuCache); + @Bean SourceLinks sourceLinks(SimpleLanguageServer server, CompilationUnitCache cuCache, BootLanguageServerParams params) { + return SourceLinkFactory.createSourceLinks(server, cuCache, params.projectFinder); } @Bean CompilationUnitCache cuCache(BootLanguageServerParams params, SimpleTextDocumentService documents) { @@ -133,13 +133,13 @@ public class BootLanguagServerBootApp { return YamlStructureProvider.DEFAULT; } - @Bean YamlAssistContextProvider yamlAssistContextProvider(BootLanguageServerParams params, JavaElementLocationProvider javaElementLocationProvider) { + @Bean YamlAssistContextProvider yamlAssistContextProvider(BootLanguageServerParams params, JavaElementLocationProvider javaElementLocationProvider, SourceLinks sourceLinks) { return new YamlAssistContextProvider() { @Override public YamlAssistContext getGlobalAssistContext(YamlDocument ydoc) { IDocument doc = ydoc.getDocument(); FuzzyMap index = params.indexProvider.getIndex(doc); - return ApplicationYamlAssistContext.global(ydoc, index, new PropertyCompletionFactory(), params.typeUtilProvider.getTypeUtil(doc), RelaxedNameConfig.COMPLETION_DEFAULTS, javaElementLocationProvider); + return ApplicationYamlAssistContext.global(ydoc, index, new PropertyCompletionFactory(), params.typeUtilProvider.getTypeUtil(sourceLinks, doc), RelaxedNameConfig.COMPLETION_DEFAULTS, javaElementLocationProvider); } }; } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerInitializer.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerInitializer.java index 74e8b294e..2354dbb0b 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerInitializer.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerInitializer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -70,7 +70,7 @@ public class BootLanguageServerInitializer implements InitializingBean { //TODO: ComposableLanguageServer object instance serves no purpose anymore. The constructor really just contains // some server intialization code. Migrate that code and get rid of the ComposableLanguageServer class CompositeLanguageServerComponents.Builder builder = new CompositeLanguageServerComponents.Builder(); - builder.add(new BootPropertiesLanguageServerComponents(server, params, javaElementLocationProvider, parser, yamlStructureProvider, yamlAssistContextProvider)); + builder.add(new BootPropertiesLanguageServerComponents(server, params, javaElementLocationProvider, parser, yamlStructureProvider, yamlAssistContextProvider, sourceLinks)); builder.add(new BootJavaLanguageServerComponents(server, params, sourceLinks, cuCache, adHocProperties)); components = builder.build(server); params.projectObserver.addListener(reconcileOpenDocuments(server, components)); 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 8e476c714..09083fda5 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 @@ -13,10 +13,12 @@ package org.springframework.ide.vscode.boot.app; import java.nio.file.Paths; import java.time.Duration; import java.util.Arrays; +import java.util.Collection; import java.util.Optional; import org.eclipse.lsp4j.TextDocumentIdentifier; import org.springframework.ide.vscode.boot.java.handlers.RunningAppProvider; +import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.boot.java.utils.SpringLiveHoverWatchdog; import org.springframework.ide.vscode.boot.jdt.ls.JavaProjectsService; import org.springframework.ide.vscode.boot.jdt.ls.JavaProjectsServiceWithFallback; @@ -101,7 +103,7 @@ public class BootLanguageServerParams { jdtProjectCache.filter(project -> SpringProjectUtil.isBootProject(project) || SpringProjectUtil.isSpringProject(project)), jdtProjectCache, indexProvider, - (IDocument doc) -> new TypeUtil(jdtProjectCache.find(new TextDocumentIdentifier(doc.getUri()))), + (SourceLinks sourceLinks, IDocument doc) -> new TypeUtil(sourceLinks, jdtProjectCache.find(new TextDocumentIdentifier(doc.getUri()))), RunningAppProvider.createDefault(server), SpringLiveHoverWatchdog.DEFAULT_INTERVAL ); @@ -141,6 +143,11 @@ public class BootLanguageServerParams { public IJavadocProvider javadocProvider(String projectUri, CPE cpe) { return javadocService.javadocProvider(projectUri, cpe); } + + @Override + public Collection all() { + return javaProjectFinder.all(); + } }; } @@ -164,7 +171,7 @@ public class BootLanguageServerParams { javaProjectFinder.filter(project -> SpringProjectUtil.isBootProject(project) || SpringProjectUtil.isSpringProject(project)), projectObserver, indexProvider, - (IDocument doc) -> new TypeUtil(javaProjectFinder.find(new TextDocumentIdentifier(doc.getUri()))), + (SourceLinks sourceLinks, IDocument doc) -> new TypeUtil(sourceLinks, javaProjectFinder.find(new TextDocumentIdentifier(doc.getUri()))), RunningAppProvider.NULL, SpringLiveHoverWatchdog.DEFAULT_INTERVAL ); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/PropertiesJavaDefinitionHandler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/PropertiesJavaDefinitionHandler.java index 47b923fb2..7327b9e3a 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/PropertiesJavaDefinitionHandler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/PropertiesJavaDefinitionHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -18,6 +18,7 @@ import org.eclipse.lsp4j.TextDocumentPositionParams; import org.gradle.internal.impldep.com.google.common.collect.ImmutableList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ide.vscode.boot.java.links.JavaElementLocationProvider; +import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.boot.metadata.PropertyInfo; import org.springframework.ide.vscode.boot.metadata.types.Type; import org.springframework.ide.vscode.boot.metadata.types.TypeUtil; @@ -46,6 +47,9 @@ public class PropertiesJavaDefinitionHandler implements DefinitionHandler, Langu @Autowired private JavaElementLocationProvider javaElementLocationProvider; + @Autowired + private SourceLinks sourceLinks; + @Autowired private BootLanguageServerParams params; @@ -53,7 +57,7 @@ public class PropertiesJavaDefinitionHandler implements DefinitionHandler, Langu public List handle(TextDocumentPositionParams position) { try { TextDocument doc = documents.get(position); - TypeUtil typeUtil = params.typeUtilProvider.getTypeUtil(doc); + TypeUtil typeUtil = params.typeUtilProvider.getTypeUtil(sourceLinks, doc); FuzzyMap index = params.indexProvider.getIndex(doc); int offset; offset = doc.toOffset(position.getPosition()); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/autowired/AutowiredHoverProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/autowired/AutowiredHoverProvider.java index 3ecfc0562..a87d920f5 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/autowired/AutowiredHoverProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/autowired/AutowiredHoverProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2018 Pivotal, Inc. + * Copyright (c) 2017, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -264,7 +264,7 @@ public class AutowiredHoverProvider implements HoverProvider { } private static boolean isCompatibleBeanType(IJavaProject jp, LiveBean bean, String bindingQualifiedName) { - String rawLiveBeanFqName = bean.getType(); + String rawLiveBeanFqName = bean.getType(true); int idx = rawLiveBeanFqName.indexOf('<'); // Trim the generic parameters part if it's present String liveBeanTypeFQName = idx < 0 ? rawLiveBeanFqName : rawLiveBeanFqName.substring(0, idx); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaHoverProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaHoverProvider.java index c722a19f7..e96d30b50 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaHoverProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaHoverProvider.java @@ -10,9 +10,11 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.handlers; +import java.io.File; import java.net.URI; import java.util.Collection; import java.util.LinkedHashSet; +import java.util.List; import java.util.Optional; import org.eclipse.jdt.core.dom.ASTNode; @@ -42,6 +44,7 @@ import org.springframework.ide.vscode.commons.java.IClasspath; import org.springframework.ide.vscode.commons.java.IClasspathUtil; 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.ls.Classpath; import org.springframework.ide.vscode.commons.languageserver.util.HoverHandler; import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService; import org.springframework.ide.vscode.commons.util.text.DocumentRegion; @@ -105,14 +108,28 @@ public class BootJavaHoverProvider implements HoverHandler { if (!hasActuatorDependency(project.get())) { // double check the running apps in case there is a non-boot app running with live beans enabled boolean nonBootLiveBeansAround = false; + boolean onAppsClasspath = false; for (SpringBootApp bootApp : runningBootApps) { if (bootApp.providesNonBootLiveBeans()) { nonBootLiveBeansAround = true; break; + } else { + try { + List binaryRoots = IClasspathUtil.getBinaryRoots(project.get().getClasspath(), Classpath::isSource); + for (String path : bootApp.getClasspath()) { + File file = new File(path); + if (binaryRoots.contains(file)) { + onAppsClasspath = true; + break; + } + } + } catch (Exception e) { + logger.error("", e); + } } } - if (!nonBootLiveBeansAround) { + if (!nonBootLiveBeansAround && !onAppsClasspath) { return new CodeLens[0]; } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AbstractSourceLinks.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AbstractSourceLinks.java index 035a91c77..d7ba09a92 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AbstractSourceLinks.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AbstractSourceLinks.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,7 +14,6 @@ import java.io.File; import java.net.URI; import java.net.URISyntaxException; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Optional; import java.util.Stack; @@ -31,6 +30,7 @@ import org.springframework.ide.vscode.commons.java.IClasspath; import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.javadoc.TypeUrlProviderFromContainerUrl; +import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.util.text.Region; /** @@ -45,12 +45,30 @@ public abstract class AbstractSourceLinks implements SourceLinks { private CompilationUnitCache cuCache; - protected AbstractSourceLinks(CompilationUnitCache cuCache) { + private JavaProjectFinder projectFinder; + + protected AbstractSourceLinks(CompilationUnitCache cuCache, JavaProjectFinder projectFinder) { this.cuCache = cuCache; + this.projectFinder = projectFinder; } @Override public Optional sourceLinkUrlForFQName(IJavaProject project, String fqName) { + Optional url = project == null ? Optional.empty() : getSourceLinkUrlForFQName(project, fqName); + if (!url.isPresent()) { + for (IJavaProject jp : projectFinder.all()) { + if (jp != project) { + url = getSourceLinkUrlForFQName(jp, fqName); + if (url.isPresent()) { + break; + } + } + } + } + return url; + } + + private Optional getSourceLinkUrlForFQName(IJavaProject project, String fqName) { IJavaModuleData classpathResource = project.getIndex().findClasspathResourceContainer(fqName); if (classpathResource != null) { File file = classpathResource.getContainer(); @@ -64,17 +82,10 @@ public abstract class AbstractSourceLinks implements SourceLinks { } @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(); + public Optional sourceLinkUrlForClasspathResource(String path) { + return SourceLinks.sourceLinkUrlForClasspathResource(this, projectFinder, path); } - - private Optional javaSourceLinkUrl(IJavaProject project, String fqName, IJavaModuleData folderModuleData) { IClasspath classpath = project.getClasspath(); return SourceLinks.sourceFromSourceFolder(fqName, classpath) diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AtomSourceLinks.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AtomSourceLinks.java index 29e58bf83..1d40793aa 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AtomSourceLinks.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/AtomSourceLinks.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -21,6 +21,7 @@ import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache; import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.util.text.Region; import com.google.common.base.Supplier; @@ -36,8 +37,8 @@ public class AtomSourceLinks extends AbstractSourceLinks { private static Supplier LOG = Suppliers.memoize(() -> LoggerFactory.getLogger(AbstractSourceLinks.class)); - public AtomSourceLinks(CompilationUnitCache cuCache) { - super(cuCache); + public AtomSourceLinks(CompilationUnitCache cuCache, JavaProjectFinder projectFinder) { + super(cuCache, projectFinder); } @Override diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseSourceLinks.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseSourceLinks.java index 5a9e1b3db..c0c8e4576 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseSourceLinks.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseSourceLinks.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,12 +10,10 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.links; -import java.io.File; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLEncoder; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Optional; import org.slf4j.Logger; @@ -23,6 +21,7 @@ import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.java.IMember; import org.springframework.ide.vscode.commons.java.IType; +import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; /** * Source links for Eclipse client. Eclipse IntroURLs. @@ -47,21 +46,37 @@ public class EclipseSourceLinks implements SourceLinks { private static final Logger log = LoggerFactory.getLogger(EclipseSourceLinks.class); - @Override - public Optional sourceLinkUrlForFQName(IJavaProject project, String fqName) { - return Optional.ofNullable(eclipseIntroUri(project, fqName)).map(uri -> uri.toString()); + private JavaProjectFinder projectFinder; + + public EclipseSourceLinks(JavaProjectFinder projectFinder) { + this.projectFinder = projectFinder; } @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, ".")); + public Optional sourceLinkUrlForFQName(IJavaProject project, String fqName) { + return findProjectForFQName(project, fqName).map(p -> eclipseIntroUri(p, fqName)).map(uri -> uri.toString()); + } + + private Optional findProjectForFQName(IJavaProject project, String fqName) { + if (project != null && project.findType(fqName) != null) { + return Optional.of(project); + } else { + for (IJavaProject jp : projectFinder.all()) { + if (jp != project) { + if (jp.findType(fqName) != null) { + return Optional.of(jp); + } + } + } } return Optional.empty(); } + @Override + public Optional sourceLinkUrlForClasspathResource(String path) { + return SourceLinks.sourceLinkUrlForClasspathResource(this, projectFinder, path); + } + @Override public Optional sourceLinkForResourcePath(Path path) { return Optional.ofNullable(eclipseIntroUri(path)).map(uri -> uri.toString()); 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 index b63e99757..70de5a7f2 100644 --- 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,9 +10,7 @@ *******************************************************************************/ 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; @@ -20,15 +18,18 @@ 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.JavaProjectFinder; 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; + private JavaProjectFinder projectFinder; - public JavaServerSourceLinks(SimpleLanguageServer server) { + public JavaServerSourceLinks(SimpleLanguageServer server, JavaProjectFinder projectFinder) { this.server = server; + this.projectFinder = projectFinder; } @Override @@ -37,7 +38,8 @@ public class JavaServerSourceLinks implements SourceLinks { bindingKey.append('L'); bindingKey.append(fqName.replace('.', '/')); bindingKey.append(';'); - CompletableFuture> link = server.getClient().javadocHoverLink(new JavaDataParams(project.getLocationUri().toString(), bindingKey.toString())) + String projectUri = project == null ? null : project.getLocationUri().toString(); + CompletableFuture> link = server.getClient().javadocHoverLink(new JavaDataParams(projectUri, bindingKey.toString(), true)) .thenApply(response -> Optional.ofNullable(response.getLink())); try { return link.get(10, TimeUnit.SECONDS); @@ -48,13 +50,8 @@ public class JavaServerSourceLinks implements SourceLinks { } @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(); + public Optional sourceLinkUrlForClasspathResource(String path) { + return SourceLinks.sourceLinkUrlForClasspathResource(this, projectFinder, path); } @Override 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 391cf1492..988d7f15a 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -13,9 +13,9 @@ package org.springframework.ide.vscode.boot.java.links; import java.nio.file.Path; import java.util.Optional; -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.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.languageserver.util.LspClient; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; @@ -35,7 +35,7 @@ public final class SourceLinkFactory { } @Override - public Optional sourceLinkUrlForClasspathResource(IJavaProject project, String path) { + public Optional sourceLinkUrlForClasspathResource(String path) { return Optional.empty(); } @@ -51,26 +51,20 @@ public final class SourceLinkFactory { * @param server the boot LS * @return appropriate source links object */ - public static SourceLinks createSourceLinks(SimpleLanguageServer server, CompilationUnitCache cuCache) { + public static SourceLinks createSourceLinks(SimpleLanguageServer server, CompilationUnitCache cuCache, JavaProjectFinder projectFinder) { switch (LspClient.currentClient()) { case VSCODE: - return /*new VSCodeSourceLinks(cuCache);*/server == null ? new VSCodeSourceLinks(cuCache) :new JavaServerSourceLinks(server); + return /*new VSCodeSourceLinks(cuCache);*/server == null ? new VSCodeSourceLinks(cuCache, projectFinder) :new JavaServerSourceLinks(server, projectFinder); case THEIA: - return new VSCodeSourceLinks(cuCache); + return new VSCodeSourceLinks(cuCache, projectFinder); case ECLIPSE: - return /*new EclipseSourceLinks();*/server == null ? new EclipseSourceLinks() : new JavaServerSourceLinks(server); + return /*new EclipseSourceLinks();*/server == null ? new EclipseSourceLinks(projectFinder) : new JavaServerSourceLinks(server, projectFinder); case ATOM: - return new AtomSourceLinks(cuCache); + return new AtomSourceLinks(cuCache, projectFinder); default: return NO_SOURCE_LINKS; } } - @Deprecated - public static SourceLinks createSourceLinks(BootJavaLanguageServerComponents server) { - return server == null - ? 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/java/links/SourceLinks.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinks.java index af347170b..b918aee79 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinks.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinks.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,6 +10,7 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.links; +import java.io.File; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; @@ -18,6 +19,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Optional; +import org.eclipse.lsp4j.TextDocumentIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.commons.java.IClasspath; @@ -25,6 +27,9 @@ import org.springframework.ide.vscode.commons.java.IClasspathUtil; import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.javadoc.TypeUrlProviderFromContainerUrl; +import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath; +import org.springframework.ide.vscode.commons.languageserver.java.ls.Classpath.CPE; /** * Instance is able to provide client specific URL links to navigate to a @@ -99,6 +104,36 @@ public interface SourceLinks { return Optional.empty(); } + public static Optional sourceLinkUrlForClasspathResource(SourceLinks sourceLinks, JavaProjectFinder projectFinder, String path) { + if (projectFinder != null) { + int idx = path.lastIndexOf(CLASS); + if (idx >= 0) { + Path filePath = Paths.get(path.substring(0, idx)); + IJavaProject project = projectFinder.find(new TextDocumentIdentifier(filePath.toUri().toString())).orElse(null); + if (project != null) { + try { + for (CPE cpe : project.getClasspath().getClasspathEntries()) { + if (Classpath.isSource(cpe)) { + Path cpeBinaryPath = IClasspathUtil.binaryLocation(cpe).toPath(); + if (filePath.startsWith(cpeBinaryPath)) { + String fqName = cpeBinaryPath.relativize(filePath).toString().replace(File.separator, "."); + Optional link = sourceLinks.sourceLinkUrlForFQName(project, fqName); + if (link.isPresent()) { + return link; + } + } + } + } + } catch (Exception e) { + log.error("", e); + } + } + + } + } + return Optional.empty(); + } + /** * Creates link to source file defining the type passed with it's fully qualified name @@ -114,7 +149,7 @@ public interface SourceLinks { * @param path the path to the classpath resource * @return the link URL optional */ - Optional sourceLinkUrlForClasspathResource(IJavaProject project, String path); + Optional sourceLinkUrlForClasspathResource(String path); /** * Creates link to a file specified by it's path diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/VSCodeSourceLinks.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/VSCodeSourceLinks.java index c34b2551c..b8b9d08cc 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/VSCodeSourceLinks.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/VSCodeSourceLinks.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -17,6 +17,7 @@ import org.eclipse.jdt.core.dom.CompilationUnit; import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache; import org.springframework.ide.vscode.commons.java.IJavaModuleData; import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.util.text.Region; /** @@ -27,8 +28,8 @@ import org.springframework.ide.vscode.commons.util.text.Region; */ public class VSCodeSourceLinks extends AbstractSourceLinks { - public VSCodeSourceLinks(CompilationUnitCache cuCache) { - super(cuCache); + public VSCodeSourceLinks(CompilationUnitCache cuCache, JavaProjectFinder projectFinder) { + super(cuCache, projectFinder); } @Override diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/LiveHoverUtils.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/LiveHoverUtils.java index 9873ee7de..7f54f281d 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/LiveHoverUtils.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/LiveHoverUtils.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2018 Pivotal, Inc. + * Copyright (c) 2017, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -145,7 +145,7 @@ public class LiveHoverUtils { LiveBeansModel beansModel = app.getBeans(); if (beansModel != null) { List relevantBeans = beansModel.getBeansOfName(definedBean.getId()); - String type = definedBean.getType(); + String type = definedBean.getType(true); if (type != null) { // TODO: check if we should check for bean type rather than id that we build ourselves based on type // if (relevantBeans.isEmpty()) { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringLiveChangeDetectionWatchdog.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringLiveChangeDetectionWatchdog.java index 095120b96..635a34998 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringLiveChangeDetectionWatchdog.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringLiveChangeDetectionWatchdog.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,6 +10,8 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.utils; +import java.io.File; +import java.nio.file.Path; import java.nio.file.Paths; import java.time.Duration; import java.util.ArrayList; @@ -241,18 +243,18 @@ public class SpringLiveChangeDetectionWatchdog { for (IJavaProject project : projects) { if (SpringResource.FILE.equals(type)) { - String relativePath = SpringResource.projectRelativePath(project, path); - - if (relativePath != path && path.endsWith(SourceLinks.CLASS)) { - result = sourceLinks.sourceLinkUrlForClasspathResource(project, relativePath).get(); - break; - } else { + result = sourceLinks.sourceLinkUrlForClasspathResource(path).get(); + if (result == null) { result = sourceLinks.sourceLinkForResourcePath(Paths.get(path)).get(); - break; } + break; } else if (SpringResource.CLASS_PATH_RESOURCE.equals(type)) { - result = sourceLinks.sourceLinkUrlForClasspathResource(project, path).get(); + int idx = path.lastIndexOf(SourceLinks.CLASS); + if (idx >= 0) { + Path p = Paths.get(path.substring(0, idx)); + result = sourceLinks.sourceLinkUrlForFQName(project, p.toString().replace(File.separator, ".")).get(); + } break; } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringResource.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringResource.java index 423d8b2fb..b59efa279 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringResource.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringResource.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2018 Pivotal, Inc. + * Copyright (c) 2017, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -67,20 +67,22 @@ public class SpringResource { if (type==null) { return path; //path is just the raw text in this case } - Optional linkUrl; + Optional linkUrl = Optional.empty(); switch (type) { case FILE: - String relativePath = projectRelativePath(project, path); - if (relativePath != path && path.endsWith(SourceLinks.CLASS)) { - linkUrl = sourceLinks.sourceLinkUrlForClasspathResource(project, relativePath); - } else { + linkUrl = sourceLinks.sourceLinkUrlForClasspathResource(path); + if (!linkUrl.isPresent()) { linkUrl = sourceLinks.sourceLinkForResourcePath(Paths.get(path)); } // not a project relative path - return linkUrl.isPresent() ? Renderables.link(relativePath, linkUrl.get()).toMarkdown() + return linkUrl.isPresent() ? Renderables.link(projectRelativePath(project, path), linkUrl.get()).toMarkdown() : "`" + projectRelativePath(project, path) + "`"; case CLASS_PATH_RESOURCE: - linkUrl = sourceLinks.sourceLinkUrlForClasspathResource(project, path); + int idx = path.lastIndexOf(SourceLinks.CLASS); + if (idx >= 0) { + Path p = Paths.get(path.substring(0, idx)); + linkUrl = sourceLinks.sourceLinkUrlForFQName(project, p.toString().replace(File.separator, ".")); + } return linkUrl.isPresent() ? Renderables.link(path, linkUrl.get()).toMarkdown() : "`"+path+"`"; default: return path; 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 5689c8485..5a075d1bd 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,6 +10,7 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.jdt.ls; +import java.util.Collection; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -24,6 +25,7 @@ import org.springframework.ide.vscode.commons.util.Assert; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableList; import reactor.core.Disposable; @@ -113,4 +115,18 @@ public class JavaProjectsServiceWithFallback implements JavaProjectsService { return IJavadocProvider.NULL; } + @Override + public Collection all() { + if (mainServiceInitialized.isDone()) { + if (mainServiceInitialized.isCompletedExceptionally()) { + return fallback.get().all(); + } else { + return main.all(); + } + } else { + log.debug("find => NOT INITIALIZED YET"); + } + return ImmutableList.of(); + } + } 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 2b74615da..c59e40b91 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -210,4 +210,9 @@ public class JdtLsProjectCache implements InitializableJavaProjectsService { } }); } + + @Override + public Collection all() { + return table.values(); + } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/ClassReferenceProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/ClassReferenceProvider.java index 8932f0f9d..ac65b2410 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/ClassReferenceProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/ClassReferenceProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016-2017 Pivotal, Inc. + * Copyright (c) 2016, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -18,12 +18,14 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.boot.metadata.ValueProviderRegistry.ValueProviderStrategy; import org.springframework.ide.vscode.boot.metadata.hints.StsValueHint; import org.springframework.ide.vscode.commons.java.Flags; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.java.IType; -import org.springframework.ide.vscode.commons.util.Log; import org.springframework.ide.vscode.commons.util.StringUtil; import com.google.common.cache.Cache; @@ -40,36 +42,35 @@ import reactor.core.publisher.Flux; * @author Alex Boyko */ public class ClassReferenceProvider extends CachingValueProvider { - + + private static final Logger log = LoggerFactory.getLogger(ClassReferenceProvider.class); + /** * Default value for the 'concrete' parameter. */ private static final boolean DEFAULT_CONCRETE = true; - private static final ClassReferenceProvider UNTARGETTED_INSTANCE = new ClassReferenceProvider(null, DEFAULT_CONCRETE); + private static final ClassReferenceProvider UNTARGETTED_INSTANCE = new ClassReferenceProvider(null, DEFAULT_CONCRETE, null); - public static final Function, ValueProviderStrategy> FACTORY = applyOn( - 1, TimeUnit.MINUTES, - (params) -> { - String target = getTarget(params); - Boolean concrete = getConcrete(params); - if (target!=null || concrete!=null) { - if (concrete==null) { - concrete = DEFAULT_CONCRETE; - } - return new ClassReferenceProvider(target, concrete); - } - return UNTARGETTED_INSTANCE; - } - ); - - private static Function applyOn(long duration, TimeUnit unit, Function func) { - Cache cache = CacheBuilder.newBuilder().expireAfterAccess(duration, unit).expireAfterWrite(duration, unit).build(); - return (k) -> { + public static final Function, ValueProviderStrategy> factory(SourceLinks sourceLinks) { + long duration = 1; + TimeUnit unit = TimeUnit.MINUTES; + Cache, ValueProviderStrategy> cache = CacheBuilder.newBuilder().expireAfterAccess(duration, unit).expireAfterWrite(duration, unit).build(); + return (params) -> { try { - return cache.get(k, () -> func.apply(k)); + return cache.get(params, () -> { + String target = getTarget(params); + Boolean concrete = getConcrete(params); + if (target!=null || concrete!=null) { + if (concrete==null) { + concrete = DEFAULT_CONCRETE; + } + return new ClassReferenceProvider(target, concrete, sourceLinks); + } + return UNTARGETTED_INSTANCE; + }); } catch (ExecutionException e) { - Log.log(e); + log.error("", e); return null; } }; @@ -92,7 +93,7 @@ public class ClassReferenceProvider extends CachingValueProvider { try { return type.isInterface() || Flags.isAbstract(type.getFlags()); } catch (Exception e) { - Log.log(e); + log.error("", e); return false; } } @@ -109,7 +110,7 @@ public class ClassReferenceProvider extends CachingValueProvider { } } } catch (Exception e) { - Log.log(e); + log.error("", e); } return null; } @@ -124,9 +125,12 @@ public class ClassReferenceProvider extends CachingValueProvider { */ private boolean concrete; - private ClassReferenceProvider(String target, boolean concrete) { + private SourceLinks sourceLinks; + + private ClassReferenceProvider(String target, boolean concrete, SourceLinks sourceLinks) { this.target = target; this.concrete = concrete; + this.sourceLinks = sourceLinks; } @Override @@ -147,7 +151,7 @@ public class ClassReferenceProvider extends CachingValueProvider { .fuzzySearchTypes(query, type -> allSubclasses.contains(type)) .collectSortedList((o1, o2) -> o2.getT2().compareTo(o1.getT2())) .flatMapIterable(l -> l) - .map(t -> StsValueHint.create(javaProject, t.getT1())); + .map(t -> StsValueHint.create(sourceLinks, javaProject, t.getT1())); } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/LoggerNameProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/LoggerNameProvider.java index fb8bfb194..e0e27d22b 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/LoggerNameProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/LoggerNameProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2018 Pivotal, Inc. + * Copyright (c) 2016, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -15,8 +15,8 @@ import java.util.Collection; import java.util.Map; import java.util.SortedMap; import java.util.function.Function; -import java.util.function.Predicate; +import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.boot.metadata.ValueProviderRegistry.ValueProviderStrategy; import org.springframework.ide.vscode.boot.metadata.hints.StsValueHint; import org.springframework.ide.vscode.commons.java.IJavaProject; @@ -41,15 +41,17 @@ public class LoggerNameProvider extends CachingValueProvider { private static final String LOGGING_GROUPS_PREFIX = "logging.group."; private final ProjectBasedPropertyIndexProvider adhocProperties; private final boolean includeGroups; + private final SourceLinks sourceLinks; - public LoggerNameProvider(ProjectBasedPropertyIndexProvider adhocProperties, boolean includeGroups) { + public LoggerNameProvider(ProjectBasedPropertyIndexProvider adhocProperties, boolean includeGroups, SourceLinks sourceLinks) { this.adhocProperties = adhocProperties; this.includeGroups = includeGroups; + this.sourceLinks = sourceLinks; } - public static final Function, ValueProviderStrategy> factory(ProjectBasedPropertyIndexProvider adhocProperties) { + public static final Function, ValueProviderStrategy> factory(ProjectBasedPropertyIndexProvider adhocProperties, SourceLinks sourceLinks) { return (params) -> { - return new LoggerNameProvider(adhocProperties, (boolean) params.getOrDefault("group", true)); + return new LoggerNameProvider(adhocProperties, (boolean) params.getOrDefault("group", true), sourceLinks); }; } @@ -83,7 +85,7 @@ public class LoggerNameProvider extends CachingValueProvider { .map(t -> Tuples.of(StsValueHint.create(t.getT1()), t.getT2())), javaProject.getIndex() .fuzzySearchTypes(query, null) - .map(t -> Tuples.of(StsValueHint.create(javaProject, t.getT1()), t.getT2())) + .map(t -> Tuples.of(StsValueHint.create(sourceLinks, javaProject, t.getT1()), t.getT2())) ) .collectSortedList((o1, o2) -> o2.getT2().compareTo(o1.getT2())) .flatMapIterable(l -> l) diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/hints/StsValueHint.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/hints/StsValueHint.java index 48edecf36..84a589ad7 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/hints/StsValueHint.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/hints/StsValueHint.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2018 Pivotal, Inc. + * Copyright (c) 2016, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -15,8 +15,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.boot.configurationmetadata.Deprecation; import org.springframework.ide.vscode.boot.configurationmetadata.ValueHint; -import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents; -import org.springframework.ide.vscode.boot.java.links.SourceLinkFactory; import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.boot.metadata.types.TypeUtil; import org.springframework.ide.vscode.boot.metadata.util.DeprecationUtil; @@ -63,8 +61,8 @@ public class StsValueHint { /** * Creates a hint out of an IJavaElement. */ - public static StsValueHint create(String value, IJavaProject project, IJavaElement javaElement) { - return new StsValueHint(value, javaDocSnippet(project, javaElement), DeprecationUtil.extract(javaElement)) { + public static StsValueHint create(SourceLinks sourceLinks, String value, IJavaProject project, IJavaElement javaElement) { + return new StsValueHint(value, javaDocSnippet(sourceLinks, project, javaElement), DeprecationUtil.extract(javaElement)) { @Override public IJavaElement getJavaElement() { return javaElement; @@ -86,7 +84,7 @@ public class StsValueHint { if (jp!=null) { IType type = jp.findType(fqName); if (type!=null) { - return create(jp, type); + return create(typeUtil.getSourceLinks(), jp, type); } } } catch (Exception e) { @@ -95,8 +93,8 @@ public class StsValueHint { return null; } - public static StsValueHint create(IJavaProject project, IType klass) { - return new StsValueHint(klass.getFullyQualifiedName(), javaDocSnippet(project, klass), DeprecationUtil.extract(klass)) { + public static StsValueHint create(SourceLinks sourceLinks, IJavaProject project, IType klass) { + return new StsValueHint(klass.getFullyQualifiedName(), javaDocSnippet(sourceLinks, project, klass), DeprecationUtil.extract(klass)) { @Override public IJavaElement getJavaElement() { return klass; @@ -122,9 +120,8 @@ public class StsValueHint { return description; } - private static Renderable javaDocSnippet(IJavaProject project, IJavaElement je) { + private static Renderable javaDocSnippet(SourceLinks sourceLinks, IJavaProject project, IJavaElement je) { return Renderables.lazy(() -> { - SourceLinks sourceLinks = SourceLinkFactory.createSourceLinks((BootJavaLanguageServerComponents)null); return PropertyDocUtils.documentJavaElement(sourceLinks, project, je); }); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/types/TypeUtil.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/types/TypeUtil.java index 37a696bcd..697b90bb6 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/types/TypeUtil.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/types/TypeUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2018 Pivotal, Inc. + * Copyright (c) 2016, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -39,8 +39,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.convert.DurationStyle; import org.springframework.ide.vscode.boot.configurationmetadata.Deprecation; -import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents; -import org.springframework.ide.vscode.boot.java.links.SourceLinkFactory; import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.boot.metadata.ResourceHintProvider; import org.springframework.ide.vscode.boot.metadata.ValueProviderRegistry.ValueProviderStrategy; @@ -134,16 +132,18 @@ public class TypeUtil { } private IJavaProject javaProject; + private SourceLinks sourceLinks; - public TypeUtil(IJavaProject jp) { + public TypeUtil(SourceLinks sourceLinks, IJavaProject jp) { //Note javaProject is allowed to be null, but only in unit testing context // (This is so some tests can be run without an explicit jp needing to be created) this.javaProject = jp; + this.sourceLinks = sourceLinks; } - public TypeUtil(Optional maybeProject) { - this(maybeProject.orElse(null)); + public TypeUtil(SourceLinks sourceLinks, Optional maybeProject) { + this(sourceLinks, maybeProject.orElse(null)); } private static final Map PRIMITIVE_TYPE_NAMES = new HashMap<>(); @@ -334,10 +334,10 @@ public class TypeUtil { type.getFields().filter(f -> f.isEnumConstant()).forEach(f -> { String rawName = f.getElementName(); if (addOriginal) { - enums.add(StsValueHint.create(rawName, javaProject, f)); + enums.add(StsValueHint.create(sourceLinks, rawName, javaProject, f)); } if (addLowerCased) { - enums.add(StsValueHint.create(StringUtil.upperCaseToHyphens(rawName), javaProject, f)); + enums.add(StsValueHint.create(sourceLinks, StringUtil.upperCaseToHyphens(rawName), javaProject, f)); } }); return enums.build(); @@ -655,6 +655,10 @@ public class TypeUtil { valueHints("org.springframework.core.io.Resource", new ResourceHintProvider()); } + public SourceLinks getSourceLinks() { + return sourceLinks; + } + /** * Determine properties that are setable on object of given type. *

@@ -695,7 +699,6 @@ public class TypeUtil { //TODO: handle type parameters. if (typeFromIndex != null) { - SourceLinks sourceLinks = SourceLinkFactory.createSourceLinks((BootJavaLanguageServerComponents)null); IJavaProject project = getJavaProject(); ArrayList properties = new ArrayList<>(); getGetterMethods(typeFromIndex).forEach(m -> { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/types/TypeUtilProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/types/TypeUtilProvider.java index ab608e32e..5d559cdf2 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/types/TypeUtilProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/types/TypeUtilProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016-2017 Pivotal, Inc. + * Copyright (c) 2016, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,9 +11,10 @@ package org.springframework.ide.vscode.boot.metadata.types; +import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.commons.util.text.IDocument; @FunctionalInterface public interface TypeUtilProvider { - TypeUtil getTypeUtil(IDocument doc); + TypeUtil getTypeUtil(SourceLinks sourceLinks, IDocument doc); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/BootPropertiesLanguageServerComponents.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/BootPropertiesLanguageServerComponents.java index 91c101d7a..29b6428c4 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/BootPropertiesLanguageServerComponents.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/BootPropertiesLanguageServerComponents.java @@ -15,6 +15,7 @@ import java.util.Set; import org.springframework.ide.vscode.boot.app.BootLanguageServerParams; import org.springframework.ide.vscode.boot.java.links.JavaElementLocationProvider; +import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider; import org.springframework.ide.vscode.boot.metadata.types.TypeUtilProvider; import org.springframework.ide.vscode.boot.properties.completions.SpringPropertiesCompletionEngine; @@ -80,7 +81,7 @@ public class BootPropertiesLanguageServerComponents implements LanguageServerCom private SpringPropertiesReconcileEngine propertiesReconciler; private ApplicationYamlReconcileEngine ymlReconciler; - + private SourceLinks sourceLinks; public BootPropertiesLanguageServerComponents( SimpleLanguageServer server, @@ -88,7 +89,8 @@ public class BootPropertiesLanguageServerComponents implements LanguageServerCom JavaElementLocationProvider javaElementLocationProvider, YamlASTProvider parser, YamlStructureProvider yamlStructureProvider, - YamlAssistContextProvider yamlAssistContextProvider) { + YamlAssistContextProvider yamlAssistContextProvider, + SourceLinks sourceLinks) { this.server = server; this.parser = parser; this.indexProvider = serverParams.indexProvider; @@ -97,15 +99,16 @@ public class BootPropertiesLanguageServerComponents implements LanguageServerCom this.projectObserver = serverParams.projectObserver; this.yamlStructureProvider = yamlStructureProvider; this.yamlAssistContextProvider = yamlAssistContextProvider; + this.sourceLinks = sourceLinks; server.getClientCapabilities().thenAccept(clientCapabilities -> { CommonQuickfixes commonQuickfixes = new CommonQuickfixes(server.getQuickfixRegistry(), javaProjectFinder, clientCapabilities); this.propertiesReconciler = new SpringPropertiesReconcileEngine(indexProvider, - typeUtilProvider, new AppPropertiesQuickFixes(server.getQuickfixRegistry(), commonQuickfixes)); + typeUtilProvider, new AppPropertiesQuickFixes(server.getQuickfixRegistry(), commonQuickfixes), sourceLinks); this.ymlReconciler = new ApplicationYamlReconcileEngine(parser, indexProvider, typeUtilProvider, new AppYamlQuickfixes(server.getQuickfixRegistry(), server.getTextDocumentService(), - yamlStructureProvider, commonQuickfixes)); + yamlStructureProvider, commonQuickfixes), sourceLinks); }); indexProvider.onChange(() -> { @@ -125,7 +128,7 @@ public class BootPropertiesLanguageServerComponents implements LanguageServerCom @Override public ICompletionEngine getCompletionEngine() { - ICompletionEngine propertiesCompletions = new SpringPropertiesCompletionEngine(indexProvider, typeUtilProvider, javaProjectFinder); + ICompletionEngine propertiesCompletions = new SpringPropertiesCompletionEngine(indexProvider, typeUtilProvider, javaProjectFinder, sourceLinks); ICompletionEngine yamlCompletions = new YamlCompletionEngine(yamlStructureProvider, yamlAssistContextProvider, COMPLETION_OPTIONS); return (TextDocument document, int offset) -> { String uri = document.getUri(); @@ -142,7 +145,7 @@ public class BootPropertiesLanguageServerComponents implements LanguageServerCom @Override public HoverHandler getHoverProvider() { - HoverInfoProvider propertiesHovers = new PropertiesHoverInfoProvider(indexProvider, typeUtilProvider, javaProjectFinder); + HoverInfoProvider propertiesHovers = new PropertiesHoverInfoProvider(indexProvider, typeUtilProvider, javaProjectFinder, sourceLinks); HoverInfoProvider ymlHovers = new YamlHoverInfoProvider(parser, yamlStructureProvider, yamlAssistContextProvider); HoverInfoProvider combined = (IDocument document, int offset) -> { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/SpringPropertiesCompletionEngine.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/SpringPropertiesCompletionEngine.java index 47bd33375..a5038bc07 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/SpringPropertiesCompletionEngine.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/completions/SpringPropertiesCompletionEngine.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2018 Pivotal, Inc. + * Copyright (c) 2016, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,6 +14,7 @@ package org.springframework.ide.vscode.boot.properties.completions; import java.util.Collection; import org.springframework.ide.vscode.boot.common.PropertyCompletionFactory; +import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider; import org.springframework.ide.vscode.boot.metadata.types.TypeUtilProvider; import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine; @@ -32,15 +33,17 @@ public class SpringPropertiesCompletionEngine implements ICompletionEngine { private SpringPropertyIndexProvider indexProvider; private TypeUtilProvider typeUtilProvider; private PropertyCompletionFactory completionFactory = null; + private SourceLinks sourceLinks; /** * Constructor used in 'production'. Wires up stuff properly for running inside a normal * Eclipse runtime. */ - public SpringPropertiesCompletionEngine(SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, JavaProjectFinder projectFinder) { + public SpringPropertiesCompletionEngine(SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, JavaProjectFinder projectFinder, SourceLinks sourceLinks) { this.indexProvider = indexProvider; this.typeUtilProvider = typeUtilProvider; this.completionFactory = new PropertyCompletionFactory(); + this.sourceLinks = sourceLinks; } /** @@ -49,7 +52,7 @@ public class SpringPropertiesCompletionEngine implements ICompletionEngine { @Override public Collection getCompletions(TextDocument doc, int offset) throws BadLocationException { return new PropertiesCompletionProposalsCalculator(indexProvider.getIndex(doc), - typeUtilProvider.getTypeUtil(doc), completionFactory, doc, offset, preferLowerCaseEnums).calculate(); + typeUtilProvider.getTypeUtil(sourceLinks, doc), completionFactory, doc, offset, preferLowerCaseEnums).calculate(); } public boolean getPreferLowerCaseEnums() { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/hover/PropertiesHoverInfoProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/hover/PropertiesHoverInfoProvider.java index 2e3179176..49ab72b88 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/hover/PropertiesHoverInfoProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/hover/PropertiesHoverInfoProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016-2017 Pivotal, Inc. + * Copyright (c) 2016, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,12 +11,9 @@ package org.springframework.ide.vscode.boot.properties.hover; -import java.util.Optional; - -import org.eclipse.lsp4j.TextDocumentIdentifier; +import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider; import org.springframework.ide.vscode.boot.metadata.types.TypeUtilProvider; -import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfoProvider; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.util.Renderable; @@ -26,20 +23,22 @@ import org.springframework.ide.vscode.commons.util.text.IRegion; import reactor.util.function.Tuple2; public class PropertiesHoverInfoProvider implements HoverInfoProvider { - + private SpringPropertyIndexProvider indexProvider; private TypeUtilProvider typeUtilProvider; private JavaProjectFinder projectFinder; - - public PropertiesHoverInfoProvider(SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, JavaProjectFinder projectFinder) { + private SourceLinks sourceLinks; + + public PropertiesHoverInfoProvider(SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, JavaProjectFinder projectFinder, SourceLinks sourceLinks) { this.indexProvider = indexProvider; this.typeUtilProvider = typeUtilProvider; this.projectFinder = projectFinder; + this.sourceLinks = sourceLinks; } @Override public Tuple2 getHoverInfo(IDocument document, int offset) throws Exception { return new PropertiesHoverCalculator(indexProvider.getIndex(document), - typeUtilProvider.getTypeUtil(document), document, offset).calculate(); + typeUtilProvider.getTypeUtil(sourceLinks, document), document, offset).calculate(); } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/reconcile/SpringPropertiesReconcileEngine.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/reconcile/SpringPropertiesReconcileEngine.java index 99c16e94f..3b54a48db 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/reconcile/SpringPropertiesReconcileEngine.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/reconcile/SpringPropertiesReconcileEngine.java @@ -21,6 +21,7 @@ import java.util.regex.Pattern; import org.eclipse.lsp4j.TextDocumentIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.boot.metadata.PropertyInfo; import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndex; import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider; @@ -78,11 +79,13 @@ public class SpringPropertiesReconcileEngine implements IReconcileEngine { private TypeUtilProvider typeUtilProvider; private Parser parser = new AntlrParser(); private AppPropertiesQuickFixes quickFixes; + private SourceLinks sourceLinks; - public SpringPropertiesReconcileEngine(SpringPropertyIndexProvider provider, TypeUtilProvider typeUtilProvider, AppPropertiesQuickFixes quickFixes) { + public SpringPropertiesReconcileEngine(SpringPropertyIndexProvider provider, TypeUtilProvider typeUtilProvider, AppPropertiesQuickFixes quickFixes, SourceLinks sourceLinks) { this.fIndexProvider = provider; this.typeUtilProvider = typeUtilProvider; this.quickFixes = quickFixes; + this.sourceLinks = sourceLinks; } @Override @@ -119,7 +122,7 @@ public class SpringPropertiesReconcileEngine implements IReconcileEngine { problemCollector.accept(problemDeprecated(propertyNameRegion, validProperty, quickFixes.DEPRECATED_PROPERTY)); } int offset = validProperty.getId().length() + propertyNameRegion.getStart(); - PropertyNavigator navigator = new PropertyNavigator(doc, problemCollector, typeUtilProvider.getTypeUtil(doc), propertyNameRegion); + PropertyNavigator navigator = new PropertyNavigator(doc, problemCollector, typeUtilProvider.getTypeUtil(sourceLinks, doc), propertyNameRegion); Type valueType = navigator.navigate(offset, TypeParser.parse(validProperty.getType())); if (valueType!=null) { reconcileType(doc, valueType, pair.getValue(), problemCollector); @@ -207,7 +210,7 @@ public class SpringPropertiesReconcileEngine implements IReconcileEngine { } private void reconcileType(DocumentRegion escapedValue, Type expectType, IProblemCollector problems) { - TypeUtil typeUtil = typeUtilProvider.getTypeUtil(escapedValue.getDocument()); + TypeUtil typeUtil = typeUtilProvider.getTypeUtil(sourceLinks, escapedValue.getDocument()); ValueParser parser = typeUtil.getValueParser(expectType); if (parser!=null) { try { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/yaml/completions/ApplicationYamlAssistContext.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/yaml/completions/ApplicationYamlAssistContext.java index db5451c08..70264ff96 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/yaml/completions/ApplicationYamlAssistContext.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/yaml/completions/ApplicationYamlAssistContext.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015, 2018 Pivotal, Inc. + * Copyright (c) 2015, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -613,7 +613,7 @@ public abstract class ApplicationYamlAssistContext extends AbstractYamlAssistCon if (jes != null) { for (IJavaElement je : jes) { if (je instanceof IMember) { - SourceLinks sourceLinks = SourceLinkFactory.createSourceLinks((BootJavaLanguageServerComponents)null); + SourceLinks sourceLinks = typeUtil.getSourceLinks(); IJavaProject project = typeUtil.getJavaProject(); return PropertyDocUtils.documentJavaElement(sourceLinks, project, je); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/yaml/reconcile/ApplicationYamlReconcileEngine.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/yaml/reconcile/ApplicationYamlReconcileEngine.java index ef5392b36..2fd8f94e9 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/yaml/reconcile/ApplicationYamlReconcileEngine.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/yaml/reconcile/ApplicationYamlReconcileEngine.java @@ -12,6 +12,7 @@ package org.springframework.ide.vscode.boot.yaml.reconcile; import static org.springframework.ide.vscode.boot.yaml.reconcile.ApplicationYamlProblems.Type.YAML_SYNTAX_ERROR; +import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.boot.metadata.IndexNavigator; import org.springframework.ide.vscode.boot.metadata.PropertyInfo; import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider; @@ -30,12 +31,14 @@ public class ApplicationYamlReconcileEngine extends YamlReconcileEngine { private SpringPropertyIndexProvider indexProvider; private TypeUtilProvider typeUtilProvider; private AppYamlQuickfixes quickFixes; + private SourceLinks sourceLinks; - public ApplicationYamlReconcileEngine(YamlASTProvider astProvider, SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, AppYamlQuickfixes quickFixes) { + public ApplicationYamlReconcileEngine(YamlASTProvider astProvider, SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, AppYamlQuickfixes quickFixes, SourceLinks sourceLinks) { super(astProvider); this.indexProvider = indexProvider; this.typeUtilProvider = typeUtilProvider; this.quickFixes = quickFixes; + this.sourceLinks = sourceLinks; } @Override @@ -43,7 +46,7 @@ public class ApplicationYamlReconcileEngine extends YamlReconcileEngine { FuzzyMap index = indexProvider.getIndex(doc); if (index!=null && !index.isEmpty()) { IndexNavigator nav = IndexNavigator.with(index); - return new ApplicationYamlASTReconciler(problemCollector, nav, typeUtilProvider.getTypeUtil(doc), quickFixes); + return new ApplicationYamlASTReconciler(problemCollector, nav, typeUtilProvider.getTypeUtil(sourceLinks, doc), quickFixes); } return null; } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/bootiful/PropertyEditorTestConf.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/bootiful/PropertyEditorTestConf.java index f0733d9c7..ff825842b 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/bootiful/PropertyEditorTestConf.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/bootiful/PropertyEditorTestConf.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -59,7 +59,7 @@ public class PropertyEditorTestConf { @Bean BootLanguageServerParams serverParams(SimpleLanguageServer server, PropertyIndexHarness indexHarness) { JavaProjectFinder projectFinder = indexHarness.getProjectFinder(); - TypeUtilProvider typeUtilProvider = (IDocument doc) -> new TypeUtil(projectFinder.find(new TextDocumentIdentifier(doc.getUri()))); + TypeUtilProvider typeUtilProvider = (SourceLinks sourceLinks, IDocument doc) -> new TypeUtil(sourceLinks, projectFinder.find(new TextDocumentIdentifier(doc.getUri()))); return new BootLanguageServerParams( projectFinder, diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/editor/harness/AbstractPropsEditorTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/editor/harness/AbstractPropsEditorTest.java index ad46c243d..ce4e0f6f9 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/editor/harness/AbstractPropsEditorTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/editor/harness/AbstractPropsEditorTest.java @@ -39,6 +39,8 @@ import org.springframework.ide.vscode.languageserver.testharness.Editor; import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness; import org.springframework.ide.vscode.project.harness.ProjectsHarness; +import com.google.common.collect.ImmutableList; + public abstract class AbstractPropsEditorTest { public static final String INTEGER = Integer.class.getName(); @@ -61,6 +63,11 @@ public abstract class AbstractPropsEditorTest { public Optional find(TextDocumentIdentifier doc) { return Optional.ofNullable(getTestProject()); } + + @Override + public Collection all() { + return getTestProject() == null ? ImmutableList.of() : ImmutableList.of(getTestProject()); + } })); abstract public Editor newEditor(String contents) throws Exception; diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/editor/harness/PropertyIndexHarness.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/editor/harness/PropertyIndexHarness.java index 6df77492f..71a91fd36 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/editor/harness/PropertyIndexHarness.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/editor/harness/PropertyIndexHarness.java @@ -10,11 +10,15 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.editor.harness; +import java.util.Collection; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import org.eclipse.lsp4j.TextDocumentIdentifier; +import org.gradle.internal.impldep.com.google.common.collect.ImmutableList; import org.springframework.ide.vscode.boot.configurationmetadata.ConfigurationMetadataProperty; import org.springframework.ide.vscode.boot.configurationmetadata.Deprecation; import org.springframework.ide.vscode.boot.configurationmetadata.ValueHint; @@ -574,7 +578,19 @@ public class PropertyIndexHarness { } public JavaProjectFinder getProjectFinder() { - return (doc) -> Optional.ofNullable(testProject); + return new JavaProjectFinder() { + + @Override + public Optional find(TextDocumentIdentifier doc) { + return Optional.ofNullable(testProject); + } + + @Override + public Collection all() { + // TODO Auto-generated method stub + return testProject == null ? Collections.emptyList() : ImmutableList.of(testProject); + } + }; } public IJavaProject getTestProject() { diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/livehover/test/ComponentInjectionsHoverProviderTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/livehover/test/ComponentInjectionsHoverProviderTest.java index 6feea840e..1d0356d28 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/livehover/test/ComponentInjectionsHoverProviderTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/livehover/test/ComponentInjectionsHoverProviderTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2018 Pivotal, Inc. + * Copyright (c) 2017, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -163,6 +163,59 @@ public class ComponentInjectionsHoverProviderTest { ); } + @Test + public void componentWithOneCGILibInjection() throws Exception { + LiveBeansModel beans = LiveBeansModel.builder() + .add(LiveBean.builder() + .id("fooImplementation") + .type("com.example.FooImplementation$$EnhancerBySpringCGLIB$$Blah") + .build() + ) + .add(LiveBean.builder() + .id("myController") + .type("com.example.MyController$$EnhancerBySpringCGLIB$$Blah") + .dependencies("fooImplementation") + .build() + ) + .add(LiveBean.builder() + .id("irrelevantBean") + .type("com.example.IrrelevantBean$$EnhancerBySpringCGLIB$$Blah") + .dependencies("myController") + .build() + ) + .build(); + mockAppProvider.builder() + .isSpringBootApp(true) + .processId("111") + .processName("the-app") + .beans(beans) + .build(); + + Editor editor = harness.newEditor(LanguageId.JAVA, + "package com.example;\n" + + "\n" + + "import org.springframework.stereotype.Component;\n" + + "\n" + + "@Component\n" + + "public class FooImplementation implements Foo {\n" + + "\n" + + " @Override\n" + + " public void doSomeFoo() {\n" + + " System.out.println(\"Foo do do do!\");\n" + + " }\n" + + "}\n" + ); + editor.assertHighlights("@Component"); + editor.assertTrimmedHover("@Component", + "**→ `MyController`**\n" + + "- Bean: `myController` \n" + + " Type: `com.example.MyController`\n" + + " \n" + + "Bean id: `fooImplementation` \n" + + "Process [PID=111, name=`the-app`]\n" + ); + } + @Test public void componentWithMultipleInjections() throws Exception { LiveBeansModel beans = LiveBeansModel.builder() diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/VSCodeSourceLinksTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/VSCodeSourceLinksTest.java index ccd6e8e52..8fbab1a72 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/VSCodeSourceLinksTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/VSCodeSourceLinksTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -56,7 +56,7 @@ public class VSCodeSourceLinksTest { @Test public void testJavaSourceUrl() throws Exception { MavenJavaProject project = mavenProjectsCache.get("empty-boot-15-web-app"); - Optional url = new VSCodeSourceLinks(new CompilationUnitCache(null, null, null)).sourceLinkUrlForFQName(project, "com.example.EmptyBoot15WebAppApplication"); + Optional url = new VSCodeSourceLinks(new CompilationUnitCache(null, null, null), null).sourceLinkUrlForFQName(project, "com.example.EmptyBoot15WebAppApplication"); assertTrue(url.isPresent()); Path projectPath = Paths.get(project.pom().getParent()); URI uri = URI.create(url.get()); @@ -73,7 +73,7 @@ public class VSCodeSourceLinksTest { @Test public void testJarUrl() throws Exception { MavenJavaProject project = mavenProjectsCache.get("empty-boot-15-web-app"); - Optional url = new VSCodeSourceLinks(new CompilationUnitCache(null, null, null)).sourceLinkUrlForFQName(project, "org.springframework.boot.autoconfigure.SpringBootApplication"); + Optional url = new VSCodeSourceLinks(new CompilationUnitCache(null, null, null), null).sourceLinkUrlForFQName(project, "org.springframework.boot.autoconfigure.SpringBootApplication"); assertTrue(url.isPresent()); String headerPart = url.get().substring(0, url.get().indexOf('?')); assertEquals("jdt://contents/spring-boot-autoconfigure-1.5.8.RELEASE.jar/org.springframework.boot.autoconfigure/SpringBootApplication.class", headerPart); @@ -84,7 +84,7 @@ public class VSCodeSourceLinksTest { @Test public void testJarUrlInnerType() throws Exception { MavenJavaProject project = mavenProjectsCache.get("empty-boot-15-web-app"); - Optional url = new VSCodeSourceLinks(new CompilationUnitCache(null, null, null)).sourceLinkUrlForFQName(project, "org.springframework.web.client.RestTemplate$AcceptHeaderRequestCallback"); + Optional url = new VSCodeSourceLinks(new CompilationUnitCache(null, null, null), null).sourceLinkUrlForFQName(project, "org.springframework.web.client.RestTemplate$AcceptHeaderRequestCallback"); assertTrue(url.isPresent()); String headerPart = url.get().substring(0, url.get().indexOf('?')); assertEquals("jdt://contents/spring-web-4.3.12.RELEASE.jar/org.springframework.web.client/RestTemplate$AcceptHeaderRequestCallback.class", headerPart); 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 c03d08a2d..73b739eaf 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Pivotal, Inc. + * Copyright (c) 2018, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -63,6 +63,11 @@ public class MockProjects { return Optional.empty(); } } + + @Override + public Collection all() { + return projectsByName.values(); + } }; public MockFileObserver fileObserver = new MockFileObserver(); diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/value/test/ValueCompletionTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/value/test/ValueCompletionTest.java index 7e74e5199..6081f1252 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/value/test/ValueCompletionTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/value/test/ValueCompletionTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. + * Copyright (c) 2017, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,12 +14,16 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.InputStream; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Optional; import org.apache.commons.io.IOUtils; import org.eclipse.lsp4j.CompletionItem; +import org.eclipse.lsp4j.TextDocumentIdentifier; import org.eclipse.xtend.lib.annotations.Accessors; +import org.gradle.internal.impldep.com.google.common.collect.ImmutableList; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -86,7 +90,19 @@ public class ValueCompletionTest { } @Bean JavaProjectFinder projectFinder(MavenJavaProject testProject) { - return (doc) -> Optional.of(testProject); + return new JavaProjectFinder() { + + @Override + public Optional find(TextDocumentIdentifier doc) { + return Optional.ofNullable(testProject); + } + + @Override + public Collection all() { + // TODO Auto-generated method stub + return testProject == null ? Collections.emptyList() : ImmutableList.of(testProject); + } + }; } @Bean BootLanguageServerHarness harness(SimpleLanguageServer server, BootLanguageServerParams serverParams, PropertyIndexHarness indexHarness, JavaProjectFinder projectFinder) throws Exception { diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metadata/LoggerNameProviderTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metadata/LoggerNameProviderTest.java index 7ed16be0a..20f42e94a 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metadata/LoggerNameProviderTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metadata/LoggerNameProviderTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. + * Copyright (c) 2017, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -121,7 +121,7 @@ public class LoggerNameProviderTest { } private LoggerNameProvider create() { - return (LoggerNameProvider) LoggerNameProvider.factory(null).apply(ImmutableMap.of()); + return (LoggerNameProvider) LoggerNameProvider.factory(null, null).apply(ImmutableMap.of()); } private void assertElementsAtLeast(List results, String[] expecteds) { diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metadata/TypeUtilTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metadata/TypeUtilTest.java index 139e550e6..e029a3e71 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metadata/TypeUtilTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metadata/TypeUtilTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Pivotal, Inc. + * Copyright (c) 2015, 2019 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -29,17 +29,17 @@ import org.springframework.ide.vscode.project.harness.ProjectsHarness; /** * Tests for TypeUtil - * + * * @author Kris De Volder - * @author Alex Boyko + * @author Alex Boyko * */ public class TypeUtilTest { - + private ProjectsHarness projects = ProjectsHarness.INSTANCE; private IJavaProject project; private TypeUtil typeUtil; - + private Type getPropertyType(Type type, String propName, EnumCaseMode enumMode, BeanPropertyNameMode beanMode) { List props = getProperties(type, enumMode, beanMode); assertNotNull(props); @@ -139,7 +139,7 @@ public class TypeUtilTest { private void useProject(String name) throws Exception { project = projects.mavenProject(name);; - typeUtil = new TypeUtil(project); + typeUtil = new TypeUtil(null, project); } }