added http method support to webflux symbol provider

This commit is contained in:
Martin Lippert
2018-02-26 11:43:21 +01:00
parent 05c0c8a901
commit 66290f0dca
4 changed files with 161 additions and 52 deletions

View File

@@ -0,0 +1,75 @@
/*******************************************************************************
* 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;
import java.util.List;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.QualifiedName;
/**
* @author Martin Lippert
*/
public class WebfluxMethodFinder extends ASTVisitor {
private String method;
private ASTNode root;
public WebfluxMethodFinder(ASTNode root) {
this.root = root;
}
public String getMethod() {
return method;
}
@Override
public boolean visit(MethodInvocation node) {
boolean visitChildren = true;
if (node != this.root) {
IMethodBinding methodBinding = node.resolveMethodBinding();
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
String name = methodBinding.getName();
if (name != null && WebfluxUtils.REQUEST_PREDICATE_HTTPMETHOD_METHODS.contains(name)) {
method = name;
}
else if (name != null && WebfluxUtils.REQUEST_PREDICATE_METHOD_METHOD.equals(name)) {
method = extractMethodValue(node);
}
}
if (WebfluxUtils.isRouteMethodInvocation(methodBinding)) {
visitChildren = false;
}
}
return visitChildren;
}
private String extractMethodValue(MethodInvocation node) {
List<?> arguments = node.arguments();
if (arguments != null && arguments.size() > 0) {
Object object = arguments.get(0);
if (object instanceof QualifiedName) {
QualifiedName qualifiedName = (QualifiedName) object;
if (qualifiedName.getName() != null) {
return qualifiedName.getName().toString();
}
}
}
return null;
}
}

View File

