added option to generate additional information while parsing symbols and do that for handler methods in webflux definitions
This commit is contained in:
@@ -23,6 +23,7 @@ import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
import org.springframework.ide.vscode.boot.java.utils.FunctionUtils;
|
||||
@@ -46,17 +47,19 @@ public class BeansSymbolProvider implements SymbolProvider {
|
||||
private static final String[] NAME_ATTRIBUTES = {"value", "name"};
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, TextDocument doc) {
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, TextDocument doc) {
|
||||
boolean isFunction = isFunctionBean(node);
|
||||
|
||||
ImmutableList.Builder<SymbolInformation> symbols = ImmutableList.builder();
|
||||
ImmutableList.Builder<EnhancedSymbolInformation> symbols = ImmutableList.builder();
|
||||
String beanType = getBeanType(node);
|
||||
for (Tuple2<String, DocumentRegion> nameAndRegion : getBeanNames(node, doc)) {
|
||||
try {
|
||||
symbols.add(new SymbolInformation(
|
||||
beanLabel(isFunction, nameAndRegion.getT1(), beanType, "@Bean"),
|
||||
SymbolKind.Interface,
|
||||
new Location(doc.getUri(), doc.toRange(nameAndRegion.getT2()))
|
||||
symbols.add(new EnhancedSymbolInformation(
|
||||
new SymbolInformation(
|
||||
beanLabel(isFunction, nameAndRegion.getT1(), beanType, "@Bean"),
|
||||
SymbolKind.Interface,
|
||||
new Location(doc.getUri(), doc.toRange(nameAndRegion.getT2()))),
|
||||
null
|
||||
));
|
||||
} catch (BadLocationException e) {
|
||||
Log.log(e);
|
||||
@@ -66,7 +69,7 @@ public class BeansSymbolProvider implements SymbolProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc) {
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc) {
|
||||
// this checks function beans that are defined as implementations of Function interfaces
|
||||
Tuple3<String, String, DocumentRegion> functionBean = FunctionUtils.getFunctionBean(typeDeclaration, doc);
|
||||
if (functionBean != null) {
|
||||
@@ -75,7 +78,7 @@ public class BeansSymbolProvider implements SymbolProvider {
|
||||
beanLabel(true, functionBean.getT1(), functionBean.getT2(), null),
|
||||
SymbolKind.Interface,
|
||||
new Location(doc.getUri(), doc.toRange(functionBean.getT3())));
|
||||
return ImmutableList.of(symbol);
|
||||
return ImmutableList.of(new EnhancedSymbolInformation(symbol, null));
|
||||
} catch (BadLocationException e) {
|
||||
Log.log(e);
|
||||
}
|
||||
@@ -166,7 +169,7 @@ public class BeansSymbolProvider implements SymbolProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(MethodDeclaration methodDeclaration, TextDocument doc) {
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(MethodDeclaration methodDeclaration, TextDocument doc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
@@ -35,7 +36,7 @@ import com.google.common.collect.ImmutableList;
|
||||
public class ComponentSymbolProvider implements SymbolProvider {
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, TextDocument doc) {
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, TextDocument doc) {
|
||||
try {
|
||||
return ImmutableList.of(
|
||||
createSymbol(node, annotationType, metaAnnotations, doc)
|
||||
@@ -47,7 +48,7 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
protected SymbolInformation createSymbol(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, TextDocument doc) throws BadLocationException {
|
||||
protected EnhancedSymbolInformation createSymbol(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, TextDocument doc) throws BadLocationException {
|
||||
String annotationTypeName = annotationType.getName();
|
||||
Collection<String> metaAnnotationNames = metaAnnotations.stream()
|
||||
.map(ITypeBinding::getName)
|
||||
@@ -58,7 +59,7 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
SymbolInformation symbol = new SymbolInformation(
|
||||
beanLabel("+", annotationTypeName, metaAnnotationNames, beanName, beanType), SymbolKind.Interface,
|
||||
new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength())));
|
||||
return symbol;
|
||||
return new EnhancedSymbolInformation(symbol, null);
|
||||
}
|
||||
|
||||
protected String beanLabel(String searchPrefix, String annotationTypeName, Collection<String> metaAnnotationNames, String beanName, String beanType) {
|
||||
@@ -113,12 +114,12 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc) {
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(MethodDeclaration methodDeclaration, TextDocument doc) {
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(MethodDeclaration methodDeclaration, TextDocument doc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
@@ -38,14 +39,8 @@ public class DataRepositorySymbolProvider implements SymbolProvider {
|
||||
|
||||
private static final String REPOSITORY_TYPE = "org.springframework.data.repository.Repository";
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, TextDocument doc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc) {
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc) {
|
||||
// this checks spring data repository beans that are defined as extensions of the repository interface
|
||||
Tuple4<String, String, String, DocumentRegion> repositoryBean = getRepositoryBean(typeDeclaration, doc);
|
||||
if (repositoryBean != null) {
|
||||
@@ -54,7 +49,7 @@ public class DataRepositorySymbolProvider implements SymbolProvider {
|
||||
beanLabel(true, repositoryBean.getT1(), repositoryBean.getT2(), repositoryBean.getT3()),
|
||||
SymbolKind.Interface,
|
||||
new Location(doc.getUri(), doc.toRange(repositoryBean.getT4())));
|
||||
return ImmutableList.of(symbol);
|
||||
return ImmutableList.of(new EnhancedSymbolInformation(symbol, null));
|
||||
} catch (BadLocationException e) {
|
||||
Log.log(e);
|
||||
}
|
||||
@@ -142,7 +137,12 @@ public class DataRepositorySymbolProvider implements SymbolProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(MethodDeclaration methodDeclaration, TextDocument doc) {
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, TextDocument doc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(MethodDeclaration methodDeclaration, TextDocument doc) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*******************************************************************************
|
||||
* 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.handlers;
|
||||
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class EnhancedSymbolInformation {
|
||||
|
||||
private final SymbolInformation symbol;
|
||||
private final Object additionalInformation;
|
||||
|
||||
public EnhancedSymbolInformation(SymbolInformation symbol, Object additionalInformation) {
|
||||
this.symbol = symbol;
|
||||
this.additionalInformation = additionalInformation;
|
||||
}
|
||||
|
||||
public SymbolInformation getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public Object getAdditionalInformation() {
|
||||
return additionalInformation;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,7 +16,6 @@ import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
@@ -25,8 +24,8 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
*/
|
||||
public interface SymbolProvider {
|
||||
|
||||
Collection<SymbolInformation> getSymbols(Annotation node, ITypeBinding typeBinding, Collection<ITypeBinding> metaAnnotations, TextDocument doc);
|
||||
Collection<SymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc);
|
||||
Collection<SymbolInformation> getSymbols(MethodDeclaration methodDeclaration, TextDocument doc);
|
||||
Collection<EnhancedSymbolInformation> getSymbols(Annotation node, ITypeBinding typeBinding, Collection<ITypeBinding> metaAnnotations, TextDocument doc);
|
||||
Collection<EnhancedSymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc);
|
||||
Collection<EnhancedSymbolInformation> getSymbols(MethodDeclaration methodDeclaration, TextDocument doc);
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
@@ -41,7 +42,7 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
public class RequestMappingSymbolProvider implements SymbolProvider {
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, TextDocument doc) {
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, TextDocument doc) {
|
||||
if (node.getParent() instanceof MethodDeclaration) {
|
||||
try {
|
||||
Location location = new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()));
|
||||
@@ -62,7 +63,7 @@ public class RequestMappingSymbolProvider implements SymbolProvider {
|
||||
return resultPath.startsWith("/") ? resultPath : "/" + resultPath;
|
||||
}))
|
||||
.map(p -> "@" + p + (methodStr.isEmpty() ? "" : " -- " + methodStr))
|
||||
.map(symbolLabel -> new SymbolInformation(symbolLabel, SymbolKind.Interface, location))
|
||||
.map(symbolLabel -> new EnhancedSymbolInformation(new SymbolInformation(symbolLabel, SymbolKind.Interface, location), null))
|
||||
.collect(Collectors.toList());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -177,12 +178,12 @@ public class RequestMappingSymbolProvider implements SymbolProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc) {
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(MethodDeclaration methodDeclaration, TextDocument doc) {
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(MethodDeclaration methodDeclaration, TextDocument doc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*******************************************************************************
|
||||
* 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.requestmapping;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxHandlerInformation {
|
||||
|
||||
private final String symbol;
|
||||
private String destinationClass;
|
||||
private String methodKey;
|
||||
|
||||
public WebfluxHandlerInformation(String symbol, String destinationClass, String methodKey) {
|
||||
this.symbol = symbol;
|
||||
this.destinationClass = destinationClass;
|
||||
this.methodKey = methodKey;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public String getDestinationClass() {
|
||||
return destinationClass;
|
||||
}
|
||||
|
||||
public String getMethodKey() {
|
||||
return methodKey;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,15 +18,18 @@ import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.Block;
|
||||
import org.eclipse.jdt.core.dom.ExpressionMethodReference;
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.MethodReference;
|
||||
import org.eclipse.jdt.core.dom.Type;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
@@ -37,18 +40,18 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(Annotation node, ITypeBinding typeBinding,
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(Annotation node, ITypeBinding typeBinding,
|
||||
Collection<ITypeBinding> metaAnnotations, TextDocument doc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc) {
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SymbolInformation> getSymbols(MethodDeclaration methodDeclaration, TextDocument doc) {
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(MethodDeclaration methodDeclaration, TextDocument doc) {
|
||||
Type returnType = methodDeclaration.getReturnType2();
|
||||
if (returnType != null) {
|
||||
ITypeBinding resolvedBinding = returnType.resolveBinding();
|
||||
@@ -61,9 +64,9 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Collection<SymbolInformation> getSymbolsForRouterFunction(MethodDeclaration methodDeclaration,
|
||||
private Collection<EnhancedSymbolInformation> getSymbolsForRouterFunction(MethodDeclaration methodDeclaration,
|
||||
TextDocument doc) {
|
||||
List<SymbolInformation> result = new ArrayList<>();
|
||||
List<EnhancedSymbolInformation> result = new ArrayList<>();
|
||||
|
||||
Block body = methodDeclaration.getBody();
|
||||
body.accept(new ASTVisitor() {
|
||||
@@ -84,7 +87,7 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void extractMappingSymbol(MethodInvocation node, TextDocument doc, List<SymbolInformation> result) {
|
||||
protected void extractMappingSymbol(MethodInvocation node, TextDocument doc, List<EnhancedSymbolInformation> result) {
|
||||
String foundPath = extractPathFromRouterFunction(node);
|
||||
String path = extractPath(node, foundPath);
|
||||
String httpMethod = extractMethod(node);
|
||||
@@ -96,7 +99,10 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
try {
|
||||
Location location = new Location(doc.getUri(), doc.toRange(methodNameStart, node.getLength() - (methodNameStart - invocationStart)));
|
||||
String label = "@" + (path.startsWith("/") ? path : ("/" + path)) + (httpMethod == null || httpMethod.isEmpty() ? "" : " -- " + httpMethod);
|
||||
result.add(new SymbolInformation(label, SymbolKind.Interface, location));
|
||||
|
||||
WebfluxHandlerInformation handler = extractHandlerInformation(node, label);
|
||||
|
||||
result.add(new EnhancedSymbolInformation(new SymbolInformation(label, SymbolKind.Interface, location), handler));
|
||||
} catch (BadLocationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -155,5 +161,28 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
String method = methodFinder.getMethod();
|
||||
return method;
|
||||
}
|
||||
|
||||
private WebfluxHandlerInformation extractHandlerInformation(MethodInvocation node, String symbol) {
|
||||
List<?> arguments = node.arguments();
|
||||
|
||||
if (arguments != null) {
|
||||
for (Object argument : arguments) {
|
||||
if (argument instanceof ExpressionMethodReference) {
|
||||
ExpressionMethodReference methodReference = (ExpressionMethodReference) argument;
|
||||
IMethodBinding methodBinding = methodReference.resolveMethodBinding();
|
||||
|
||||
if (methodBinding != null && methodBinding.getDeclaringClass() != null && methodBinding.getMethodDeclaration() != null) {
|
||||
ITypeBinding declaringClass = methodBinding.getDeclaringClass();
|
||||
String destinationClass = declaringClass.getBinaryName();
|
||||
String methodKey = methodBinding.getMethodDeclaration().getKey();
|
||||
|
||||
return new WebfluxHandlerInformation(symbol, destinationClass, methodKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -56,6 +57,7 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.BootLanguageServerParams;
|
||||
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchies;
|
||||
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchyAwareLookup;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
@@ -80,7 +82,9 @@ public class SpringIndexer {
|
||||
private final AnnotationHierarchyAwareLookup<SymbolProvider> symbolProviders;
|
||||
|
||||
private final List<SymbolInformation> symbols;
|
||||
private final List<Object> addonInformation;
|
||||
private final ConcurrentMap<String, List<SymbolInformation>> symbolsByDoc;
|
||||
private final ConcurrentMap<String, List<Object>> addonInformationByDoc;
|
||||
|
||||
private final Thread updateWorker;
|
||||
private final BlockingQueue<WorkerItem> updateQueue;
|
||||
@@ -119,6 +123,8 @@ public class SpringIndexer {
|
||||
|
||||
this.symbols = Collections.synchronizedList(new ArrayList<>());
|
||||
this.symbolsByDoc = new ConcurrentHashMap<>();
|
||||
this.addonInformation = Collections.synchronizedList(new ArrayList<>());
|
||||
this.addonInformationByDoc = new ConcurrentHashMap<>();
|
||||
|
||||
this.updateQueue = new LinkedBlockingQueue<>();
|
||||
this.updateWorker = new Thread(new Runnable() {
|
||||
@@ -208,6 +214,9 @@ public class SpringIndexer {
|
||||
symbols.clear();
|
||||
symbolsByDoc.clear();
|
||||
|
||||
addonInformation.clear();
|
||||
addonInformationByDoc.clear();
|
||||
|
||||
Collection<WorkspaceFolder> roots = server.getWorkspaceRoots();
|
||||
log.debug("refresh spring indexer for roots: {}", roots.toString());
|
||||
initialize(roots);
|
||||
@@ -305,6 +314,22 @@ public class SpringIndexer {
|
||||
return this.symbolsByDoc.get(docURI);
|
||||
}
|
||||
|
||||
public List<Object> getAllAdditionalInformation(Predicate<Object> filter) {
|
||||
waitForInitializeTask();
|
||||
|
||||
if (filter != null) {
|
||||
return addonInformation.stream().filter(filter).collect(Collectors.toList());
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public List<? extends Object> getAdditonalInformation(String docURI) {
|
||||
waitForInitializeTask();
|
||||
return this.addonInformationByDoc.get(docURI);
|
||||
}
|
||||
|
||||
private List<SymbolInformation> searchMatchingSymbols(List<SymbolInformation> allsymbols, String query) {
|
||||
waitForInitializeTask();
|
||||
return allsymbols.stream()
|
||||
@@ -365,6 +390,11 @@ public class SpringIndexer {
|
||||
symbols.removeAll(oldSymbols);
|
||||
}
|
||||
|
||||
List<Object> oldAddInInformation = addonInformationByDoc.remove(docURI);
|
||||
if (oldAddInInformation != null) {
|
||||
addonInformation.removeAll(oldAddInInformation);
|
||||
}
|
||||
|
||||
AtomicReference<TextDocument> docRef = new AtomicReference<>();
|
||||
scanAST(cu, docURI, docRef, content);
|
||||
}
|
||||
@@ -464,11 +494,16 @@ public class SpringIndexer {
|
||||
if (!providers.isEmpty()) {
|
||||
TextDocument doc = getTempTextDocument(docURI, docRef, content);
|
||||
for (SymbolProvider provider : providers) {
|
||||
Collection<SymbolInformation> sbls = provider.getSymbols(typeDeclaration, doc);
|
||||
Collection<EnhancedSymbolInformation> sbls = provider.getSymbols(typeDeclaration, doc);
|
||||
if (sbls != null) {
|
||||
sbls.forEach(symbol -> {
|
||||
symbols.add(symbol);
|
||||
symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList<SymbolInformation>()).add(symbol);
|
||||
sbls.forEach(enhancedSymbol -> {
|
||||
symbols.add(enhancedSymbol.getSymbol());
|
||||
symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList<SymbolInformation>()).add(enhancedSymbol.getSymbol());
|
||||
|
||||
if (enhancedSymbol.getAdditionalInformation() != null) {
|
||||
addonInformation.add(enhancedSymbol.getAdditionalInformation());
|
||||
addonInformationByDoc.computeIfAbsent(docURI, s -> new ArrayList<Object>()).add(enhancedSymbol.getAdditionalInformation());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -480,11 +515,16 @@ public class SpringIndexer {
|
||||
if (!providers.isEmpty()) {
|
||||
TextDocument doc = getTempTextDocument(docURI, docRef, content);
|
||||
for (SymbolProvider provider : providers) {
|
||||
Collection<SymbolInformation> sbls = provider.getSymbols(methodDeclaration, doc);
|
||||
Collection<EnhancedSymbolInformation> sbls = provider.getSymbols(methodDeclaration, doc);
|
||||
if (sbls != null) {
|
||||
sbls.forEach(symbol -> {
|
||||
symbols.add(symbol);
|
||||
symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList<SymbolInformation>()).add(symbol);
|
||||
sbls.forEach(enhancedSymbol -> {
|
||||
symbols.add(enhancedSymbol.getSymbol());
|
||||
symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList<SymbolInformation>()).add(enhancedSymbol.getSymbol());
|
||||
|
||||
if (enhancedSymbol.getAdditionalInformation() != null) {
|
||||
addonInformation.add(enhancedSymbol.getAdditionalInformation());
|
||||
addonInformationByDoc.computeIfAbsent(docURI, s -> new ArrayList<Object>()).add(enhancedSymbol.getAdditionalInformation());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -500,11 +540,16 @@ public class SpringIndexer {
|
||||
if (!providers.isEmpty()) {
|
||||
TextDocument doc = getTempTextDocument(docURI, docRef, content);
|
||||
for (SymbolProvider provider : providers) {
|
||||
Collection<SymbolInformation> sbls = provider.getSymbols(node, typeBinding, metaAnnotations, doc);
|
||||
Collection<EnhancedSymbolInformation> sbls = provider.getSymbols(node, typeBinding, metaAnnotations, doc);
|
||||
if (sbls != null) {
|
||||
sbls.forEach(symbol -> {
|
||||
symbols.add(symbol);
|
||||
symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList<SymbolInformation>()).add(symbol);
|
||||
sbls.forEach(enhancedSymbol -> {
|
||||
symbols.add(enhancedSymbol.getSymbol());
|
||||
symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList<SymbolInformation>()).add(enhancedSymbol.getSymbol());
|
||||
|
||||
if (enhancedSymbol.getAdditionalInformation() != null) {
|
||||
addonInformation.add(enhancedSymbol.getAdditionalInformation());
|
||||
addonInformationByDoc.computeIfAbsent(docURI, s -> new ArrayList<Object>()).add(enhancedSymbol.getAdditionalInformation());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -660,10 +705,17 @@ public class SpringIndexer {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
|
||||
List<SymbolInformation> oldSymbols = symbolsByDoc.remove(docURI);
|
||||
if (oldSymbols != null) {
|
||||
symbols.removeAll(oldSymbols);
|
||||
}
|
||||
|
||||
List<Object> oldAddInInformation = addonInformationByDoc.remove(docURI);
|
||||
if (oldAddInInformation != null) {
|
||||
addonInformation.removeAll(oldAddInInformation);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("{}", e);
|
||||
}
|
||||
|
||||
@@ -11,15 +11,18 @@
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.WebfluxHandlerInformation;
|
||||
import org.springframework.ide.vscode.project.harness.BootJavaLanguageServerHarness;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
|
||||
|
||||
@@ -45,6 +48,9 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
assertEquals(4, symbols.size());
|
||||
assertTrue(containsSymbol(symbols, "@/users", docUri, 19, 1, 19, 74));
|
||||
assertTrue(containsSymbol(symbols, "@/users/{username}", docUri, 24, 1, 24, 85));
|
||||
|
||||
List<? extends Object> addons = getAdditionalInformation(docUri);
|
||||
assertNull(addons);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -59,6 +65,29 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
assertTrue(containsSymbol(symbols, "@/echo -- POST", docUri, 23, 5, 23, 101));
|
||||
assertTrue(containsSymbol(symbols, "@/quotes -- GET", docUri, 24, 5, 24, 86));
|
||||
assertTrue(containsSymbol(symbols, "@/quotes -- GET", docUri, 25, 5, 25, 94));
|
||||
|
||||
List<? extends Object> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(4, addons.size());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "@/hello -- GET").get(0);
|
||||
assertEquals("@/hello -- GET", handlerInfo1.getSymbol());
|
||||
assertEquals("org.test.QuoteHandler", handlerInfo1.getDestinationClass());
|
||||
assertEquals("Lorg/test/QuoteHandler;.hello(Lorg/springframework/web/reactive/function/server/ServerRequest;)Lreactor/core/publisher/Mono<Lorg/springframework/web/reactive/function/server/ServerResponse;>;", handlerInfo1.getMethodKey());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo2 = getWebfluxHandler(addons, "@/echo -- POST").get(0);
|
||||
assertEquals("@/echo -- POST", handlerInfo2.getSymbol());
|
||||
assertEquals("org.test.QuoteHandler", handlerInfo2.getDestinationClass());
|
||||
assertEquals("Lorg/test/QuoteHandler;.echo(Lorg/springframework/web/reactive/function/server/ServerRequest;)Lreactor/core/publisher/Mono<Lorg/springframework/web/reactive/function/server/ServerResponse;>;", handlerInfo2.getMethodKey());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo3 = getWebfluxHandler(addons, "@/quotes -- GET").get(0);
|
||||
assertEquals("@/quotes -- GET", handlerInfo3.getSymbol());
|
||||
assertEquals("org.test.QuoteHandler", handlerInfo3.getDestinationClass());
|
||||
assertEquals("Lorg/test/QuoteHandler;.streamQuotes(Lorg/springframework/web/reactive/function/server/ServerRequest;)Lreactor/core/publisher/Mono<Lorg/springframework/web/reactive/function/server/ServerResponse;>;", handlerInfo3.getMethodKey());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo4 = getWebfluxHandler(addons, "@/quotes -- GET").get(1);
|
||||
assertEquals("@/quotes -- GET", handlerInfo4.getSymbol());
|
||||
assertEquals("org.test.QuoteHandler", handlerInfo4.getDestinationClass());
|
||||
assertEquals("Lorg/test/QuoteHandler;.fetchQuotes(Lorg/springframework/web/reactive/function/server/ServerRequest;)Lreactor/core/publisher/Mono<Lorg/springframework/web/reactive/function/server/ServerResponse;>;", handlerInfo4.getMethodKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -72,6 +101,24 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
assertTrue(containsSymbol(symbols, "@/person/{id} -- GET", docUri, 27, 6, 27, 45));
|
||||
assertTrue(containsSymbol(symbols, "@/person/ -- POST", docUri, 29, 6, 29, 83));
|
||||
assertTrue(containsSymbol(symbols, "@/person -- GET", docUri, 28, 7, 28, 60));
|
||||
|
||||
List<? extends Object> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(3, addons.size());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "@/person/{id} -- GET").get(0);
|
||||
assertEquals("@/person/{id} -- GET", handlerInfo1.getSymbol());
|
||||
assertEquals("org.test.PersonHandler", handlerInfo1.getDestinationClass());
|
||||
assertEquals("Lorg/test/PersonHandler;.getPerson(Lorg/springframework/web/reactive/function/server/ServerRequest;)Lreactor/core/publisher/Mono<Lorg/springframework/web/reactive/function/server/ServerResponse;>;", handlerInfo1.getMethodKey());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo2 = getWebfluxHandler(addons, "@/person/ -- POST").get(0);
|
||||
assertEquals("@/person/ -- POST", handlerInfo2.getSymbol());
|
||||
assertEquals("org.test.PersonHandler", handlerInfo2.getDestinationClass());
|
||||
assertEquals("Lorg/test/PersonHandler;.createPerson(Lorg/springframework/web/reactive/function/server/ServerRequest;)Lreactor/core/publisher/Mono<Lorg/springframework/web/reactive/function/server/ServerResponse;>;", handlerInfo2.getMethodKey());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo3 = getWebfluxHandler(addons, "@/person -- GET").get(0);
|
||||
assertEquals("@/person -- GET", handlerInfo3.getSymbol());
|
||||
assertEquals("org.test.PersonHandler", handlerInfo3.getDestinationClass());
|
||||
assertEquals("Lorg/test/PersonHandler;.listPeople(Lorg/springframework/web/reactive/function/server/ServerRequest;)Lreactor/core/publisher/Mono<Lorg/springframework/web/reactive/function/server/ServerResponse;>;", handlerInfo3.getMethodKey());
|
||||
}
|
||||
|
||||
private boolean containsSymbol(List<? extends SymbolInformation> symbols, String name, String uri, int startLine, int startCHaracter, int endLine, int endCharacter) {
|
||||
@@ -94,4 +141,17 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
private List<? extends SymbolInformation> getSymbols(String docUri) {
|
||||
return harness.getServerWrapper().getComponents().getSpringIndexer().getSymbols(docUri);
|
||||
}
|
||||
|
||||
private List<? extends Object> getAdditionalInformation(String docUri) {
|
||||
return harness.getServerWrapper().getComponents().getSpringIndexer().getAdditonalInformation(docUri);
|
||||
}
|
||||
|
||||
private List<WebfluxHandlerInformation> getWebfluxHandler(List<? extends Object> addons, String symbol) {
|
||||
return addons.stream()
|
||||
.filter((obj) -> obj instanceof WebfluxHandlerInformation)
|
||||
.map((obj -> (WebfluxHandlerInformation) obj))
|
||||
.filter((addon) -> addon.getSymbol().equals(symbol))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user