Merge branch 'master' of github.com:spring-projects/sts4
This commit is contained in:
@@ -5,10 +5,10 @@ Bundle-SymbolicName: org.springframework.boot.ide.properties.editors;singleton:=
|
||||
Bundle-Version: 4.0.0.qualifier
|
||||
Bundle-Vendor: Pivotal, Inc.
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Require-Bundle: org.eclipse.languageserver;bundle-version="0.1.0",
|
||||
org.eclipse.ui.genericeditor;bundle-version="1.0.0",
|
||||
Require-Bundle: org.eclipse.ui.genericeditor;bundle-version="1.0.0",
|
||||
org.eclipse.core.runtime;bundle-version="3.12.0",
|
||||
org.eclipse.jface.text;bundle-version="3.11.100",
|
||||
org.eclipse.jdt.ui;bundle-version="3.13.0",
|
||||
org.dadacoalition.yedit;bundle-version="1.0.20"
|
||||
org.dadacoalition.yedit;bundle-version="1.0.20",
|
||||
org.eclipse.lsp4e;bundle-version="0.1.0"
|
||||
Import-Package: org.eclipse.jface.preference
|
||||
|
||||
@@ -4,7 +4,7 @@ Bundle-Name: Server
|
||||
Bundle-SymbolicName: org.springframework.boot.ide.cloudfoundry.server;singleton:=true
|
||||
Bundle-Version: 4.0.0.qualifier
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Require-Bundle: org.eclipse.languageserver;bundle-version="0.1.0",
|
||||
org.eclipse.jdt.launching;bundle-version="3.9.0",
|
||||
org.eclipse.core.runtime;bundle-version="3.12.0"
|
||||
Require-Bundle: org.eclipse.jdt.launching;bundle-version="3.9.0",
|
||||
org.eclipse.core.runtime;bundle-version="3.12.0",
|
||||
org.eclipse.lsp4e;bundle-version="0.1.0"
|
||||
Import-Package: org.osgi.framework
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<plugin>
|
||||
|
||||
<extension
|
||||
point="org.eclipse.languageserver.languageServer">
|
||||
point="org.eclipse.lsp4e.languageServer">
|
||||
<server
|
||||
class="org.springframework.boot.ide.cloudfoundry.server.CloudFoundryManifestLanguageServer"
|
||||
id="org.eclipse.languageserver.languages.cloudfoundrymanifest"
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.jdt.internal.launching.StandardVMType;
|
||||
import org.eclipse.jdt.launching.IVMInstall;
|
||||
import org.eclipse.jdt.launching.JavaRuntime;
|
||||
import org.eclipse.languageserver.ProcessStreamConnectionProvider;
|
||||
import org.eclipse.lsp4e.ProcessStreamConnectionProvider;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@ Bundle-Name: Servers
|
||||
Bundle-SymbolicName: org.springframework.boot.ide.properties.servers;singleton:=true
|
||||
Bundle-Version: 4.0.0.qualifier
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Require-Bundle: org.eclipse.languageserver;bundle-version="0.1.0",
|
||||
org.eclipse.jdt.launching;bundle-version="3.9.0",
|
||||
org.eclipse.core.runtime;bundle-version="3.12.0"
|
||||
Require-Bundle: org.eclipse.jdt.launching;bundle-version="3.9.0",
|
||||
org.eclipse.core.runtime;bundle-version="3.12.0",
|
||||
org.eclipse.lsp4e;bundle-version="0.1.0"
|
||||
Import-Package: org.osgi.framework
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<plugin>
|
||||
|
||||
<extension
|
||||
point="org.eclipse.languageserver.languageServer">
|
||||
point="org.eclipse.lsp4e.languageServer">
|
||||
<server
|
||||
class="org.springframework.boot.ide.properties.servers.SpringBootPropertiesLanguageServer"
|
||||
id="org.eclipse.languageserver.languages.springbootproperties"
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.jdt.internal.launching.StandardVMType;
|
||||
import org.eclipse.jdt.launching.IVMInstall;
|
||||
import org.eclipse.jdt.launching.JavaRuntime;
|
||||
import org.eclipse.languageserver.ProcessStreamConnectionProvider;
|
||||
import org.eclipse.lsp4e.ProcessStreamConnectionProvider;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
<category-def name="deps" label="Dependencies"/>
|
||||
|
||||
<bundle id="org.eclipse.languageserver">
|
||||
<bundle id="org.eclipse.lsp4e">
|
||||
<category name="deps"/>
|
||||
</bundle>
|
||||
|
||||
|
||||
@@ -51,8 +51,6 @@
|
||||
|
||||
<tycho-version>0.26.0</tycho-version>
|
||||
<encoding>UTF-8</encoding>
|
||||
|
||||
<eclipse-lsp-support-repo>file:///${basedir}/../../../eclipse-language-service/repository/target/repository</eclipse-lsp-support-repo>
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
@@ -86,7 +84,12 @@
|
||||
<repository>
|
||||
<id>orbit</id>
|
||||
<layout>p2</layout>
|
||||
<url>http://download.eclipse.org/tools/orbit/downloads/drops/R20160520211859/repository/</url>
|
||||
<url>http://download.eclipse.org/tools/orbit/downloads/drops/S20161021172207/repository/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>lsp4e</id>
|
||||
<layout>p2</layout>
|
||||
<url>http://download.eclipse.org/lsp4e/snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</profile>
|
||||
@@ -118,14 +121,6 @@
|
||||
|
||||
</profiles>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>eclipse-language-server-local-repo</id>
|
||||
<layout>p2</layout>
|
||||
<url>${eclipse-lsp-support-repo}</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>tycho-snapshots</id>
|
||||
|
||||
@@ -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