PT #166343444: Type hierarchy for anonymous inner types

This commit is contained in:
BoykoAlex
2019-05-29 18:03:05 -04:00
parent ef1195e9a8
commit d181c17d2b
4 changed files with 46 additions and 8 deletions

View File

@@ -182,6 +182,27 @@ public class JavaLangugeClientTest {
assertEquals(expected, actual);
}
@Test
public void anonymousInnerType_SuperTypes() throws Exception {
List<TypeDescriptorData> data = client
.javaSuperTypes(new JavaTypeHierarchyParams(project.getLocationURI().toString(), "org.test.Application$1", false))
.get(1000000000, TimeUnit.SECONDS);
assertNotNull(data);
Set<String> actual = data.stream().map(t -> t.getFqName()).collect(Collectors.toSet());
Set<String> expected = new HashSet<>(Arrays.asList(
"org.springframework.scheduling.concurrent.ConcurrentTaskScheduler",
"java.util.concurrent.Executor",
"org.springframework.scheduling.SchedulingTaskExecutor",
"org.springframework.core.task.AsyncTaskExecutor",
"org.springframework.scheduling.concurrent.ConcurrentTaskExecutor",
"org.springframework.scheduling.TaskScheduler",
"org.springframework.core.task.TaskExecutor",
"org.springframework.core.task.AsyncListenableTaskExecutor",
"java.lang.Object"
));
assertEquals(expected, actual);
}
@Test
public void arrayList_SuperTypes_with_Itself() throws Exception {
List<TypeDescriptorData> data = client

View File

@@ -4,6 +4,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
@SpringBootApplication
public class Application {
@@ -13,5 +14,11 @@ public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
ConcurrentTaskScheduler sched() {
return new ConcurrentTaskScheduler() {
};
}
}

View File

@@ -90,7 +90,7 @@ public class JavaData {
return element;
}
private static IJavaElement findElement(IJavaProject project, String bindingKey) {
public static IJavaElement findElement(IJavaProject project, String bindingKey) {
IJavaElement element = null;
// JDT cannot find anonymous inner type from its binding key
// Find its declaring type. If declaring type found then anonymous inner type is present in the binding key
@@ -119,6 +119,17 @@ public class JavaData {
return element;
}
public static String toBindingKey(String fqName) {
StringBuilder sb = new StringBuilder("L");
sb.append(fqName.replace('.', '/'));
sb.append(";");
return sb.toString();
}
public static String toJdtFqName(String bindingKey) {
return bindingKey.substring(1, bindingKey.length() - 1).replace('/', '.').replace('$', '.');
}
private static IJavaElement findInnerElement(IJavaElement container, String bindingKey) {
if (container instanceof IField) {
if (bindingKey.equals(((IField)container).getKey())) {
@@ -156,7 +167,7 @@ public class JavaData {
if (rest.charAt(rest.length() - 1) == ';') {
rest = rest.substring(0, rest.length() - 1);
}
String[] tokens = rest.split("$");
String[] tokens = rest.split("\\$");
for (String token : tokens) {
int dotIdx = token.indexOf('.');
String typeToken = dotIdx < 0 ? token : token.substring(0, dotIdx);

View File

@@ -33,15 +33,13 @@ public class TypeHierarchy {
this.javaData = javaData;
}
private static String jdtCompatibleFqName(String fqName) {
return fqName.replace('$', '.');
}
private ITypeHierarchy hierarchy(URI projectUri, String fqName, boolean superTypes) {
try {
String bindingKey = JavaData.toBindingKey(fqName);
if (projectUri == null) {
for (IJavaProject jp : ResourceUtils.allJavaProjects()) {
IType type = jp.findType(jdtCompatibleFqName(fqName));
// In case it's an anonymous inner type try the following rather than just find type on the project
IType type = (IType) JavaData.findElement(jp, bindingKey);
if (type != null) {
return superTypes ? type.newSupertypeHierarchy(new NullProgressMonitor()) : type.newTypeHierarchy(new NullProgressMonitor());
}
@@ -50,7 +48,8 @@ public class TypeHierarchy {
} else {
IJavaProject javaProject = projectUri == null ? null : ResourceUtils.getJavaProject(projectUri);
if (javaProject != null) {
IType type = javaProject.findType(jdtCompatibleFqName(fqName));
// In case it's an anonymous inner type try the following rather than just find type on the project
IType type = (IType) JavaData.findElement(javaProject, bindingKey);
if (type != null) {
return superTypes ? type.newSupertypeHierarchy(new NullProgressMonitor()) : type.newTypeHierarchy(javaProject, new NullProgressMonitor());
}