From 21e0543730283df8de69526e9abf896d81a51889 Mon Sep 17 00:00:00 2001 From: BoykoAlex Date: Tue, 31 Jul 2018 00:26:02 -0400 Subject: [PATCH] PT #159307292: Anonymous inner class bean type wiring --- .../boot/app/cli/livebean/LiveBean.java | 5 +- .../autowired/AutowiredHoverProvider.java | 12 ++- .../ComponentInjectionsHoverProvider.java | 14 +++- .../test/AutowiredHoverProviderTest.java | 75 +++++++++++++++++++ 4 files changed, 97 insertions(+), 9 deletions(-) diff --git a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/livebean/LiveBean.java b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/livebean/LiveBean.java index e21badb98..ead218549 100644 --- a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/livebean/LiveBean.java +++ b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/livebean/LiveBean.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. + * Copyright (c) 2017, 2018 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -103,9 +103,6 @@ public class LiveBean { type = type.substring(0, chop); } } - - // convert inner classes from $ to . notation - type = type.replace('$', '.'); } return type; 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 add03f263..2e7550575 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 @@ -209,12 +209,12 @@ public class AutowiredHoverProvider implements HoverProvider { if (type != null) { String fqName = type.getQualifiedName(); if (fqName != null) { - relevant = matchBeans(project, beans, fqName); + relevant = matchBeans(project, beans, fqName, true); if (relevant.isEmpty()) { IType indexType = project.findType(fqName); if (indexType != null) { relevant = project.allSubtypesOf(indexType) - .map(subType -> matchBeans(project, beans, subType.getFullyQualifiedName())) + .map(subType -> matchBeans(project, beans, subType.getFullyQualifiedName(), false)) .filter(relevantBeans -> !relevantBeans.isEmpty()) .blockFirst(); if (relevant == null) { @@ -227,9 +227,13 @@ public class AutowiredHoverProvider implements HoverProvider { return relevant; } - private List matchBeans(IJavaProject project, Collection beans, String fqName) { + private List matchBeans(IJavaProject project, Collection beans, String fqName, boolean allDots) { if (fqName != null) { - return beans.stream().filter(b -> fqName.equals(b.getType(true))).collect(Collectors.toList()); + if (allDots) { + return beans.stream().filter(b -> fqName.equals(b.getType(true).replace('$', '.'))).collect(Collectors.toList()); + } else { + return beans.stream().filter(b -> fqName.equals(b.getType(true))).collect(Collectors.toList()); + } } else { return Collections.emptyList(); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/ComponentInjectionsHoverProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/ComponentInjectionsHoverProvider.java index aa6d9da57..cc78b3544 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/ComponentInjectionsHoverProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/ComponentInjectionsHoverProvider.java @@ -61,7 +61,7 @@ public class ComponentInjectionsHoverProvider extends AbstractInjectedIntoHoverP if (beanType != null) { String id = getBeanId(annotation, beanType); if (StringUtil.hasText(id)) { - return LiveBean.builder().id(id).type(beanType.getQualifiedName()).build(); + return LiveBean.builder().id(id).type(getBeanType(beanType).toString()).build(); } } } @@ -86,6 +86,18 @@ public class ComponentInjectionsHoverProvider extends AbstractInjectedIntoHoverP }); } + private static StringBuilder getBeanType(ITypeBinding beanType) { + ITypeBinding declaringClass = beanType.getDeclaringClass(); + if (declaringClass == null) { + return new StringBuilder(beanType.getQualifiedName()); + } else { + StringBuilder sb = getBeanType(declaringClass); + sb.append('$'); + sb.append(beanType.getName()); + return sb; + } + } + @Override public Collection getLiveHoverHints(IJavaProject project, TypeDeclaration typeDeclaration, TextDocument doc, SpringBootApp[] runningApps) { 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 098a99075..fed26d0a7 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 @@ -14,6 +14,8 @@ import static org.junit.Assert.assertTrue; import java.nio.file.Paths; import java.time.Duration; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.junit.Before; import org.junit.Test; @@ -84,6 +86,34 @@ public class AutowiredHoverProviderTest { "}\n" ); + p.createType("com.example.RuntimeBeanFactory", + Stream.of( + "package com.example;", + "public interface RuntimeBeanFactory {", + "void createRuntimeBean(String info);", + "}" + ).collect(Collectors.joining("\n")) + ); + + p.createType("com.example.SomeComponent", + Stream.of("package com.example;", + "", + "import org.springframework.context.annotation.Bean;", + "", +// "@Component", + "public class SomeComponent {", + "", + "@Bean", + "public RuntimeBeanFactory getBeanFactory() {", + "\treturn new RuntimeBeanFactory() {", + "\t\tpublic void createRuntimeBean(String info){}", + "\t};", + "}", + "", + "}" + ).collect(Collectors.joining("\n")) + ); + p.createType("com.example.FooImplementation", FOO_IMPL_CONTENTS); }; @@ -577,4 +607,49 @@ public class AutowiredHoverProviderTest { } } + @Test + public void anonymousInnerClassBeanWiring() throws Exception { + LiveBeansModel beans = LiveBeansModel.builder() + .add(LiveBean.builder() + .id("anotherComponent") + .type("com.example.AnotherComponent") + .dependencies("anonymousBeanFactory") + .build() + ) + .add(LiveBean.builder() + .id("anonymousBeanFactory") + .type("com.example.SomeComponent$1") + .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.stereotype.Component;\n" + + "\n" + + "@Component\n" + + "public class AnotherComponent {\n" + + "\n" + + " @Autowired\n" + + " RuntimeBeanFactory beanFactory;\n" + + "}\n" + ); + + editor.assertHighlights("@Component", "@Autowired"); + editor.assertTrimmedHover("@Autowired", 1, + "**Autowired `anotherComponent` → `anonymousBeanFactory`**\n" + + "- Bean: `anonymousBeanFactory` \n" + + " Type: `com.example.SomeComponent$1`\n" + + " \n" + + "Process [PID=111, name=`the-app`]\n" + ); + } }