PT #151991870: first rough implementation for live hovers for components without autowired annotation

This commit is contained in:
Martin Lippert
2017-10-16 18:46:08 +02:00
parent fd29f9cb1a
commit aef5d309c6
13 changed files with 671 additions and 32 deletions

View File

@@ -19,6 +19,7 @@ import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.InitializeResult;
import org.springframework.ide.vscode.boot.java.autowired.AutowiredHoverProvider;
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolProvider;
import org.springframework.ide.vscode.boot.java.beans.ComponentHoverProvider;
import org.springframework.ide.vscode.boot.java.beans.ComponentSymbolProvider;
import org.springframework.ide.vscode.boot.java.handlers.BootJavaCodeLensEngine;
import org.springframework.ide.vscode.boot.java.handlers.BootJavaCompletionEngine;
@@ -235,6 +236,7 @@ public class BootJavaLanguageServer extends SimpleLanguageServer {
providers.put(org.springframework.ide.vscode.boot.java.requestmapping.Constants.SPRING_PATCH_MAPPING, new RequestMappingHoverProvider());
providers.put(org.springframework.ide.vscode.boot.java.autowired.Constants.SPRING_AUTOWIRED, new AutowiredHoverProvider());
providers.put(org.springframework.ide.vscode.boot.java.beans.Constants.SPRING_COMPONENT, new ComponentHoverProvider());
return new BootJavaHoverProvider(this, javaProjectFinder, providers);
}

View File

