PT #164474609: Light TypeDescriptorData and caching super, sub-types
This commit is contained in:
@@ -1,12 +1,5 @@
|
||||
{
|
||||
"fqName": "java.util.Map",
|
||||
"bindingKey": "Ljava/util/Map;",
|
||||
"clazz": false,
|
||||
"annotation": false,
|
||||
"interfaze": true,
|
||||
"enam": false,
|
||||
"superClassName": "java.lang.Object",
|
||||
"superInterfaceNames": [],
|
||||
"fields": [],
|
||||
"methods": [
|
||||
{
|
||||
@@ -713,6 +706,13 @@
|
||||
"isOwn": false
|
||||
}
|
||||
},
|
||||
"fqName": "java.util.Map",
|
||||
"clazz": false,
|
||||
"annotation": false,
|
||||
"interfaze": true,
|
||||
"enam": false,
|
||||
"superClassName": "java.lang.Object",
|
||||
"superInterfaceNames": [],
|
||||
"flags": 1537,
|
||||
"name": "Map",
|
||||
"handleIdentifier": "\u003dtest-webflux-project/\\/Library\\/Java\\/JavaVirtualMachines\\/jdk1.8.0_151.jdk\\/Contents\\/Home\\/jre\\/lib\\/rt.jar\u003cjava.util(Map.class[Map",
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
{
|
||||
"fqName": "org.test.NestedRouter3",
|
||||
"bindingKey": "Lorg/test/NestedRouter3;",
|
||||
"clazz": true,
|
||||
"annotation": false,
|
||||
"interfaze": false,
|
||||
"enam": false,
|
||||
"superInterfaceNames": [],
|
||||
"fields": [],
|
||||
"methods": [
|
||||
{
|
||||
@@ -62,6 +56,12 @@
|
||||
"isOwn": true
|
||||
}
|
||||
},
|
||||
"fqName": "org.test.NestedRouter3",
|
||||
"clazz": true,
|
||||
"annotation": false,
|
||||
"interfaze": false,
|
||||
"enam": false,
|
||||
"superInterfaceNames": [],
|
||||
"flags": 1,
|
||||
"name": "NestedRouter3",
|
||||
"handleIdentifier": "\u003dtest-webflux-project/src\\/main\\/java\u003corg.test{NestedRouter3.java[NestedRouter3",
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
{
|
||||
"fqName": "org.test.Quote",
|
||||
"bindingKey": "Lorg/test/Quote;",
|
||||
"clazz": true,
|
||||
"annotation": false,
|
||||
"interfaze": false,
|
||||
"enam": false,
|
||||
"superInterfaceNames": [],
|
||||
"fields": [
|
||||
{
|
||||
"bindingKey": "Lorg/test/Quote;.MATH_CONTEXT",
|
||||
@@ -267,6 +261,12 @@
|
||||
"isOwn": true
|
||||
}
|
||||
},
|
||||
"fqName": "org.test.Quote",
|
||||
"clazz": true,
|
||||
"annotation": false,
|
||||
"interfaze": false,
|
||||
"enam": false,
|
||||
"superInterfaceNames": [],
|
||||
"flags": 1,
|
||||
"name": "Quote",
|
||||
"handleIdentifier": "\u003dtest-webflux-project/src\\/main\\/java\u003corg.test{Quote.java[Quote",
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
{
|
||||
"fqName": "org.springframework.boot.autoconfigure.web.ServerProperties",
|
||||
"bindingKey": "Lorg/springframework/boot/autoconfigure/web/ServerProperties;",
|
||||
"clazz": true,
|
||||
"annotation": false,
|
||||
"interfaze": false,
|
||||
"enam": false,
|
||||
"superClassName": "java.lang.Object",
|
||||
"superInterfaceNames": [],
|
||||
"fields": [
|
||||
{
|
||||
"bindingKey": "Lorg/springframework/boot/autoconfigure/web/ServerProperties;.port",
|
||||
@@ -625,6 +618,13 @@
|
||||
"isOwn": false
|
||||
}
|
||||
},
|
||||
"fqName": "org.springframework.boot.autoconfigure.web.ServerProperties",
|
||||
"clazz": true,
|
||||
"annotation": false,
|
||||
"interfaze": false,
|
||||
"enam": false,
|
||||
"superClassName": "java.lang.Object",
|
||||
"superInterfaceNames": [],
|
||||
"flags": 1,
|
||||
"name": "ServerProperties",
|
||||
"handleIdentifier": "\u003dtest-webflux-project/\\/Users\\/aboyko\\/.m2\\/repository\\/org\\/springframework\\/boot\\/spring-boot-autoconfigure\\/2.0.0.RELEASE\\/spring-boot-autoconfigure-2.0.0.RELEASE.jar\u003corg.springframework.boot.autoconfigure.web(ServerProperties.class[ServerProperties",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,7 @@ import org.springframework.ide.vscode.commons.protocol.java.JavaDataParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaSearchParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaTypeHierarchyParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeDescriptorData;
|
||||
import org.springframework.tooling.ls.eclipse.commons.STS4LanguageClientImpl;
|
||||
|
||||
public class JavaLangugeClientTest {
|
||||
@@ -87,32 +88,32 @@ public class JavaLangugeClientTest {
|
||||
|
||||
@Test
|
||||
public void fuzzyFindTypesIncludingSysLibs() throws Exception {
|
||||
List<String> data = client
|
||||
List<TypeDescriptorData> data = client
|
||||
.javaSearchTypes(new JavaSearchParams(project.getLocationURI().toString(), "util.Map", true, true))
|
||||
.get(100, TimeUnit.SECONDS);
|
||||
assertNotNull(data);
|
||||
assertEquals(500, data.size());
|
||||
List<String> closeMatches = data.stream().filter(t -> t.contains("util.Map")).collect(Collectors.toList());
|
||||
List<String> closeMatches = data.stream().map(t -> t.getFqName()).filter(t -> t.contains("util.Map")).collect(Collectors.toList());
|
||||
assertEquals(2, closeMatches.size());
|
||||
assertNotNull(closeMatches.stream().filter(t -> "java.util.Map".equals(t)).findFirst().orElse(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fuzzyFindTypesExcludingSysLibs() throws Exception {
|
||||
List<String> data = client
|
||||
List<TypeDescriptorData> data = client
|
||||
.javaSearchTypes(new JavaSearchParams(project.getLocationURI().toString(), "util.Map", true, false))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertNotNull(data);
|
||||
assertEquals(186, data.size());
|
||||
// TestUtils.saveJsonData("search-util-map.json", data);
|
||||
List<String> closeMatches = data.stream().filter(t -> t.contains("util.Map")).collect(Collectors.toList());
|
||||
TestUtils.saveJsonData("search-util-map.json", data);
|
||||
List<String> closeMatches = data.stream().map(t -> t.getFqName()).filter(t -> t.contains("util.Map")).collect(Collectors.toList());
|
||||
assertEquals(1, closeMatches.size());
|
||||
assertEquals("io.netty.util.Mapping", closeMatches.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fuzzyFindAllTypesExcludingSysLibs() throws Exception {
|
||||
List<String> data = client
|
||||
List<TypeDescriptorData> data = client
|
||||
.javaSearchTypes(new JavaSearchParams(project.getLocationURI().toString(), "", true, false))
|
||||
.get(1000, TimeUnit.SECONDS);
|
||||
assertNotNull(data);
|
||||
@@ -141,18 +142,28 @@ public class JavaLangugeClientTest {
|
||||
|
||||
@Test
|
||||
public void map_Subtypes() throws Exception {
|
||||
List<TypeData> data = client
|
||||
.javaSubTypes(new JavaTypeHierarchyParams(project.getLocationURI().toString(), "java.util.Map"))
|
||||
List<TypeDescriptorData> data = client
|
||||
.javaSubTypes(new JavaTypeHierarchyParams(project.getLocationURI().toString(), "java.util.Map", false))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertNotNull(data);
|
||||
assertTrue(data.size() > 200);
|
||||
assertTrue(data.stream().filter(t -> "java.util.AbstractMap".equals(t.getFqName())).findFirst().isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void map_Subtypes_with_Itself() throws Exception {
|
||||
List<TypeDescriptorData> data = client
|
||||
.javaSubTypes(new JavaTypeHierarchyParams(project.getLocationURI().toString(), "java.util.Map", true))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertNotNull(data);
|
||||
assertTrue(data.size() > 200);
|
||||
assertTrue(data.stream().filter(t -> "java.util.Map".equals(t.getFqName())).findFirst().isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arrayList_SuperTypes() throws Exception {
|
||||
List<TypeData> data = client
|
||||
.javaSuperTypes(new JavaTypeHierarchyParams(project.getLocationURI().toString(), "java.util.ArrayList"))
|
||||
List<TypeDescriptorData> data = client
|
||||
.javaSuperTypes(new JavaTypeHierarchyParams(project.getLocationURI().toString(), "java.util.ArrayList", false))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertNotNull(data);
|
||||
Set<String> actual = data.stream().map(t -> t.getFqName()).collect(Collectors.toSet());
|
||||
@@ -170,11 +181,33 @@ public class JavaLangugeClientTest {
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arrayList_SuperTypes_with_Itself() throws Exception {
|
||||
List<TypeDescriptorData> data = client
|
||||
.javaSuperTypes(new JavaTypeHierarchyParams(project.getLocationURI().toString(), "java.util.ArrayList", true))
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertNotNull(data);
|
||||
Set<String> actual = data.stream().map(t -> t.getFqName()).collect(Collectors.toSet());
|
||||
Set<String> expected = new HashSet<>(Arrays.asList(
|
||||
"java.util.ArrayList",
|
||||
"java.util.List",
|
||||
"java.util.RandomAccess",
|
||||
"java.lang.Cloneable",
|
||||
"java.io.Serializable",
|
||||
"java.util.AbstractList",
|
||||
"java.util.Collection",
|
||||
"java.lang.Object",
|
||||
"java.util.AbstractCollection",
|
||||
"java.lang.Iterable"
|
||||
));
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void taskExecutorFactoryBean_SuperTypes() throws Exception {
|
||||
List<TypeData> data = client
|
||||
List<TypeDescriptorData> data = client
|
||||
.javaSuperTypes(new JavaTypeHierarchyParams(project.getLocationURI().toString(), "org.springframework.scheduling.config.TaskExecutorFactoryBean"))
|
||||
.get(100000, TimeUnit.SECONDS);
|
||||
.get(10, TimeUnit.SECONDS);
|
||||
assertNotNull(data);
|
||||
Set<String> actual = data.stream().map(t -> t.getFqName()).collect(Collectors.toSet());
|
||||
Set<String> expected = new HashSet<>(Arrays.asList(
|
||||
|
||||
@@ -72,6 +72,7 @@ import org.springframework.ide.vscode.commons.protocol.java.JavaDataParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaSearchParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaTypeHierarchyParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeDescriptorData;
|
||||
import org.springframework.tooling.jdt.ls.commons.Logger;
|
||||
import org.springframework.tooling.jdt.ls.commons.classpath.ReusableClasspathListenerHandler;
|
||||
import org.springframework.tooling.jdt.ls.commons.java.JavaData;
|
||||
@@ -126,7 +127,7 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La
|
||||
|
||||
final private JavaData javaData = new JavaData(STS4LanguageClientImpl::label , Logger.forEclipsePlugin(LanguageServerCommonsActivator::getInstance));
|
||||
|
||||
final private JavaFluxSearch javaFluxSearch = new JavaFluxSearch(Logger.forEclipsePlugin(LanguageServerCommonsActivator::getInstance));
|
||||
final private JavaFluxSearch javaFluxSearch = new JavaFluxSearch(Logger.forEclipsePlugin(LanguageServerCommonsActivator::getInstance), javaData);
|
||||
|
||||
final private TypeHierarchy typeHierarchy = new TypeHierarchy(Logger.forEclipsePlugin(LanguageServerCommonsActivator::getInstance), javaData);
|
||||
|
||||
@@ -440,11 +441,10 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<String>> javaSearchTypes(JavaSearchParams params) {
|
||||
public CompletableFuture<List<TypeDescriptorData>> javaSearchTypes(JavaSearchParams params) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
List<String> types = javaFluxSearch.fuzzySearchTypes(params);
|
||||
return types;
|
||||
return javaFluxSearch.fuzzySearchTypes(params);
|
||||
} catch (Exception e) {
|
||||
LanguageServerCommonsActivator.logError(e, "Failed to search type with term '" + params.getTerm()
|
||||
+ "' in project " + params.getProjectUri());
|
||||
@@ -467,16 +467,16 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<TypeData>> javaSubTypes(JavaTypeHierarchyParams params) {
|
||||
public CompletableFuture<List<TypeDescriptorData>> javaSubTypes(JavaTypeHierarchyParams params) {
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
typeHierarchy.subTypes(params.getProjectUri() == null ? null : URI.create(params.getProjectUri()), params.getFqName()).collect(Collectors.toList())
|
||||
typeHierarchy.subTypes(params).collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<TypeData>> javaSuperTypes(JavaTypeHierarchyParams params) {
|
||||
public CompletableFuture<List<TypeDescriptorData>> javaSuperTypes(JavaTypeHierarchyParams params) {
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
typeHierarchy.superTypes(params.getProjectUri() == null ? null : URI.create(params.getProjectUri()), params.getFqName()).collect(Collectors.toList())
|
||||
typeHierarchy.superTypes(params).collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -36,7 +37,6 @@ import reactor.core.Disposable;
|
||||
import reactor.core.Disposables;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuples;
|
||||
|
||||
/**
|
||||
* Classpath with Jandex Java index for searching types
|
||||
@@ -101,8 +101,8 @@ public final class JandexClasspath implements ClasspathIndex {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Tuple2<String, Double>> fuzzySearchTypes(String searchTerm, boolean includeBinaries, boolean includeSystemLibs) {
|
||||
return javaIndex.get().fuzzySearchTypes(searchTerm).map(m -> Tuples.of(m.getT2().name().toString(), m.getT3()));
|
||||
public Flux<Tuple2<IType, Double>> fuzzySearchTypes(String searchTerm, boolean includeBinaries, boolean includeSystemLibs) {
|
||||
return javaIndex.get().fuzzySearchITypes(searchTerm);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,8 +111,13 @@ public final class JandexClasspath implements ClasspathIndex {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<IType> allSubtypesOf(IType type) {
|
||||
return javaIndex.get().allSubtypesOf(type);
|
||||
public Flux<IType> allSubtypesOf(String fqName, boolean includeFocusType) {
|
||||
IType type = javaIndex.get().findType(fqName);
|
||||
if (type == null) {
|
||||
return Flux.empty();
|
||||
} else {
|
||||
return Flux.concat(includeFocusType ? Flux.fromStream(Stream.of(type)) : Flux.empty(), javaIndex.get().allSubtypesOf(type));
|
||||
}
|
||||
}
|
||||
|
||||
private File findIndexFile(File jarFile) {
|
||||
@@ -152,25 +157,25 @@ public final class JandexClasspath implements ClasspathIndex {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<IType> allSuperTypesOf(IType type) {
|
||||
public Flux<IType> allSuperTypesOf(String fqName, boolean includeFocusType) {
|
||||
Queue<String> queue = new LinkedList<>();
|
||||
HashSet<String> visited = new HashSet<>();
|
||||
updateQueue(queue, visited, type);
|
||||
return Flux.generate(() -> queue, (state, sink) -> {
|
||||
IType nextType = null;
|
||||
while (nextType == null && state.peek() != null) {
|
||||
queue.add(fqName);
|
||||
visited.add(fqName);
|
||||
Flux<IType> typesFlux = Flux.generate(() -> queue, (state, sink) -> {
|
||||
if (state.peek() == null) {
|
||||
sink.complete();
|
||||
} else {
|
||||
String typeName = state.poll();
|
||||
nextType = findType(typeName);
|
||||
IType nextType = findType(typeName);
|
||||
if (nextType != null) {
|
||||
sink.next(nextType);
|
||||
updateQueue(state, visited, nextType);
|
||||
}
|
||||
}
|
||||
if (state.peek() == null) {
|
||||
sink.complete();
|
||||
}
|
||||
return state;
|
||||
});
|
||||
return includeFocusType ? typesFlux : typesFlux.skip(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.google.common.cache.CacheBuilder;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuples;
|
||||
|
||||
public class JandexIndex extends BasicJandexIndex {
|
||||
|
||||
@@ -81,6 +82,10 @@ public class JandexIndex extends BasicJandexIndex {
|
||||
return Wrappers.wrap(this, match.getT1(), match.getT2(), javadocProvider);
|
||||
}
|
||||
|
||||
Flux<Tuple2<IType, Double>> fuzzySearchITypes(String searchTerm) {
|
||||
return fuzzySearchTypes(searchTerm).map(m -> Tuples.of(createType(Tuples.of(m.getT1(), m.getT2())), m.getT3()));
|
||||
}
|
||||
|
||||
public Flux<IType> allSubtypesOf(IType type) {
|
||||
DotName name = DotName.createSimple(type.getFullyQualifiedName());
|
||||
return allSubtypesOf(name, type.isInterface()).map(match -> createType(match));
|
||||
|
||||
@@ -17,10 +17,10 @@ import reactor.util.function.Tuple2;
|
||||
public interface ClasspathIndex extends Disposable {
|
||||
|
||||
IType findType(String fqName);
|
||||
Flux<Tuple2<String, Double>> fuzzySearchTypes(String searchTerm, boolean includeBinaries, boolean includeSystemLibs);
|
||||
Flux<Tuple2<IType, Double>> fuzzySearchTypes(String searchTerm, boolean includeBinaries, boolean includeSystemLibs);
|
||||
Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm, boolean includeBinaries, boolean includeSystemLibs);
|
||||
Flux<IType> allSubtypesOf(IType type);
|
||||
Flux<IType> allSuperTypesOf(IType type);
|
||||
Flux<IType> allSubtypesOf(String fqName, boolean includeFocusType);
|
||||
Flux<IType> allSuperTypesOf(String fqName, boolean includeFocusType);
|
||||
IJavaModuleData findClasspathResourceContainer(String fqName);
|
||||
|
||||
}
|
||||
|
||||
@@ -127,4 +127,11 @@ public class JavaUtils {
|
||||
return bindingKey == null ? null : bindingKey.substring(1, bindingKey.length() - 1).replace('/', '.');
|
||||
}
|
||||
|
||||
public static String typeFqNametoBindingKey(String fqName) {
|
||||
StringBuilder sb = new StringBuilder('L');
|
||||
sb.append(fqName.replace('.', '/'));
|
||||
sb.append(';');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,8 +11,11 @@
|
||||
package org.springframework.ide.vscode.commons.jdtls;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
@@ -29,6 +32,7 @@ import org.springframework.ide.vscode.commons.protocol.java.JavaDataParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaSearchParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaTypeHierarchyParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeDescriptorData;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMatcher;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
@@ -51,7 +55,9 @@ public class JdtLsIndex implements ClasspathIndex {
|
||||
private final URI projectUri;
|
||||
private final JdtLsJavadocProvider javadocProvider;
|
||||
|
||||
private Cache<String, Optional<IType>> cache = CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.SECONDS).build();
|
||||
final private Cache<String, Optional<IType>> typeCache = CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.SECONDS).build();
|
||||
final private Cache<JavaTypeHierarchyParams, CompletableFuture<List<IType>>> supertypesCache = CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.SECONDS).build();
|
||||
final private Cache<JavaTypeHierarchyParams, CompletableFuture<List<IType>>> subtypesCache = CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.SECONDS).build();
|
||||
|
||||
public JdtLsIndex(STS4LanguageClient client, URI projectUri) {
|
||||
this.client = client;
|
||||
@@ -69,10 +75,16 @@ public class JdtLsIndex implements ClasspathIndex {
|
||||
return Wrappers.wrap(data, Suppliers.memoize(() -> declaringTypeFqName == null ? null : findType(declaringTypeFqName)), javadocProvider);
|
||||
}
|
||||
|
||||
private IType toTypeFromDescriptor(TypeDescriptorData data) {
|
||||
String declaringTypeBindingKey = data.getDeclaringType();
|
||||
String declaringTypeFqName = JavaUtils.typeBindingKeyToFqName(declaringTypeBindingKey);
|
||||
return Wrappers.wrap(data, Suppliers.memoize(() -> findType(data.getFqName())), Suppliers.memoize(() -> declaringTypeFqName == null ? null : findType(declaringTypeFqName)), javadocProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType findType(String fqName) {
|
||||
try {
|
||||
return cache.get(fqName, () -> {
|
||||
return typeCache.get(fqName, () -> {
|
||||
JavaDataParams params = new JavaDataParams(projectUri.toString(), "L" + fqName.replace('.', '/') + ";", false);
|
||||
try {
|
||||
TypeData data = client.javaType(params).get(500, TimeUnit.MILLISECONDS);
|
||||
@@ -91,12 +103,12 @@ public class JdtLsIndex implements ClasspathIndex {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Tuple2<String, Double>> fuzzySearchTypes(String searchTerm, boolean includeBinaries, boolean includeSystemLibs) {
|
||||
public Flux<Tuple2<IType, Double>> fuzzySearchTypes(String searchTerm, boolean includeBinaries, boolean includeSystemLibs) {
|
||||
JavaSearchParams searchParams = new JavaSearchParams(projectUri.toString(), searchTerm, includeBinaries, includeSystemLibs, SEARCH_TIMEOUT);
|
||||
return Mono.fromFuture(client.javaSearchTypes(searchParams))
|
||||
.flatMapMany(results -> Flux.fromIterable(results).publishOn(Schedulers.parallel()))
|
||||
.filter(Objects::nonNull)
|
||||
.map(type -> Tuples.of(type, FuzzyMatcher.matchScore(searchTerm, type)))
|
||||
.map(type -> Tuples.of(toTypeFromDescriptor(type), FuzzyMatcher.matchScore(searchTerm, type.getFqName())))
|
||||
.filter(tuple -> tuple.getT2() != 0.0);
|
||||
}
|
||||
|
||||
@@ -110,22 +122,42 @@ public class JdtLsIndex implements ClasspathIndex {
|
||||
.filter(tuple -> tuple.getT2() != 0.0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<IType> allSubtypesOf(IType type) {
|
||||
JavaTypeHierarchyParams searchParams = new JavaTypeHierarchyParams(projectUri.toString(), type.getFullyQualifiedName());
|
||||
return Mono.fromFuture(client.javaSubTypes(searchParams))
|
||||
.flatMapMany(results -> Flux.fromIterable(results).publishOn(Schedulers.parallel()))
|
||||
.filter(Objects::nonNull)
|
||||
.map(this::toType);
|
||||
private List<IType> convertTypeDescriptors(List<TypeDescriptorData> descriptors) {
|
||||
List<IType> types = new ArrayList<>(descriptors.size());
|
||||
for (TypeDescriptorData data : descriptors) {
|
||||
if (data != null) {
|
||||
types.add(toTypeFromDescriptor(data));
|
||||
}
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<IType> allSuperTypesOf(IType type) {
|
||||
JavaTypeHierarchyParams searchParams = new JavaTypeHierarchyParams(projectUri.toString(), type.getFullyQualifiedName());
|
||||
return Mono.fromFuture(client.javaSuperTypes(searchParams))
|
||||
.flatMapMany(results -> Flux.fromIterable(results).publishOn(Schedulers.parallel()))
|
||||
.filter(Objects::nonNull)
|
||||
.map(this::toType);
|
||||
public Flux<IType> allSubtypesOf(String fqName, boolean includeFocusType) {
|
||||
JavaTypeHierarchyParams searchParams = new JavaTypeHierarchyParams(projectUri.toString(), fqName, includeFocusType);
|
||||
try {
|
||||
CompletableFuture<List<IType>> future = subtypesCache.get(searchParams, () -> client
|
||||
.javaSubTypes(searchParams).handle((results, exception) -> convertTypeDescriptors(results)));
|
||||
return Mono.fromFuture(future)
|
||||
.flatMapMany(results -> Flux.fromIterable(results));
|
||||
} catch (ExecutionException e) {
|
||||
log.error("{}", e);
|
||||
return Flux.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<IType> allSuperTypesOf(String fqName, boolean includeFocusType) {
|
||||
JavaTypeHierarchyParams searchParams = new JavaTypeHierarchyParams(projectUri.toString(), fqName, includeFocusType);
|
||||
try {
|
||||
CompletableFuture<List<IType>> future = supertypesCache.get(searchParams, () -> client
|
||||
.javaSuperTypes(searchParams).handle((results, exception) -> convertTypeDescriptors(results)));
|
||||
return Mono.fromFuture(future)
|
||||
.flatMapMany(results -> Flux.fromIterable(results));
|
||||
} catch (ExecutionException e) {
|
||||
log.error("{}", e);
|
||||
return Flux.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,12 +32,14 @@ import org.springframework.ide.vscode.commons.java.ITypeVariable;
|
||||
import org.springframework.ide.vscode.commons.java.IUnresolvedTypeVariable;
|
||||
import org.springframework.ide.vscode.commons.java.IVoidType;
|
||||
import org.springframework.ide.vscode.commons.java.IWildcardType;
|
||||
import org.springframework.ide.vscode.commons.java.JavaUtils;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaTypeData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeData.AnnotationData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeData.FieldData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeData.MethodData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeDescriptorData;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
@@ -491,4 +493,111 @@ public class Wrappers {
|
||||
};
|
||||
}
|
||||
|
||||
public static IType wrap(TypeDescriptorData descriptor, Supplier<IType> lazyType, Supplier<IType> declaringTypeSupplier, IJavadocProvider javadocProvider) {
|
||||
return new IType() {
|
||||
|
||||
@Override
|
||||
public int getFlags() {
|
||||
return descriptor.getFlags();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType getDeclaringType() {
|
||||
return declaringTypeSupplier.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaModuleData classpathContainer() {
|
||||
return lazyType.get().classpathContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String signature() {
|
||||
return descriptor.getLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return descriptor.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavaDoc() {
|
||||
return javadocProvider.getJavadoc(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBindingKey() {
|
||||
return JavaUtils.typeFqNametoBindingKey(getFullyQualifiedName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<IAnnotation> getAnnotations() {
|
||||
return lazyType.get().getAnnotations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClass() {
|
||||
return descriptor.isClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnum() {
|
||||
return descriptor.isEnum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInterface() {
|
||||
return descriptor.isInterface();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnnotation() {
|
||||
return descriptor.isAnnotation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullyQualifiedName() {
|
||||
return descriptor.getFqName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IField getField(String name) {
|
||||
return getFields().filter(f -> name.equals(f.getElementName())).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<IField> getFields() {
|
||||
return lazyType.get().getFields();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMethod getMethod(String name, Stream<IJavaType> parameters) {
|
||||
return lazyType.get().getMethod(name, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<IMethod> getMethods() {
|
||||
return lazyType.get().getMethods();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSuperclassName() {
|
||||
return descriptor.getSuperClassName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSuperInterfaceNames() {
|
||||
return descriptor.getSuperInterfaceNames();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.jdtls.JdtLsIndex;
|
||||
import org.springframework.ide.vscode.commons.protocol.STS4LanguageClient;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeDescriptorData;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
@@ -51,9 +52,9 @@ public class JdtLsIndexTest {
|
||||
return gson.fromJson(new FileReader(jsonFile), TypeData.class);
|
||||
}
|
||||
|
||||
private List<String> loadJsonSearchTypeResults(String fileName) throws Exception {
|
||||
private List<TypeDescriptorData> loadJsonSearchTypeResults(String fileName) throws Exception {
|
||||
File jsonFile = new File(JdtLsIndexTest.class.getResource("/java-data-json/" + fileName).toURI());
|
||||
Type listType = new TypeToken<List<String>>(){}.getType();
|
||||
Type listType = new TypeToken<List<TypeDescriptorData>>(){}.getType();
|
||||
return gson.fromJson(new FileReader(jsonFile), listType);
|
||||
}
|
||||
|
||||
@@ -138,9 +139,9 @@ public class JdtLsIndexTest {
|
||||
}));
|
||||
// Some valid URI necessary for URI#toString() to succeed
|
||||
JdtLsIndex index = new JdtLsIndex(client, URI.create(System.getProperty("java.io.tmpdir")));
|
||||
List<Tuple2<String, Double>> results = index.fuzzySearchTypes("util.Map", true, false).collectSortedList((o1, o2) -> o2.getT2().compareTo(o1.getT2())).block();
|
||||
String type = results.get(0).getT1();
|
||||
assertEquals("io.netty.util.Mapping", type);
|
||||
List<Tuple2<IType, Double>> results = index.fuzzySearchTypes("util.Map", true, false).collectSortedList((o1, o2) -> o2.getT2().compareTo(o1.getT2())).block();
|
||||
IType type = results.get(0).getT1();
|
||||
assertEquals("io.netty.util.Mapping", type.getFullyQualifiedName());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,7 @@ import org.springframework.ide.vscode.commons.protocol.java.JavaDataParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaSearchParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaTypeHierarchyParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeDescriptorData;
|
||||
|
||||
/**
|
||||
* Some 'custom' extensions to standard LSP {@link LanguageClient}.
|
||||
@@ -59,15 +60,15 @@ public interface STS4LanguageClient extends LanguageClient {
|
||||
CompletableFuture<Location> javaLocation(JavaDataParams params);
|
||||
|
||||
@JsonRequest("sts/javaSearchTypes")
|
||||
CompletableFuture<List<String>> javaSearchTypes(JavaSearchParams params);
|
||||
CompletableFuture<List<TypeDescriptorData>> javaSearchTypes(JavaSearchParams params);
|
||||
|
||||
@JsonRequest("sts/javaSearchPackages")
|
||||
CompletableFuture<List<String>> javaSearchPackages(JavaSearchParams params);
|
||||
|
||||
@JsonRequest("sts/javaSubTypes")
|
||||
CompletableFuture<List<TypeData>> javaSubTypes(JavaTypeHierarchyParams params);
|
||||
CompletableFuture<List<TypeDescriptorData>> javaSubTypes(JavaTypeHierarchyParams params);
|
||||
|
||||
@JsonRequest("sts/javaSuperTypes")
|
||||
CompletableFuture<List<TypeData>> javaSuperTypes(JavaTypeHierarchyParams params);
|
||||
CompletableFuture<List<TypeDescriptorData>> javaSuperTypes(JavaTypeHierarchyParams params);
|
||||
|
||||
}
|
||||
|
||||
@@ -14,11 +14,17 @@ public class JavaTypeHierarchyParams {
|
||||
|
||||
private String projectUri;
|
||||
private String fqName;
|
||||
private boolean includeFocusType;
|
||||
|
||||
public JavaTypeHierarchyParams(String projectUri, String fqName) {
|
||||
public JavaTypeHierarchyParams(String projectUri, String fqName, boolean includeFocusType) {
|
||||
super();
|
||||
this.projectUri = projectUri;
|
||||
this.fqName = fqName;
|
||||
this.setIncludeFocusType(includeFocusType);
|
||||
}
|
||||
|
||||
public JavaTypeHierarchyParams(String projectUri, String fqName) {
|
||||
this(projectUri, fqName, false);
|
||||
}
|
||||
|
||||
public String getProjectUri() {
|
||||
@@ -36,5 +42,47 @@ public class JavaTypeHierarchyParams {
|
||||
public void setFqName(String fqName) {
|
||||
this.fqName = fqName;
|
||||
}
|
||||
|
||||
public boolean isIncludeFocusType() {
|
||||
return includeFocusType;
|
||||
}
|
||||
|
||||
public void setIncludeFocusType(boolean includeFocusType) {
|
||||
this.includeFocusType = includeFocusType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((fqName == null) ? 0 : fqName.hashCode());
|
||||
result = prime * result + (includeFocusType ? 1231 : 1237);
|
||||
result = prime * result + ((projectUri == null) ? 0 : projectUri.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
JavaTypeHierarchyParams other = (JavaTypeHierarchyParams) obj;
|
||||
if (fqName == null) {
|
||||
if (other.fqName != null)
|
||||
return false;
|
||||
} else if (!fqName.equals(other.fqName))
|
||||
return false;
|
||||
if (includeFocusType != other.includeFocusType)
|
||||
return false;
|
||||
if (projectUri == null) {
|
||||
if (other.projectUri != null)
|
||||
return false;
|
||||
} else if (!projectUri.equals(other.projectUri))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,36 +10,19 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.protocol.java;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.ide.vscode.commons.protocol.java.Classpath.CPE;
|
||||
|
||||
public class TypeData extends MemberData {
|
||||
public class TypeData extends TypeDescriptorData {
|
||||
|
||||
private String fqName;
|
||||
private String bindingKey;
|
||||
private boolean clazz;
|
||||
private boolean annotation;
|
||||
private boolean interfaze;
|
||||
private boolean enam;
|
||||
private String superClassName;
|
||||
private String[] superInterfaceNames;
|
||||
private List<FieldData> fields;
|
||||
private List<MethodData> methods;
|
||||
private List<AnnotationData> annotations;
|
||||
|
||||
private ClasspathEntryData classpathEntry;
|
||||
|
||||
public String getFqName() {
|
||||
return fqName;
|
||||
}
|
||||
|
||||
public void setFqName(String fqName) {
|
||||
this.fqName = fqName;
|
||||
}
|
||||
|
||||
public List<FieldData> getFields() {
|
||||
return fields;
|
||||
}
|
||||
@@ -72,54 +55,6 @@ public class TypeData extends MemberData {
|
||||
this.classpathEntry = classpathContainer;
|
||||
}
|
||||
|
||||
public boolean isClass() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public void setClass(boolean clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public boolean isAnnotation() {
|
||||
return annotation;
|
||||
}
|
||||
|
||||
public void setAnnotation(boolean annotation) {
|
||||
this.annotation = annotation;
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return interfaze;
|
||||
}
|
||||
|
||||
public void setInterface(boolean interfaze) {
|
||||
this.interfaze = interfaze;
|
||||
}
|
||||
|
||||
public boolean isEnum() {
|
||||
return enam;
|
||||
}
|
||||
|
||||
public void setEnum(boolean enam) {
|
||||
this.enam = enam;
|
||||
}
|
||||
|
||||
public String getSuperClassName() {
|
||||
return superClassName;
|
||||
}
|
||||
|
||||
public void setSuperClassName(String superClassName) {
|
||||
this.superClassName = superClassName;
|
||||
}
|
||||
|
||||
public String[] getSuperInterfaceNames() {
|
||||
return superInterfaceNames;
|
||||
}
|
||||
|
||||
public void setSuperInterfaceNames(String[] superInterfaceNames) {
|
||||
this.superInterfaceNames = superInterfaceNames;
|
||||
}
|
||||
|
||||
public List<AnnotationData> getAnnotations() {
|
||||
return annotations;
|
||||
}
|
||||
@@ -129,23 +64,15 @@ public class TypeData extends MemberData {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + (annotation ? 1231 : 1237);
|
||||
result = prime * result + ((annotations == null) ? 0 : annotations.hashCode());
|
||||
result = prime * result + ((bindingKey == null) ? 0 : bindingKey.hashCode());
|
||||
result = prime * result + ((classpathEntry == null) ? 0 : classpathEntry.hashCode());
|
||||
result = prime * result + (clazz ? 1231 : 1237);
|
||||
result = prime * result + (enam ? 1231 : 1237);
|
||||
result = prime * result + ((fields == null) ? 0 : fields.hashCode());
|
||||
result = prime * result + ((fqName == null) ? 0 : fqName.hashCode());
|
||||
result = prime * result + (interfaze ? 1231 : 1237);
|
||||
result = prime * result + ((methods == null) ? 0 : methods.hashCode());
|
||||
result = prime * result + ((superClassName == null) ? 0 : superClassName.hashCode());
|
||||
result = prime * result + Arrays.hashCode(superInterfaceNames);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -158,8 +85,6 @@ public class TypeData extends MemberData {
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
TypeData other = (TypeData) obj;
|
||||
if (annotation != other.annotation)
|
||||
return false;
|
||||
if (annotations == null) {
|
||||
if (other.annotations != null)
|
||||
return false;
|
||||
@@ -175,37 +100,20 @@ public class TypeData extends MemberData {
|
||||
return false;
|
||||
} else if (!classpathEntry.equals(other.classpathEntry))
|
||||
return false;
|
||||
if (clazz != other.clazz)
|
||||
return false;
|
||||
if (enam != other.enam)
|
||||
return false;
|
||||
if (fields == null) {
|
||||
if (other.fields != null)
|
||||
return false;
|
||||
} else if (!fields.equals(other.fields))
|
||||
return false;
|
||||
if (fqName == null) {
|
||||
if (other.fqName != null)
|
||||
return false;
|
||||
} else if (!fqName.equals(other.fqName))
|
||||
return false;
|
||||
if (interfaze != other.interfaze)
|
||||
return false;
|
||||
if (methods == null) {
|
||||
if (other.methods != null)
|
||||
return false;
|
||||
} else if (!methods.equals(other.methods))
|
||||
return false;
|
||||
if (superClassName == null) {
|
||||
if (other.superClassName != null)
|
||||
return false;
|
||||
} else if (!superClassName.equals(other.superClassName))
|
||||
return false;
|
||||
if (!Arrays.equals(superInterfaceNames, other.superInterfaceNames))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static class AnnotationData extends JavaElementData {
|
||||
|
||||
String fqName;
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.protocol.java;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class TypeDescriptorData extends MemberData {
|
||||
|
||||
private String fqName;
|
||||
private boolean clazz;
|
||||
private boolean annotation;
|
||||
private boolean interfaze;
|
||||
private boolean enam;
|
||||
private String superClassName;
|
||||
private String[] superInterfaceNames;
|
||||
|
||||
public String getFqName() {
|
||||
return fqName;
|
||||
}
|
||||
|
||||
public void setFqName(String fqName) {
|
||||
this.fqName = fqName;
|
||||
}
|
||||
|
||||
public boolean isClass() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public void setClass(boolean clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public boolean isAnnotation() {
|
||||
return annotation;
|
||||
}
|
||||
|
||||
public void setAnnotation(boolean annotation) {
|
||||
this.annotation = annotation;
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return interfaze;
|
||||
}
|
||||
|
||||
public void setInterface(boolean interfaze) {
|
||||
this.interfaze = interfaze;
|
||||
}
|
||||
|
||||
public boolean isEnum() {
|
||||
return enam;
|
||||
}
|
||||
|
||||
public void setEnum(boolean enam) {
|
||||
this.enam = enam;
|
||||
}
|
||||
|
||||
public String getSuperClassName() {
|
||||
return superClassName;
|
||||
}
|
||||
|
||||
public void setSuperClassName(String superClassName) {
|
||||
this.superClassName = superClassName;
|
||||
}
|
||||
|
||||
public String[] getSuperInterfaceNames() {
|
||||
return superInterfaceNames;
|
||||
}
|
||||
|
||||
public void setSuperInterfaceNames(String[] superInterfaceNames) {
|
||||
this.superInterfaceNames = superInterfaceNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + (annotation ? 1231 : 1237);
|
||||
result = prime * result + (clazz ? 1231 : 1237);
|
||||
result = prime * result + (enam ? 1231 : 1237);
|
||||
result = prime * result + ((fqName == null) ? 0 : fqName.hashCode());
|
||||
result = prime * result + (interfaze ? 1231 : 1237);
|
||||
result = prime * result + ((superClassName == null) ? 0 : superClassName.hashCode());
|
||||
result = prime * result + Arrays.hashCode(superInterfaceNames);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
TypeDescriptorData other = (TypeDescriptorData) obj;
|
||||
if (annotation != other.annotation)
|
||||
return false;
|
||||
if (clazz != other.clazz)
|
||||
return false;
|
||||
if (enam != other.enam)
|
||||
return false;
|
||||
if (fqName == null) {
|
||||
if (other.fqName != null)
|
||||
return false;
|
||||
} else if (!fqName.equals(other.fqName))
|
||||
return false;
|
||||
if (interfaze != other.interfaze)
|
||||
return false;
|
||||
if (superClassName == null) {
|
||||
if (other.superClassName != null)
|
||||
return false;
|
||||
} else if (!superClassName.equals(other.superClassName))
|
||||
return false;
|
||||
if (!Arrays.equals(superInterfaceNames, other.superInterfaceNames))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -61,12 +61,12 @@ public class JavaIndexTest {
|
||||
@Test
|
||||
public void fuzzySearchNoFilter() throws Exception {
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
List<Tuple2<String, Double>> results = project.getIndex().fuzzySearchTypes("util.Map", true, true)
|
||||
List<Tuple2<IType, Double>> results = project.getIndex().fuzzySearchTypes("util.Map", true, true)
|
||||
.collectSortedList((o1, o2) -> o2.getT2().compareTo(o1.getT2()))
|
||||
.block();
|
||||
assertTrue(results.size() > 10);
|
||||
String type = results.get(0).getT1();
|
||||
assertEquals("java.util.Map", type);
|
||||
IType type = results.get(0).getT1();
|
||||
assertEquals("java.util.Map", type.getFullyQualifiedName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -116,7 +116,6 @@ public class JavaIndexTest {
|
||||
IType type = project.getIndex().findType("java.util.ArrayList");
|
||||
assertNotNull(type);
|
||||
IMethod m = type.getMethod("clear", Stream.empty());
|
||||
System.out.println("Method clear: " + m.getBindingKey());
|
||||
assertEquals("clear", m.getElementName());
|
||||
assertEquals(IVoidType.DEFAULT, m.getReturnType());
|
||||
assertEquals(0, m.parameters().count());
|
||||
@@ -164,9 +163,7 @@ public class JavaIndexTest {
|
||||
@Test
|
||||
public void testFindAllSuperTypes() throws Exception {
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
IType type = project.getIndex().findType("java.util.ArrayList");
|
||||
assertNotNull(type);
|
||||
Set<String> actual = project.getIndex().allSuperTypesOf(type).map(t -> t.getFullyQualifiedName()).collect(Collectors.toSet()).block();
|
||||
Set<String> actual = project.getIndex().allSuperTypesOf("java.util.ArrayList", false).map(t -> t.getFullyQualifiedName()).collect(Collectors.toSet()).block();
|
||||
Set<String> expected = new HashSet<>(Arrays.asList(
|
||||
"java.util.List",
|
||||
"java.util.RandomAccess",
|
||||
@@ -180,4 +177,23 @@ public class JavaIndexTest {
|
||||
));
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindAllSuperTypesWithFocusType() throws Exception {
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
Set<String> actual = project.getIndex().allSuperTypesOf("java.util.ArrayList", true).map(t -> t.getFullyQualifiedName()).collect(Collectors.toSet()).block();
|
||||
Set<String> expected = new HashSet<>(Arrays.asList(
|
||||
"java.util.ArrayList",
|
||||
"java.util.List",
|
||||
"java.util.RandomAccess",
|
||||
"java.lang.Cloneable",
|
||||
"java.io.Serializable",
|
||||
"java.util.AbstractList",
|
||||
"java.util.Collection",
|
||||
"java.lang.Object",
|
||||
"java.util.AbstractCollection",
|
||||
"java.lang.Iterable"
|
||||
));
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +113,7 @@ import org.springframework.ide.vscode.commons.protocol.java.JavaDataParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaSearchParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaTypeHierarchyParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeDescriptorData;
|
||||
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
|
||||
import org.springframework.ide.vscode.commons.util.IOUtil;
|
||||
import org.springframework.ide.vscode.commons.util.UriUtil;
|
||||
@@ -362,7 +363,7 @@ public class LanguageServerHarness {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<String>> javaSearchTypes(JavaSearchParams params) {
|
||||
public CompletableFuture<List<TypeDescriptorData>> javaSearchTypes(JavaSearchParams params) {
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
}
|
||||
|
||||
@@ -372,12 +373,12 @@ public class LanguageServerHarness {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<TypeData>> javaSubTypes(JavaTypeHierarchyParams params) {
|
||||
public CompletableFuture<List<TypeDescriptorData>> javaSubTypes(JavaTypeHierarchyParams params) {
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<TypeData>> javaSuperTypes(JavaTypeHierarchyParams params) {
|
||||
public CompletableFuture<List<TypeDescriptorData>> javaSuperTypes(JavaTypeHierarchyParams params) {
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.springframework.ide.vscode.commons.protocol.java.TypeData.AnnotationD
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeData.ClasspathEntryData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeData.FieldData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeData.MethodData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeDescriptorData;
|
||||
import org.springframework.tooling.jdt.ls.commons.Logger;
|
||||
import org.springframework.tooling.jdt.ls.commons.classpath.ClasspathUtil;
|
||||
import org.springframework.tooling.jdt.ls.commons.javadoc.JavadocUtils;
|
||||
@@ -256,10 +257,29 @@ public class JavaData {
|
||||
return data;
|
||||
}
|
||||
|
||||
private void fillTypeData(IType type, TypeData data) {
|
||||
fillMemberData(type, data);
|
||||
|
||||
public TypeDescriptorData createTypeDescriptorData(IType type) {
|
||||
TypeDescriptorData data = new TypeDescriptorData();
|
||||
fillTypeDescriptorData(type, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
private void fillTypeDescriptorData(IType type, TypeDescriptorData data) {
|
||||
fillMemberData(type, data);
|
||||
data.setFqName(type.getFullyQualifiedName());
|
||||
try {
|
||||
data.setAnnotation(type.isAnnotation());
|
||||
data.setClass(type.isClass());
|
||||
data.setEnum(type.isEnum());
|
||||
data.setInterface(type.isInterface());
|
||||
data.setSuperClassName(type.getSuperclassName());
|
||||
data.setSuperInterfaceNames(type.getSuperInterfaceNames());
|
||||
} catch (JavaModelException e) {
|
||||
logger.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void fillTypeData(IType type, TypeData data) {
|
||||
fillTypeDescriptorData(type, data);
|
||||
|
||||
data.setBindingKey(type.getKey());
|
||||
|
||||
@@ -276,12 +296,6 @@ public class JavaData {
|
||||
for (IAnnotation annotation : type.getAnnotations()) {
|
||||
annotationsBuilder.add(createAnnotationData(type, annotation));
|
||||
}
|
||||
data.setAnnotation(type.isAnnotation());
|
||||
data.setClass(type.isClass());
|
||||
data.setEnum(type.isEnum());
|
||||
data.setInterface(type.isInterface());
|
||||
data.setSuperClassName(type.getSuperclassName());
|
||||
data.setSuperInterfaceNames(type.getSuperInterfaceNames());
|
||||
} catch (JavaModelException e) {
|
||||
logger.log(e);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaSearchParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeDescriptorData;
|
||||
import org.springframework.tooling.jdt.ls.commons.Logger;
|
||||
import org.springframework.tooling.jdt.ls.commons.resources.ResourceUtils;
|
||||
|
||||
@@ -27,12 +28,14 @@ import reactor.util.function.Tuples;
|
||||
public class JavaFluxSearch {
|
||||
|
||||
final private Logger logger;
|
||||
final private JavaData javaData;
|
||||
final private Cache<Tuple2<Boolean, Boolean>, PackageFluxSearch> packageSearchCache = CacheBuilder.newBuilder().build();
|
||||
final private Cache<Tuple2<Boolean, Boolean>, TypeFluxSearch> typeSearchCache = CacheBuilder.newBuilder().build();
|
||||
|
||||
public JavaFluxSearch(Logger logger) {
|
||||
public JavaFluxSearch(Logger logger, JavaData javaData) {
|
||||
super();
|
||||
this.logger = logger;
|
||||
this.javaData = javaData;
|
||||
}
|
||||
|
||||
public List<String> fuzzySearchPackages(JavaSearchParams params) throws Exception {
|
||||
@@ -44,11 +47,11 @@ public class JavaFluxSearch {
|
||||
return fluxPackageSearch.searchWithLimits(javaProject, params.getTerm(), params.getTimeLimit());
|
||||
}
|
||||
|
||||
public List<String> fuzzySearchTypes(JavaSearchParams params) throws Exception {
|
||||
public List<TypeDescriptorData> fuzzySearchTypes(JavaSearchParams params) throws Exception {
|
||||
URI projectUri = params.getProjectUri() == null ? null : URI.create(params.getProjectUri());
|
||||
IJavaProject javaProject = projectUri == null ? null : ResourceUtils.getJavaProject(projectUri);
|
||||
TypeFluxSearch fluxTypeSearch = typeSearchCache.get(
|
||||
Tuples.of(params.isIncludeBinaries(), params.isIncludeSystemLibs()), () -> new TypeFluxSearch(logger, params.isIncludeBinaries(), params.isIncludeSystemLibs())
|
||||
Tuples.of(params.isIncludeBinaries(), params.isIncludeSystemLibs()), () -> new TypeFluxSearch(logger, javaData, params.isIncludeBinaries(), params.isIncludeSystemLibs())
|
||||
);
|
||||
return fluxTypeSearch.searchWithLimits(javaProject, params.getTerm(), params.getTimeLimit());
|
||||
}
|
||||
|
||||
@@ -17,18 +17,22 @@ import static org.springframework.tooling.jdt.ls.commons.java.SearchUtils.toWild
|
||||
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.core.IType;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeDescriptorData;
|
||||
import org.springframework.tooling.jdt.ls.commons.Logger;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
public class TypeFluxSearch extends CachingFluxJavaSearch<String> {
|
||||
public class TypeFluxSearch extends CachingFluxJavaSearch<TypeDescriptorData> {
|
||||
|
||||
public TypeFluxSearch(Logger logger, boolean includeBinaries, boolean includeSystemLibs) {
|
||||
private JavaData javaData;
|
||||
|
||||
public TypeFluxSearch(Logger logger, JavaData javaData, boolean includeBinaries, boolean includeSystemLibs) {
|
||||
super(logger, includeBinaries, includeSystemLibs);
|
||||
this.javaData = javaData;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Flux<String> getValuesAsync(IJavaProject javaProject, String searchTerm) {
|
||||
protected Flux<TypeDescriptorData> getValuesAsync(IJavaProject javaProject, String searchTerm) {
|
||||
try {
|
||||
return new FluxJdtSearch(logger)
|
||||
.scope(searchScope(javaProject, includeBinaries, includeSystemLibs))
|
||||
@@ -36,7 +40,7 @@ public class TypeFluxSearch extends CachingFluxJavaSearch<String> {
|
||||
.search()
|
||||
.map(match -> match.getElement())
|
||||
.filter(o -> o instanceof IType)
|
||||
.map(e -> ((IType) e).getFullyQualifiedName());
|
||||
.map(e -> javaData.createTypeDescriptorData((IType) e));
|
||||
} catch (Exception e) {
|
||||
logger.log(e);
|
||||
return Flux.empty();
|
||||
@@ -44,8 +48,8 @@ public class TypeFluxSearch extends CachingFluxJavaSearch<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String stringValue(String t) {
|
||||
return t;
|
||||
protected String stringValue(TypeDescriptorData t) {
|
||||
return t.getFqName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
package org.springframework.tooling.jdt.ls.commons.java;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.core.IType;
|
||||
import org.eclipse.jdt.core.ITypeHierarchy;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeData;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaTypeHierarchyParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeDescriptorData;
|
||||
import org.springframework.tooling.jdt.ls.commons.Logger;
|
||||
import org.springframework.tooling.jdt.ls.commons.resources.ResourceUtils;
|
||||
|
||||
@@ -62,20 +62,26 @@ public class TypeHierarchy {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Stream<TypeData> subTypes(URI projectUri, String fqName) {
|
||||
ITypeHierarchy hierarchy = hierarchy(projectUri, fqName, false);
|
||||
public Stream<TypeDescriptorData> subTypes(JavaTypeHierarchyParams params) {
|
||||
URI projectUri = params.getProjectUri() == null ? null : URI.create(params.getProjectUri());
|
||||
ITypeHierarchy hierarchy = hierarchy(projectUri, params.getFqName(), false);
|
||||
if (hierarchy != null) {
|
||||
return Arrays.stream(hierarchy.getAllSubtypes(hierarchy.getType())).parallel().map(javaData::createTypeData);
|
||||
IType focusType = hierarchy.getType();
|
||||
return Stream.concat(params.isIncludeFocusType() ? Stream.of(focusType) : Stream.empty(), Stream.of(hierarchy.getAllSubtypes(focusType)))
|
||||
.parallel()
|
||||
.map(javaData::createTypeDescriptorData);
|
||||
}
|
||||
return Stream.of();
|
||||
}
|
||||
|
||||
public Stream<TypeData> superTypes(URI projectUri, String fqName) {
|
||||
ITypeHierarchy hierarchy = hierarchy(projectUri, fqName, true);
|
||||
public Stream<TypeDescriptorData> superTypes(JavaTypeHierarchyParams params) {
|
||||
URI projectUri = params.getProjectUri() == null ? null : URI.create(params.getProjectUri());
|
||||
ITypeHierarchy hierarchy = hierarchy(projectUri, params.getFqName(), true);
|
||||
if (hierarchy != null) {
|
||||
return Arrays.stream(hierarchy.getAllSupertypes(hierarchy.getType()))
|
||||
IType focusType = hierarchy.getType();
|
||||
return Stream.concat(params.isIncludeFocusType() ? Stream.of(focusType) : Stream.empty(), Stream.of(hierarchy.getAllSupertypes(focusType)))
|
||||
.parallel()
|
||||
.map(javaData::createTypeData);
|
||||
.map(javaData::createTypeDescriptorData);
|
||||
}
|
||||
return Stream.of();
|
||||
}
|
||||
|
||||
@@ -10,28 +10,28 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.jdt.ls.extension;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.jdt.ls.core.internal.IDelegateCommandHandler;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaTypeHierarchyParams;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class HierarchyHandler implements IDelegateCommandHandler {
|
||||
|
||||
private Gson gson = new Gson();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Object executeCommand(String commandId, List<Object> arguments, IProgressMonitor monitor) throws Exception {
|
||||
Map<String, Object> obj = (Map<String, Object>) arguments.get(0);
|
||||
String projectUri = (String) obj.get("projectUri");
|
||||
String fqName = (String) obj.get("fqName");
|
||||
JavaTypeHierarchyParams params = gson.fromJson(gson.toJson(arguments.get(0)), JavaTypeHierarchyParams.class);
|
||||
switch (commandId) {
|
||||
case "sts.java.hierarchy.subtypes":
|
||||
return JavaHelpers.HIERARCHY.get().subTypes(URI.create(projectUri), fqName).collect(Collectors.toList());
|
||||
return JavaHelpers.HIERARCHY.get().subTypes(params).collect(Collectors.toList());
|
||||
case "sts.java.hierarchy.supertypes":
|
||||
return JavaHelpers.HIERARCHY.get().superTypes(URI.create(projectUri), fqName).collect(Collectors.toList());
|
||||
return JavaHelpers.HIERARCHY.get().superTypes(params).collect(Collectors.toList());
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class JavaHelpers {
|
||||
|
||||
final public static Supplier<JavaData> DATA = Suppliers.memoize(() -> new JavaData(element -> HoverInfoProvider.computeSignature(element).getValue(), logger));
|
||||
|
||||
final public static Supplier<JavaFluxSearch> SEARCH = Suppliers.memoize(() -> new JavaFluxSearch(logger));
|
||||
final public static Supplier<JavaFluxSearch> SEARCH = Suppliers.memoize(() -> new JavaFluxSearch(logger, DATA.get()));
|
||||
|
||||
final public static Supplier<TypeHierarchy> HIERARCHY = Suppliers.memoize(() -> new TypeHierarchy(logger, DATA.get()));
|
||||
|
||||
|
||||
@@ -242,9 +242,9 @@ public class AutowiredHoverProvider implements HoverProvider {
|
||||
// Raw collections shouldn't match any beans
|
||||
return type.getTypeArguments().length == 1 ? matchBeansByType(project, beans, type.getTypeArguments()[0].getQualifiedName(), false) : ImmutableList.of();
|
||||
} else if (type.isArray() && type.getDimensions() == 1) {
|
||||
return matchBeansByType(project, beans, type.getElementType().getErasure().getQualifiedName(), false);
|
||||
return matchBeansByType(project, beans, type.getElementType().getErasure().getBinaryName(), false);
|
||||
} else {
|
||||
return matchBeansByType(project, beans, type.getErasure().getQualifiedName(), true);
|
||||
return matchBeansByType(project, beans, type.getErasure().getBinaryName(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,16 +269,8 @@ public class AutowiredHoverProvider implements HoverProvider {
|
||||
// Trim the generic parameters part if it's present
|
||||
String liveBeanTypeFQName = idx < 0 ? rawLiveBeanFqName : rawLiveBeanFqName.substring(0, idx);
|
||||
if (liveBeanTypeFQName != null) {
|
||||
if (liveBeanTypeFQName.replace('$', '.').equals(bindingQualifiedName)) {
|
||||
return true;
|
||||
} else {
|
||||
IType type = jp.getIndex().findType(liveBeanTypeFQName);
|
||||
String fqTypeName = bindingQualifiedName;
|
||||
if (type != null) {
|
||||
return jp.getIndex().allSuperTypesOf(type).map(IType::getFullyQualifiedName)
|
||||
.filter(fqn -> fqTypeName.equals(fqn.replace('$', '.'))).blockFirst() != null;
|
||||
}
|
||||
}
|
||||
return jp.getIndex().allSuperTypesOf(liveBeanTypeFQName, true).map(IType::getFullyQualifiedName)
|
||||
.filter(fqn -> bindingQualifiedName.equals(fqn)).blockFirst() != null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,11 +12,9 @@
|
||||
package org.springframework.ide.vscode.boot.metadata;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -33,6 +31,7 @@ import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuples;
|
||||
|
||||
/**
|
||||
@@ -137,24 +136,17 @@ public class ClassReferenceProvider extends CachingValueProvider {
|
||||
|
||||
@Override
|
||||
protected Flux<StsValueHint> getValuesAsync(IJavaProject javaProject, String query) {
|
||||
IType targetType = target == null || target.isEmpty() ? javaProject.getIndex().findType("java.lang.Object") : javaProject.getIndex().findType(target);
|
||||
if (targetType == null) {
|
||||
return Flux.empty();
|
||||
}
|
||||
Set<IType> allSubclasses = javaProject.getIndex()
|
||||
.allSubtypesOf(targetType)
|
||||
.filter(t -> Flags.isPublic(t.getFlags()) && !concrete || !isAbstract(t))
|
||||
.collect(Collectors.toSet())
|
||||
.block();
|
||||
if (allSubclasses.isEmpty()) {
|
||||
return Flux.empty();
|
||||
Flux<Tuple2<IType, Double>> typesWithScoresFlux = Flux.empty();
|
||||
|
||||
if (target == null) {
|
||||
typesWithScoresFlux = javaProject.getIndex().fuzzySearchTypes(query, true, false);
|
||||
} else {
|
||||
return Flux.fromIterable(allSubclasses)
|
||||
.map(type -> Tuples.of(type, FuzzyMatcher.matchScore(query, type.getFullyQualifiedName())))
|
||||
.collectSortedList((o1, o2) -> o2.getT2().compareTo(o1.getT2()))
|
||||
.flatMapIterable(l -> l)
|
||||
.map(t -> StsValueHint.create(sourceLinks, javaProject, t.getT1()));
|
||||
typesWithScoresFlux = javaProject.getIndex().allSubtypesOf(target, true)
|
||||
.filter(t -> Flags.isPublic(t.getFlags()) && !concrete || !isAbstract(t))
|
||||
.map(type -> Tuples.of(type, FuzzyMatcher.matchScore(query, type.getFullyQualifiedName())));
|
||||
}
|
||||
return typesWithScoresFlux.collectSortedList((o1, o2) -> o2.getT2().compareTo(o1.getT2()))
|
||||
.flatMapIterable(l -> l).map(t -> StsValueHint.create(sourceLinks, javaProject, t.getT1()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.springframework.ide.vscode.boot.metadata.hints.StsValueHint;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMatcher;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSet.Builder;
|
||||
|
||||
@@ -90,7 +89,7 @@ public class LoggerNameProvider implements ValueProviderStrategy {
|
||||
.map(t -> Tuples.of(StsValueHint.create(t.getT1()), t.getT2())),
|
||||
javaProject.getIndex()
|
||||
.fuzzySearchTypes(query, true, false)
|
||||
.map(t -> Tuples.of(StsValueHint.create(sourceLinks, t.getT1(), javaProject, Suppliers.memoize(() -> javaProject.getIndex().findType(t.getT1()))), t.getT2()))
|
||||
.map(t -> Tuples.of(StsValueHint.create(sourceLinks, javaProject, t.getT1()), t.getT2()))
|
||||
)
|
||||
.collectSortedList((o1, o2) -> o2.getT2().compareTo(o1.getT2()))
|
||||
.flatMapIterable(l -> l)
|
||||
|
||||
@@ -53,9 +53,11 @@ interface JavaSearchParams {
|
||||
term: string;
|
||||
includeBinaries: boolean;
|
||||
includeSystemLibs: boolean;
|
||||
timeLimit: number
|
||||
}
|
||||
|
||||
interface JavaTypeHierarchyParams {
|
||||
projectUri?: string;
|
||||
fqName: string;
|
||||
includeFocusType: boolean;
|
||||
}
|
||||
@@ -55,9 +55,11 @@ interface JavaSearchParams {
|
||||
term: string;
|
||||
includeBinaries: boolean;
|
||||
includeSystemLibs: boolean;
|
||||
timeLimit: number;
|
||||
}
|
||||
|
||||
interface JavaTypeHierarchyParams {
|
||||
projectUri?: string;
|
||||
fqName: string;
|
||||
includeFocusType: boolean;
|
||||
}
|
||||
Reference in New Issue
Block a user