PT 150711216 - Initial implementation
Includes basic completion of a request mapping snippet
This commit is contained in:
@@ -13,6 +13,7 @@ package org.springframework.ide.vscode.boot.java;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.lsp4j.CompletionItemKind;
|
||||
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.handlers.BootJavaCodeLensEngine;
|
||||
@@ -29,6 +30,9 @@ import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.RequestMappingHoverProvider;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.RequestMappingSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.scope.ScopeCompletionProcessor;
|
||||
import org.springframework.ide.vscode.boot.java.snippets.JavaSnippet;
|
||||
import org.springframework.ide.vscode.boot.java.snippets.JavaSnippetManager;
|
||||
import org.springframework.ide.vscode.boot.java.snippets.JavaSnippetContext;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexer;
|
||||
import org.springframework.ide.vscode.boot.java.value.ValueCompletionProcessor;
|
||||
import org.springframework.ide.vscode.boot.java.value.ValueHoverProvider;
|
||||
@@ -52,6 +56,8 @@ import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenProjectFinderStrategy;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* Language Server for Spring Boot Application Properties files
|
||||
*
|
||||
@@ -109,7 +115,22 @@ public class BootJavaLanguageServer extends SimpleLanguageServer {
|
||||
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));
|
||||
|
||||
return new BootJavaCompletionEngine(javaProjectFinder, providers);
|
||||
JavaSnippetManager snippetManager = new JavaSnippetManager(this::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"
|
||||
));
|
||||
return new BootJavaCompletionEngine(javaProjectFinder, providers, snippetManager);
|
||||
}
|
||||
|
||||
protected HoverHandler createHoverHandler(JavaProjectFinder javaProjectFinder) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
package org.springframework.ide.vscode.boot.java.handlers;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
@@ -24,6 +25,7 @@ import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.NodeFinder;
|
||||
import org.springframework.ide.vscode.boot.java.snippets.JavaSnippetManager;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
|
||||
@@ -38,10 +40,12 @@ public class BootJavaCompletionEngine implements ICompletionEngine {
|
||||
|
||||
private JavaProjectFinder projectFinder;
|
||||
private Map<String, CompletionProvider> completionProviders;
|
||||
private JavaSnippetManager snippets;
|
||||
|
||||
public BootJavaCompletionEngine(JavaProjectFinder projectFinder, Map<String, CompletionProvider> specificProviders) {
|
||||
public BootJavaCompletionEngine(JavaProjectFinder projectFinder, Map<String, CompletionProvider> specificProviders, JavaSnippetManager snippets) {
|
||||
this.projectFinder = projectFinder;
|
||||
this.completionProviders = specificProviders;
|
||||
this.snippets = snippets;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,7 +73,10 @@ public class BootJavaCompletionEngine implements ICompletionEngine {
|
||||
|
||||
if (node != null) {
|
||||
System.out.println("AST node found: " + node.getClass().getName());
|
||||
return collectCompletionsForAnnotations(node, offset, document);
|
||||
Collection<ICompletionProposal> completions = new ArrayList<ICompletionProposal>();
|
||||
completions.addAll(collectCompletionsForAnnotations(node, offset, document));
|
||||
completions.addAll(snippets.getCompletions(document, offset, node));
|
||||
return completions;
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
|
||||
@@ -18,34 +18,60 @@ import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
public class SimpleCompletionFactory {
|
||||
|
||||
public ICompletionProposal simpleProposal(IDocument doc, int offset, String query, CompletionItemKind kind, String value, String detail, Renderable info) {
|
||||
|
||||
public static class SimpleProposal implements ICompletionProposal{
|
||||
|
||||
private DocumentEdits edits;
|
||||
private CompletionItemKind kind;
|
||||
private Renderable info;
|
||||
private String detail;
|
||||
private String label;
|
||||
|
||||
public SimpleProposal(DocumentEdits edits, CompletionItemKind kind, Renderable info,
|
||||
String detail, String label) {
|
||||
this.edits = edits;
|
||||
this.kind = kind;
|
||||
this.info = info;
|
||||
this.detail = detail;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public SimpleProposal setLabel(String label) {
|
||||
this.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocumentEdits getTextEdit() {
|
||||
return edits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionItemKind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Renderable getDocumentation() {
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetail() {
|
||||
return detail;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static SimpleProposal simpleProposal(IDocument doc, int offset, String query, CompletionItemKind kind, String value, String detail, Renderable info) {
|
||||
DocumentEdits edits = new DocumentEdits(doc);
|
||||
edits.replace(offset-query.length(), offset, value);
|
||||
return new ICompletionProposal() {
|
||||
@Override
|
||||
public DocumentEdits getTextEdit() {
|
||||
return edits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionItemKind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Renderable getDocumentation() {
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetail() {
|
||||
return detail;
|
||||
}
|
||||
};
|
||||
return new SimpleProposal(edits, kind, info, detail, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,59 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.snippets;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.lsp4j.CompletionItemKind;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SimpleCompletionFactory;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SnippetBuilder;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
public class JavaSnippet {
|
||||
|
||||
private SnippetContext context;
|
||||
private JavaSnippetContext context;
|
||||
|
||||
private String name;
|
||||
|
||||
private String template;
|
||||
|
||||
private List<String> imports;
|
||||
|
||||
private CompletionItemKind kind;
|
||||
|
||||
public JavaSnippet(String name, JavaSnippetContext context, CompletionItemKind kind, List<String> imports,
|
||||
String template) {
|
||||
super();
|
||||
this.context = context;
|
||||
this.name = name;
|
||||
this.template = template;
|
||||
this.imports = imports;
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
public Optional<ICompletionProposal> generateCompletion(Supplier<SnippetBuilder> snippetBuilderFactory,
|
||||
IDocument doc, int offset, ASTNode node, String query) {
|
||||
|
||||
if (context.appliesTo(node)) {
|
||||
return Optional.of(
|
||||
SimpleCompletionFactory.simpleProposal(doc,
|
||||
offset,
|
||||
query,
|
||||
kind, template, "Snippet", Renderables.NO_DESCRIPTION
|
||||
).setLabel(name)
|
||||
);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
package org.springframework.ide.vscode.boot.java.snippets;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
|
||||
public interface JavaSnippetContext {
|
||||
JavaSnippetContext BOOT_MEMBERS = (node) -> node instanceof TypeDeclaration;
|
||||
|
||||
public interface SnippetContext {
|
||||
boolean appliesTo(ASTNode node);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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.snippets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.PrefixFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SnippetBuilder;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMatcher;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
public class JavaSnippetManager {
|
||||
|
||||
private List<JavaSnippet> snippets = new ArrayList<>();
|
||||
private Supplier<SnippetBuilder> snippetBuilderFactory;
|
||||
|
||||
private static PrefixFinder PREFIX_FINDER = new PrefixFinder() {
|
||||
|
||||
@Override
|
||||
protected boolean isPrefixChar(char c) {
|
||||
return Character.isJavaIdentifierPart(c);
|
||||
}
|
||||
};
|
||||
|
||||
public JavaSnippetManager(Supplier<SnippetBuilder> snippetBuilderFactory) {
|
||||
this.snippetBuilderFactory = snippetBuilderFactory;
|
||||
}
|
||||
|
||||
public void add(JavaSnippet javaSnippet) {
|
||||
snippets.add(javaSnippet);
|
||||
|
||||
}
|
||||
|
||||
public Collection<ICompletionProposal> getCompletions(IDocument doc, int offset, ASTNode node) {
|
||||
Collection<ICompletionProposal> completions = new ArrayList<>();
|
||||
|
||||
String query = PREFIX_FINDER.getPrefix(doc, offset);
|
||||
|
||||
for (JavaSnippet javaSnippet : snippets) {
|
||||
if (FuzzyMatcher.matchScore(query, javaSnippet.getName()) != 0) {
|
||||
javaSnippet.generateCompletion(snippetBuilderFactory, doc, offset, node, query)
|
||||
.ifPresent((completion) -> completions.add(completion));
|
||||
}
|
||||
}
|
||||
|
||||
return completions;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user