PT #159866210: Highlights,hovers for paramneters of bean methods and component constructors
This commit is contained in:
@@ -71,32 +71,30 @@ public class AutowiredHoverProvider implements HoverProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<CodeLens> getLiveHintCodeLenses(IJavaProject project, Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
public Collection<CodeLens> getLiveHintCodeLenses(IJavaProject project, Annotation annotation, TextDocument doc,
|
||||
SpringBootApp[] runningApps) {
|
||||
ImmutableList.Builder<CodeLens> builder = ImmutableList.builder();
|
||||
if (runningApps.length > 0) {
|
||||
LiveBean definedBean = getDefinedBeanForTypeDeclaration(ASTUtils.findDeclaringType(annotation));
|
||||
// Annotation is MarkerNode, parent is some field, method, variable declaration node.
|
||||
// Annotation is MarkerNode, parent is some field, method, variable declaration
|
||||
// node.
|
||||
ASTNode declarationNode = annotation.getParent();
|
||||
try {
|
||||
Range hoverRange = doc.toRange(annotation.getStartPosition(), annotation.getLength());
|
||||
return getLiveHoverHints(project, declarationNode, hoverRange, runningApps, definedBean);
|
||||
for (SpringBootApp app : runningApps) {
|
||||
List<LiveBean> relevantBeans = getRelevantAutowiredBeans(project, declarationNode, app,
|
||||
definedBean);
|
||||
if (!relevantBeans.isEmpty()) {
|
||||
builder.addAll(LiveHoverUtils.createCodeLensesForBeans(hoverRange, relevantBeans,
|
||||
BEANS_PREFIX_PLAIN_TEXT, MAX_INLINE_BEANS_STRING_LENGTH,
|
||||
INLINE_BEANS_STRING_SEPARATOR));
|
||||
}
|
||||
}
|
||||
} catch (BadLocationException e) {
|
||||
log.error("", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Collection<CodeLens> getLiveHoverHints(IJavaProject project, ASTNode declarationNode, Range range,
|
||||
SpringBootApp[] runningApps, LiveBean definedBean) {
|
||||
if (declarationNode != null && definedBean != null) {
|
||||
for (SpringBootApp app : runningApps) {
|
||||
List<LiveBean> relevantBeans = getRelevantAutowiredBeans(project, declarationNode, app, definedBean);
|
||||
if (!relevantBeans.isEmpty()) {
|
||||
return LiveHoverUtils.createCodeLensesForBeans(range, relevantBeans, BEANS_PREFIX_PLAIN_TEXT, MAX_INLINE_BEANS_STRING_LENGTH, INLINE_BEANS_STRING_SEPARATOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,16 +123,12 @@ public class AutowiredHoverProvider implements HoverProvider {
|
||||
|
||||
StringBuilder hover = new StringBuilder();
|
||||
|
||||
boolean hasContent = false;
|
||||
|
||||
for (SpringBootApp app : runningApps) {
|
||||
|
||||
List<LiveBean> autowiredBeans = getRelevantAutowiredBeans(project, declarationNode, app, definedBean);
|
||||
|
||||
if (!autowiredBeans.isEmpty()) {
|
||||
if (!hasContent) {
|
||||
hasContent = true;
|
||||
} else {
|
||||
if (hover.length() > 0) {
|
||||
hover.append(" \n \n");
|
||||
}
|
||||
createHoverContentForBeans(sourceLinks, project, hover, autowiredBeans);
|
||||
@@ -145,7 +139,7 @@ public class AutowiredHoverProvider implements HoverProvider {
|
||||
}
|
||||
|
||||
}
|
||||
if (hasContent) {
|
||||
if (hover.length() > 0) {
|
||||
return new Hover(ImmutableList.of(Either.forLeft(hover.toString())));
|
||||
}
|
||||
}
|
||||
@@ -189,7 +183,7 @@ public class AutowiredHoverProvider implements HoverProvider {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static List<LiveBean> findAutowiredBeans(IJavaProject project, ASTNode declarationNode, Collection<LiveBean> beans) {
|
||||
public static List<LiveBean> findAutowiredBeans(IJavaProject project, ASTNode declarationNode, Collection<LiveBean> beans) {
|
||||
if (declarationNode instanceof MethodDeclaration) {
|
||||
MethodDeclaration methodDeclaration = (MethodDeclaration)declarationNode;
|
||||
return ((List<Object>)methodDeclaration.parameters()).stream()
|
||||
@@ -325,16 +319,54 @@ public class AutowiredHoverProvider implements HoverProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<CodeLens> getLiveHintCodeLenses(IJavaProject project, MethodDeclaration methodDeclaration, TextDocument doc,
|
||||
SpringBootApp[] runningApps) {
|
||||
LiveBean definedBean = getDefinedBeanForImplicitAutowiredConstructor(methodDeclaration);
|
||||
try {
|
||||
Range hoverRange = doc.toRange(methodDeclaration.getName().getStartPosition(), methodDeclaration.getName().getLength());
|
||||
return getLiveHoverHints(project, methodDeclaration, hoverRange, runningApps, definedBean);
|
||||
} catch (BadLocationException e) {
|
||||
log.error("", e);
|
||||
public Hover provideMethodParameterHover(SingleVariableDeclaration parameter, int offset, TextDocument doc,
|
||||
IJavaProject project, SpringBootApp[] runningApps) {
|
||||
MethodDeclaration method = (MethodDeclaration) parameter.getParent();
|
||||
LiveBean definedBean = getDefinedBeanForImplicitAutowiredConstructor(method);
|
||||
Hover hover = provideHover(definedBean, parameter, offset, doc, project, runningApps);
|
||||
if (hover != null) {
|
||||
SimpleName name = parameter.getName();
|
||||
try {
|
||||
hover.setRange(doc.toRange(name.getStartPosition(), name.getLength()));
|
||||
} catch (BadLocationException e) {
|
||||
log.error("", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return hover;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<CodeLens> getLiveHintCodeLenses(IJavaProject project, MethodDeclaration methodDeclaration,
|
||||
TextDocument doc, SpringBootApp[] runningApps) {
|
||||
ImmutableList.Builder<CodeLens> builder = ImmutableList.builder();
|
||||
LiveBean definedBean = getDefinedBeanForImplicitAutowiredConstructor(methodDeclaration);
|
||||
if (definedBean != null) {
|
||||
try {
|
||||
Range hoverRange = doc.toRange(methodDeclaration.getName().getStartPosition(),
|
||||
methodDeclaration.getName().getLength());
|
||||
|
||||
for (SpringBootApp app : runningApps) {
|
||||
List<LiveBean> relevantBeans = getRelevantAutowiredBeans(project, methodDeclaration, app,
|
||||
definedBean);
|
||||
if (!relevantBeans.isEmpty()) {
|
||||
|
||||
// CodeLens for the method
|
||||
builder.addAll(LiveHoverUtils.createCodeLensesForBeans(hoverRange, relevantBeans,
|
||||
BEANS_PREFIX_PLAIN_TEXT, MAX_INLINE_BEANS_STRING_LENGTH,
|
||||
INLINE_BEANS_STRING_SEPARATOR));
|
||||
|
||||
// CodeLenses for the method parameters. Only ranges just to provide a highlight
|
||||
// for the hover
|
||||
builder.addAll(LiveHoverUtils.createCodeLensForMethodParameters(app, project, methodDeclaration, doc, relevantBeans));
|
||||
|
||||
}
|
||||
}
|
||||
} catch (BadLocationException e) {
|
||||
log.error("", e);
|
||||
}
|
||||
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private LiveBean getDefinedBeanForImplicitAutowiredConstructor(MethodDeclaration methodDeclaration) {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.handlers;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Optional;
|
||||
@@ -24,6 +25,7 @@ import org.eclipse.jdt.core.dom.NodeFinder;
|
||||
import org.eclipse.jdt.core.dom.NormalAnnotation;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
|
||||
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.CodeLens;
|
||||
import org.eclipse.lsp4j.Hover;
|
||||
@@ -101,7 +103,7 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
if (!project.isPresent()) return new CodeLens[0];
|
||||
if (!hasActuatorDependency(project.get())) return new CodeLens[0];
|
||||
|
||||
return server.getCompilationUnitCache().withCompilationUnit(document, cu -> {
|
||||
return server.getCompilationUnitCache().withCompilationUnit(project.get(), URI.create(document.getUri()), cu -> {
|
||||
Collection<CodeLens> result = new LinkedHashSet<>();
|
||||
try {
|
||||
if (cu != null) {
|
||||
@@ -210,7 +212,7 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
private Hover provideHover(TextDocument document, int offset) throws Exception {
|
||||
IJavaProject project = getProject(document).orElse(null);
|
||||
if (project != null) {
|
||||
return server.getCompilationUnitCache().withCompilationUnit(document, cu -> {
|
||||
return server.getCompilationUnitCache().withCompilationUnit(project, URI.create(document.getUri()), cu -> {
|
||||
ASTNode node = NodeFinder.perform(cu, offset, 0);
|
||||
if (node != null) {
|
||||
return provideHover(node, offset, document, project);
|
||||
@@ -239,6 +241,23 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
return provideHoverForTypeDeclaration(node, (TypeDeclaration) parent, offset, doc, project);
|
||||
} else if (parent instanceof MethodDeclaration) {
|
||||
return provideHoverForMethodDeclaration((MethodDeclaration) parent, offset, doc, project);
|
||||
} else if (parent instanceof SingleVariableDeclaration && parent.getParent() instanceof MethodDeclaration) {
|
||||
return provideHoverForMethodParameter((SingleVariableDeclaration) parent, offset, doc, project);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Hover provideHoverForMethodParameter(SingleVariableDeclaration parameter, int offset, TextDocument doc,
|
||||
IJavaProject project) {
|
||||
SpringBootApp[] runningApps = getRunningSpringApps(project);
|
||||
|
||||
if (runningApps.length > 0) {
|
||||
for (HoverProvider provider : this.hoverProviders.getAll()) {
|
||||
Hover hover = provider.provideMethodParameterHover(parameter, offset, doc, project, runningApps);
|
||||
if (hover != null) {
|
||||
return hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -16,6 +16,7 @@ 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.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.CodeLens;
|
||||
import org.eclipse.lsp4j.Hover;
|
||||
@@ -31,13 +32,19 @@ public interface HoverProvider {
|
||||
default Hover provideHover(ASTNode node, Annotation annotation, ITypeBinding type, int offset, TextDocument doc, IJavaProject project, SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
default Hover provideHover(ASTNode node, TypeDeclaration typeDeclaration, ITypeBinding type, int offset, TextDocument doc, IJavaProject project, SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
default Hover provideHover(MethodDeclaration methodDeclaration, int offset, TextDocument doc, IJavaProject project, SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
default Hover provideMethodParameterHover(SingleVariableDeclaration parameter, int offset, TextDocument doc, IJavaProject project, SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
default Collection<CodeLens> getLiveHintCodeLenses(IJavaProject project, Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.livehover;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -65,7 +64,7 @@ public abstract class AbstractInjectedIntoHoverProvider implements HoverProvider
|
||||
if (Stream.of(runningApps).anyMatch(app -> LiveHoverUtils.hasRelevantBeans(app, definedBean))) {
|
||||
Optional<Range> nameRange = ASTUtils.nameRange(doc, annotation);
|
||||
if (nameRange.isPresent()) {
|
||||
List<CodeLens> codeLenses = assembleCodeLenses(project, runningApps, definedBean, nameRange.get(), annotation);
|
||||
List<CodeLens> codeLenses = assembleCodeLenses(project, runningApps, definedBean, doc, nameRange.get(), annotation);
|
||||
return codeLenses.isEmpty() ? ImmutableList.of(new CodeLens(nameRange.get())) : codeLenses;
|
||||
}
|
||||
}
|
||||
@@ -97,31 +96,38 @@ public abstract class AbstractInjectedIntoHoverProvider implements HoverProvider
|
||||
return null;
|
||||
}
|
||||
|
||||
protected List<CodeLens> assembleCodeLenses(IJavaProject project, SpringBootApp[] runningApps, LiveBean definedBean, Range range, ASTNode astNode) {
|
||||
List<CodeLens> codeLensList = new ArrayList<>();
|
||||
for (SpringBootApp app : runningApps) {
|
||||
protected List<CodeLens> assembleCodeLenses(IJavaProject project, SpringBootApp[] runningApps, LiveBean definedBean,
|
||||
TextDocument doc, Range range, ASTNode node) {
|
||||
for (SpringBootApp app : runningApps) {
|
||||
|
||||
List<LiveBean> relevantBeans = LiveHoverUtils.findRelevantBeans(app, definedBean);
|
||||
List<LiveBean> relevantBeans = LiveHoverUtils.findRelevantBeans(app, definedBean);
|
||||
|
||||
if (!relevantBeans.isEmpty()) {
|
||||
List<LiveBean> injectedBeans = getRelevantInjectedIntoBeans(project, app, definedBean, relevantBeans);
|
||||
ImmutableList.Builder<CodeLens> builder = ImmutableList.builder();
|
||||
if (!injectedBeans.isEmpty()) {
|
||||
// Break out of the loop. Just look for the first app with injected into beans
|
||||
List<CodeLens> injectedCodeLenses = LiveHoverUtils.createCodeLensesForBeans(range, injectedBeans, BEANS_PREFIX_PLAIN_TEXT, MAX_INLINE_BEANS_STRING_LENGTH, INLINE_BEANS_STRING_SEPARATOR);
|
||||
builder.addAll(injectedCodeLenses.isEmpty() ? ImmutableList.of(new CodeLens(range)) : injectedCodeLenses);
|
||||
}
|
||||
|
||||
// Wired beans code lenses
|
||||
List<LiveBean> wiredBeans = findWiredBeans(project, app, relevantBeans, astNode);
|
||||
builder.addAll(LiveHoverUtils.createCodeLensesForBeans(range, wiredBeans,
|
||||
AutowiredHoverProvider.BEANS_PREFIX_PLAIN_TEXT, MAX_INLINE_BEANS_STRING_LENGTH,
|
||||
INLINE_BEANS_STRING_SEPARATOR));
|
||||
|
||||
return builder.build();
|
||||
if (!relevantBeans.isEmpty()) {
|
||||
List<LiveBean> injectedBeans = getRelevantInjectedIntoBeans(project, app, definedBean, relevantBeans);
|
||||
ImmutableList.Builder<CodeLens> builder = ImmutableList.builder();
|
||||
if (!injectedBeans.isEmpty()) {
|
||||
// Break out of the loop. Just look for the first app with injected into beans
|
||||
List<CodeLens> injectedCodeLenses = LiveHoverUtils.createCodeLensesForBeans(range, injectedBeans,
|
||||
BEANS_PREFIX_PLAIN_TEXT, MAX_INLINE_BEANS_STRING_LENGTH, INLINE_BEANS_STRING_SEPARATOR);
|
||||
builder.addAll(
|
||||
injectedCodeLenses.isEmpty() ? ImmutableList.of(new CodeLens(range)) : injectedCodeLenses);
|
||||
}
|
||||
|
||||
// Wired beans code lenses
|
||||
List<LiveBean> wiredBeans = findWiredBeans(project, app, relevantBeans, node);
|
||||
builder.addAll(assembleCodeLenseForAutowired(wiredBeans, project, app, doc, range, node));
|
||||
|
||||
List<CodeLens> codeLenses = builder.build();
|
||||
return codeLenses.isEmpty() ? ImmutableList.of(new CodeLens(range)) : codeLenses;
|
||||
}
|
||||
}
|
||||
return codeLensList;
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
protected List<CodeLens> assembleCodeLenseForAutowired(List<LiveBean> wiredBeans, IJavaProject project, SpringBootApp app, TextDocument doc, Range nameRange, ASTNode astNode) {
|
||||
return LiveHoverUtils.createCodeLensesForBeans(nameRange, wiredBeans,
|
||||
AutowiredHoverProvider.BEANS_PREFIX_PLAIN_TEXT, MAX_INLINE_BEANS_STRING_LENGTH,
|
||||
INLINE_BEANS_STRING_SEPARATOR);
|
||||
}
|
||||
|
||||
protected List<LiveBean> findWiredBeans(IJavaProject project, SpringBootApp app, List<LiveBean> relevantBeans, ASTNode astNode) {
|
||||
@@ -131,8 +137,6 @@ public abstract class AbstractInjectedIntoHoverProvider implements HoverProvider
|
||||
protected Hover assembleHover(IJavaProject project, SpringBootApp[] runningApps, LiveBean definedBean, ASTNode astNode) {
|
||||
StringBuilder hover = new StringBuilder();
|
||||
|
||||
boolean hasContent = false;
|
||||
|
||||
for (SpringBootApp app : runningApps) {
|
||||
|
||||
List<LiveBean> relevantBeans = LiveHoverUtils.findRelevantBeans(app, definedBean);
|
||||
@@ -140,9 +144,7 @@ public abstract class AbstractInjectedIntoHoverProvider implements HoverProvider
|
||||
if (!relevantBeans.isEmpty()) {
|
||||
List<LiveBean> injectedBeans = getRelevantInjectedIntoBeans(project, app, definedBean, relevantBeans);
|
||||
|
||||
if (!hasContent) {
|
||||
hasContent = true;
|
||||
} else {
|
||||
if (hover.length() > 0) {
|
||||
hover.append(" \n \n");
|
||||
}
|
||||
|
||||
@@ -167,7 +169,7 @@ public abstract class AbstractInjectedIntoHoverProvider implements HoverProvider
|
||||
}
|
||||
|
||||
}
|
||||
if (hasContent) {
|
||||
if (hover.length() > 0) {
|
||||
return new Hover(ImmutableList.of(Either.forLeft(hover.toString())));
|
||||
} else {
|
||||
return null;
|
||||
|
||||
@@ -16,7 +16,16 @@ import java.util.Optional;
|
||||
|
||||
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.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
|
||||
import org.eclipse.lsp4j.CodeLens;
|
||||
import org.eclipse.lsp4j.Hover;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.gradle.internal.impldep.com.google.common.collect.ImmutableList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.autowired.AutowiredHoverProvider;
|
||||
import org.springframework.ide.vscode.boot.java.links.SourceLinks;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
@@ -24,9 +33,12 @@ import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.livebean.LiveBean;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.Optionals;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
public class BeanInjectedIntoHoverProvider extends AbstractInjectedIntoHoverProvider {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(BeanInjectedIntoHoverProvider.class);
|
||||
|
||||
public BeanInjectedIntoHoverProvider(SourceLinks sourceLinks) {
|
||||
super(sourceLinks);
|
||||
}
|
||||
@@ -75,12 +87,79 @@ public class BeanInjectedIntoHoverProvider extends AbstractInjectedIntoHoverProv
|
||||
@Override
|
||||
protected List<LiveBean> findWiredBeans(IJavaProject project, SpringBootApp app, List<LiveBean> relevantBeans, ASTNode astNode) {
|
||||
if (astNode instanceof Annotation) {
|
||||
// @Bean annotation case
|
||||
MethodDeclaration beanMethod = ASTUtils.getAnnotatedMethod((Annotation) astNode);
|
||||
if (beanMethod != null) {
|
||||
return AutowiredHoverProvider.getRelevantAutowiredBeans(project, beanMethod, app, relevantBeans);
|
||||
}
|
||||
} else if (astNode instanceof SingleVariableDeclaration) {
|
||||
// Bean method parameter case
|
||||
return AutowiredHoverProvider.getRelevantAutowiredBeans(project, astNode, app, relevantBeans);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<CodeLens> assembleCodeLenseForAutowired(List<LiveBean> wiredBeans, IJavaProject project,
|
||||
SpringBootApp app, TextDocument doc, Range nameRange, ASTNode astNode) {
|
||||
ImmutableList.Builder<CodeLens> builder = ImmutableList.builder();
|
||||
|
||||
// Code lens for the @Bean annotation
|
||||
builder.addAll(super.assembleCodeLenseForAutowired(wiredBeans, project, app, doc, nameRange, astNode));
|
||||
|
||||
if (astNode instanceof Annotation) {
|
||||
// Add code lenses for method parameters
|
||||
MethodDeclaration beanMethod = ASTUtils.getAnnotatedMethod((Annotation) astNode);
|
||||
if (beanMethod != null) {
|
||||
builder.addAll(LiveHoverUtils.createCodeLensForMethodParameters(app, project, beanMethod, doc, wiredBeans));
|
||||
}
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hover provideMethodParameterHover(SingleVariableDeclaration parameter, int offset, TextDocument doc,
|
||||
IJavaProject project, SpringBootApp[] runningApps) {
|
||||
try {
|
||||
if (runningApps.length > 0) {
|
||||
Range range = ASTUtils.nodeRegion(doc, parameter.getName()).asRange();
|
||||
MethodDeclaration method = (MethodDeclaration) parameter.getParent();
|
||||
Annotation beanAnnotation = getBeanAnnotation(method);
|
||||
if (beanAnnotation != null) {
|
||||
LiveBean definedBean = getDefinedBean(beanAnnotation);
|
||||
if (definedBean != null) {
|
||||
Hover hover = assembleHover(project, runningApps, definedBean, parameter);
|
||||
if (hover != null) {
|
||||
hover.setRange(range);
|
||||
}
|
||||
return hover;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Annotation getBeanAnnotation(MethodDeclaration method) {
|
||||
List<?> modifiers = method.modifiers();
|
||||
for (Object modifier : modifiers) {
|
||||
if (modifier instanceof Annotation) {
|
||||
Annotation annotation = (Annotation) modifier;
|
||||
ITypeBinding typeBinding = annotation.resolveTypeBinding();
|
||||
if (typeBinding != null) {
|
||||
String fqName = typeBinding.getQualifiedName();
|
||||
if (Annotations.BEAN.equals(fqName)) {
|
||||
return annotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ public class ComponentInjectionsHoverProvider extends AbstractInjectedIntoHoverP
|
||||
if (Stream.of(runningApps).anyMatch(app -> LiveHoverUtils.hasRelevantBeans(app, definedBean))) {
|
||||
Optional<Range> nameRange = Optional.of(ASTUtils.nodeRegion(doc, typeDeclaration.getName()).asRange());
|
||||
if (nameRange.isPresent()) {
|
||||
List<CodeLens> codeLenses = assembleCodeLenses(project, runningApps, definedBean, nameRange.get(), typeDeclaration);
|
||||
List<CodeLens> codeLenses = assembleCodeLenses(project, runningApps, definedBean, doc, nameRange.get(), typeDeclaration);
|
||||
return codeLenses.isEmpty() ? ImmutableList.of(new CodeLens(nameRange.get())) : codeLenses;
|
||||
}
|
||||
}
|
||||
@@ -146,8 +146,6 @@ public class ComponentInjectionsHoverProvider extends AbstractInjectedIntoHoverP
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected List<LiveBean> findWiredBeans(IJavaProject project, SpringBootApp app, List<LiveBean> relevantBeans,
|
||||
ASTNode astNode) {
|
||||
|
||||
@@ -17,22 +17,32 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
|
||||
import org.eclipse.lsp4j.CodeLens;
|
||||
import org.eclipse.lsp4j.Command;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.autowired.AutowiredHoverProvider;
|
||||
import org.springframework.ide.vscode.boot.java.links.SourceLinks;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringResource;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.livebean.LiveBean;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.livebean.LiveBeansModel;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
public class LiveHoverUtils {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(LiveHoverUtils.class);
|
||||
|
||||
public static final LiveBean CANT_MATCH_PROPER_BEAN = LiveBean.builder().id("UNKNOWN").build();
|
||||
|
||||
public static String showBean(LiveBean bean) {
|
||||
@@ -161,7 +171,7 @@ public class LiveHoverUtils {
|
||||
try {
|
||||
return niceAppName(app.getProcessID(), app.getProcessName());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("", e);
|
||||
return app.toString();
|
||||
}
|
||||
}
|
||||
@@ -189,6 +199,27 @@ public class LiveHoverUtils {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<CodeLens> createCodeLensForMethodParameters(SpringBootApp app, IJavaProject project, MethodDeclaration method, TextDocument doc, List<LiveBean> wiredBeans) {
|
||||
ImmutableList.Builder<CodeLens> builder = ImmutableList.builder();
|
||||
method.parameters().forEach(p -> {
|
||||
if (p instanceof SingleVariableDeclaration) {
|
||||
SingleVariableDeclaration parameter = (SingleVariableDeclaration) p;
|
||||
List<LiveBean> parameterMatchingBean = AutowiredHoverProvider.findAutowiredBeans(project, parameter, wiredBeans);
|
||||
if (parameterMatchingBean.size() == 0) {
|
||||
log.warn("No Live Bean matching parameter `" + parameter.getName().getIdentifier() + " for method " + method);
|
||||
} else {
|
||||
try {
|
||||
builder.add(new CodeLens(ASTUtils.nodeRegion(doc, parameter.getName()).asRange()));
|
||||
} catch (BadLocationException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static StringBuilder createBeansTitlePlainText(Collection<LiveBean> beans, String prefix, int maxInlineBeansStringLength, String beansSeparator) {
|
||||
StringBuilder sb = new StringBuilder(prefix);
|
||||
if (LiveHoverUtils.doBeansFitInline(beans, maxInlineBeansStringLength, beansSeparator)) {
|
||||
|
||||
@@ -507,7 +507,7 @@ public class AutowiredHoverProviderTest {
|
||||
"}\n"
|
||||
);
|
||||
|
||||
editor.assertHighlights("@Component", "SomeComponent");
|
||||
editor.assertHighlights("@Component", "SomeComponent", "depA", "depB");
|
||||
|
||||
editor.assertTrimmedHover("SomeComponent", 2,
|
||||
"**← `DependencyA` `DependencyB`**\n" +
|
||||
@@ -519,6 +519,25 @@ public class AutowiredHoverProviderTest {
|
||||
"Bean id: `someComponent` \n" +
|
||||
"Process [PID=111, name=`the-app`]\n"
|
||||
);
|
||||
|
||||
editor.assertTrimmedHover("depA", 2,
|
||||
"**← `DependencyA`**\n" +
|
||||
"- Bean: `dependencyA` \n" +
|
||||
" Type: `com.example.DependencyA`\n" +
|
||||
" \n" +
|
||||
"Bean id: `someComponent` \n" +
|
||||
"Process [PID=111, name=`the-app`]\n"
|
||||
);
|
||||
|
||||
editor.assertTrimmedHover("depB", 2,
|
||||
"**← `DependencyB`**\n" +
|
||||
"- Bean: `dependencyB` \n" +
|
||||
" Type: `com.example.DependencyB`\n" +
|
||||
" \n" +
|
||||
"Bean id: `someComponent` \n" +
|
||||
"Process [PID=111, name=`the-app`]\n"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -718,7 +737,7 @@ public class AutowiredHoverProviderTest {
|
||||
" private IDependency a;\n" +
|
||||
" private IDependency b;\n" +
|
||||
"\n" +
|
||||
" public SomeComponent(@Qualifier(\"dependencyA\") IDependency a, @Qualifier(\"dependencyB\") IDependency b) {\n" +
|
||||
" public SomeComponent(@Qualifier(\"dependencyA\") IDependency depA, @Qualifier(\"dependencyB\") IDependency depB) {\n" +
|
||||
" this.a = a;\n" +
|
||||
" this.b = b;\n" +
|
||||
" }\n" +
|
||||
@@ -726,7 +745,7 @@ public class AutowiredHoverProviderTest {
|
||||
"}\n"
|
||||
);
|
||||
|
||||
editor.assertHighlights("@Component", "SomeComponent");
|
||||
editor.assertHighlights("@Component", "SomeComponent", "depA", "depB");
|
||||
editor.assertTrimmedHover("SomeComponent", 2,
|
||||
"**← `DependencyA` `DependencyB`**\n" +
|
||||
"- Bean: `dependencyA` \n" +
|
||||
@@ -737,6 +756,25 @@ public class AutowiredHoverProviderTest {
|
||||
"Bean id: `someComponent` \n" +
|
||||
"Process [PID=111, name=`the-app`]\n"
|
||||
);
|
||||
|
||||
editor.assertTrimmedHover("depA",
|
||||
"**← `DependencyA`**\n" +
|
||||
"- Bean: `dependencyA` \n" +
|
||||
" Type: `com.example.DependencyA`\n" +
|
||||
" \n" +
|
||||
"Bean id: `someComponent` \n" +
|
||||
"Process [PID=111, name=`the-app`]\n"
|
||||
);
|
||||
|
||||
editor.assertTrimmedHover("depB",
|
||||
"**← `DependencyB`**\n" +
|
||||
"- Bean: `dependencyB` \n" +
|
||||
" Type: `com.example.DependencyB`\n" +
|
||||
" \n" +
|
||||
"Bean id: `someComponent` \n" +
|
||||
"Process [PID=111, name=`the-app`]\n"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -549,12 +549,12 @@ public class BeanInjectedIntoHoverProviderTest {
|
||||
"public class LocalConfig {\n" +
|
||||
" \n" +
|
||||
" @Bean(\"fooImplementation\")\n" +
|
||||
" Foo someFoo(DependencyA a) {\n" +
|
||||
" Foo someFoo(DependencyA depA) {\n" +
|
||||
" return new FooImplementation();\n" +
|
||||
" }\n" +
|
||||
"}"
|
||||
);
|
||||
editor.assertHighlights("@Bean");
|
||||
editor.assertHighlights("@Bean", "depA");
|
||||
editor.assertTrimmedHover("@Bean",
|
||||
"**← `DependencyA`**\n" +
|
||||
"- Bean: `depA` \n" +
|
||||
@@ -563,6 +563,16 @@ public class BeanInjectedIntoHoverProviderTest {
|
||||
"Bean id: `fooImplementation` \n" +
|
||||
"Process [PID=111, name=`the-app`]"
|
||||
);
|
||||
|
||||
editor.assertTrimmedHover("depA",
|
||||
"**← `DependencyA`**\n" +
|
||||
"- Bean: `depA` \n" +
|
||||
" Type: `hello.DependencyA`\n" +
|
||||
" \n" +
|
||||
"Bean id: `fooImplementation` \n" +
|
||||
"Process [PID=111, name=`the-app`]"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -603,12 +613,12 @@ public class BeanInjectedIntoHoverProviderTest {
|
||||
"public class LocalConfig {\n" +
|
||||
" \n" +
|
||||
" @Bean(\"fooImplementation\")\n" +
|
||||
" Foo someFoo(DependencyA a, DependencyB b) {\n" +
|
||||
" Foo someFoo(DependencyA depA, DependencyB depB) {\n" +
|
||||
" return new FooImplementation();\n" +
|
||||
" }\n" +
|
||||
"}"
|
||||
);
|
||||
editor.assertHighlights("@Bean");
|
||||
editor.assertHighlights("@Bean", "depA", "depB");
|
||||
editor.assertTrimmedHover("@Bean",
|
||||
"**← `DependencyA` `DependencyB`**\n" +
|
||||
"- Bean: `depA` \n" +
|
||||
@@ -619,6 +629,25 @@ public class BeanInjectedIntoHoverProviderTest {
|
||||
"Bean id: `fooImplementation` \n" +
|
||||
"Process [PID=111, name=`the-app`]"
|
||||
);
|
||||
|
||||
editor.assertTrimmedHover("depA",
|
||||
"**← `DependencyA`**\n" +
|
||||
"- Bean: `depA` \n" +
|
||||
" Type: `hello.DependencyA`\n" +
|
||||
" \n" +
|
||||
"Bean id: `fooImplementation` \n" +
|
||||
"Process [PID=111, name=`the-app`]"
|
||||
);
|
||||
|
||||
editor.assertTrimmedHover("depB",
|
||||
"**← `DependencyB`**\n" +
|
||||
"- Bean: `depB` \n" +
|
||||
" Type: `hello.DependencyB`\n" +
|
||||
" \n" +
|
||||
"Bean id: `fooImplementation` \n" +
|
||||
"Process [PID=111, name=`the-app`]"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -664,7 +693,7 @@ public class BeanInjectedIntoHoverProviderTest {
|
||||
" }\n" +
|
||||
"}"
|
||||
);
|
||||
editor.assertHighlights("@Bean");
|
||||
editor.assertHighlights("@Bean", "deps");
|
||||
editor.assertTrimmedHover("@Bean",
|
||||
"**← `DependencyA` `DependencyB`**\n" +
|
||||
"- Bean: `depA` \n" +
|
||||
@@ -675,7 +704,18 @@ public class BeanInjectedIntoHoverProviderTest {
|
||||
"Bean id: `fooImplementation` \n" +
|
||||
"Process [PID=111, name=`the-app`]"
|
||||
);
|
||||
}
|
||||
|
||||
editor.assertTrimmedHover("deps",
|
||||
"**← `DependencyA` `DependencyB`**\n" +
|
||||
"- Bean: `depA` \n" +
|
||||
" Type: `hello.DependencyA`\n" +
|
||||
"- Bean: `depB` \n" +
|
||||
" Type: `hello.DependencyB`\n" +
|
||||
" \n" +
|
||||
"Bean id: `fooImplementation` \n" +
|
||||
"Process [PID=111, name=`the-app`]"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beanWithQualifierWiring() throws Exception {
|
||||
@@ -715,7 +755,7 @@ public class BeanInjectedIntoHoverProviderTest {
|
||||
" }\n" +
|
||||
"}"
|
||||
);
|
||||
editor.assertHighlights("@Bean");
|
||||
editor.assertHighlights("@Bean", "deps");
|
||||
editor.assertTrimmedHover("@Bean",
|
||||
"**← `DependencyB`**\n" +
|
||||
"- Bean: `depB` \n" +
|
||||
@@ -724,5 +764,15 @@ public class BeanInjectedIntoHoverProviderTest {
|
||||
"Bean id: `fooImplementation` \n" +
|
||||
"Process [PID=111, name=`the-app`]"
|
||||
);
|
||||
|
||||
editor.assertTrimmedHover("deps",
|
||||
"**← `DependencyB`**\n" +
|
||||
"- Bean: `depB` \n" +
|
||||
" Type: `hello.DependencyB`\n" +
|
||||
" \n" +
|
||||
"Bean id: `fooImplementation` \n" +
|
||||
"Process [PID=111, name=`the-app`]"
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -501,7 +501,7 @@ public class ComponentInjectionsHoverProviderTest {
|
||||
" }\n" +
|
||||
"}\n"
|
||||
);
|
||||
editor.assertHighlights("@Component", "AutowiredClass");
|
||||
editor.assertHighlights("@Component", "AutowiredClass", "depA", "depB");
|
||||
editor.assertTrimmedHover("@Component",
|
||||
"**← `DependencyA` `DependencyB`**\n" +
|
||||
"- Bean: `dependencyA` \n" +
|
||||
|
||||
Reference in New Issue
Block a user