From 3a6dd8b0127f500d7e34b02e3a5683e7a3e44b38 Mon Sep 17 00:00:00 2001 From: aboyko Date: Tue, 1 Apr 2025 20:27:22 -0400 Subject: [PATCH] Handle duplicates for bean completion proposals --- .../java/beans/BeanCompletionProposal.java | 20 +++++++++++++++++++ .../java/beans/BeanCompletionProvider.java | 5 ++++- .../test/BeanCompletionProviderTest.java | 4 +++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeanCompletionProposal.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeanCompletionProposal.java index b2393c863..40ed08c8b 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeanCompletionProposal.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeanCompletionProposal.java @@ -12,6 +12,7 @@ package org.springframework.ide.vscode.boot.java.beans; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import org.apache.commons.text.similarity.JaroWinklerSimilarity; @@ -201,4 +202,23 @@ public class BeanCompletionProposal implements ICompletionProposalWithScore { return false; } + @Override + public int hashCode() { + return Objects.hash(beanId, beanType); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + BeanCompletionProposal other = (BeanCompletionProposal) obj; + return Objects.equals(beanId, other.beanId) && Objects.equals(beanType, other.beanType); + } + + + } 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 365d47975..d399979e4 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 @@ -109,6 +109,8 @@ public class BeanCompletionProvider implements CompletionProvider { fieldNames.add(vd.getName()); fieldTypes.add(vd.getType().getQualifiedName()); } + // Collect bean completions in a set to exclude possible bean symbol duplications + Set beanCompletions = new HashSet<>(); for (Bean bean : beans) { // If current class is a bean - ignore it if (className.equals(bean.getType())) { @@ -127,9 +129,10 @@ public class BeanCompletionProvider implements CompletionProvider { bean.getType(), fieldName, className, rewriteRefactorings); if (proposal.getScore() > 0) { - completions.add(proposal); + beanCompletions.add(proposal); } } + completions.addAll(beanCompletions); } } catch (Exception e) { log.error("problem while looking for bean completions", e); 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 b96130973..6b0c152fe 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 @@ -71,6 +71,7 @@ public class BeanCompletionProviderTest { private Bean bean5; private Bean bean6; private Bean bean7; + private Bean bean8; @BeforeEach public void setup() throws Exception { @@ -97,8 +98,9 @@ public class BeanCompletionProviderTest { bean5 = new Bean("petService", "org.springframework.samples.petclinic.pet.Inner.PetService", new Location(tempJavaDocUri, new Range(new Position(1,1), new Position(1, 20))), null, null, null, false, "symbolLabel"); bean6 = new Bean("testBeanCompletionClass", "org.sample.test.TestBeanCompletionClass", new Location(tempJavaDocUri, new Range(new Position(1,1), new Position(1, 20))), null, null, null, false, "symbolLabel"); bean7 = new Bean("testIntBean", "java.lang.Integer", new Location(tempJavaDocUri, new Range(new Position(1,1), new Position(1, 20))), null, null, null, false, "symbolLabel"); + bean8 = new Bean("testIntBean", "java.lang.Integer", new Location(tempJavaDocUri, new Range(new Position(1,1), new Position(1, 20))), null, null, null, false, "symbolLabelDuplicate"); - springIndex.updateBeans(project.getElementName(), new Bean[] {bean1, bean2, bean3, bean4, bean5, bean6, bean7}); + springIndex.updateBeans(project.getElementName(), new Bean[] {bean1, bean2, bean3, bean4, bean5, bean6, bean7, bean8}); } @AfterEach