Logger name content asisst
This commit is contained in:
@@ -20,6 +20,14 @@ import com.google.common.cache.CacheBuilder;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
/**
|
||||
* Provides the algorithm for 'class-reference' valueProvider.
|
||||
* <p>
|
||||
* See: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-docs/src/main/asciidoc/appendix-configuration-metadata.adoc
|
||||
*
|
||||
* @author Kris De Volder
|
||||
* @author Alex Boyko
|
||||
*/
|
||||
public class ClassReferenceProvider extends CachingValueProvider {
|
||||
|
||||
/**
|
||||
@@ -44,7 +52,7 @@ public class ClassReferenceProvider extends CachingValueProvider {
|
||||
}
|
||||
);
|
||||
|
||||
public static <K,V> Function<K,V> applyOn(long duration, TimeUnit unit, Function<K,V> func) {
|
||||
private static <K,V> Function<K,V> applyOn(long duration, TimeUnit unit, Function<K,V> func) {
|
||||
Cache<K,V> cache = CacheBuilder.newBuilder().expireAfterAccess(duration, unit).expireAfterWrite(duration, unit).build();
|
||||
return (k) -> {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.springframework.ide.vscode.application.properties.metadata;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.ide.vscode.application.properties.metadata.ValueProviderRegistry.ValueProviderStrategy;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.hints.StsValueHint;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.util.function.Tuples;
|
||||
|
||||
/**
|
||||
* Provides the algorithm for 'logger-name' valueProvider.
|
||||
* <p>
|
||||
* See: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-docs/src/main/asciidoc/appendix-configuration-metadata.adoc
|
||||
*
|
||||
* @author Kris De Volder
|
||||
* @author Alex Boyko
|
||||
*/
|
||||
public class LoggerNameProvider extends CachingValueProvider {
|
||||
|
||||
private static final ValueProviderStrategy INSTANCE = new LoggerNameProvider();
|
||||
public static final Function<Map<String, Object>, ValueProviderStrategy> FACTORY = (params) -> INSTANCE;
|
||||
|
||||
@Override
|
||||
protected Flux<StsValueHint> getValuesAsync(IJavaProject javaProject, String query) {
|
||||
return Flux.concat(
|
||||
javaProject
|
||||
.fuzzySearchPackages(query)
|
||||
.map(t -> Tuples.of(StsValueHint.create(t.getT1()), t.getT2())),
|
||||
javaProject
|
||||
.fuzzySearchTypes(query, null)
|
||||
.map(t -> Tuples.of(StsValueHint.create(t.getT1()), t.getT2()))
|
||||
)
|
||||
.collectSortedList((o1, o2) -> o2.getT2().compareTo(o1.getT2()))
|
||||
.flatMap(l -> Flux.fromIterable(l))
|
||||
.map(t -> t.getT1());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -48,7 +48,7 @@ public class ValueProviderRegistry {
|
||||
}
|
||||
|
||||
protected void initializeDefaults(ValueProviderRegistry r) {
|
||||
// def("logger-name", LoggerNameProvider.FACTORY);
|
||||
def("logger-name", LoggerNameProvider.FACTORY);
|
||||
def("class-reference", ClassReferenceProvider.FACTORY);
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,8 @@ public class JandexIndex {
|
||||
|
||||
private Map<File, Supplier<List<Tuple2<String, IType>>>> knownTypes;
|
||||
|
||||
private Map<File, Supplier<List<String>>> knownPackages;
|
||||
|
||||
private Cache<File, IJavadocProvider> javadocProvidersCache = CacheBuilder.newBuilder().build();
|
||||
|
||||
private JandexIndex[] baseIndex;
|
||||
@@ -100,10 +102,12 @@ public class JandexIndex {
|
||||
this.baseIndex = baseIndex;
|
||||
this.index = new ConcurrentHashMap<>();
|
||||
this.knownTypes = new HashMap<>();
|
||||
this.knownPackages = new HashMap<>();
|
||||
this.javadocProviderFactory = javadocProviderFactory;
|
||||
classpathEntries.forEach(file -> {
|
||||
index.put(file, Suppliers.memoize(() -> createIndex(file, indexFileFinder)));
|
||||
knownTypes.put(file, Suppliers.memoize(() -> getKnownTypesStream(file).collect(Collectors.toList())));
|
||||
knownPackages.put(file, Suppliers.memoize(() -> getKnownPackages(file).collect(Collectors.toList())));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -225,6 +229,21 @@ public class JandexIndex {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
private Stream<String> getKnownPackages(File file) {
|
||||
Optional<IndexView> indexView = index.get(file).get();
|
||||
if (indexView.isPresent()) {
|
||||
return indexView.get()
|
||||
.getKnownClasses()
|
||||
.parallelStream()
|
||||
.map(info -> {
|
||||
String name = info.name().toString();
|
||||
return name.substring(0, name.lastIndexOf('.'));
|
||||
})
|
||||
.distinct();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
public Flux<Tuple2<IType, Double>> fuzzySearchTypes(String searchTerm, TypeFilter typeFilter) {
|
||||
Flux<Tuple2<IType, Double>> flux = Flux.fromIterable(knownTypes.values())
|
||||
.publishOn(Schedulers.parallel())
|
||||
@@ -239,6 +258,19 @@ public class JandexIndex {
|
||||
}
|
||||
}
|
||||
|
||||
public Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm) {
|
||||
Flux<Tuple2<String, Double>> flux = Flux.fromIterable(knownPackages.values())
|
||||
.publishOn(Schedulers.parallel())
|
||||
.flatMap(s -> Flux.fromIterable(s.get()))
|
||||
.map(pkg -> Tuples.of(pkg, FuzzyMatcher.matchScore(searchTerm, pkg)))
|
||||
.filter(t -> t.getT2() != 0.0);
|
||||
if (baseIndex == null) {
|
||||
return flux;
|
||||
} else {
|
||||
return Flux.merge(flux, Flux.fromArray(baseIndex).flatMap(index -> index.fuzzySearchPackages(searchTerm)));
|
||||
}
|
||||
}
|
||||
|
||||
public Flux<IType> allSubtypesOf(IType type) {
|
||||
DotName name = DotName.createSimple(type.getFullyQualifiedName());
|
||||
Flux<IType> flux = Flux.fromIterable(index.keySet())
|
||||
|
||||
@@ -14,6 +14,8 @@ public interface IJavaProject extends IJavaElement {
|
||||
|
||||
Flux<Tuple2<IType, Double>> fuzzySearchTypes(String searchTerm, TypeFilter typeFilter);
|
||||
|
||||
Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm);
|
||||
|
||||
Flux<IType> allSubtypesOf(IType type);
|
||||
|
||||
IClasspath getClasspath();
|
||||
|
||||
@@ -66,6 +66,11 @@ public class MavenJavaProject implements IJavaProject {
|
||||
return classpath.fuzzySearchType(searchTerm, typeFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm) {
|
||||
return classpath.fuzzySearchPackages(searchTerm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<IType> allSubtypesOf(IType type) {
|
||||
return classpath.allSubtypesOf(type);
|
||||
|
||||
@@ -104,6 +104,10 @@ public class MavenProjectClasspath implements IClasspath {
|
||||
return javaIndex.get().fuzzySearchTypes(searchTerm, typeFilter);
|
||||
}
|
||||
|
||||
public Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm) {
|
||||
return javaIndex.get().fuzzySearchPackages(searchTerm);
|
||||
}
|
||||
|
||||
public Flux<IType> allSubtypesOf(IType type) {
|
||||
return javaIndex.get().allSubtypesOf(type);
|
||||
}
|
||||
|
||||
@@ -63,6 +63,11 @@ public class JavaProjectWithClasspathFile implements IJavaProject {
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm) {
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<IType> allSubtypesOf(IType type) {
|
||||
return Flux.empty();
|
||||
|
||||
@@ -87,6 +87,16 @@ public class JavaIndexTest {
|
||||
assertEquals("java.util.EnumMap$KeySet", results.get(0).getT1().getFullyQualifiedName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fuzzySearchPackage() throws Exception {
|
||||
List<Tuple2<String, Double>> results = MavenCore.getInstance().getJavaIndexForJreLibs()
|
||||
.fuzzySearchPackages("util")
|
||||
.collectSortedList((o1, o2) -> o2.getT2().compareTo(o1.getT2()))
|
||||
.block();
|
||||
assertTrue(results.size() > 10);
|
||||
assertEquals("java.util", results.get(0).getT1());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findClassInJar() throws Exception {
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
|
||||
@@ -3056,7 +3056,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
}
|
||||
|
||||
@Ignore @Test public void testLoggerNameCompletion() throws Exception {
|
||||
@Test public void testLoggerNameCompletion() throws Exception {
|
||||
CachingValueProvider.TIMEOUT = Duration.ofSeconds(20); // the provider can't be reliably tested if its not allowed to
|
||||
// fetch all its values (even though in 'production' you
|
||||
// wouldn't want it to block the UI thread for this long.
|
||||
|
||||
Reference in New Issue
Block a user