PT #165285833: XML beans for VScode, Theia and Atom
This commit is contained in:
@@ -26,7 +26,7 @@ export class SpringBootLanguageClient extends JavaProcessLanguageClient {
|
||||
}
|
||||
|
||||
getGrammarScopes() {
|
||||
return ['source.java', 'source.boot-properties', 'source.boot-properties-yaml'];
|
||||
return ['source.java', 'source.boot-properties', 'source.boot-properties-yaml', 'text.xml'];
|
||||
}
|
||||
|
||||
getLanguageName() {
|
||||
|
||||
@@ -108,7 +108,8 @@ public final class JandexClasspath implements ClasspathIndex {
|
||||
@Override
|
||||
public Flux<Tuple2<IType, Double>> camelcaseSearchTypes(String searchTerm, boolean includeBinaries,
|
||||
boolean includeSystemLibs) {
|
||||
throw new UnsupportedOperationException("Not implemented for Jandex index!");
|
||||
// throw new UnsupportedOperationException("Not implemented for Jandex index!");
|
||||
return fuzzySearchTypes(searchTerm, includeBinaries, includeSystemLibs);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -29,6 +29,8 @@ import org.eclipse.lsp4j.TextEdit;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits.TextReplace;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.LspClient;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.LspClient.Client;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SortKeys;
|
||||
@@ -266,6 +268,9 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
|
||||
if (isMagicIndentingClient()) {
|
||||
newText = vscodeIndentFix(doc, vscodeEdit.getRange().getStart(), replaceEdit.newText);
|
||||
}
|
||||
if (LspClient.currentClient() == Client.THEIA || LspClient.currentClient() == Client.VSCODE) {
|
||||
newText = newText.replace("$", "\\$");
|
||||
}
|
||||
vscodeEdit.setNewText(newText);
|
||||
return Optional.of(vscodeEdit);
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@ package org.springframework.ide.vscode.commons.protocol.java;
|
||||
|
||||
public class JavaSearchParams {
|
||||
|
||||
public enum SearchType {
|
||||
FUZZY,
|
||||
CAMELCASE
|
||||
public final class SearchType {
|
||||
public static final String FUZZY = "fuzzy";
|
||||
public static final String CAMELCASE = "camelcase";
|
||||
}
|
||||
|
||||
private String projectUri;
|
||||
@@ -22,13 +22,13 @@ public class JavaSearchParams {
|
||||
private boolean includeBinaries;
|
||||
private boolean includeSystemLibs;
|
||||
private long timeLimit = -1;
|
||||
private SearchType searchType;
|
||||
private String searchType;
|
||||
|
||||
public JavaSearchParams(String projectUri, String term, SearchType searchType) {
|
||||
public JavaSearchParams(String projectUri, String term, String searchType) {
|
||||
this(projectUri, term, searchType, true, false);
|
||||
}
|
||||
|
||||
public JavaSearchParams(String projectUri, String term, SearchType searchType, boolean includeBinaries, boolean includeSystemLibs, long timeLimit) {
|
||||
public JavaSearchParams(String projectUri, String term, String searchType, boolean includeBinaries, boolean includeSystemLibs, long timeLimit) {
|
||||
super();
|
||||
this.projectUri = projectUri;
|
||||
this.term = term;
|
||||
@@ -38,7 +38,7 @@ public class JavaSearchParams {
|
||||
this.setTimeLimit(timeLimit);
|
||||
}
|
||||
|
||||
public JavaSearchParams(String projectUri, String term, SearchType searchType, boolean includeBinaries, boolean includeSystemLibs) {
|
||||
public JavaSearchParams(String projectUri, String term, String searchType, boolean includeBinaries, boolean includeSystemLibs) {
|
||||
this(projectUri, term, searchType, includeBinaries, includeSystemLibs, -1);
|
||||
}
|
||||
|
||||
@@ -82,11 +82,11 @@ public class JavaSearchParams {
|
||||
this.timeLimit = timeLimit;
|
||||
}
|
||||
|
||||
public SearchType getSearchType() {
|
||||
public String getSearchType() {
|
||||
return searchType;
|
||||
}
|
||||
|
||||
public void setSearchType(SearchType searchType) {
|
||||
public void setSearchType(String searchType) {
|
||||
this.searchType = searchType;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaSearchParams.SearchType;
|
||||
import org.springframework.tooling.jdt.ls.commons.Logger;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
@@ -64,8 +63,8 @@ public abstract class CachingFluxJavaSearch<T> implements FluxSearch<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Flux<T> search(IJavaProject javaProject, String query, SearchType searchType) {
|
||||
Tuple2<String, String> key = key(javaProject, query, searchType);
|
||||
public final Flux<T> search(IJavaProject javaProject, String query, String searchType) {
|
||||
Tuple3<String, String, String> key = key(javaProject, query, searchType);
|
||||
CacheEntry cached = null;
|
||||
try {
|
||||
cached = cache.get(key, () -> new CacheEntry(query, getValuesIncremental(javaProject, query, searchType)));
|
||||
@@ -80,7 +79,7 @@ public abstract class CachingFluxJavaSearch<T> implements FluxSearch<T> {
|
||||
* <p>
|
||||
* Falls back on doing a full-blown search if there's no usable 'prefix-query' in the cache.
|
||||
*/
|
||||
private Flux<T> getValuesIncremental(IJavaProject javaProject, String query, SearchType searchType) {
|
||||
private Flux<T> getValuesIncremental(IJavaProject javaProject, String query, String searchType) {
|
||||
// debug("trying to solve "+query+" incrementally");
|
||||
String subquery = query;
|
||||
while (subquery.length()>=1) {
|
||||
@@ -106,11 +105,11 @@ public abstract class CachingFluxJavaSearch<T> implements FluxSearch<T> {
|
||||
return getValuesAsync(javaProject, query, searchType);
|
||||
}
|
||||
|
||||
protected abstract Flux<T> getValuesAsync(IJavaProject javaProject, String query, SearchType searchType);
|
||||
protected abstract Flux<T> getValuesAsync(IJavaProject javaProject, String query, String searchType);
|
||||
|
||||
protected abstract String stringValue(T t);
|
||||
|
||||
private Tuple3<String,String,SearchType> key(IJavaProject javaProject, String query, SearchType searchType) {
|
||||
private Tuple3<String,String,String> key(IJavaProject javaProject, String query, String searchType) {
|
||||
return Tuples.of(javaProject==null?null:javaProject.getElementName(), query, searchType);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,15 +14,14 @@ import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaSearchParams.SearchType;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
public interface FluxSearch<T> {
|
||||
|
||||
Flux<T> search(IJavaProject project, String searchTerm, SearchType searchType);
|
||||
Flux<T> search(IJavaProject project, String searchTerm, String searchType);
|
||||
|
||||
default List<T> searchWithLimits(IJavaProject javaProject, String searchTerm, SearchType searchType, long timeLimit) {
|
||||
default List<T> searchWithLimits(IJavaProject javaProject, String searchTerm, String searchType, long timeLimit) {
|
||||
Flux<T> flux = this.search(javaProject, searchTerm, searchType);
|
||||
if (timeLimit > 0) {
|
||||
flux = flux.take(Duration.ofMillis(timeLimit));
|
||||
|
||||
@@ -16,7 +16,6 @@ import static org.springframework.tooling.jdt.ls.commons.java.SearchUtils.toPack
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.core.IPackageFragment;
|
||||
import org.eclipse.jdt.core.JavaModelException;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaSearchParams.SearchType;
|
||||
import org.springframework.tooling.jdt.ls.commons.Logger;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
@@ -28,7 +27,7 @@ public class PackageFluxSearch extends CachingFluxJavaSearch<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Flux<String> getValuesAsync(IJavaProject javaProject, String searchTerm, SearchType searchType) {
|
||||
protected Flux<String> getValuesAsync(IJavaProject javaProject, String searchTerm, String searchType) {
|
||||
try {
|
||||
return new FluxJdtSearch(logger)
|
||||
.scope(searchScope(javaProject, includeBinaries, includeSystemLibs))
|
||||
|
||||
@@ -17,7 +17,7 @@ import org.eclipse.jdt.core.search.IJavaSearchConstants;
|
||||
import org.eclipse.jdt.core.search.IJavaSearchScope;
|
||||
import org.eclipse.jdt.core.search.SearchEngine;
|
||||
import org.eclipse.jdt.core.search.SearchPattern;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaSearchParams.SearchType;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaSearchParams;
|
||||
|
||||
public class SearchUtils {
|
||||
|
||||
@@ -48,28 +48,28 @@ public class SearchUtils {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String toSearchPattern(SearchType searchType, String query) {
|
||||
public static String toSearchPattern(String searchType, String query) {
|
||||
switch(searchType) {
|
||||
case FUZZY:
|
||||
case JavaSearchParams.SearchType.FUZZY:
|
||||
return toWildCardPattern(query);
|
||||
case CAMELCASE:
|
||||
case JavaSearchParams.SearchType.CAMELCASE:
|
||||
return toCamelCasePattern(query);
|
||||
default:
|
||||
return query;
|
||||
}
|
||||
}
|
||||
|
||||
public static SearchPattern toPackagePattern(SearchType searchType, String query) {
|
||||
public static SearchPattern toPackagePattern(String searchType, String query) {
|
||||
int searchFor = IJavaSearchConstants.PACKAGE;
|
||||
int limitTo = IJavaSearchConstants.DECLARATIONS;
|
||||
int matchRule = SearchPattern.R_EXACT_MATCH;
|
||||
String finalQuery = query;
|
||||
switch (searchType) {
|
||||
case FUZZY:
|
||||
case JavaSearchParams.SearchType.FUZZY:
|
||||
matchRule = SearchPattern.R_PATTERN_MATCH;
|
||||
finalQuery = toWildCardPattern(query);
|
||||
break;
|
||||
case CAMELCASE:
|
||||
case JavaSearchParams.SearchType.CAMELCASE:
|
||||
matchRule = SearchPattern.R_CAMELCASE_MATCH;
|
||||
finalQuery = query.isEmpty() ? WILDCARD : query;
|
||||
break;
|
||||
@@ -77,17 +77,17 @@ public class SearchUtils {
|
||||
return SearchPattern.createPattern(finalQuery, searchFor, limitTo, matchRule);
|
||||
}
|
||||
|
||||
public static SearchPattern toClassPattern(SearchType searchType, String query) {
|
||||
public static SearchPattern toClassPattern(String searchType, String query) {
|
||||
int searchFor = IJavaSearchConstants.CLASS;
|
||||
int limitTo = IJavaSearchConstants.DECLARATIONS;
|
||||
int matchRule = SearchPattern.R_EXACT_MATCH;
|
||||
String finalQuery = query;
|
||||
switch (searchType) {
|
||||
case FUZZY:
|
||||
case JavaSearchParams.SearchType.FUZZY:
|
||||
matchRule = SearchPattern.R_PATTERN_MATCH;
|
||||
finalQuery = toWildCardPattern(query);
|
||||
break;
|
||||
case CAMELCASE:
|
||||
case JavaSearchParams.SearchType.CAMELCASE:
|
||||
matchRule = SearchPattern.R_CAMELCASE_MATCH;
|
||||
finalQuery = query.isEmpty() ? WILDCARD : query;
|
||||
break;
|
||||
@@ -95,17 +95,17 @@ public class SearchUtils {
|
||||
return SearchPattern.createPattern(finalQuery, searchFor, limitTo, matchRule);
|
||||
}
|
||||
|
||||
public static SearchPattern toTypePattern(SearchType searchType, String query) {
|
||||
public static SearchPattern toTypePattern(String searchType, String query) {
|
||||
int searchFor = IJavaSearchConstants.TYPE;
|
||||
int limitTo = IJavaSearchConstants.DECLARATIONS;
|
||||
int matchRule = SearchPattern.R_EXACT_MATCH;
|
||||
String finalQuery = query;
|
||||
switch (searchType) {
|
||||
case FUZZY:
|
||||
case JavaSearchParams.SearchType.FUZZY:
|
||||
matchRule = SearchPattern.R_PATTERN_MATCH;
|
||||
finalQuery = toWildCardPattern(query);
|
||||
break;
|
||||
case CAMELCASE:
|
||||
case JavaSearchParams.SearchType.CAMELCASE:
|
||||
matchRule = SearchPattern.R_CAMELCASE_MATCH;
|
||||
finalQuery = query.isEmpty() ? WILDCARD : query;
|
||||
break;
|
||||
|
||||
@@ -15,7 +15,6 @@ import static org.springframework.tooling.jdt.ls.commons.java.SearchUtils.toType
|
||||
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.core.IType;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.JavaSearchParams.SearchType;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.TypeDescriptorData;
|
||||
import org.springframework.tooling.jdt.ls.commons.Logger;
|
||||
|
||||
@@ -31,7 +30,7 @@ public class TypeFluxSearch extends CachingFluxJavaSearch<TypeDescriptorData> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Flux<TypeDescriptorData> getValuesAsync(IJavaProject javaProject, String searchTerm, SearchType searchType) {
|
||||
protected Flux<TypeDescriptorData> getValuesAsync(IJavaProject javaProject, String searchTerm, String searchType) {
|
||||
try {
|
||||
return new FluxJdtSearch(logger)
|
||||
.scope(searchScope(javaProject, includeBinaries, includeSystemLibs))
|
||||
|
||||
@@ -76,18 +76,19 @@ public class BeanRefCompletionProposalProvider implements XMLCompletionProvider
|
||||
.filter(beanID -> beanID != null && beanID.length() > 0)
|
||||
.map(beanID -> Tuples.of(beanID, FuzzyMatcher.matchScore(searchPrefix, beanID)))
|
||||
.filter(tuple -> tuple.getT2() != 0.0)
|
||||
.map(tuple -> createProposal(tuple.getT1(), doc, offset, tokenOffset, tokenEnd, tuple.getT2()))
|
||||
.map(tuple -> createProposal(tuple.getT1(), doc, offset, searchPrefix, tuple.getT2()))
|
||||
.collect(Collectors.toList());
|
||||
};
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private ICompletionProposal createProposal(String beanID, TextDocument doc, int offset, int tokenStart, int tokenEnd, Double score) {
|
||||
private ICompletionProposal createProposal(String beanID, TextDocument doc, int offset, String prefix, Double score) {
|
||||
CompletionItemKind kind = CompletionItemKind.Reference;
|
||||
|
||||
DocumentEdits edits = new DocumentEdits(doc);
|
||||
edits.replace(tokenStart, tokenEnd, "\"" + beanID + "\"");
|
||||
edits.delete(offset - prefix.length(), offset);
|
||||
edits.insert(offset, beanID);
|
||||
|
||||
Renderable renderable = null;
|
||||
|
||||
|
||||
@@ -63,17 +63,19 @@ public class TypeCompletionProposalProvider implements XMLCompletionProvider {
|
||||
// Flux<Tuple2<IType, Double>> types = project.getIndex().fuzzySearchTypes(prefix, true, true);
|
||||
Flux<Tuple2<IType, Double>> types = project.getIndex().camelcaseSearchTypes(prefix, true, true);
|
||||
|
||||
final String prefixStr = prefix;
|
||||
|
||||
return types
|
||||
.filter(result -> result.getT1() != null && result.getT1().getElementName() != null && result.getT1().getElementName().length() > 0)
|
||||
.filter(result -> classesOnly ? result.getT1().isClass() : true)
|
||||
.map(t -> createProposal(t, doc, offset, tokenOffset, tokenEnd))
|
||||
.map(t -> createProposal(t, doc, offset, prefixStr))
|
||||
.collectList().block();
|
||||
};
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private ICompletionProposal createProposal(Tuple2<IType, Double> t, TextDocument doc, int offset, int tokenStart, int tokenEnd) {
|
||||
private ICompletionProposal createProposal(Tuple2<IType, Double> t, TextDocument doc, int offset, String prefix) {
|
||||
IType type = t.getT1();
|
||||
|
||||
String label = type.getFullyQualifiedName();
|
||||
@@ -98,7 +100,8 @@ public class TypeCompletionProposalProvider implements XMLCompletionProvider {
|
||||
}
|
||||
|
||||
DocumentEdits edits = new DocumentEdits(doc);
|
||||
edits.replace(tokenStart, tokenEnd, "\"" + type.getFullyQualifiedName() + "\"");
|
||||
edits.delete(offset - prefix.length(), offset);
|
||||
edits.insert(offset, type.getFullyQualifiedName());
|
||||
|
||||
Renderable renderable = null;
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ interface JavaDataParams {
|
||||
interface JavaSearchParams {
|
||||
projectUri: string;
|
||||
term: string;
|
||||
searchType: string;
|
||||
includeBinaries: boolean;
|
||||
includeSystemLibs: boolean;
|
||||
timeLimit: number
|
||||
|
||||
@@ -14,7 +14,8 @@ import {
|
||||
SPRING_BOOT_SERVER_ID,
|
||||
SPRING_BOOT_SERVER_NAME,
|
||||
BOOT_PROPERTIES_YAML_LANGUAGE_ID,
|
||||
BOOT_PROPERTIES_LANGUAGE_ID
|
||||
BOOT_PROPERTIES_LANGUAGE_ID,
|
||||
XML_LANGUAGE_ID
|
||||
} from '../common';
|
||||
import { DocumentSelector } from '@theia/languages/lib/browser';
|
||||
import { JAVA_LANGUAGE_ID } from '@theia/java/lib/common';
|
||||
@@ -90,12 +91,13 @@ export class SpringBootClientContribution extends StsLanguageClientContribution<
|
||||
}
|
||||
|
||||
protected get documentSelector(): DocumentSelector | undefined {
|
||||
return [JAVA_LANGUAGE_ID, BOOT_PROPERTIES_YAML_LANGUAGE_ID, BOOT_PROPERTIES_LANGUAGE_ID];
|
||||
return [JAVA_LANGUAGE_ID, BOOT_PROPERTIES_YAML_LANGUAGE_ID, BOOT_PROPERTIES_LANGUAGE_ID, XML_LANGUAGE_ID];
|
||||
}
|
||||
|
||||
protected get globPatterns() {
|
||||
return [
|
||||
'**/*.java',
|
||||
'**/*.xml',
|
||||
'**/application*.yml',
|
||||
'**/application*.yaml',
|
||||
'**/bootstrap*.yml',
|
||||
|
||||
@@ -16,3 +16,5 @@ export const BOOT_PROPERTIES_YAML_LANGUAGE_NAME = 'Spring-Boot-Properties-YAML';
|
||||
|
||||
export const BOOT_PROPERTIES_LANGUAGE_ID = 'spring-boot-properties';
|
||||
export const BOOT_PROPERTIES_LANGUAGE_NAME = 'Spring-Boot-Properties';
|
||||
|
||||
export const XML_LANGUAGE_ID = 'xml';
|
||||
|
||||
@@ -53,6 +53,7 @@ interface JavaDataParams {
|
||||
interface JavaSearchParams {
|
||||
projectUri: string;
|
||||
term: string;
|
||||
searchType: string;
|
||||
includeBinaries: boolean;
|
||||
includeSystemLibs: boolean;
|
||||
timeLimit: number;
|
||||
|
||||
@@ -11,6 +11,7 @@ import {LanguageClient} from "vscode-languageclient";
|
||||
const PROPERTIES_LANGUAGE_ID = "spring-boot-properties";
|
||||
const YAML_LANGUAGE_ID = "spring-boot-properties-yaml";
|
||||
const JAVA_LANGUAGE_ID = "java";
|
||||
const XML_LANGUAGE_ID = "xml";
|
||||
|
||||
/** Called when extension is activated */
|
||||
export function activate(context: VSCode.ExtensionContext): Thenable<LanguageClient> {
|
||||
@@ -42,6 +43,10 @@ export function activate(context: VSCode.ExtensionContext): Thenable<LanguageCli
|
||||
{
|
||||
language: JAVA_LANGUAGE_ID,
|
||||
scheme: 'file'
|
||||
},
|
||||
{
|
||||
language: XML_LANGUAGE_ID,
|
||||
scheme: 'file'
|
||||
}
|
||||
],
|
||||
synchronize: {
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
"activationEvents": [
|
||||
"onLanguage:spring-boot-properties",
|
||||
"onLanguage:spring-boot-properties-yaml",
|
||||
"onLanguage:java"
|
||||
"onLanguage:java",
|
||||
"onLanguage:xml"
|
||||
],
|
||||
"contributes": {
|
||||
"javaExtensions": [
|
||||
|
||||
Reference in New Issue
Block a user