diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeanCompletionProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeanCompletionProvider.java index fe24fa5074..13d84f1c77 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeanCompletionProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeanCompletionProvider.java @@ -19,11 +19,14 @@ import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.Annotation; +import org.eclipse.jdt.core.dom.Assignment; import org.eclipse.jdt.core.dom.Block; import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.FieldAccess; import org.eclipse.jdt.core.dom.IAnnotationBinding; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.ThisExpression; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.VariableDeclaration; import org.slf4j.Logger; @@ -81,6 +84,14 @@ public void provideCompletions(ASTNode node, int offset, TextDocument doc, return; } + // Empty SimpleName usually comes from unresolved FieldAccess, i.e. `this.owner` where `owner` field is not defined + if (node instanceof SimpleName se && se.getLength() == 0 + && node.getParent() instanceof Assignment assign + && assign.getLeftHandSide() instanceof FieldAccess fa + && fa.getExpression() instanceof ThisExpression) { + node = fa.getName(); + } + if (isSpringComponent(topLevelClass)) { String className = getFullyQualifiedName(topLevelClass); Bean[] beans = this.springIndex.getBeansOfProject(project.getElementName()); diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/BeanCompletionProviderTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/BeanCompletionProviderTest.java index 9d89eaa3af..2b431dfddb 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/BeanCompletionProviderTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/BeanCompletionProviderTest.java @@ -482,6 +482,43 @@ public void test() { """); } + @Test + public void beanCompletionWithThis() throws Exception { + String content = """ + package org.sample.test; + + import org.springframework.stereotype.Controller; + + @Controller + public class TestBeanCompletionClass { + public void test() { + this.owner<*> + } + } + """; + + + assertCompletions(content, new String[] {"ownerRepository", "ownerService"}, 0, + """ + package org.sample.test; + + import org.springframework.samples.petclinic.owner.OwnerRepository; + import org.springframework.stereotype.Controller; + + @Controller + public class TestBeanCompletionClass { + + private final OwnerRepository ownerRepository; + + TestBeanCompletionClass(OwnerRepository ownerRepository) { + this.ownerRepository = ownerRepository; + } + public void test() { + this.ownerRepository<*> + } + } + """); + } private void assertCompletions(String completionLine, String[] expectedCompletions, int chosenCompletion, String expectedResult) throws Exception {