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
This commit is contained in:
BoykoAlex
2019-01-17 19:01:04 -05:00
parent a115b736e4
commit 0681baa876
58 changed files with 710 additions and 312 deletions

View File

@@ -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<JavaTypeResponse> 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<JavadocHoverLinkResponse> 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));
}

View File

@@ -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);
}

View File

@@ -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<PathMatcher> 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<IJavaProject> findProjectByName(String name) {
return cache.projectByName(name);
}
@Override
public Collection<? extends IJavaProject> all() {
return cache.all();
}
}

View File

@@ -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) {

View File

@@ -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 <K> key class
* @param <P> project class
*/
public abstract class AbstractJavaProjectCache<K, P extends IJavaProject> implements JavaProjectCache<K, P> {
private static final Logger log = LoggerFactory.getLogger(AbstractJavaProjectCache.class);
protected Sts4LanguageServer server;
private ListenerList<Listener> listeners = new ListenerList<>();
protected Cache<K, P> cache = CacheBuilder.newBuilder().build();
public AbstractJavaProjectCache(Sts4LanguageServer server) {
this.server = server;
}
@@ -70,16 +70,16 @@ public abstract class AbstractJavaProjectCache<K, P extends IJavaProject> implem
}
}
} catch (ExecutionException e) {
Log.log(e);
log.error("", e);
return null;
}
}
return null;
}
public Optional<IJavaProject> projectByName(String name) {
ConcurrentMap<K, P> 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<K, P extends IJavaProject> 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<K, P extends IJavaProject> 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<K, P extends IJavaProject> implem
final protected FileObserver getFileObserver() {
return server.getWorkspaceService().getFileObserver();
}
final public Collection<? extends IJavaProject> all() {
return cache.asMap().values();
}
}

View File

@@ -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<JavaProjectFinder> projectFinders;
public CompositeJavaProjectFinder(Collection<JavaProjectFinder> 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<IJavaProject> find(TextDocumentIdentifier doc) {
for (JavaProjectFinder finder : projectFinders) {
@@ -56,4 +58,13 @@ public class CompositeJavaProjectFinder implements JavaProjectFinder {
return Optional.empty();
}
@Override
public Collection<? extends IJavaProject> all() {
ImmutableList.Builder<IJavaProject> builder = ImmutableList.builder();
for (JavaProjectFinder projectFinder : projectFinders) {
builder.addAll(projectFinder.all());
}
return builder.build();
}
}

View File

@@ -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<IJavaProject> find(TextDocumentIdentifier doc);
Collection<? extends IJavaProject> all();
default JavaProjectFinder filter(Predicate<IJavaProject> 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<IJavaProject> 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<? extends IJavaProject> all() {
return delegate.all().stream().filter(acceptWhen).collect(Collectors.toList());
}
};
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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) {

View File

@@ -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 <code>pom.xml</code> 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<IJavaProject> findProjectByName(String name) {
return cache.projectByName(name);
}
@Override
public Collection<? extends IJavaProject> all() {
return cache.all();
}
}

View File

@@ -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 + "]";
}
}

View File

@@ -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<CPE> 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<String> systemLibs, IJavaProject javaProject, IClasspathEntry entry)
private static List<CPE> createCpes(Set<String> 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<CPE> 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<CPE> 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);

View File

@@ -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<CPE> 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);

View File

@@ -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();
}
}

View File

@@ -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<IJavaElement, Reader> readerProvider, URI projectUri, String bindingKey) throws Exception {
IJavaElement element = JavaData.findElement(projectUri, bindingKey);
public static final String javadoc(Function<IJavaElement, Reader> readerProvider, URI projectUri, String bindingKey, boolean lookInOtherProjects) throws Exception {
IJavaElement element = JavaData.findElement(projectUri, bindingKey, lookInOtherProjects);
return computeJavadoc(readerProvider, element);
}

View File

@@ -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<IJavaProject> allJavaProjects() {
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
ArrayList<IJavaProject> 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.

View File

@@ -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<String, Object> obj = (Map<String, Object>) 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)));
}

View File

@@ -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;

View File

@@ -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<String, Object> obj = (Map<String, Object>) 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

View File

@@ -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<PropertyInfo> 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);
}
};
}

View File

@@ -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));

View File

@@ -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<? extends IJavaProject> 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
);

View File

@@ -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<Location> handle(TextDocumentPositionParams position) {
try {
TextDocument doc = documents.get(position);
TypeUtil typeUtil = params.typeUtilProvider.getTypeUtil(doc);
TypeUtil typeUtil = params.typeUtilProvider.getTypeUtil(sourceLinks, doc);
FuzzyMap<PropertyInfo> index = params.indexProvider.getIndex(doc);
int offset;
offset = doc.toOffset(position.getPosition());

View File

@@ -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);

View File

@@ -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<File> 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];
}
}

View File