@@ -36,30 +36,40 @@ public class AutowiredHoverProvider implements HoverProvider {
@Override
public CompletableFuture<Hover> provideHover(ASTNode node, Annotation annotation,
ITypeBinding type, int offset, TextDocument doc, SpringBootApp[] runningApps) {
SpringBootAppProvider[] bootApps = new SpringBootAppProvider[runningApps.length];
for (int i = 0; i < runningApps.length; i++) {
bootApps[i] = new SpringBootAppProviderImpl(runningApps[i]);
}
return provideHover(node, annotation, type, offset, doc, bootApps);
}
public CompletableFuture<Hover> provideHover(ASTNode node, Annotation annotation,
ITypeBinding type, int offset, TextDocument doc, SpringBootAppProvider[] runningApps) {
try {
List<Either<String, MarkedString>> hoverContent = new ArrayList<>();
if (runningApps.length > 0) {
for (SpringBootApp bootApp : runningApps) {
try {
String liveBeans = bootApp.getBeans();
if (liveBeans != null && liveBeans.length() > 0) {
addLiveHoverContent(annotation, doc, liveBeans, bootApp, hoverContent);
}
}
catch (Exception e) {
e.printStackTrace();
for (SpringBootAppProvider bootApp : runningApps) {
try {
String liveBeans = bootApp.getBeans();
if (liveBeans != null && liveBeans.length() > 0) {
addLiveHoverContent(annotation, doc, liveBeans, bootApp, hoverContent);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
Range hoverRange = doc.toRange(annotation.getStartPosition(), annotation.getLength());
Hover hover = new Hover();
if (hoverContent.size() > 0) {
Range hoverRange = doc.toRange(annotation.getStartPosition(), annotation.getLength());
Hover hover = new Hover();
hover.setContents(hoverContent);
hover.setRange(hoverRange);
hover.setContents(hoverContent);
hover.setRange(hoverRange);
return CompletableFuture.completedFuture(hover);
return CompletableFuture.completedFuture(hover);
}
} catch (Exception e) {
Log.log(e);
}
@@ -70,20 +80,18 @@ public class AutowiredHoverProvider implements HoverProvider {
@Override
public Range getLiveHoverHint(Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
try {
if (runningApps.length > 0) {
for (SpringBootApp bootApp : runningApps) {
try {
String liveBeans = bootApp.getBeans();
if (liveBeans != null && liveBeans.length() > 0) {
Range range = getLiveHoverHint(annotation, doc, liveBeans);
if (range != null) {
return range;
}
for (SpringBootApp bootApp : runningApps) {
try {
String liveBeans = bootApp.getBeans();
if (liveBeans != null && liveBeans.length() > 0) {
Range range = getLiveHoverHint(annotation, doc, liveBeans);
if (range != null) {
return range;
}
}
catch (Exception e) {
e.printStackTrace();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -115,7 +123,7 @@ public class AutowiredHoverProvider implements HoverProvider {
return null;
}
public void addLiveHoverContent(Annotation annotation, TextDocument doc, String liveBeansJSON, SpringBootApp bootApp, List<Either<String, MarkedString>> hoverContent) {
public void addLiveHoverContent(Annotation annotation, TextDocument doc, String liveBeansJSON, SpringBootAppProvider bootApp, List<Either<String, MarkedString>> hoverContent) {
String type = findDeclaredType(annotation);
if (type != null && liveBeansJSON != null) {

View File

@@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright (c) 2017 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.autowired;
/**
* @author Martin Lippert
*/
public interface SpringBootAppProvider {
public String getBeans() throws Exception;
public String getProcessID();
public String getProcessName();
}

View File

@@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright (c) 2017 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.autowired;
import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp;
/**
* @author Martin Lippert
*/
public class SpringBootAppProviderImpl implements SpringBootAppProvider {
private SpringBootApp bootApp;
public SpringBootAppProviderImpl(SpringBootApp bootApp) {
this.bootApp = bootApp;
}
@Override
public String getBeans() throws Exception {
return bootApp.getBeans();
}
@Override
public String getProcessID() {
return bootApp.getProcessID();
}
@Override
public String getProcessName() {
return bootApp.getProcessName();
}
}

View File

@@ -0,0 +1,216 @@
/*******************************************************************************
* Copyright (c) 2017 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.beans;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.lsp4j.Hover;
import org.eclipse.lsp4j.MarkedString;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.springframework.ide.vscode.boot.java.autowired.Constants;
import org.springframework.ide.vscode.boot.java.autowired.LiveBean;
import org.springframework.ide.vscode.boot.java.autowired.LiveBeansModel;
import org.springframework.ide.vscode.boot.java.autowired.SpringBootAppProvider;
import org.springframework.ide.vscode.boot.java.autowired.SpringBootAppProviderImpl;
import org.springframework.ide.vscode.boot.java.handlers.HoverProvider;
import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp;
import org.springframework.ide.vscode.commons.util.BadLocationException;
import org.springframework.ide.vscode.commons.util.Log;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
/**
* @author Martin Lippert
*/
public class ComponentHoverProvider implements HoverProvider {
@Override
public CompletableFuture<Hover> provideHover(ASTNode node, Annotation annotation,
ITypeBinding type, int offset, TextDocument doc, SpringBootApp[] runningApps) {
SpringBootAppProvider[] bootApps = new SpringBootAppProvider[runningApps.length];
for (int i = 0; i < runningApps.length; i++) {
bootApps[i] = new SpringBootAppProviderImpl(runningApps[i]);
}
return provideHover(node, annotation, type, offset, doc, bootApps);
}
public CompletableFuture<Hover> provideHover(ASTNode node, Annotation annotation,
ITypeBinding type, int offset, TextDocument doc, SpringBootAppProvider[] runningApps) {
try {
Range range = null;
TypeDeclaration typeDecl = findDeclaredType(annotation);
if (typeDecl != null) {
MethodDeclaration constructor = findConstructor(typeDecl);
if (constructor != null && !hasAutowiredAnnotation(constructor)) {
range = doc.toRange(constructor.getName().getStartPosition(), constructor.getName().getLength());
List<Either<String, MarkedString>> hoverContent = new ArrayList<>();
for (SpringBootAppProvider bootApp : runningApps) {
try {
String liveBeans = bootApp.getBeans();
if (liveBeans != null && liveBeans.length() > 0) {
addLiveHoverContent(typeDecl, doc, liveBeans, bootApp, hoverContent);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
if (hoverContent.size() > 0) {
Hover hover = new Hover();
hover.setContents(hoverContent);
hover.setRange(range);
return CompletableFuture.completedFuture(hover);
}
}
}
} catch (Exception e) {
Log.log(e);
}
return null;
}
@Override
public Range getLiveHoverHint(Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
try {
for (SpringBootApp bootApp : runningApps) {
try {
String liveBeans = bootApp.getBeans();
if (liveBeans != null && liveBeans.length() > 0) {
Range range = getLiveHoverHint(annotation, doc, liveBeans);
if (range != null) {
return range;
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
catch (Exception e) {
Log.log(e);
}
return null;
}
public Range getLiveHoverHint(Annotation annotation, TextDocument doc, String liveBeansJSON) {
try {
TypeDeclaration type = findDeclaredType(annotation);
if (type != null && liveBeansJSON != null) {
String typeName = type.resolveBinding().getQualifiedName();
LiveBeansModel beansModel = LiveBeansModel.parse(liveBeansJSON);
LiveBean[] beansOfType = beansModel.getBeansOfType(typeName);
if (beansOfType.length > 0) {
MethodDeclaration constructor = findConstructor(type);
if (constructor != null && !hasAutowiredAnnotation(constructor)) {
Range hoverRange = doc.toRange(constructor.getName().getStartPosition(), constructor.getName().getLength());
return hoverRange;
}
}
}
}
catch (BadLocationException e) {
Log.log(e);
}
return null;
}
private boolean hasAutowiredAnnotation(MethodDeclaration constructor) {
List<?> modifiers = constructor.modifiers();
for (Object modifier : modifiers) {
if (modifier instanceof MarkerAnnotation) {
ITypeBinding typeBinding = ((MarkerAnnotation) modifier).resolveTypeBinding();
if (typeBinding != null && typeBinding.getQualifiedName().equals(Constants.SPRING_AUTOWIRED)) {
return true;
}
}
}
return false;
}
public void addLiveHoverContent(TypeDeclaration declaringType, TextDocument doc, String liveBeansJSON, SpringBootAppProvider bootApp, List<Either<String, MarkedString>> hoverContent) {
String type = declaringType.resolveBinding().getQualifiedName();
if (type != null && liveBeansJSON != null) {
LiveBeansModel beansModel = LiveBeansModel.parse(liveBeansJSON);
LiveBean[] beansOfType = beansModel.getBeansOfType(type);
if (beansOfType.length > 0) {
String processId = bootApp.getProcessID();
String processName = bootApp.getProcessName();
for (LiveBean liveBean : beansOfType) {
String[] dependencies = liveBean.getDependencies();
if (dependencies != null && dependencies.length > 0) {
hoverContent.add(Either.forLeft("bean: " + liveBean.getId()));
hoverContent.add(Either.forLeft("injected beans:"));
for (String dependency : dependencies) {
LiveBean[] dependencyBeans = beansModel.getBeansOfName(dependency);
for (LiveBean dependencyBean : dependencyBeans) {
hoverContent.add(Either.forLeft("- '" + dependencyBean.getId() + "' - from: " + dependencyBean.getResource()));
}
}
}
else {
// TODO: no dependencies found
}
}
hoverContent.add(Either.forLeft("Process ID: " + processId));
hoverContent.add(Either.forLeft("Process Name: " + processName));
}
}
}
private TypeDeclaration findDeclaredType(Annotation annotation) {
ASTNode node = annotation;
while (node != null && !(node instanceof TypeDeclaration)) {
node = node.getParent();
}
return node != null ? (TypeDeclaration) node : null;
}
private MethodDeclaration findConstructor(TypeDeclaration typeDecl) {
MethodDeclaration[] methods = typeDecl.getMethods();
for (MethodDeclaration methodDeclaration : methods) {
if (methodDeclaration.isConstructor()) {
return methodDeclaration;
}
}
return null;
}
}

View File

@@ -13,14 +13,17 @@ package org.springframework.ide.vscode.boot.java.autowired.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;
import org.eclipse.jdt.core.JavaCore;
@@ -30,12 +33,16 @@ import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.lsp4j.Hover;
import org.eclipse.lsp4j.MarkedString;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.junit.Before;
import org.junit.Test;
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer;
import org.springframework.ide.vscode.boot.java.autowired.AutowiredHoverProvider;
import org.springframework.ide.vscode.boot.java.autowired.SpringBootAppProvider;
import org.springframework.ide.vscode.commons.java.IClasspath;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectManager;
@@ -147,6 +154,58 @@ public class AutowiredHoverProviderTest {
assertNull(hint);
}
@Test
public void testLiveHoverContentForAutowiredOnConstructor() throws Exception {
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-autowired/").toURI());
harness.intialize(directory);
String docURI = "file://" + directory.getAbsolutePath() + "/src/main/java/org/test/MyAutowiredComponent.java";
IJavaProject project = projectManager.find(directory);
TextDocument document = createTempTextDocument(docURI);
CompilationUnit cu = parse(document, project);
int offset = document.toOffset(new Position(11, 4));
ASTNode node = NodeFinder.perform(cu, offset, 0).getParent();
AutowiredHoverProvider provider = new AutowiredHoverProvider();
String beansJSON = new String(Files.readAllBytes(new File(directory, "runtime-bean-information.json").toPath()));
SpringBootAppProvider bootApp = new SpringBootAppProvider() {
@Override
public String getProcessName() {
return "test process name";
}
@Override
public String getProcessID() {
return "test process id";
}
@Override
public String getBeans() throws Exception {
return beansJSON;
}
};
CompletableFuture<Hover> hoverFuture = provider.provideHover(null, (Annotation)node, null, offset, document, new SpringBootAppProvider[] {bootApp});
Hover hover = hoverFuture.get();
assertNotNull(hover);
assertEquals(11, hover.getRange().getStart().getLine());
assertEquals(1, hover.getRange().getStart().getCharacter());
assertEquals(11, hover.getRange().getEnd().getLine());
assertEquals(11, hover.getRange().getEnd().getCharacter());
List<Either<String, MarkedString>> contents = hover.getContents();
assertEquals(6, contents.size());
assertTrue(contents.get(0).getLeft().contains("myAutowiredComponent"));
assertTrue(contents.get(2).getLeft().contains("dependencyA"));
assertTrue(contents.get(3).getLeft().contains("dependencyB"));
assertTrue(contents.get(4).getLeft().contains("test process id"));
assertTrue(contents.get(5).getLeft().contains("test process name"));
}
private TextDocument createTempTextDocument(String docURI) throws Exception {
Path path = Paths.get(new URI(docURI));
String content = new String(Files.readAllBytes(path));

View File

@@ -0,0 +1,232 @@
/*******************************************************************************
* Copyright (c) 2017 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.beans.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.lsp4j.Hover;
import org.eclipse.lsp4j.MarkedString;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.junit.Before;
import org.junit.Test;
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer;
import org.springframework.ide.vscode.boot.java.autowired.SpringBootAppProvider;
import org.springframework.ide.vscode.boot.java.beans.ComponentHoverProvider;
import org.springframework.ide.vscode.commons.java.IClasspath;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectManager;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
import org.springframework.ide.vscode.commons.maven.MavenCore;
import org.springframework.ide.vscode.commons.maven.java.MavenProjectManager;
import org.springframework.ide.vscode.commons.util.BadLocationException;
import org.springframework.ide.vscode.commons.util.BasicFileObserver;
import org.springframework.ide.vscode.commons.util.text.LanguageId;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
import org.springframework.ide.vscode.project.harness.PropertyIndexHarness;
/**
* @author Martin Lippert
*/
public class ComponentHoverProviderTest {
private JavaProjectManager projectManager;
private LanguageServerHarness<BootJavaLanguageServer> harness;
private PropertyIndexHarness indexHarness;
private BasicFileObserver fileObserver;
@Before
public void setup() throws Exception {
projectManager = new CompositeJavaProjectManager(new JavaProjectManager[] {new MavenProjectManager(MavenCore.getDefault())});
fileObserver = new BasicFileObserver();
projectManager.setFileObserver(fileObserver);
indexHarness = new PropertyIndexHarness();
harness = new LanguageServerHarness<BootJavaLanguageServer>(new Callable<BootJavaLanguageServer>() {
@Override
public BootJavaLanguageServer call() throws Exception {
BootJavaLanguageServer server = new BootJavaLanguageServer(projectManager, indexHarness.getIndexProvider());
return server;
}
}) {
@Override
protected String getFileExtension() {
return ".java";
}
};
}
@Test
public void testLiveHoverHintForAutomaicallywiredConstructor() throws Exception {
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-autowired/").toURI());
harness.intialize(directory);
String docURI = "file://" + directory.getAbsolutePath() + "/src/main/java/org/test/MyAutomaticallyWiredComponent.java";
IJavaProject project = projectManager.find(directory);
TextDocument document = createTempTextDocument(docURI);
CompilationUnit cu = parse(document, project);
int offset = document.toOffset(new Position(4, 2));
ASTNode node = NodeFinder.perform(cu, offset, 0).getParent();
ComponentHoverProvider provider = new ComponentHoverProvider();
String beansJSON = new String(Files.readAllBytes(new File(directory, "runtime-bean-information-automatically-wired.json").toPath()));
Range hint = provider.getLiveHoverHint((Annotation)node, document, beansJSON);
assertNotNull(hint);
assertEquals(10, hint.getStart().getLine());
assertEquals(8, hint.getStart().getCharacter());
assertEquals(10, hint.getEnd().getLine());
assertEquals(37, hint.getEnd().getCharacter());
}
@Test
public void testNoLiveHoverHintForComponentWhenAutowiredAnnotationIsUsed() throws Exception {
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-autowired/").toURI());
harness.intialize(directory);
String docURI = "file://" + directory.getAbsolutePath() + "/src/main/java/org/test/MyAutowiredComponent.java";
IJavaProject project = projectManager.find(directory);
TextDocument document = createTempTextDocument(docURI);
CompilationUnit cu = parse(document, project);
int offset = document.toOffset(new Position(5, 2));
ASTNode node = NodeFinder.perform(cu, offset, 0).getParent();
ComponentHoverProvider provider = new ComponentHoverProvider();
String beansJSON = new String(Files.readAllBytes(new File(directory, "runtime-bean-information.json").toPath()));
Range hint = provider.getLiveHoverHint((Annotation)node, document, beansJSON);
assertNull(hint);
}
@Test
public void testLiveHoverContentForAutomaicallywiredConstructor() throws Exception {
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-autowired/").toURI());
harness.intialize(directory);
String docURI = "file://" + directory.getAbsolutePath() + "/src/main/java/org/test/MyAutomaticallyWiredComponent.java";
IJavaProject project = projectManager.find(directory);
TextDocument document = createTempTextDocument(docURI);
CompilationUnit cu = parse(document, project);
int offset = document.toOffset(new Position(4, 2));
ASTNode node = NodeFinder.perform(cu, offset, 0).getParent();
ComponentHoverProvider provider = new ComponentHoverProvider();
String beansJSON = new String(Files.readAllBytes(new File(directory, "runtime-bean-information-automatically-wired.json").toPath()));
SpringBootAppProvider bootApp = new SpringBootAppProvider() {
@Override
public String getProcessName() {
return "test process name";
}
@Override
public String getProcessID() {
return "test process id";
}
@Override
public String getBeans() throws Exception {
return beansJSON;
}
};
CompletableFuture<Hover> hoverFuture = provider.provideHover(null, (Annotation) node, null, 0, document, new SpringBootAppProvider[] {bootApp});
Hover hover = hoverFuture.get();
assertNotNull(hover);
assertEquals(10, hover.getRange().getStart().getLine());
assertEquals(8, hover.getRange().getStart().getCharacter());
assertEquals(10, hover.getRange().getEnd().getLine());
assertEquals(37, hover.getRange().getEnd().getCharacter());
List<Either<String, MarkedString>> contents = hover.getContents();
assertEquals(6, contents.size());
assertTrue(contents.get(0).getLeft().contains("myAutomaticallyWiredComponent"));
assertTrue(contents.get(2).getLeft().contains("dependencyA"));
assertTrue(contents.get(3).getLeft().contains("dependencyB"));
assertTrue(contents.get(4).getLeft().contains("test process id"));
assertTrue(contents.get(5).getLeft().contains("test process name"));
}
private TextDocument createTempTextDocument(String docURI) throws Exception {
Path path = Paths.get(new URI(docURI));
String content = new String(Files.readAllBytes(path));
TextDocument doc = new TextDocument(docURI, LanguageId.PLAINTEXT, 0, content);
return doc;
}
private CompilationUnit parse(TextDocument document, IJavaProject project)
throws Exception, BadLocationException {
ASTParser parser = ASTParser.newParser(AST.JLS8);
Map<String, String> options = JavaCore.getOptions();
JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, options);
parser.setCompilerOptions(options);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setStatementsRecovery(true);
parser.setBindingsRecovery(true);
parser.setResolveBindings(true);
String[] classpathEntries = getClasspathEntries(project);
String[] sourceEntries = new String[] {};
parser.setEnvironment(classpathEntries, sourceEntries, null, true);
String docURI = document.getUri();
String unitName = docURI.substring(docURI.lastIndexOf("/"));
parser.setUnitName(unitName);
parser.setSource(document.get(0, document.getLength()).toCharArray());
CompilationUnit cu = (CompilationUnit) parser.createAST(null);
return cu;
}
private String[] getClasspathEntries(IJavaProject project) throws Exception {
IClasspath classpath = project.getClasspath();
Stream<Path> classpathEntries = classpath.getClasspathEntries();
return classpathEntries
.filter(path -> path.toFile().exists())
.map(path -> path.toAbsolutePath().toString()).toArray(String[]::new);
}
}

View File

@@ -8,7 +8,7 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.utils.test;
package org.springframework.ide.vscode.boot.java.beans.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

View File

@@ -8,7 +8,7 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.completions.test;
package org.springframework.ide.vscode.boot.java.scope.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

View File

@@ -8,7 +8,7 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.completions.test;
package org.springframework.ide.vscode.boot.java.value.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

View File

@@ -8,7 +8,7 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.hover.test;
package org.springframework.ide.vscode.boot.java.value.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

View File

@@ -0,0 +1,35 @@
[
{
"context": "application",
"parent": null,
"beans": [
{
"bean": "dependencyA",
"aliases": [],
"scope": "singleton",
"type": "org.test.DependencyA",
"resource": "file [/Users/mlippert/Entwicklung/vmware/projects/sts4/headless-services/boot-java-language-server/src/test/resources/test-projects/test-annotation-indexing-autowired/target/classes/org/test/DependencyA.class]",
"dependencies": []
},
{
"bean": "dependencyB",
"aliases": [],
"scope": "singleton",
"type": "org.test.DependencyB",
"resource": "file [/Users/mlippert/Entwicklung/vmware/projects/sts4/headless-services/boot-java-language-server/src/test/resources/test-projects/test-annotation-indexing-autowired/target/classes/org/test/DependencyB.class]",
"dependencies": []
},
{
"bean": "myAutomaticallyWiredComponent",
"aliases": [],
"scope": "singleton",
"type": "org.test.MyAutomaticallyWiredComponent",
"resource": "file [/Users/mlippert/Entwicklung/vmware/projects/sts4/headless-services/boot-java-language-server/src/test/resources/test-projects/test-annotation-indexing-autowired/target/classes/org/test/MyAutomaticallyWiredComponent.class]",
"dependencies": [
"dependencyA",
"dependencyB"
]
}
]
}
]

View File

@@ -0,0 +1,24 @@
package org.test;
import org.springframework.stereotype.Component;
@Component
public class MyAutomaticallyWiredComponent {
private DependencyA depA;
private DependencyB depB;
public MyAutomaticallyWiredComponent(DependencyA depA, DependencyB depB) {
this.depA = depA;
this.depB = depB;
}
public DependencyA getDepA() {
return depA;
}
public DependencyB getDepB() {
return depB;
}
}