PT #164071043: Calculate different ids for nested and static inner types

This commit is contained in:
BoykoAlex
2019-02-20 12:31:35 -05:00
parent 5cecebf95c
commit 96958c3363
2 changed files with 90 additions and 25 deletions

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2018 Pivotal, Inc.
* Copyright (c) 2017, 2019 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
@@ -17,6 +17,7 @@ import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.ITypeBinding;
@@ -64,7 +65,7 @@ public class ComponentInjectionsHoverProvider extends AbstractInjectedIntoHoverP
if (declaringType != null) {
ITypeBinding beanType = declaringType.resolveBinding();
if (beanType != null) {
String id = getBeanId(annotation, beanType);
String id = getBeanId(annotation, beanType, Flags.isStatic(declaringType.getModifiers()));
if (StringUtil.hasText(id)) {
return LiveBean.builder().id(id).type(getBeanType(beanType).toString()).build();
}
@@ -73,30 +74,31 @@ public class ComponentInjectionsHoverProvider extends AbstractInjectedIntoHoverP
return null;
}
private static String getBeanId(Annotation annotation, ITypeBinding beanType) {
return ASTUtils.getAttribute(annotation, "value").flatMap(ASTUtils::getFirstString)
.orElseGet(() -> {
String typeName = beanType.getName();
private static String getBeanId(Annotation annotation, ITypeBinding beanType, boolean isStatic) {
return ASTUtils.getAttribute(annotation, "value").flatMap(ASTUtils::getFirstString).orElseGet(() -> {
ITypeBinding declaringClass = beanType.getDeclaringClass();
if (declaringClass != null) {
return getBeanType(beanType).toString();
if (declaringClass == null) {
return BeanUtils.getBeanNameFromType(beanType.getName());
} else {
if (isStatic) {
// Static inner class case id `outerClass.InnerClass`
String typeName = beanType.getBinaryName();
// Trim package prefix and replace $ with . inner class separator
int idx = typeName.lastIndexOf('.');
if (idx >= 0) {
typeName = typeName.substring(idx + 1).replace('$', '.');
}
return BeanUtils.getBeanNameFromType(typeName);
} else {
// Non-static inner class id case is binary type name
return getBeanType(beanType).toString();
}
}
return BeanUtils.getBeanNameFromType(typeName);
});
}
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;
}
private static String getBeanType(ITypeBinding beanType) {
return beanType.getBinaryName();
}
@Override

View File

@@ -664,13 +664,18 @@ public class ComponentInjectionsHoverProviderTest {
}
@Test
public void componentFromInnerClass() throws Exception {
public void componentFromStaticInnerClass() throws Exception {
LiveBeansModel beans = LiveBeansModel.builder()
.add(LiveBean.builder()
.id("com.example.DemoApplication$InnerClass")
.type("com.example.DemoApplication$InnerClass")
.build()
)
.add(LiveBean.builder()
.id("demoApplication.InnerClass")
.type("com.example.DemoApplication$InnerClass")
.build()
)
.build();
mockAppProvider.builder()
.isSpringBootApp(true)
@@ -700,19 +705,77 @@ public class ComponentInjectionsHoverProviderTest {
);
editor.assertHighlights("@SpringBootApplication");
editor.assertHoverContains("@SpringBootApplication",
"Bean id: `com.example.DemoApplication$InnerClass` \n" +
"Bean id: `demoApplication.InnerClass` \n" +
"Process [PID=111, name=`the-app`]"
);
}
@Test
public void componentFromInnerInnerClass() throws Exception {
public void componentFromNestedClass() throws Exception {
LiveBeansModel beans = LiveBeansModel.builder()
.add(LiveBean.builder()
.id("com.example.Example$Inner")
.type("com.example.Example$Inner")
.build()
)
.add(LiveBean.builder()
.id("example.Inner")
.type("com.example.Example$Inner")
.build()
)
.add(LiveBean.builder()
.id("example")
.type("com.example.Example")
.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 Example { \n" +
" @Component\n" +
" public class Inner {\n" +
" @Autowired\n" +
" public Inner() {\n" +
" }\n" +
" }\n" +
"}\n"
);
editor.assertHighlights("@Component", "@Component");
editor.assertHoverContains("@Component", 1,
"Bean id: `example` \n" +
"Process [PID=111, name=`the-app`]"
);
editor.assertHoverContains("@Component", 2,
"Bean id: `com.example.Example$Inner` \n" +
"Process [PID=111, name=`the-app`]"
);
}
@Test
public void componentFromStaticInnerInnerClass() throws Exception {
LiveBeansModel beans = LiveBeansModel.builder()
.add(LiveBean.builder()
.id("com.example.DemoApplication$InnerClass$InnerInnerClass")
.type("com.example.DemoApplication$InnerClass$InnerInnerClass")
.build()
)
.add(LiveBean.builder()
.id("demoApplication.InnerClass.InnerInnerClass")
.type("com.example.DemoApplication$InnerClass$InnerInnerClass")
.build()
)
.build();
mockAppProvider.builder()
.isSpringBootApp(true)
@@ -745,7 +808,7 @@ public class ComponentInjectionsHoverProviderTest {
);
editor.assertHighlights("@SpringBootApplication");
editor.assertHoverContains("@SpringBootApplication",
"Bean id: `com.example.DemoApplication$InnerClass$InnerInnerClass` \n" +
"Bean id: `demoApplication.InnerClass.InnerInnerClass` \n" +
"Process [PID=111, name=`the-app`]"
);
}