@@ -38,25 +38,17 @@ public class WebfluxPathFinder extends ASTVisitor {
if (node != this.root) {
IMethodBinding methodBinding = node.resolveMethodBinding();
if (WebfluxRouterSymbolProvider.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
String name = methodBinding.getName();
if (name != null && WebfluxRouterSymbolProvider.REQUEST_PREDICATE_PATH_METHODS.contains(name)) {
path = WebfluxRouterSymbolProvider.extractPath(node);
if (name != null && WebfluxUtils.REQUEST_PREDICATE_ALL_PATH_METHODS.contains(name)) {
path = WebfluxUtils.extractPath(node);
}
}
if (WebfluxRouterSymbolProvider.ROUTER_FUNCTIONS_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
String name = methodBinding.getName();
if ("route".equals(name)) {
visitChildren = false;
}
}
else if (WebfluxRouterSymbolProvider.ROUTER_FUNCTION_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
String name = methodBinding.getName();
if ("andRoute".equals(name)) {
visitChildren = false;
}
if (WebfluxUtils.isRouteMethodInvocation(methodBinding)) {
visitChildren = false;
}
}
return visitChildren;
}

View File

@@ -11,11 +11,8 @@
package org.springframework.ide.vscode.boot.java.requestmapping;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
@@ -25,7 +22,6 @@ 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.StringLiteral;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.lsp4j.Location;
@@ -40,12 +36,6 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
*/
public class WebfluxRouterSymbolProvider implements SymbolProvider {
public static final String ROUTER_FUNCTION_TYPE = "org.springframework.web.reactive.function.server.RouterFunction";
public static final String ROUTER_FUNCTIONS_TYPE = "org.springframework.web.reactive.function.server.RouterFunctions";
public static final String REQUEST_PREDICATES_TYPE = "org.springframework.web.reactive.function.server.RequestPredicates";
public static final Set<String> REQUEST_PREDICATE_PATH_METHODS = new HashSet<>(Arrays.asList("path", "GET", "POST", "DELETE", "PUT", "PATCH", "HEAD", "OPTIONS"));
@Override
public Collection<SymbolInformation> getSymbols(Annotation node, ITypeBinding typeBinding,
Collection<ITypeBinding> metaAnnotations, TextDocument doc) {
@@ -63,7 +53,7 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
if (returnType != null) {
ITypeBinding resolvedBinding = returnType.resolveBinding();
if (resolvedBinding != null) {
if (ROUTER_FUNCTION_TYPE.equals(resolvedBinding.getBinaryName())) {
if (WebfluxUtils.ROUTER_FUNCTION_TYPE.equals(resolvedBinding.getBinaryName())) {
return getSymbolsForRouterFunction(methodDeclaration, doc);
}
}
@@ -82,17 +72,8 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
public boolean visit(MethodInvocation node) {
IMethodBinding methodBinding = node.resolveMethodBinding();
if (ROUTER_FUNCTIONS_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
String name = methodBinding.getName();
if ("route".equals(name)) {
extractMappingSymbol(node, doc, result);
}
}
else if (ROUTER_FUNCTION_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
String name = methodBinding.getName();
if ("andRoute".equals(name)) {
extractMappingSymbol(node, doc, result);
}
if (WebfluxUtils.isRouteMethodInvocation(methodBinding)) {
extractMappingSymbol(node, doc, result);
}
return super.visit(node);
@@ -141,7 +122,7 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
MethodInvocation methodInvocation = (MethodInvocation) node;
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
if (ROUTER_FUNCTIONS_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
if (WebfluxUtils.ROUTER_FUNCTIONS_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
String name = methodBinding.getName();
if ("nest".equals(name)) {
List<?> arguments = methodInvocation.arguments();
@@ -152,7 +133,7 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
String nestedMethodName = nestedMethodBinding.getName();
if ("path".equals(nestedMethodName)) {
String additionalPath = extractPath(nestedMethod);
String additionalPath = WebfluxUtils.extractPath(nestedMethod);
if (additionalPath != null && additionalPath.length() > 0) {
path = additionalPath + path;
}
@@ -167,20 +148,12 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
return extractPath(node.getParent(), path);
}
protected static String extractPath(MethodInvocation node) {
List<?> arguments = node.arguments();
if (arguments != null && arguments.size() > 0) {
Object object = arguments.get(0);
if (object instanceof StringLiteral) {
String path = ((StringLiteral) object).getLiteralValue();
return path;
}
}
return null;
}
private String extractMethod(MethodInvocation node) {
return null;
private String extractMethod(MethodInvocation routerInvocation) {
WebfluxMethodFinder methodFinder = new WebfluxMethodFinder(routerInvocation);
routerInvocation.accept(methodFinder);
String method = methodFinder.getMethod();
return method;
}
}

View File

@@ -0,0 +1,69 @@
/*******************************************************************************
* 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;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.StringLiteral;
/**
* @author Martin Lippert
*/
public class WebfluxUtils {
public static final String ROUTER_FUNCTION_TYPE = "org.springframework.web.reactive.function.server.RouterFunction";
public static final String ROUTER_FUNCTIONS_TYPE = "org.springframework.web.reactive.function.server.RouterFunctions";
public static final String REQUEST_PREDICATES_TYPE = "org.springframework.web.reactive.function.server.RequestPredicates";
public static final String REQUEST_PREDICATE_PATH_METHOD = "path";
public static final String REQUEST_PREDICATE_METHOD_METHOD = "method";
public static final Set<String> REQUEST_PREDICATE_HTTPMETHOD_METHODS = new HashSet<>(Arrays.asList("GET", "POST", "DELETE", "PUT", "PATCH", "HEAD", "OPTIONS"));
public static final Set<String> REQUEST_PREDICATE_ALL_PATH_METHODS = new HashSet<>(Arrays.asList(REQUEST_PREDICATE_PATH_METHOD, "GET", "POST", "DELETE", "PUT", "PATCH", "HEAD", "OPTIONS"));
public static String extractPath(MethodInvocation node) {
List<?> arguments = node.arguments();
if (arguments != null && arguments.size() > 0) {
Object object = arguments.get(0);
if (object instanceof StringLiteral) {
String path = ((StringLiteral) object).getLiteralValue();
return path;
}
}
return null;
}
public static boolean isRouteMethodInvocation(IMethodBinding methodBinding) {
if (ROUTER_FUNCTIONS_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
String name = methodBinding.getName();
if ("route".equals(name)) {
return true;
}
}
else if (ROUTER_FUNCTION_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
String name = methodBinding.getName();
if ("andRoute".equals(name)) {
return true;
}
}
return false;
}
}