@@ -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<String> sourceLinkUrlForFQName(IJavaProject project, String fqName) {
Optional<String> 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<String> 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<String> 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<String> sourceLinkUrlForClasspathResource(String path) {
return SourceLinks.sourceLinkUrlForClasspathResource(this, projectFinder, path);
}
private Optional<String> javaSourceLinkUrl(IJavaProject project, String fqName, IJavaModuleData folderModuleData) {
IClasspath classpath = project.getClasspath();
return SourceLinks.sourceFromSourceFolder(fqName, classpath)

View File

@@ -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<Logger> LOG = Suppliers.memoize(() -> LoggerFactory.getLogger(AbstractSourceLinks.class));
public AtomSourceLinks(CompilationUnitCache cuCache) {
super(cuCache);
public AtomSourceLinks(CompilationUnitCache cuCache, JavaProjectFinder projectFinder) {
super(cuCache, projectFinder);
}
@Override

View File

@@ -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<String> 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<String> 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<String> sourceLinkUrlForFQName(IJavaProject project, String fqName) {
return findProjectForFQName(project, fqName).map(p -> eclipseIntroUri(p, fqName)).map(uri -> uri.toString());
}
private Optional<IJavaProject> 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<String> sourceLinkUrlForClasspathResource(String path) {
return SourceLinks.sourceLinkUrlForClasspathResource(this, projectFinder, path);
}
@Override
public Optional<String> sourceLinkForResourcePath(Path path) {
return Optional.ofNullable(eclipseIntroUri(path)).map(uri -> uri.toString());

View File

@@ -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<Optional<String>> link = server.getClient().javadocHoverLink(new JavaDataParams(project.getLocationUri().toString(), bindingKey.toString()))
String projectUri = project == null ? null : project.getLocationUri().toString();
CompletableFuture<Optional<String>> 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<String> 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<String> sourceLinkUrlForClasspathResource(String path) {
return SourceLinks.sourceLinkUrlForClasspathResource(this, projectFinder, path);
}
@Override

View File

@@ -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<String> sourceLinkUrlForClasspathResource(IJavaProject project, String path) {
public Optional<String> 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());
}
}

View File

@@ -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<String> 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<String> 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<String> sourceLinkUrlForClasspathResource(IJavaProject project, String path);
Optional<String> sourceLinkUrlForClasspathResource(String path);
/**
* Creates link to a file specified by it's path

View File

@@ -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

View File

@@ -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<LiveBean> 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()) {

View File

@@ -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;
}
}

View File

@@ -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<String> linkUrl;
Optional<String> 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;

View File

@@ -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<? extends IJavaProject> 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();
}
}

View File

@@ -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<? extends IJavaProject> all() {
return table.values();
}
}

View File

@@ -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<Map<String, Object>, 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 <K,V> Function<K,V> applyOn(long duration, TimeUnit unit, Function<K,V> func) {
Cache<K,V> cache = CacheBuilder.newBuilder().expireAfterAccess(duration, unit).expireAfterWrite(duration, unit).build();
return (k) -> {
public static final Function<Map<String, Object>, ValueProviderStrategy> factory(SourceLinks sourceLinks) {
long duration = 1;
TimeUnit unit = TimeUnit.MINUTES;
Cache<Map<String, Object>, 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()));
}
}

View File

@@ -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<Map<String, Object>, ValueProviderStrategy> factory(ProjectBasedPropertyIndexProvider adhocProperties) {
public static final Function<Map<String, Object>, 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)

View File

@@ -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);
});
}

View File

@@ -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<IJavaProject> maybeProject) {
this(maybeProject.orElse(null));
public TypeUtil(SourceLinks sourceLinks, Optional<IJavaProject> maybeProject) {
this(sourceLinks, maybeProject.orElse(null));
}
private static final Map<String, String> 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.
* <p>
@@ -695,7 +699,6 @@ public class TypeUtil {
//TODO: handle type parameters.
if (typeFromIndex != null) {
SourceLinks sourceLinks = SourceLinkFactory.createSourceLinks((BootJavaLanguageServerComponents)null);
IJavaProject project = getJavaProject();
ArrayList<TypedProperty> properties = new ArrayList<>();
getGetterMethods(typeFromIndex).forEach(m -> {

View File

@@ -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);
}

View File

@@ -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) -> {

View File

@@ -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<ICompletionProposal> 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() {

View File

@@ -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<Renderable, IRegion> 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();
}
}

View File

@@ -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 {

View File

@@ -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);
}

View File

@@ -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<PropertyInfo> 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;
}

View File

@@ -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,

View File

@@ -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<IJavaProject> find(TextDocumentIdentifier doc) {
return Optional.ofNullable(getTestProject());
}
@Override
public Collection<? extends IJavaProject> all() {
return getTestProject() == null ? ImmutableList.of() : ImmutableList.of(getTestProject());
}
}));
abstract public Editor newEditor(String contents) throws Exception;

View File

@@ -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<IJavaProject> find(TextDocumentIdentifier doc) {
return Optional.ofNullable(testProject);
}
@Override
public Collection<? extends IJavaProject> all() {
// TODO Auto-generated method stub
return testProject == null ? Collections.emptyList() : ImmutableList.of(testProject);
}
};
}
public IJavaProject getTestProject() {

View File

@@ -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",
"**&#8594; `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()

View File

@@ -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<String> url = new VSCodeSourceLinks(new CompilationUnitCache(null, null, null)).sourceLinkUrlForFQName(project, "com.example.EmptyBoot15WebAppApplication");
Optional<String> 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<String> url = new VSCodeSourceLinks(new CompilationUnitCache(null, null, null)).sourceLinkUrlForFQName(project, "org.springframework.boot.autoconfigure.SpringBootApplication");
Optional<String> 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<String> url = new VSCodeSourceLinks(new CompilationUnitCache(null, null, null)).sourceLinkUrlForFQName(project, "org.springframework.web.client.RestTemplate$AcceptHeaderRequestCallback");
Optional<String> 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);

View File

@@ -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<? extends IJavaProject> all() {
return projectsByName.values();
}
};
public MockFileObserver fileObserver = new MockFileObserver();

View File

@@ -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<IJavaProject> find(TextDocumentIdentifier doc) {
return Optional.ofNullable(testProject);
}
@Override
public Collection<? extends IJavaProject> 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 {

View File

@@ -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<String> results, String[] expecteds) {

View File

@@ -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<TypedProperty> 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);
}
}