Merge branch 'master' of github.com:spring-projects/sts4

This commit is contained in:
Kris De Volder
2016-11-30 14:10:09 -08:00
19 changed files with 130 additions and 28 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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;
/**

View File

@@ -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

View File

@@ -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"

View File

@@ -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;
/**

View File

@@ -12,7 +12,7 @@
<category-def name="deps" label="Dependencies"/>
<bundle id="org.eclipse.languageserver">
<bundle id="org.eclipse.lsp4e">
<category name="deps"/>
</bundle>

View File

@@ -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>

View File

@@ -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 {

View File

@@ -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());
}
}

View File

@@ -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);
}

View File

@@ -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())

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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");

View 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.