first version of re-introduced content-assist for spring data repositories
This commit is contained in:
@@ -26,6 +26,7 @@ import org.springframework.ide.vscode.boot.java.autowired.AutowiredHoverProvider
|
||||
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.beans.ComponentSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.conditionals.ConditionalsLiveHoverProvider;
|
||||
import org.springframework.ide.vscode.boot.java.data.DataRepositoryCompletionProcessor;
|
||||
import org.springframework.ide.vscode.boot.java.data.DataRepositorySymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.BootJavaCodeLensEngine;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.BootJavaCompletionEngine;
|
||||
@@ -257,45 +258,44 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
|
||||
protected ICompletionEngine createCompletionEngine(
|
||||
JavaProjectFinder javaProjectFinder,
|
||||
SpringPropertyIndexProvider indexProvider,
|
||||
SpringPropertyIndexProvider adHocIndexProvider
|
||||
) {
|
||||
SpringPropertyIndexProvider adHocIndexProvider)
|
||||
{
|
||||
Map<String, CompletionProvider> providers = new HashMap<>();
|
||||
providers.put(org.springframework.ide.vscode.boot.java.scope.Constants.SPRING_SCOPE,
|
||||
new ScopeCompletionProcessor());
|
||||
providers.put(org.springframework.ide.vscode.boot.java.value.Constants.SPRING_VALUE,
|
||||
new ValueCompletionProcessor(indexProvider, adHocIndexProvider));
|
||||
providers.put(org.springframework.ide.vscode.boot.java.scope.Constants.SPRING_SCOPE, new ScopeCompletionProcessor());
|
||||
providers.put(org.springframework.ide.vscode.boot.java.value.Constants.SPRING_VALUE, new ValueCompletionProcessor(indexProvider, adHocIndexProvider));
|
||||
providers.put(Annotations.REPOSITORY, new DataRepositoryCompletionProcessor());
|
||||
|
||||
JavaSnippetManager snippetManager = new JavaSnippetManager(server::createSnippetBuilder);
|
||||
snippetManager.add(
|
||||
new JavaSnippet("RequestMapping method", JavaSnippetContext.BOOT_MEMBERS, CompletionItemKind.Method,
|
||||
ImmutableList.of("org.springframework.web.bind.annotation.RequestMapping",
|
||||
"org.springframework.web.bind.annotation.RequestMethod",
|
||||
"org.springframework.web.bind.annotation.RequestParam"),
|
||||
"@RequestMapping(value=\"${path}\", method=RequestMethod.${GET})\n"
|
||||
+ "public ${SomeData} ${requestMethodName}(@RequestParam ${String} ${param}) {\n"
|
||||
+ " return new ${SomeData}(${cursor});\n" + "}\n"));
|
||||
snippetManager
|
||||
.add(new JavaSnippet("GetMapping method", JavaSnippetContext.BOOT_MEMBERS, CompletionItemKind.Method,
|
||||
ImmutableList.of("org.springframework.web.bind.annotation.GetMapping",
|
||||
"org.springframework.web.bind.annotation.RequestParam"),
|
||||
"@GetMapping(value=\"${path}\")\n"
|
||||
+ "public ${SomeData} ${getMethodName}(@RequestParam ${String} ${param}) {\n"
|
||||
+ " return new ${SomeData}(${cursor});\n" + "}\n"));
|
||||
snippetManager.add(new JavaSnippet("PostMapping method", JavaSnippetContext.BOOT_MEMBERS,
|
||||
CompletionItemKind.Method,
|
||||
ImmutableList.of("org.springframework.web.bind.annotation.PostMapping",
|
||||
"org.springframework.web.bind.annotation.RequestBody"),
|
||||
"@PostMapping(value=\"${path}\")\n"
|
||||
+ "public ${SomeEnityData} ${postMethodName}(@RequestBody ${SomeEnityData} ${entity}) {\n"
|
||||
+ " //TODO: process POST request\n" + " ${cursor}\n" + " return ${entity};\n" + "}\n"));
|
||||
snippetManager.add(new JavaSnippet("PutMapping method", JavaSnippetContext.BOOT_MEMBERS,
|
||||
CompletionItemKind.Method,
|
||||
ImmutableList.of("org.springframework.web.bind.annotation.PutMapping",
|
||||
"org.springframework.web.bind.annotation.RequestBody",
|
||||
"org.springframework.web.bind.annotation.PathVariable"),
|
||||
"@PutMapping(value=\"${path}/{${id}}\")\n"
|
||||
+ "public ${SomeEnityData} ${putMethodName}(@PathVariable ${pvt:String} ${id}, @RequestBody ${SomeEnityData} ${entity}) {\n"
|
||||
+ " //TODO: process PUT request\n" + " ${cursor}\n" + " return ${entity};\n" + "}"));
|
||||
// snippetManager.add(
|
||||
// new JavaSnippet("RequestMapping method", JavaSnippetContext.BOOT_MEMBERS, CompletionItemKind.Method,
|
||||
// ImmutableList.of("org.springframework.web.bind.annotation.RequestMapping",
|
||||
// "org.springframework.web.bind.annotation.RequestMethod",
|
||||
// "org.springframework.web.bind.annotation.RequestParam"),
|
||||
// "@RequestMapping(value=\"${path}\", method=RequestMethod.${GET})\n"
|
||||
// + "public ${SomeData} ${requestMethodName}(@RequestParam ${String} ${param}) {\n"
|
||||
// + " return new ${SomeData}(${cursor});\n" + "}\n"));
|
||||
// snippetManager
|
||||
// .add(new JavaSnippet("GetMapping method", JavaSnippetContext.BOOT_MEMBERS, CompletionItemKind.Method,
|
||||
// ImmutableList.of("org.springframework.web.bind.annotation.GetMapping",
|
||||
// "org.springframework.web.bind.annotation.RequestParam"),
|
||||
// "@GetMapping(value=\"${path}\")\n"
|
||||
// + "public ${SomeData} ${getMethodName}(@RequestParam ${String} ${param}) {\n"
|
||||
// + " return new ${SomeData}(${cursor});\n" + "}\n"));
|
||||
// snippetManager.add(new JavaSnippet("PostMapping method", JavaSnippetContext.BOOT_MEMBERS,
|
||||
// CompletionItemKind.Method,
|
||||
// ImmutableList.of("org.springframework.web.bind.annotation.PostMapping",
|
||||
// "org.springframework.web.bind.annotation.RequestBody"),
|
||||
// "@PostMapping(value=\"${path}\")\n"
|
||||
// + "public ${SomeEnityData} ${postMethodName}(@RequestBody ${SomeEnityData} ${entity}) {\n"
|
||||
// + " //TODO: process POST request\n" + " ${cursor}\n" + " return ${entity};\n" + "}\n"));
|
||||
// snippetManager.add(new JavaSnippet("PutMapping method", JavaSnippetContext.BOOT_MEMBERS,
|
||||
// CompletionItemKind.Method,
|
||||
// ImmutableList.of("org.springframework.web.bind.annotation.PutMapping",
|
||||
// "org.springframework.web.bind.annotation.RequestBody",
|
||||
// "org.springframework.web.bind.annotation.PathVariable"),
|
||||
// "@PutMapping(value=\"${path}/{${id}}\")\n"
|
||||
// + "public ${SomeEnityData} ${putMethodName}(@PathVariable ${pvt:String} ${id}, @RequestBody ${SomeEnityData} ${entity}) {\n"
|
||||
// + " //TODO: process PUT request\n" + " ${cursor}\n" + " return ${entity};\n" + "}"));
|
||||
return new BootJavaCompletionEngine(this, providers, snippetManager);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 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.boot.java.data;
|
||||
|
||||
public class Constants {
|
||||
|
||||
public static final String REPOSITORY_TYPE = "org.springframework.data.repository.Repository";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 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.boot.java.data;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.CompletionItemKind;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.CompletionProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class DataRepositoryCompletionProcessor implements CompletionProvider {
|
||||
|
||||
@Override
|
||||
public void provideCompletions(ASTNode node, Annotation annotation, ITypeBinding type,
|
||||
int offset, IDocument doc, Collection<ICompletionProposal> completions) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void provideCompletions(ASTNode node, int offset, IDocument doc, Collection<ICompletionProposal> completions) {
|
||||
TypeDeclaration type = ASTUtils.findDeclaringType(node);
|
||||
DataRepositoryDefinition repo = getDataRepositoryDefinition(type);
|
||||
if (repo != null) {
|
||||
DocumentEdits edits = new DocumentEdits(null);
|
||||
edits.insert(offset, "List<Customer> findByLastName${1|(String lastName);,And,Or|}");
|
||||
|
||||
DocumentEdits additionalEdits = new DocumentEdits(null);
|
||||
// additionalEdits.insert(offset, "(String lastName);");
|
||||
|
||||
completions.add(new FindByCompletionProposal("findByLastName(String lastName);", CompletionItemKind.Method, edits, null, null, Optional.of(additionalEdits)));
|
||||
|
||||
System.out.println("data completion proposal calculation for: " + node.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private DataRepositoryDefinition getDataRepositoryDefinition(TypeDeclaration type) {
|
||||
if (type != null) {
|
||||
ITypeBinding resolvedType = type.resolveBinding();
|
||||
return getDataRepositoryDefinition(type, resolvedType);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private DataRepositoryDefinition getDataRepositoryDefinition(TypeDeclaration type, ITypeBinding resolvedType) {
|
||||
if (resolvedType != null) {
|
||||
|
||||
// interface analysis
|
||||
ITypeBinding[] interfaces = resolvedType.getInterfaces();
|
||||
for (ITypeBinding resolvedInterface : interfaces) {
|
||||
String simplifiedType = null;
|
||||
if (resolvedInterface.isParameterizedType()) {
|
||||
simplifiedType = resolvedInterface.getBinaryName();
|
||||
}
|
||||
else {
|
||||
simplifiedType = resolvedType.getQualifiedName();
|
||||
}
|
||||
|
||||
if (Constants.REPOSITORY_TYPE.equals(simplifiedType)) {
|
||||
return new DataRepositoryDefinition();
|
||||
}
|
||||
else {
|
||||
DataRepositoryDefinition repo = getDataRepositoryDefinition(type, resolvedInterface);
|
||||
if (repo != null) {
|
||||
return repo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// super type analysis
|
||||
ITypeBinding superclass = resolvedType.getSuperclass();
|
||||
if (superclass != null) {
|
||||
return getDataRepositoryDefinition(type, superclass);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 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.boot.java.data;
|
||||
|
||||
public class DataRepositoryDefinition {
|
||||
|
||||
}
|
||||
@@ -36,8 +36,6 @@ import reactor.util.function.Tuples;
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class DataRepositorySymbolProvider implements SymbolProvider {
|
||||
|
||||
private static final String REPOSITORY_TYPE = "org.springframework.data.repository.Repository";
|
||||
|
||||
@Override
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc) {
|
||||
@@ -96,10 +94,10 @@ public class DataRepositorySymbolProvider implements SymbolProvider {
|
||||
simplifiedType = resolvedType.getQualifiedName();
|
||||
}
|
||||
|
||||
if (REPOSITORY_TYPE.equals(simplifiedType)) {
|
||||
if (Constants.REPOSITORY_TYPE.equals(simplifiedType)) {
|
||||
String beanName = getBeanName(typeDeclaration);
|
||||
String beanType = resolvedInterface.getName();
|
||||
|
||||
|
||||
String domainType = null;
|
||||
if (resolvedInterface.isParameterizedType()) {
|
||||
ITypeBinding[] typeParameters = resolvedInterface.getTypeArguments();
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 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.boot.java.data;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.lsp4j.CompletionItemKind;
|
||||
import org.eclipse.lsp4j.InsertTextFormat;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
public class FindByCompletionProposal implements ICompletionProposal {
|
||||
|
||||
private String label;
|
||||
private CompletionItemKind kind;
|
||||
private DocumentEdits edits;
|
||||
private String details;
|
||||
private Renderable doc;
|
||||
private Optional<DocumentEdits> additionalEdits;
|
||||
|
||||
public FindByCompletionProposal(String label, CompletionItemKind kind, DocumentEdits edits, String details,
|
||||
Renderable doc, Optional<DocumentEdits> additionalEdits) {
|
||||
super();
|
||||
this.label = label;
|
||||
this.kind = kind;
|
||||
this.edits = edits;
|
||||
this.details = details;
|
||||
this.doc = doc;
|
||||
this.additionalEdits = additionalEdits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionItemKind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocumentEdits getTextEdit() {
|
||||
return edits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetail() {
|
||||
return details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Renderable getDocumentation() {
|
||||
return doc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<DocumentEdits> getAdditionalEdit() {
|
||||
return additionalEdits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsertTextFormat getInsertTextFormat() {
|
||||
return InsertTextFormat.Snippet;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -49,8 +49,9 @@ public class BootJavaCompletionEngine implements ICompletionEngine {
|
||||
|
||||
if (node != null) {
|
||||
Collection<ICompletionProposal> completions = new ArrayList<ICompletionProposal>();
|
||||
completions.addAll(collectCompletionsForAnnotations(node, offset, document));
|
||||
completions.addAll(snippets.getCompletions(document, offset, node, cu));
|
||||
collectCompletionsForAnnotations(node, offset, document, completions);
|
||||
collectCompletions(node, offset, document, completions);
|
||||
snippets.getCompletions(document, offset, node, cu, completions);
|
||||
return completions;
|
||||
}
|
||||
}
|
||||
@@ -59,7 +60,7 @@ public class BootJavaCompletionEngine implements ICompletionEngine {
|
||||
});
|
||||
}
|
||||
|
||||
private Collection<ICompletionProposal> collectCompletionsForAnnotations(ASTNode node, int offset, IDocument doc) {
|
||||
private void collectCompletionsForAnnotations(ASTNode node, int offset, IDocument doc, Collection<ICompletionProposal> completions) {
|
||||
Annotation annotation = null;
|
||||
ASTNode exactNode = node;
|
||||
|
||||
@@ -75,13 +76,19 @@ public class BootJavaCompletionEngine implements ICompletionEngine {
|
||||
if (qualifiedName != null) {
|
||||
CompletionProvider provider = this.completionProviders.get(qualifiedName);
|
||||
if (provider != null) {
|
||||
return provider.provideCompletions(exactNode, annotation, type, offset, doc);
|
||||
provider.provideCompletions(exactNode, annotation, type, offset, doc, completions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
private void collectCompletions(ASTNode node, int offset, TextDocument document, Collection<ICompletionProposal> completions) {
|
||||
if (node != null) {
|
||||
for (CompletionProvider completionProvider : this.completionProviders.values()) {
|
||||
completionProvider.provideCompletions(node, offset, document, completions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2018 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
|
||||
@@ -23,6 +23,7 @@ import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
*/
|
||||
public interface CompletionProvider {
|
||||
|
||||
Collection<ICompletionProposal> provideCompletions(ASTNode node, Annotation annotation, ITypeBinding type, int offset, IDocument doc);
|
||||
void provideCompletions(ASTNode node, Annotation annotation, ITypeBinding type, int offset, IDocument doc, Collection<ICompletionProposal> completions);
|
||||
void provideCompletions(ASTNode node, int offset, IDocument doc, Collection<ICompletionProposal> completions);
|
||||
|
||||
}
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.scope;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
@@ -30,10 +28,8 @@ import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
public class ScopeCompletionProcessor implements CompletionProvider {
|
||||
|
||||
@Override
|
||||
public Collection<ICompletionProposal> provideCompletions(ASTNode node, Annotation annotation, ITypeBinding type,
|
||||
int offset, IDocument doc) {
|
||||
|
||||
List<ICompletionProposal> result = new ArrayList<>();
|
||||
public void provideCompletions(ASTNode node, Annotation annotation, ITypeBinding type,
|
||||
int offset, IDocument doc, Collection<ICompletionProposal> completions) {
|
||||
|
||||
try {
|
||||
if (node instanceof SimpleName && node.getParent() instanceof MemberValuePair) {
|
||||
@@ -43,7 +39,7 @@ public class ScopeCompletionProcessor implements CompletionProvider {
|
||||
if ("value".equals(memberPair.getName().toString()) && memberPair.getValue().toString().equals("$missing$")) {
|
||||
for (ScopeNameCompletion completion : ScopeNameCompletionProposal.COMPLETIONS) {
|
||||
ICompletionProposal proposal = new ScopeNameCompletionProposal(completion, doc, offset, offset, "");
|
||||
result.add(proposal);
|
||||
completions.add(proposal);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,7 +47,7 @@ public class ScopeCompletionProcessor implements CompletionProvider {
|
||||
else if (node == annotation && doc.get(offset - 1, 2).endsWith("()")) {
|
||||
for (ScopeNameCompletion completion : ScopeNameCompletionProposal.COMPLETIONS) {
|
||||
ICompletionProposal proposal = new ScopeNameCompletionProposal(completion, doc, offset, offset, "");
|
||||
result.add(proposal);
|
||||
completions.add(proposal);
|
||||
}
|
||||
}
|
||||
else if (node instanceof StringLiteral && node.getParent() instanceof Annotation) {
|
||||
@@ -61,7 +57,7 @@ public class ScopeCompletionProcessor implements CompletionProvider {
|
||||
for (ScopeNameCompletion completion : ScopeNameCompletionProposal.COMPLETIONS) {
|
||||
if (completion.getValue().startsWith(prefix)) {
|
||||
ICompletionProposal proposal = new ScopeNameCompletionProposal(completion, doc, node.getStartPosition(), node.getStartPosition() + node.getLength(), prefix);
|
||||
result.add(proposal);
|
||||
completions.add(proposal);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,7 +71,7 @@ public class ScopeCompletionProcessor implements CompletionProvider {
|
||||
for (ScopeNameCompletion completion : ScopeNameCompletionProposal.COMPLETIONS) {
|
||||
if (completion.getValue().startsWith(prefix)) {
|
||||
ICompletionProposal proposal = new ScopeNameCompletionProposal(completion, doc, node.getStartPosition(), node.getStartPosition() + node.getLength(), prefix);
|
||||
result.add(proposal);
|
||||
completions.add(proposal);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,8 +80,10 @@ public class ScopeCompletionProcessor implements CompletionProvider {
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@Override
|
||||
public void provideCompletions(ASTNode node, int offset, IDocument doc, Collection<ICompletionProposal> completions) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2018 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
|
||||
@@ -47,9 +47,7 @@ public class JavaSnippetManager {
|
||||
|
||||
}
|
||||
|
||||
public Collection<ICompletionProposal> getCompletions(IDocument doc, int offset, ASTNode node, CompilationUnit cu) {
|
||||
Collection<ICompletionProposal> completions = new ArrayList<>();
|
||||
|
||||
public void getCompletions(IDocument doc, int offset, ASTNode node, CompilationUnit cu, Collection<ICompletionProposal> completions) {
|
||||
DocumentRegion query = PREFIX_FINDER.getPrefixRegion(doc, offset);
|
||||
|
||||
for (JavaSnippet javaSnippet : snippets) {
|
||||
@@ -58,8 +56,6 @@ public class JavaSnippetManager {
|
||||
.ifPresent((completion) -> completions.add(completion));
|
||||
}
|
||||
}
|
||||
|
||||
return completions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ package org.springframework.ide.vscode.boot.java.value;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.util.StringUtil.camelCaseToHyphens;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -49,10 +48,8 @@ public class ValueCompletionProcessor implements CompletionProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ICompletionProposal> provideCompletions(ASTNode node, Annotation annotation, ITypeBinding type,
|
||||
int offset, IDocument doc) {
|
||||
|
||||
List<ICompletionProposal> result = new ArrayList<>();
|
||||
public void provideCompletions(ASTNode node, Annotation annotation, ITypeBinding type,
|
||||
int offset, IDocument doc, Collection<ICompletionProposal> completions) {
|
||||
|
||||
try {
|
||||
// case: @Value(<*>)
|
||||
@@ -69,40 +66,42 @@ public class ValueCompletionProcessor implements CompletionProvider {
|
||||
// if it cannot resolve it. If sending this as plain text, then insertion happens correctly
|
||||
ValuePropertyKeyProposal proposal = new ValuePropertyKeyProposal(edits, match, InsertTextFormat.PlainText);
|
||||
|
||||
result.add(proposal);
|
||||
completions.add(proposal);
|
||||
}
|
||||
}
|
||||
// case: @Value(prefix<*>)
|
||||
else if (node instanceof SimpleName && node.getParent() instanceof Annotation) {
|
||||
computeProposalsForSimpleName(node, result, offset, doc);
|
||||
computeProposalsForSimpleName(node, completions, offset, doc);
|
||||
}
|
||||
// case: @Value(value=<*>)
|
||||
else if (node instanceof SimpleName && node.getParent() instanceof MemberValuePair
|
||||
&& "value".equals(((MemberValuePair)node.getParent()).getName().toString())) {
|
||||
computeProposalsForSimpleName(node, result, offset, doc);
|
||||
computeProposalsForSimpleName(node, completions, offset, doc);
|
||||
}
|
||||
// case: @Value("prefix<*>")
|
||||
else if (node instanceof StringLiteral && node.getParent() instanceof Annotation) {
|
||||
if (node.toString().startsWith("\"") && node.toString().endsWith("\"")) {
|
||||
computeProposalsForStringLiteral(node, result, offset, doc);
|
||||
computeProposalsForStringLiteral(node, completions, offset, doc);
|
||||
}
|
||||
}
|
||||
// case: @Value(value="prefix<*>")
|
||||
else if (node instanceof StringLiteral && node.getParent() instanceof MemberValuePair
|
||||
&& "value".equals(((MemberValuePair)node.getParent()).getName().toString())) {
|
||||
if (node.toString().startsWith("\"") && node.toString().endsWith("\"")) {
|
||||
computeProposalsForStringLiteral(node, result, offset, doc);
|
||||
computeProposalsForStringLiteral(node, completions, offset, doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void computeProposalsForSimpleName(ASTNode node, List<ICompletionProposal> completions, int offset,
|
||||
@Override
|
||||
public void provideCompletions(ASTNode node, int offset, IDocument doc, Collection<ICompletionProposal> completions) {
|
||||
}
|
||||
|
||||
private void computeProposalsForSimpleName(ASTNode node, Collection<ICompletionProposal> completions, int offset,
|
||||
IDocument doc) {
|
||||
String prefix = identifyPropertyPrefix(node.toString(), offset - node.getStartPosition());
|
||||
|
||||
@@ -125,7 +124,7 @@ public class ValueCompletionProcessor implements CompletionProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private void computeProposalsForStringLiteral(ASTNode node, List<ICompletionProposal> completions, int offset,
|
||||
private void computeProposalsForStringLiteral(ASTNode node, Collection<ICompletionProposal> completions, int offset,
|
||||
IDocument doc) throws BadLocationException {
|
||||
String prefix = identifyPropertyPrefix(doc.get(node.getStartPosition() + 1, offset - (node.getStartPosition() + 1)), offset - (node.getStartPosition() + 1));
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 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.boot.java.data.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.eclipse.lsp4j.CompletionItem;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest;
|
||||
import org.springframework.ide.vscode.boot.bootiful.HoverTestConf;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.Editor;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.TestAsserts;
|
||||
import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@BootLanguageServerTest
|
||||
@Import(HoverTestConf.class)
|
||||
public class DataRepositoryCompletionProcessorTest {
|
||||
|
||||
@Autowired private BootLanguageServerHarness harness;
|
||||
private Editor editor;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
IJavaProject testProject = ProjectsHarness.INSTANCE.mavenProject("test-spring-data-symbols");
|
||||
harness.useProject(testProject);
|
||||
harness.intialize(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStandardFindByCompletions() throws Exception {
|
||||
prepareCase("{", "{<*>");
|
||||
assertAnnotationCompletions(
|
||||
"findByLastName<*>(String lastName);");
|
||||
}
|
||||
|
||||
private void prepareCase(String selectedAnnotation, String annotationStatementBeforeTest) throws Exception {
|
||||
InputStream resource = this.getClass().getResourceAsStream("/test-projects/test-spring-data-symbols/src/main/java/org/test/TestCustomerRepositoryForCompletions.java");
|
||||
String content = IOUtils.toString(resource);
|
||||
|
||||
content = content.replace(selectedAnnotation, annotationStatementBeforeTest);
|
||||
editor = new Editor(harness, content, LanguageId.JAVA);
|
||||
}
|
||||
|
||||
private void assertAnnotationCompletions(String... completedAnnotations) throws Exception {
|
||||
List<CompletionItem> completions = editor.getCompletions();
|
||||
int i = 0;
|
||||
for (String expectedCompleted : completedAnnotations) {
|
||||
Editor clonedEditor = editor.clone();
|
||||
clonedEditor.apply(completions.get(i++));
|
||||
TestAsserts.assertContains(expectedCompleted, clonedEditor.getText());
|
||||
}
|
||||
|
||||
assertEquals(i, completions.size());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public class DataRepositorySymbolProviderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleReppositorySymbol() throws Exception {
|
||||
public void testSimpleRepositorySymbol() throws Exception {
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/CustomerRepository.java").toUri().toString();
|
||||
List<? extends SymbolInformation> symbols = indexer.getSymbols(docUri);
|
||||
assertEquals(1, symbols.size());
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
public interface TestCustomerRepositoryForCompletions extends CrudRepository<Customer, Long> {
|
||||
}
|
||||
Reference in New Issue
Block a user