From 42a308d9c8745f4b2c9a3f170bd0b24fbd00b795 Mon Sep 17 00:00:00 2001 From: BoykoAlex Date: Mon, 20 Aug 2018 17:15:25 -0400 Subject: [PATCH] PT #159444911: Addition - id matching, type verification --- .../autowired/AutowiredHoverProvider.java | 61 ++++++++++++++----- .../test/AutowiredHoverProviderTest.java | 51 +++++++++++++++- 2 files changed, 96 insertions(+), 16 deletions(-) diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/autowired/AutowiredHoverProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/autowired/AutowiredHoverProvider.java index 20e573fa2..b7117d772 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/autowired/AutowiredHoverProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/autowired/AutowiredHoverProvider.java @@ -208,30 +208,63 @@ public class AutowiredHoverProvider implements HoverProvider { .collect(Collectors.toList()); } else if (declarationNode instanceof FieldDeclaration) { FieldDeclaration fieldDeclaration = (FieldDeclaration)declarationNode; - Optional beanId = ASTUtils.beanId(fieldDeclaration.modifiers()); - if (beanId.isPresent()) { - return beans.stream().filter(b -> beanId.get().equals(b.getId())).findFirst().map(b -> ImmutableList.of(b)).orElseGet(() -> ImmutableList.of()); - } else { - LiveBean matchedBean = matchBeanByType(project, beans, fieldDeclaration.getType().resolveBinding()); - if (matchedBean != null) { - return ImmutableList.of(matchedBean); + ITypeBinding fieldType = fieldDeclaration.getType().resolveBinding(); + if (fieldType != null) { + Optional beanId = ASTUtils.beanId(fieldDeclaration.modifiers()); + if (beanId.isPresent()) { + return beans.stream() + .filter(b -> beanId.get().equals(b.getId())) + .findFirst() + .filter(b -> verfyBeanType(project, b, fieldType)) + .map(b -> ImmutableList.of(b)) + .orElseGet(() -> ImmutableList.of()); + } else { + LiveBean matchedBean = matchBeanByType(project, beans, fieldType); + if (matchedBean != null) { + return ImmutableList.of(matchedBean); + } } } } else if (declarationNode instanceof SingleVariableDeclaration) { SingleVariableDeclaration singleVariableDeclaration = (SingleVariableDeclaration)declarationNode; - Optional beanId = ASTUtils.beanId(singleVariableDeclaration.modifiers()); - if (beanId.isPresent()) { - return beans.stream().filter(b -> beanId.get().equals(b.getId())).findFirst().map(b -> ImmutableList.of(b)).orElseGet(() -> ImmutableList.of()); - } else { - LiveBean matchedBean = matchBeanByType(project, beans, singleVariableDeclaration.getType().resolveBinding()); - if (matchedBean != null) { - return ImmutableList.of(matchedBean); + ITypeBinding varType = singleVariableDeclaration.getType().resolveBinding(); + if (varType != null) { + Optional beanId = ASTUtils.beanId(singleVariableDeclaration.modifiers()); + if (beanId.isPresent()) { + return beans.stream() + .filter(b -> beanId.get().equals(b.getId())) + .findFirst() + .filter(b -> verfyBeanType(project, b, varType)) + .map(b -> ImmutableList.of(b)) + .orElseGet(() -> ImmutableList.of()); + } else { + LiveBean matchedBean = matchBeanByType(project, beans, varType); + if (matchedBean != null) { + return ImmutableList.of(matchedBean); + } } } } return Collections.emptyList(); } + private static boolean verfyBeanType(IJavaProject jp, LiveBean bean, ITypeBinding typeBinding) { + String liveBeanTypeFQName = bean.getType(); + if (liveBeanTypeFQName != null) { + String bindingQualifiedName = typeBinding.getQualifiedName(); + if (liveBeanTypeFQName.replace('$', '.').equals(bindingQualifiedName)) { + return true; + } else { + IType type = jp.findType(liveBeanTypeFQName); + String fqTypeName = bindingQualifiedName; + if (type != null) { + return jp.allSuperTypesOf(type).map(IType::getFullyQualifiedName).filter(fqn -> fqTypeName.equals(fqn.replace('$', '.'))).blockFirst() != null; + } + } + } + return false; + } + private static LiveBean matchBeanByType(IJavaProject project, Collection beans, ITypeBinding type) { if (type != null) { String fqName = type.getQualifiedName(); diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/autowired/test/AutowiredHoverProviderTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/autowired/test/AutowiredHoverProviderTest.java index 6f2681d33..5e9131278 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/autowired/test/AutowiredHoverProviderTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/autowired/test/AutowiredHoverProviderTest.java @@ -732,7 +732,7 @@ public class AutowiredHoverProviderTest { .add(LiveBean.builder() .id("someComponent") .type("com.example.SomeComponent") - .dependencies("dependencyA", "dependencyB") + .dependencies("dependencyA") .build() ) .add(LiveBean.builder() @@ -784,7 +784,7 @@ public class AutowiredHoverProviderTest { .add(LiveBean.builder() .id("someComponent") .type("com.example.SomeComponent") - .dependencies("dependencyA", "dependencyB") + .dependencies("dependencyA") .build() ) .add(LiveBean.builder() @@ -824,6 +824,53 @@ public class AutowiredHoverProviderTest { editor.assertNoHover("@Autowired"); } + @Test + public void qualifierWrongTypeWiredBean() throws Exception { + LiveBeansModel beans = LiveBeansModel.builder() + .add(LiveBean.builder() + .id("someComponent") + .type("com.example.SomeComponent") + .dependencies("dependency") + .build() + ) + .add(LiveBean.builder() + .id("dependency") + .type("com.example.DependencyA") + .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.beans.factory.annotation.Autowired;\n" + + "import org.springframework.beans.factory.annotation.Qualifier;\n" + + "import org.springframework.stereotype.Component;\n" + + "\n" + + "@Component\n" + + "public class SomeComponent {\n" + + "\n" + + " @Autowired\n" + + " @Qualifier(\"dependency\")\n" + + " private DependencyB a;\n" + + "\n" + + " public SomeComponent() {\n" + + " }\n" + + "\n" + + "}\n" + ); + + editor.assertHighlights("@Component"); + editor.assertNoHover("@Autowired"); + } + + @Test public void anonymousInnerClassBeanWiring() throws Exception { LiveBeansModel beans = LiveBeansModel.builder()