PT #159371605: Implicitly autowired constructor boot hint and hover
This commit is contained in:
@@ -600,18 +600,26 @@ public class Editor {
|
||||
}
|
||||
|
||||
public void assertTrimmedHover(String hoverOver, String expectedHover) throws Exception {
|
||||
int hoverPosition = getHoverPosition(hoverOver,1);
|
||||
assertTrimmedHover(hoverOver, 1, expectedHover);
|
||||
}
|
||||
|
||||
public void assertTrimmedHover(String hoverOver, int occurence, String expectedHover) throws Exception {
|
||||
int hoverPosition = getHoverPosition(hoverOver,occurence);
|
||||
Hover hover = harness.getHover(doc, doc.toPosition(hoverPosition));
|
||||
assertEquals(expectedHover.trim(), hoverString(hover).trim());
|
||||
}
|
||||
|
||||
public void assertNoHover(String hoverOver) throws Exception {
|
||||
int hoverPosition = getRawText().indexOf(hoverOver) + hoverOver.length() / 2;
|
||||
public void assertNoHover(String hoverOver, int occurence) throws Exception {
|
||||
int hoverPosition = getHoverPosition(hoverOver,occurence);
|
||||
Hover hover = harness.getHover(doc, doc.toPosition(hoverPosition));
|
||||
List<Either<String, MarkedString>> contents = hover.getContents().getLeft();
|
||||
assertTrue(contents.toString(), contents.isEmpty());
|
||||
}
|
||||
|
||||
public void assertNoHover(String hoverOver) throws Exception {
|
||||
assertNoHover(hoverOver, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies an expected textSnippet is contained in the hover text that is
|
||||
* computed when hovering mouse at position at the end of first occurrence of
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.FieldDeclaration;
|
||||
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.SingleVariableDeclaration;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
@@ -40,6 +41,7 @@ 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.java.IType;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
@@ -63,109 +65,116 @@ public class AutowiredHoverProvider implements HoverProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Range> getLiveHoverHints(Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
public Collection<Range> getLiveHoverHints(IJavaProject project, Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
LiveBean definedBean = getDefinedBeanForTypeDeclaration(ASTUtils.findDeclaringType(annotation));
|
||||
// Annotation is MarkerNode, parent is some field, method, variable declaration node.
|
||||
ASTNode declarationNode = annotation.getParent();
|
||||
try {
|
||||
LiveBean definedBean = getDefinedBean(annotation);
|
||||
if (definedBean != null) {
|
||||
for (SpringBootApp app : runningApps) {
|
||||
try {
|
||||
List<LiveBean> relevantBeans = LiveHoverUtils.findRelevantBeans(app, definedBean).collect(Collectors.toList());
|
||||
Range hoverRange = doc.toRange(annotation.getStartPosition(), annotation.getLength());
|
||||
return getLiveHoverHints(project, declarationNode, hoverRange, runningApps, definedBean);
|
||||
} catch (BadLocationException e) {
|
||||
log.error("", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!relevantBeans.isEmpty()) {
|
||||
for (LiveBean bean : relevantBeans) {
|
||||
String[] dependencies = bean.getDependencies();
|
||||
if (dependencies != null && dependencies.length > 0) {
|
||||
Range hoverRange = doc.toRange(annotation.getStartPosition(), annotation.getLength());
|
||||
return ImmutableList.of(hoverRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("", e);
|
||||
}
|
||||
private Collection<Range> 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 ImmutableList.of(range);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hover provideHover(ASTNode node, Annotation annotation, ITypeBinding type, int offset,
|
||||
TextDocument doc, IJavaProject project, SpringBootApp[] runningApps) {
|
||||
if (runningApps.length > 0) {
|
||||
LiveBean definedBean = getDefinedBeanForTypeDeclaration(ASTUtils.findDeclaringType(annotation));
|
||||
// Annotation is MarkerNode, parent is some field, method, variable declaration node.
|
||||
ASTNode declarationNode = annotation.getParent();
|
||||
return provideHover(definedBean, declarationNode, offset, doc, project, runningApps);
|
||||
}
|
||||
|
||||
private Hover provideHover(LiveBean definedBean, ASTNode declarationNode, int offset, TextDocument doc,
|
||||
IJavaProject project, SpringBootApp[] runningApps) {
|
||||
if (definedBean != null && runningApps.length > 0) {
|
||||
|
||||
StringBuilder hover = new StringBuilder();
|
||||
|
||||
LiveBean definedBean = getDefinedBean(annotation);
|
||||
if (definedBean != null) {
|
||||
boolean hasContent = false;
|
||||
|
||||
boolean hasContent = false;
|
||||
for (SpringBootApp app : runningApps) {
|
||||
|
||||
for (SpringBootApp app : runningApps) {
|
||||
LiveBeansModel beans = app.getBeans();
|
||||
List<LiveBean> relevantBeans = LiveHoverUtils.findRelevantBeans(app, definedBean).collect(Collectors.toList());
|
||||
List<LiveBean> autowiredBeans = getRelevantAutowiredBeans(project, declarationNode, app, definedBean);
|
||||
|
||||
if (!relevantBeans.isEmpty()) {
|
||||
List<LiveBean> allDependencyBeans = relevantBeans.stream()
|
||||
.flatMap(b -> Arrays.stream(b.getDependencies()))
|
||||
.distinct()
|
||||
.flatMap(d -> beans.getBeansOfName(d).stream())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!allDependencyBeans.isEmpty()) {
|
||||
|
||||
// parent is marker node, grandparent is some field, method, variable declaration node.
|
||||
ASTNode declarationNode = node.getParent().getParent();
|
||||
List<LiveBean> autowiredBeans = findAutowiredBeans(project, declarationNode, allDependencyBeans);
|
||||
if (autowiredBeans.isEmpty()) {
|
||||
// Show all relevant dependency beans
|
||||
autowiredBeans = allDependencyBeans;
|
||||
}
|
||||
|
||||
if (!autowiredBeans.isEmpty()) {
|
||||
if (!hasContent) {
|
||||
hasContent = true;
|
||||
} else {
|
||||
hover.append(" \n \n");
|
||||
}
|
||||
hover.append("**Autowired → ");
|
||||
if (LiveHoverUtils.doBeansFitInline(autowiredBeans, MAX_INLINE_BEANS_STRING_LENGTH, INLINE_BEANS_STRING_SEPARATOR)) {
|
||||
hover.append(autowiredBeans.stream().map(b -> LiveHoverUtils.showBeanInline(server, project, b)).collect(Collectors.joining(INLINE_BEANS_STRING_SEPARATOR)));
|
||||
hover.append("**\n");
|
||||
} else {
|
||||
hover.append(autowiredBeans.size());
|
||||
hover.append(" beans**\n");
|
||||
}
|
||||
if (!autowiredBeans.isEmpty()) {
|
||||
if (!hasContent) {
|
||||
hasContent = true;
|
||||
} else {
|
||||
hover.append(" \n \n");
|
||||
}
|
||||
hover.append("**Autowired → ");
|
||||
if (LiveHoverUtils.doBeansFitInline(autowiredBeans, MAX_INLINE_BEANS_STRING_LENGTH,
|
||||
INLINE_BEANS_STRING_SEPARATOR)) {
|
||||
hover.append(autowiredBeans.stream().map(b -> LiveHoverUtils.showBeanInline(server, project, b))
|
||||
.collect(Collectors.joining(INLINE_BEANS_STRING_SEPARATOR)));
|
||||
hover.append("**\n");
|
||||
} else {
|
||||
hover.append(autowiredBeans.size());
|
||||
hover.append(" beans**\n");
|
||||
}
|
||||
// if (autowiredBeans.size() == 1) {
|
||||
// hover.append(LiveHoverUtils.showBeanIdAndTypeInline(server, project, autowiredBeans.get(0)));
|
||||
// } else {
|
||||
// hover.append(autowiredBeans.size());
|
||||
// hover.append(" beans**\n");
|
||||
// }
|
||||
hover.append(autowiredBeans.stream()
|
||||
.map(b -> "- " + LiveHoverUtils.showBeanWithResource(server, b, " ", project))
|
||||
.collect(Collectors.joining("\n"))
|
||||
);
|
||||
hover.append("\n \n");
|
||||
hover.append(LiveHoverUtils.niceAppName(app));
|
||||
}
|
||||
}
|
||||
}
|
||||
hover.append(autowiredBeans.stream()
|
||||
.map(b -> "- " + LiveHoverUtils.showBeanWithResource(server, b, " ", project))
|
||||
.collect(Collectors.joining("\n")));
|
||||
hover.append("\n \n");
|
||||
hover.append(LiveHoverUtils.niceAppName(app));
|
||||
}
|
||||
|
||||
}
|
||||
if (hasContent) {
|
||||
return new Hover(ImmutableList.of(Either.forLeft(hover.toString())));
|
||||
}
|
||||
}
|
||||
if (hasContent) {
|
||||
return new Hover(ImmutableList.of(Either.forLeft(hover.toString())));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<LiveBean> getRelevantAutowiredBeans(IJavaProject project, ASTNode declarationNode, SpringBootApp app, LiveBean definedBean) {
|
||||
LiveBeansModel beans = app.getBeans();
|
||||
List<LiveBean> relevantBeans = LiveHoverUtils.findRelevantBeans(app, definedBean)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!relevantBeans.isEmpty()) {
|
||||
List<LiveBean> allDependencyBeans = relevantBeans.stream()
|
||||
.flatMap(b -> Arrays.stream(b.getDependencies())).distinct()
|
||||
.flatMap(d -> beans.getBeansOfName(d).stream()).collect(Collectors.toList());
|
||||
|
||||
if (!allDependencyBeans.isEmpty()) {
|
||||
|
||||
List<LiveBean> autowiredBeans = findAutowiredBeans(project, declarationNode,
|
||||
allDependencyBeans);
|
||||
if (autowiredBeans.isEmpty()) {
|
||||
// Show all relevant dependency beans
|
||||
autowiredBeans = allDependencyBeans;
|
||||
} else {
|
||||
return autowiredBeans;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<LiveBean> findAutowiredBeans(IJavaProject project, ASTNode declarationNode, Collection<LiveBean> beans) {
|
||||
if (declarationNode instanceof MethodDeclaration) {
|
||||
@@ -198,6 +207,9 @@ public class AutowiredHoverProvider implements HoverProvider {
|
||||
.map(subType -> matchBeans(project, beans, subType.getFullyQualifiedName()))
|
||||
.filter(relevantBeans -> !relevantBeans.isEmpty())
|
||||
.blockFirst();
|
||||
if (relevant == null) {
|
||||
relevant = Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,40 +225,71 @@ public class AutowiredHoverProvider implements HoverProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private LiveBean getDefinedBean(Annotation autowiredAnnotation) {
|
||||
TypeDeclaration declaringType = ASTUtils.findDeclaringType(autowiredAnnotation);
|
||||
private LiveBean getDefinedBeanForTypeDeclaration(TypeDeclaration declaringType) {
|
||||
if (declaringType != null) {
|
||||
for (Annotation annotation : ASTUtils.getAnnotations(declaringType)) {
|
||||
if (AnnotationHierarchies.isSubtypeOf(annotation, Annotations.COMPONENT)) {
|
||||
return ComponentInjectionsHoverProvider.getDefinedBeanForComponent(annotation);
|
||||
}
|
||||
}
|
||||
//TODO: handler below is an attempt to do something that may work in many cases, but is probably
|
||||
// missing logics for special cases where annotation attributes on the declaring type matter.
|
||||
// TODO: handler below is an attempt to do something that may work in many
|
||||
// cases, but is probably
|
||||
// missing logics for special cases where annotation attributes on the declaring
|
||||
// type matter.
|
||||
ITypeBinding beanType = declaringType.resolveBinding();
|
||||
if (beanType!=null) {
|
||||
if (beanType != null) {
|
||||
String beanTypeName = beanType.getName();
|
||||
if (StringUtil.hasText(beanTypeName)) {
|
||||
return LiveBean.builder()
|
||||
.id(Character.toLowerCase(beanTypeName.charAt(0)) + beanTypeName.substring(1))
|
||||
.type(beanTypeName)
|
||||
.build();
|
||||
.type(beanTypeName).build();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hover provideHover(ASTNode node, TypeDeclaration typeDeclaration, ITypeBinding type, int offset,
|
||||
TextDocument doc, IJavaProject project, SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
public Hover provideHover(MethodDeclaration methodDeclaration, int offset, TextDocument doc, IJavaProject project, SpringBootApp[] runningApps) {
|
||||
LiveBean definedBean = getDefinedBeanForImplicitAutowiredConstructor(methodDeclaration);
|
||||
return provideHover(definedBean, methodDeclaration, offset, doc, project, runningApps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Range> getLiveHoverHints(TypeDeclaration typeDeclaration, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
public Collection<Range> getLiveHoverHints(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);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private LiveBean getDefinedBeanForImplicitAutowiredConstructor(MethodDeclaration methodDeclaration) {
|
||||
if (methodDeclaration.isConstructor() && !methodDeclaration.parameters().isEmpty()) {
|
||||
TypeDeclaration typeDeclaration = ASTUtils.findDeclaringType(methodDeclaration);
|
||||
if (typeDeclaration != null && ASTUtils.hasExactlyOneConstructor(typeDeclaration) && !hasAutowiredAnnotation(methodDeclaration)) {
|
||||
return getDefinedBeanForTypeDeclaration(typeDeclaration);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
String fqName = typeBinding.getQualifiedName();
|
||||
return Annotations.AUTOWIRED.equals(fqName) || Annotations.INJECT.equals(fqName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.HoverProvider;
|
||||
import org.springframework.ide.vscode.boot.java.livehover.LiveHoverUtils;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.LiveConditional;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.LocalSpringBootApp;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
@@ -50,7 +49,7 @@ public class ConditionalsLiveHoverProvider implements HoverProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Range> getLiveHoverHints(Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
public Collection<Range> getLiveHoverHints(IJavaProject project, Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
try {
|
||||
Optional<List<LiveConditional>> val = getMatchedLiveConditionals(annotation, runningApps);
|
||||
if (val.isPresent()) {
|
||||
@@ -156,16 +155,4 @@ public class ConditionalsLiveHoverProvider implements HoverProvider {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hover provideHover(ASTNode node, TypeDeclaration typeDeclaration, ITypeBinding type, int offset,
|
||||
TextDocument doc, IJavaProject project, SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Range> getLiveHoverHints(TypeDeclaration typeDeclaration, TextDocument doc,
|
||||
SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
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.NodeFinder;
|
||||
import org.eclipse.jdt.core.dom.NormalAnnotation;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
@@ -140,6 +141,19 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
|
||||
return super.visit(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MethodDeclaration node) {
|
||||
try {
|
||||
extractLiveHintsForMethod(node, document, runningBootApps, result);
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
|
||||
return super.visit(node);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -149,13 +163,33 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
});
|
||||
}
|
||||
|
||||
protected void extractLiveHintsForMethod(MethodDeclaration methodDeclaration, TextDocument doc,
|
||||
SpringBootApp[] runningApps, Collection<Range> result) {
|
||||
Collection<HoverProvider> providers = this.hoverProviders.getAll();
|
||||
if (!providers.isEmpty()) {
|
||||
for (HoverProvider provider : providers) {
|
||||
getProject(doc).ifPresent(project -> {
|
||||
if (hasActuatorDependency(project)) {
|
||||
Collection<Range> hints = provider.getLiveHoverHints(project, methodDeclaration, doc, runningApps);
|
||||
if (hints!=null) {
|
||||
result.addAll(hints);
|
||||
}
|
||||
} else {
|
||||
//Do nothing... we don't want a highlight for the 'no actuator warning'
|
||||
//ASTUtils.nameRange(doc, annotation).ifPresent(result::add);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void extractLiveHintsForType(TypeDeclaration typeDeclaration, TextDocument doc, SpringBootApp[] runningApps, Collection<Range> result) {
|
||||
Collection<HoverProvider> providers = this.hoverProviders.getAll();
|
||||
if (!providers.isEmpty()) {
|
||||
for (HoverProvider provider : providers) {
|
||||
getProject(doc).ifPresent(project -> {
|
||||
if (hasActuatorDependency(project)) {
|
||||
Collection<Range> hints = provider.getLiveHoverHints(typeDeclaration, doc, runningApps);
|
||||
Collection<Range> hints = provider.getLiveHoverHints(project, typeDeclaration, doc, runningApps);
|
||||
if (hints!=null) {
|
||||
result.addAll(hints);
|
||||
}
|
||||
@@ -175,7 +209,7 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
for (HoverProvider provider : this.hoverProviders.get(type)) {
|
||||
getProject(doc).ifPresent(project -> {
|
||||
if (hasActuatorDependency(project)) {
|
||||
Collection<Range> hints = provider.getLiveHoverHints(annotation, doc, runningApps);
|
||||
Collection<Range> hints = provider.getLiveHoverHints(project, annotation, doc, runningApps);
|
||||
if (hints!=null) {
|
||||
result.addAll(hints);
|
||||
}
|
||||
@@ -215,10 +249,29 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
}
|
||||
|
||||
// then do additional AST node coverage
|
||||
if (node instanceof SimpleName && node.getParent() instanceof TypeDeclaration) {
|
||||
return provideHoverForTypeDeclaration(node, (TypeDeclaration) node.getParent(), offset, doc, project);
|
||||
if (node instanceof SimpleName) {
|
||||
ASTNode parent = node.getParent();
|
||||
if (parent instanceof TypeDeclaration) {
|
||||
return provideHoverForTypeDeclaration(node, (TypeDeclaration) parent, offset, doc, project);
|
||||
} else if (parent instanceof MethodDeclaration) {
|
||||
return provideHoverForMethodDeclaration((MethodDeclaration) parent, offset, doc, project);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Hover provideHoverForMethodDeclaration(MethodDeclaration methodDeclaration, int offset, TextDocument doc,
|
||||
IJavaProject project) {
|
||||
SpringBootApp[] runningApps = getRunningSpringApps(project);
|
||||
if (runningApps.length > 0) {
|
||||
for (HoverProvider provider : this.hoverProviders.getAll()) {
|
||||
Hover hover = provider.provideHover(methodDeclaration, offset, doc, project, runningApps);
|
||||
if (hover!=null) {
|
||||
//TODO: compose multiple hovers somehow instead of just returning the first one?
|
||||
return hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import java.util.Collection;
|
||||
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.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.Hover;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
@@ -27,10 +28,24 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
*/
|
||||
public interface HoverProvider {
|
||||
|
||||
Hover provideHover(ASTNode node, Annotation annotation, ITypeBinding type, int offset, TextDocument doc, IJavaProject project, SpringBootApp[] runningApps);
|
||||
Hover provideHover(ASTNode node, TypeDeclaration typeDeclaration, ITypeBinding type, int offset, TextDocument doc, IJavaProject project, SpringBootApp[] runningApps);
|
||||
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;
|
||||
}
|
||||
|
||||
Collection<Range> getLiveHoverHints(Annotation annotation, TextDocument doc, SpringBootApp[] runningApps);
|
||||
Collection<Range> getLiveHoverHints(TypeDeclaration typeDeclaration, TextDocument doc, SpringBootApp[] runningApps);
|
||||
default Collection<Range> getLiveHoverHints(IJavaProject project, Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
default Collection<Range> getLiveHoverHints(IJavaProject project,TypeDeclaration typeDeclaration, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
default Collection<Range> getLiveHoverHints(IJavaProject project, MethodDeclaration methodDeclaration, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ 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.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
@@ -44,7 +43,7 @@ public abstract class AbstractInjectedIntoHoverProvider implements HoverProvider
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Range> getLiveHoverHints(Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
public Collection<Range> getLiveHoverHints(IJavaProject project, Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
// Highlight if any running app contains an instance of this component
|
||||
try {
|
||||
if (runningApps.length > 0) {
|
||||
@@ -89,7 +88,6 @@ public abstract class AbstractInjectedIntoHoverProvider implements HoverProvider
|
||||
|
||||
for (LiveBean bean : relevantBeans) {
|
||||
addInjectedInto(definedBean, hover, beans, bean, project);
|
||||
addAutomaticallyWiredContructor(hover, annotation, beans, bean, project);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,12 +101,6 @@ public abstract class AbstractInjectedIntoHoverProvider implements HoverProvider
|
||||
|
||||
protected abstract LiveBean getDefinedBean(Annotation annotation);
|
||||
|
||||
protected void addAutomaticallyWiredContructor(StringBuilder hover, Annotation annotation, LiveBeansModel beans, LiveBean bean, IJavaProject project) {
|
||||
//This doesn't really belong here, but it accomodates Martin's additional logic to handle implicitly
|
||||
//@Autowired constructor.
|
||||
//This does nothing by default as its really only relevant to @Component annotation report.
|
||||
}
|
||||
|
||||
protected void addInjectedInto(LiveBean definedBean, StringBuilder hover, LiveBeansModel beans, LiveBean bean, IJavaProject project) {
|
||||
hover.append("\n\n");
|
||||
List<LiveBean> dependers = beans.getBeansDependingOn(bean.getId());
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.Hover;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
@@ -81,7 +80,7 @@ public class ActiveProfilesProvider implements HoverProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Range> getLiveHoverHints(Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
public Collection<Range> getLiveHoverHints(IJavaProject project, Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
if (runningApps.length > 0) {
|
||||
Builder<Range> ranges = ImmutableList.builder();
|
||||
nameRange(doc, annotation).ifPresent(ranges::add);
|
||||
@@ -130,16 +129,4 @@ public class ActiveProfilesProvider implements HoverProvider {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hover provideHover(ASTNode node, TypeDeclaration typeDeclaration, ITypeBinding type, int offset,
|
||||
TextDocument doc, IJavaProject project, SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Range> getLiveHoverHints(TypeDeclaration typeDeclaration, TextDocument doc,
|
||||
SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,24 +10,14 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.livehover;
|
||||
|
||||
import java.util.Collection;
|
||||
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.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.Hover;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
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.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.util.Optionals;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
public class BeanInjectedIntoHoverProvider extends AbstractInjectedIntoHoverProvider {
|
||||
|
||||
@@ -76,16 +66,4 @@ public class BeanInjectedIntoHoverProvider extends AbstractInjectedIntoHoverProv
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hover provideHover(ASTNode node, TypeDeclaration typeDeclaration, ITypeBinding type, int offset,
|
||||
TextDocument doc, IJavaProject project, SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Range> getLiveHoverHints(TypeDeclaration typeDeclaration, TextDocument doc,
|
||||
SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,8 +20,6 @@ import java.util.stream.Stream;
|
||||
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.Range;
|
||||
@@ -46,49 +44,6 @@ public class ComponentInjectionsHoverProvider extends AbstractInjectedIntoHoverP
|
||||
super(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addAutomaticallyWiredContructor(StringBuilder hover, Annotation annotation, LiveBeansModel beans, LiveBean bean, IJavaProject project) {
|
||||
TypeDeclaration typeDecl = ASTUtils.findDeclaringType(annotation);
|
||||
if (typeDecl != null) {
|
||||
MethodDeclaration[] constructors = ASTUtils.findConstructors(typeDecl);
|
||||
|
||||
if (constructors != null && constructors.length == 1 && !hasAutowiredAnnotation(constructors[0])) {
|
||||
String[] dependencies = bean.getDependencies();
|
||||
|
||||
if (dependencies != null && dependencies.length > 0) {
|
||||
hover.append("\n\n");
|
||||
hover.append(LiveHoverUtils.showBean(bean) + " got autowired with:\n\n");
|
||||
|
||||
boolean firstDependency = true;
|
||||
for (String injectedBean : dependencies) {
|
||||
if (!firstDependency) {
|
||||
hover.append("\n");
|
||||
}
|
||||
List<LiveBean> dependencyBeans = beans.getBeansOfName(injectedBean);
|
||||
for (LiveBean dependencyBean : dependencyBeans) {
|
||||
hover.append("- " + LiveHoverUtils.showBeanWithResource(server, dependencyBean, " ", project));
|
||||
}
|
||||
firstDependency = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
String fqName = typeBinding.getQualifiedName();
|
||||
return Annotations.AUTOWIRED.equals(fqName) || Annotations.INJECT.equals(fqName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LiveBean getDefinedBean(Annotation annotation) {
|
||||
return getDefinedBeanForComponent(annotation);
|
||||
@@ -132,7 +87,7 @@ public class ComponentInjectionsHoverProvider extends AbstractInjectedIntoHoverP
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Range> getLiveHoverHints(TypeDeclaration typeDeclaration, TextDocument doc,
|
||||
public Collection<Range> getLiveHoverHints(IJavaProject project, TypeDeclaration typeDeclaration, TextDocument doc,
|
||||
SpringBootApp[] runningApps) {
|
||||
if (runningApps.length > 0 && !isComponentAnnotatedType(typeDeclaration)) {
|
||||
try {
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
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;
|
||||
@@ -55,7 +54,7 @@ public class RequestMappingHoverProvider implements HoverProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Range> getLiveHoverHints(Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
public Collection<Range> getLiveHoverHints(IJavaProject project, Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
try {
|
||||
if (runningApps.length > 0) {
|
||||
List<Tuple2<RequestMapping, SpringBootApp>> val = getRequestMappingMethodFromRunningApp(annotation, runningApps);
|
||||
@@ -173,16 +172,4 @@ public class RequestMappingHoverProvider implements HoverProvider {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hover provideHover(ASTNode node, TypeDeclaration typeDeclaration, ITypeBinding type, int offset,
|
||||
TextDocument doc, IJavaProject project, SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Range> getLiveHoverHints(TypeDeclaration typeDeclaration, TextDocument doc,
|
||||
SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -128,8 +127,7 @@ public class ASTUtils {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public static TypeDeclaration findDeclaringType(Annotation annotation) {
|
||||
ASTNode node = annotation;
|
||||
public static TypeDeclaration findDeclaringType(ASTNode node) {
|
||||
while (node != null && !(node instanceof TypeDeclaration)) {
|
||||
node = node.getParent();
|
||||
}
|
||||
@@ -137,20 +135,21 @@ public class ASTUtils {
|
||||
return node != null ? (TypeDeclaration) node : null;
|
||||
}
|
||||
|
||||
public static MethodDeclaration[] findConstructors(TypeDeclaration typeDecl) {
|
||||
List<MethodDeclaration> constructors = new ArrayList<>();
|
||||
|
||||
public static boolean hasExactlyOneConstructor(TypeDeclaration typeDecl) {
|
||||
boolean oneFound = false;
|
||||
MethodDeclaration[] methods = typeDecl.getMethods();
|
||||
for (MethodDeclaration methodDeclaration : methods) {
|
||||
if (methodDeclaration.isConstructor()) {
|
||||
constructors.add(methodDeclaration);
|
||||
if (oneFound) {
|
||||
return false;
|
||||
} else {
|
||||
oneFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return constructors.toArray(new MethodDeclaration[constructors.size()]);
|
||||
return oneFound;
|
||||
}
|
||||
|
||||
|
||||
public static MethodDeclaration getAnnotatedMethod(Annotation annotation) {
|
||||
ASTNode parent = annotation.getParent();
|
||||
if (parent instanceof MethodDeclaration) {
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.value;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
@@ -67,11 +66,6 @@ public class ValueHoverProvider implements HoverProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Range> getLiveHoverHints(Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Hover provideHover(String value, int offset, int nodeStartOffset, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
|
||||
try {
|
||||
@@ -206,10 +200,4 @@ public class ValueHoverProvider implements HoverProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Range> getLiveHoverHints(TypeDeclaration typeDeclaration, TextDocument doc,
|
||||
SpringBootApp[] runningApps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -415,4 +415,165 @@ public class AutowiredHoverProviderTest {
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void implicitAutowiringSingleConstructor() throws Exception {
|
||||
LiveBeansModel beans = LiveBeansModel.builder()
|
||||
.add(LiveBean.builder()
|
||||
.id("someComponent")
|
||||
.type("com.example.SomeComponent")
|
||||
.dependencies("dependencyA", "dependencyB")
|
||||
.build()
|
||||
)
|
||||
.add(LiveBean.builder()
|
||||
.id("dependencyA")
|
||||
.type("com.example.DependencyA")
|
||||
.build()
|
||||
)
|
||||
.add(LiveBean.builder()
|
||||
.id("dependencyB")
|
||||
.type("com.example.DependencyB")
|
||||
.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 SomeComponent {\n" +
|
||||
"\n" +
|
||||
" private DepedencyA depA;\n" +
|
||||
" private DepedencyB depB;\n" +
|
||||
"\n" +
|
||||
" public SomeComponent(DependencyA depA, DependencyB depB) {\n" +
|
||||
" this.depA = depA;\n" +
|
||||
" this.depB = depB;\n" +
|
||||
" }\n" +
|
||||
"}\n"
|
||||
);
|
||||
|
||||
editor.assertHighlights("@Component", "SomeComponent");
|
||||
|
||||
editor.assertTrimmedHover("SomeComponent", 2,
|
||||
"**Autowired → `dependencyA` `dependencyB`**\n" +
|
||||
"- Bean: `dependencyA` \n" +
|
||||
" Type: `com.example.DependencyA`\n" +
|
||||
"- Bean: `dependencyB` \n" +
|
||||
" Type: `com.example.DependencyB`\n" +
|
||||
" \n" +
|
||||
"Process [PID=111, name=`the-app`]\n"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noImplicitAutowiringForConstructorFromNonBean() throws Exception {
|
||||
LiveBeansModel beans = LiveBeansModel.builder()
|
||||
.add(LiveBean.builder()
|
||||
.id("someOtherComponent")
|
||||
.type("com.example.SomeOtherComponent")
|
||||
.dependencies("dependencyA", "dependencyB")
|
||||
.build()
|
||||
)
|
||||
.add(LiveBean.builder()
|
||||
.id("dependencyA")
|
||||
.type("com.example.DependencyA")
|
||||
.build()
|
||||
)
|
||||
.add(LiveBean.builder()
|
||||
.id("dependencyB")
|
||||
.type("com.example.DependencyB")
|
||||
.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" +
|
||||
"public class SomeComponent {\n" +
|
||||
"\n" +
|
||||
" private DepedencyA depA;\n" +
|
||||
" private DepedencyB depB;\n" +
|
||||
"\n" +
|
||||
" public SomeComponent(DependencyA depA, DependencyB depB) {\n" +
|
||||
" this.depA = depA;\n" +
|
||||
" this.depB = depB;\n" +
|
||||
" }\n" +
|
||||
"}\n"
|
||||
);
|
||||
|
||||
editor.assertHighlights();
|
||||
|
||||
for (int i = 1; i < 2; i++) {
|
||||
editor.assertNoHover("SomeComponent", i);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noImplicitAutowiringForMultipleConstructors() throws Exception {
|
||||
LiveBeansModel beans = LiveBeansModel.builder()
|
||||
.add(LiveBean.builder()
|
||||
.id("someComponent")
|
||||
.type("com.example.SomeComponent")
|
||||
.dependencies("dependencyA", "dependencyB")
|
||||
.build()
|
||||
)
|
||||
.add(LiveBean.builder()
|
||||
.id("dependencyA")
|
||||
.type("com.example.DependencyA")
|
||||
.build()
|
||||
)
|
||||
.add(LiveBean.builder()
|
||||
.id("dependencyB")
|
||||
.type("com.example.DependencyB")
|
||||
.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 SomeComponent {\n" +
|
||||
"\n" +
|
||||
" private DepedencyA depA;\n" +
|
||||
" private DepedencyB depB;\n" +
|
||||
"\n" +
|
||||
" public SomeComponent() {\n" +
|
||||
" }\n" +
|
||||
"\n" +
|
||||
" public SomeComponent(DependencyA depA, DependencyB depB) {\n" +
|
||||
" this.depA = depA;\n" +
|
||||
" this.depB = depB;\n" +
|
||||
" }\n" +
|
||||
"}\n"
|
||||
);
|
||||
|
||||
editor.assertHighlights("@Component");
|
||||
for (int i = 1; i < 3; i++) {
|
||||
editor.assertNoHover("SomeComponent", i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -516,22 +516,14 @@ public class ComponentInjectionsHoverProviderTest {
|
||||
" }\n" +
|
||||
"}\n"
|
||||
);
|
||||
editor.assertHighlights("@Component");
|
||||
editor.assertHighlights("@Component", "AutowiredClass");
|
||||
editor.assertTrimmedHover("@Component",
|
||||
"**Injection report for Bean [id: autowiredClass, type: `com.example.AutowiredClass`]**\n" +
|
||||
"\n" +
|
||||
"Process [PID=111, name=`the-app`]:\n" +
|
||||
"\n" +
|
||||
"Bean [id: autowiredClass, type: `com.example.AutowiredClass`] exists but is **Not injected anywhere**\n" +
|
||||
"\n\n" +
|
||||
"Bean [id: autowiredClass, type: `com.example.AutowiredClass`] got autowired with:\n" +
|
||||
"\n" +
|
||||
"- Bean: `dependencyA` \n" +
|
||||
" Type: `com.example.DependencyA` \n" +
|
||||
" Resource: `" + Paths.get("com/example/DependencyA.class") + "`\n" +
|
||||
"- Bean: `dependencyB` \n" +
|
||||
" Type: `com.example.DependencyB` \n" +
|
||||
" Resource: `com/example/DependencyB.class`"
|
||||
"\n\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user