Everything compiles
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2019 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2022 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
|
||||
@@ -13,19 +13,20 @@ package org.springframework.ide.vscode.boot.java.beans;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.IAnnotationBinding;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.Modifier;
|
||||
import org.eclipse.jdt.core.dom.ParameterizedType;
|
||||
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;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.openrewrite.internal.lang.Nullable;
|
||||
import org.openrewrite.java.tree.J;
|
||||
import org.openrewrite.java.tree.J.Annotation;
|
||||
import org.openrewrite.java.tree.J.ClassDeclaration;
|
||||
import org.openrewrite.java.tree.J.Literal;
|
||||
import org.openrewrite.java.tree.J.MethodDeclaration;
|
||||
import org.openrewrite.java.tree.J.Modifier;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified;
|
||||
import org.openrewrite.java.tree.JavaType.Method;
|
||||
import org.openrewrite.java.tree.JavaType.Parameterized;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.AbstractSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
@@ -33,6 +34,7 @@ import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
|
||||
import org.springframework.ide.vscode.boot.java.utils.FunctionUtils;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ORAstUtils;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
@@ -40,6 +42,7 @@ import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.reflect.Parameter;
|
||||
|
||||
import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuple3;
|
||||
@@ -54,7 +57,7 @@ public class BeansSymbolProvider extends AbstractSymbolProvider {
|
||||
private static final String[] NAME_ATTRIBUTES = {"value", "name"};
|
||||
|
||||
@Override
|
||||
protected void addSymbolsPass1(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, SpringIndexerJavaContext context, TextDocument doc) {
|
||||
protected void addSymbolsPass1(Annotation node, FullyQualified annotationType, Collection<FullyQualified> metaAnnotations, SpringIndexerJavaContext context, TextDocument doc) {
|
||||
if (isMethodAbstract(node)) return;
|
||||
|
||||
boolean isFunction = isFunctionBean(node);
|
||||
@@ -79,7 +82,7 @@ public class BeansSymbolProvider extends AbstractSymbolProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addSymbolsPass1(TypeDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) {
|
||||
protected void addSymbolsPass1(ClassDeclaration typeDeclaration, SpringIndexerJavaContext context, 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) {
|
||||
@@ -99,23 +102,23 @@ public class BeansSymbolProvider extends AbstractSymbolProvider {
|
||||
}
|
||||
|
||||
protected Collection<Tuple2<String, DocumentRegion>> getBeanNames(Annotation node, TextDocument doc) {
|
||||
Collection<StringLiteral> beanNameNodes = getBeanNameLiterals(node);
|
||||
Collection<Literal> beanNameNodes = getBeanNameLiterals(node);
|
||||
|
||||
if (beanNameNodes != null && !beanNameNodes.isEmpty()) {
|
||||
ImmutableList.Builder<Tuple2<String,DocumentRegion>> namesAndRegions = ImmutableList.builder();
|
||||
for (StringLiteral nameNode : beanNameNodes) {
|
||||
String name = ASTUtils.getLiteralValue(nameNode);
|
||||
namesAndRegions.add(Tuples.of(name, ASTUtils.stringRegion(doc, nameNode)));
|
||||
for (Literal nameNode : beanNameNodes) {
|
||||
String name = ORAstUtils.getLiteralValue(nameNode);
|
||||
namesAndRegions.add(Tuples.of(name, ORAstUtils.stringRegion(doc, nameNode)));
|
||||
}
|
||||
return namesAndRegions.build();
|
||||
}
|
||||
else {
|
||||
ASTNode parent = node.getParent();
|
||||
J parent = ORAstUtils.getParent(node);
|
||||
if (parent instanceof MethodDeclaration) {
|
||||
MethodDeclaration method = (MethodDeclaration) parent;
|
||||
return ImmutableList.of(Tuples.of(
|
||||
method.getName().toString(),
|
||||
ASTUtils.nameRegion(doc, node)
|
||||
ORAstUtils.nameRegion(doc, node)
|
||||
));
|
||||
}
|
||||
return ImmutableList.of();
|
||||
@@ -138,81 +141,71 @@ public class BeansSymbolProvider extends AbstractSymbolProvider {
|
||||
return symbolLabel.toString();
|
||||
}
|
||||
|
||||
protected Collection<StringLiteral> getBeanNameLiterals(Annotation node) {
|
||||
ImmutableList.Builder<StringLiteral> literals = ImmutableList.builder();
|
||||
protected Collection<Literal> getBeanNameLiterals(Annotation node) {
|
||||
ImmutableList.Builder<Literal> literals = ImmutableList.builder();
|
||||
for (String attrib : NAME_ATTRIBUTES) {
|
||||
ASTUtils.getAttribute(node, attrib).ifPresent((valueExp) -> {
|
||||
literals.addAll(ASTUtils.getExpressionValueAsListOfLiterals(valueExp));
|
||||
ORAstUtils.getAttribute(node, attrib).ifPresent((valueExp) -> {
|
||||
literals.addAll(ORAstUtils.getExpressionValueAsListOfLiterals(valueExp));
|
||||
});
|
||||
}
|
||||
return literals.build();
|
||||
}
|
||||
|
||||
protected String getBeanType(Annotation node) {
|
||||
ASTNode parent = node.getParent();
|
||||
J parent = ORAstUtils.getParent(node);
|
||||
if (parent instanceof MethodDeclaration) {
|
||||
MethodDeclaration method = (MethodDeclaration) parent;
|
||||
String returnType = method.getReturnType2().resolveBinding().getName();
|
||||
return returnType;
|
||||
Method method = ((MethodDeclaration) parent).getMethodType();
|
||||
if (method != null) {
|
||||
FullyQualified returnType = TypeUtils.asFullyQualified(method.getReturnType());
|
||||
if (returnType != null) {
|
||||
return returnType.getFullyQualifiedName();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isFunctionBean(Annotation node) {
|
||||
ASTNode parent = node.getParent();
|
||||
J parent = ORAstUtils.getParent(node);
|
||||
if (parent instanceof MethodDeclaration) {
|
||||
MethodDeclaration method = (MethodDeclaration) parent;
|
||||
String returnType = null;
|
||||
|
||||
if (method.getReturnType2().isParameterizedType()) {
|
||||
ParameterizedType paramType = (ParameterizedType) method.getReturnType2();
|
||||
Type type = paramType.getType();
|
||||
ITypeBinding typeBinding = type.resolveBinding();
|
||||
returnType = typeBinding.getBinaryName();
|
||||
Method method = ((MethodDeclaration) parent).getMethodType();
|
||||
if (method != null) {
|
||||
FullyQualified returnType = TypeUtils.asFullyQualified(method.getReturnType());
|
||||
if (returnType != null) {
|
||||
String fqName = returnType.getFullyQualifiedName();
|
||||
|
||||
return FunctionUtils.FUNCTION_FUNCTION_TYPE.equals(fqName) || FunctionUtils.FUNCTION_CONSUMER_TYPE.equals(fqName)
|
||||
|| FunctionUtils.FUNCTION_SUPPLIER_TYPE.equals(fqName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
returnType = method.getReturnType2().resolveBinding().getQualifiedName();
|
||||
}
|
||||
|
||||
return FunctionUtils.FUNCTION_FUNCTION_TYPE.equals(returnType) || FunctionUtils.FUNCTION_CONSUMER_TYPE.equals(returnType)
|
||||
|| FunctionUtils.FUNCTION_SUPPLIER_TYPE.equals(returnType);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getAnnotations(Annotation node) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
ASTNode parent = node.getParent();
|
||||
J parent = ORAstUtils.getParent(node);
|
||||
if (parent instanceof MethodDeclaration) {
|
||||
MethodDeclaration method = (MethodDeclaration) parent;
|
||||
|
||||
List<?> modifiers = method.modifiers();
|
||||
for (Object modifier : modifiers) {
|
||||
if (modifier instanceof Annotation) {
|
||||
Annotation annotation = (Annotation) modifier;
|
||||
IAnnotationBinding annotationBinding = annotation.resolveAnnotationBinding();
|
||||
String type = annotationBinding.getAnnotationType().getBinaryName();
|
||||
|
||||
if (type != null && !Annotations.BEAN.equals(type)) {
|
||||
result.append(' ');
|
||||
result.append(annotation.toString());
|
||||
}
|
||||
|
||||
for (Annotation a : method.getLeadingAnnotations()) {
|
||||
FullyQualified type = TypeUtils.asFullyQualified(a.getType());
|
||||
if (type != null && !Annotations.BEAN.equals(type.getFullyQualifiedName())) {
|
||||
result.append(' ');
|
||||
result.append(a.printTrimmed());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private boolean isMethodAbstract(Annotation node) {
|
||||
if (node != null && node.getParent() != null && node.getParent() instanceof MethodDeclaration) {
|
||||
MethodDeclaration method = (MethodDeclaration) node.getParent();
|
||||
List<?> modifiers = method.modifiers();
|
||||
for (Object modifier : modifiers) {
|
||||
if (modifier instanceof Modifier && ((Modifier) modifier).isAbstract()) {
|
||||
return true;
|
||||
}
|
||||
if (node != null) {
|
||||
J parent = ORAstUtils.getParent(node);
|
||||
if (parent instanceof MethodDeclaration) {
|
||||
MethodDeclaration method = (MethodDeclaration) parent;
|
||||
return Modifier.hasModifier(method.getModifiers(), Modifier.Type.Abstract);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2019 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2022 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
|
||||
@@ -13,17 +13,19 @@ package org.springframework.ide.vscode.boot.java.beans;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.Location;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.openrewrite.java.tree.J;
|
||||
import org.openrewrite.java.tree.J.Annotation;
|
||||
import org.openrewrite.java.tree.J.ClassDeclaration;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified;
|
||||
import org.openrewrite.marker.Range;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.AbstractSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ORAstUtils;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
@@ -36,7 +38,7 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
public class ComponentSymbolProvider extends AbstractSymbolProvider {
|
||||
|
||||
@Override
|
||||
protected void addSymbolsPass1(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, SpringIndexerJavaContext context, TextDocument doc) {
|
||||
protected void addSymbolsPass1(Annotation node, FullyQualified annotationType, Collection<FullyQualified> metaAnnotations, SpringIndexerJavaContext context, TextDocument doc) {
|
||||
try {
|
||||
EnhancedSymbolInformation enhancedSymbol = createSymbol(node, annotationType, metaAnnotations, doc);
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol));
|
||||
@@ -46,17 +48,18 @@ public class ComponentSymbolProvider extends AbstractSymbolProvider {
|
||||
}
|
||||
}
|
||||
|
||||
protected EnhancedSymbolInformation createSymbol(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, TextDocument doc) throws BadLocationException {
|
||||
String annotationTypeName = annotationType.getName();
|
||||
protected EnhancedSymbolInformation createSymbol(Annotation node, FullyQualified annotationType, Collection<FullyQualified> metaAnnotations, TextDocument doc) throws BadLocationException {
|
||||
String annotationTypeName = annotationType.getFullyQualifiedName();
|
||||
Collection<String> metaAnnotationNames = metaAnnotations.stream()
|
||||
.map(ITypeBinding::getName)
|
||||
.map(FullyQualified::getFullyQualifiedName)
|
||||
.collect(Collectors.toList());
|
||||
String beanName = getBeanName(node);
|
||||
String beanType = getBeanType(node);
|
||||
|
||||
Range r = ORAstUtils.getRange(node);
|
||||
SymbolInformation symbol = new SymbolInformation(
|
||||
beanLabel("+", annotationTypeName, metaAnnotationNames, beanName, beanType), SymbolKind.Interface,
|
||||
new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength())));
|
||||
new Location(doc.getUri(), doc.toRange(r.getStart().getOffset(), r.length())));
|
||||
|
||||
SymbolAddOnInformation[] addon = new SymbolAddOnInformation[] {new BeansSymbolAddOnInformation(beanName)};
|
||||
|
||||
@@ -91,21 +94,21 @@ public class ComponentSymbolProvider extends AbstractSymbolProvider {
|
||||
}
|
||||
|
||||
private String getBeanName(Annotation node) {
|
||||
ASTNode parent = node.getParent();
|
||||
if (parent instanceof TypeDeclaration) {
|
||||
TypeDeclaration type = (TypeDeclaration) parent;
|
||||
J parent = ORAstUtils.getParent(node);
|
||||
if (parent instanceof ClassDeclaration) {
|
||||
ClassDeclaration type = (ClassDeclaration) parent;
|
||||
|
||||
String beanName = type.getName().toString();
|
||||
String beanName = type.getSimpleName();
|
||||
return BeanUtils.getBeanNameFromType(beanName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getBeanType(Annotation node) {
|
||||
ASTNode parent = node.getParent();
|
||||
if (parent instanceof TypeDeclaration) {
|
||||
TypeDeclaration type = (TypeDeclaration) parent;
|
||||
String returnType = type.resolveBinding().getName();
|
||||
J parent = ORAstUtils.getParent(node);
|
||||
if (parent instanceof ClassDeclaration) {
|
||||
ClassDeclaration type = (ClassDeclaration) parent;
|
||||
String returnType = type.getType().getFullyQualifiedName();
|
||||
return returnType;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -10,11 +10,16 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.data;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.openrewrite.java.tree.J.ClassDeclaration;
|
||||
import org.openrewrite.java.tree.JavaType;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified;
|
||||
import org.openrewrite.java.tree.JavaType.Parameterized;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.beans.BeanUtils;
|
||||
@@ -22,8 +27,8 @@ import org.springframework.ide.vscode.boot.java.beans.BeansSymbolAddOnInformatio
|
||||
import org.springframework.ide.vscode.boot.java.handlers.AbstractSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ORAstUtils;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
|
||||
@@ -40,7 +45,7 @@ public class DataRepositorySymbolProvider extends AbstractSymbolProvider {
|
||||
private static final Logger log = LoggerFactory.getLogger(DataRepositorySymbolProvider.class);
|
||||
|
||||
@Override
|
||||
protected void addSymbolsPass1(TypeDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) {
|
||||
protected void addSymbolsPass1(ClassDeclaration typeDeclaration, SpringIndexerJavaContext context, 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) {
|
||||
@@ -75,8 +80,8 @@ public class DataRepositorySymbolProvider extends AbstractSymbolProvider {
|
||||
return symbolLabel.toString();
|
||||
}
|
||||
|
||||
private static Tuple4<String, String, String, DocumentRegion> getRepositoryBean(TypeDeclaration typeDeclaration, TextDocument doc) {
|
||||
ITypeBinding resolvedType = typeDeclaration.resolveBinding();
|
||||
private static Tuple4<String, String, String, DocumentRegion> getRepositoryBean(ClassDeclaration typeDeclaration, TextDocument doc) {
|
||||
FullyQualified resolvedType = typeDeclaration.getType();
|
||||
|
||||
if (resolvedType != null) {
|
||||
return getRepositoryBean(typeDeclaration, doc, resolvedType);
|
||||
@@ -86,53 +91,46 @@ public class DataRepositorySymbolProvider extends AbstractSymbolProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private static Tuple4<String, String, String, DocumentRegion> getRepositoryBean(TypeDeclaration typeDeclaration, TextDocument doc,
|
||||
ITypeBinding resolvedType) {
|
||||
|
||||
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)) {
|
||||
private static Tuple4<String, String, String, DocumentRegion> getRepositoryBean(ClassDeclaration typeDeclaration, TextDocument doc,
|
||||
FullyQualified resolvedType) {
|
||||
|
||||
for (FullyQualified resolvedInterface : resolvedType.getInterfaces()) {
|
||||
if (Constants.REPOSITORY_TYPE.equals(resolvedInterface.getFullyQualifiedName())) {
|
||||
String beanName = getBeanName(typeDeclaration);
|
||||
String beanType = resolvedInterface.getName();
|
||||
|
||||
String beanType = resolvedInterface.toString();
|
||||
|
||||
String domainType = null;
|
||||
if (resolvedInterface.isParameterizedType()) {
|
||||
ITypeBinding[] typeParameters = resolvedInterface.getTypeArguments();
|
||||
if (typeParameters != null && typeParameters.length > 0) {
|
||||
domainType = typeParameters[0].getName();
|
||||
if (resolvedType instanceof Parameterized) {
|
||||
List<JavaType> typeParams = ((Parameterized)resolvedType).getTypeParameters();
|
||||
if (typeParams != null && !typeParams.isEmpty()) {
|
||||
FullyQualified typeParam = TypeUtils.asFullyQualified(typeParams.get(0));
|
||||
domainType = typeParam == null ? null : typeParam.getFullyQualifiedName();
|
||||
}
|
||||
}
|
||||
DocumentRegion region = ASTUtils.nodeRegion(doc, typeDeclaration.getName());
|
||||
|
||||
DocumentRegion region = ORAstUtils.nodeRegion(doc, typeDeclaration.getName());
|
||||
|
||||
return Tuples.of(beanName, beanType, domainType, region);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Tuple4<String, String, String, DocumentRegion> result = getRepositoryBean(typeDeclaration, doc, resolvedInterface);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ITypeBinding superclass = resolvedType.getSuperclass();
|
||||
|
||||
FullyQualified superclass = resolvedType.getSupertype();
|
||||
if (superclass != null) {
|
||||
return getRepositoryBean(typeDeclaration, doc, superclass);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static String getBeanName(TypeDeclaration typeDeclaration) {
|
||||
String beanName = typeDeclaration.getName().toString();
|
||||
private static String getBeanName(ClassDeclaration typeDeclaration) {
|
||||
String beanName = typeDeclaration.getSimpleName();
|
||||
return BeanUtils.getBeanNameFromType(beanName);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2019 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2022 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
|
||||
@@ -12,23 +12,21 @@ package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.openrewrite.internal.lang.Nullable;
|
||||
import org.openrewrite.java.tree.Expression;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.openrewrite.java.tree.J.Annotation;
|
||||
import org.openrewrite.java.tree.J.Assignment;
|
||||
import org.openrewrite.java.tree.J.ClassDeclaration;
|
||||
import org.openrewrite.java.tree.J.MethodDeclaration;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.openrewrite.marker.Range;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.AbstractSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ORAstUtils;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext;
|
||||
@@ -89,7 +87,6 @@ public class RequestMappingSymbolProvider extends AbstractSymbolProvider {
|
||||
private String[] getMethod(Annotation node, SpringIndexerJavaContext context) {
|
||||
String[] methods = null;
|
||||
|
||||
|
||||
List<Expression> args = node.getArguments();
|
||||
|
||||
// TODO: OR AST Annotation parameter
|
||||
@@ -97,34 +94,11 @@ public class RequestMappingSymbolProvider extends AbstractSymbolProvider {
|
||||
&& (!(args.get(0) instanceof Assignment)) || "value".equals(((Assignment)args.get(0)).getVariable().printTrimmed()) )
|
||||
) {
|
||||
methods = getRequestMethod(node);
|
||||
} else if () {
|
||||
for (Expression arg : args) {
|
||||
if (arg instanceof Assignment && "method".equals(((Assignment) arg).getVariable().printTrimmed())) {
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
methods = getRequestMethodFromMultiArgs(node, context);
|
||||
}
|
||||
|
||||
if (node.isNormalAnnotation()) {
|
||||
NormalAnnotation normNode = (NormalAnnotation) node;
|
||||
List<?> values = normNode.values();
|
||||
for (Iterator<?> iterator = values.iterator(); iterator.hasNext();) {
|
||||
Object object = iterator.next();
|
||||
if (object instanceof MemberValuePair) {
|
||||
MemberValuePair pair = (MemberValuePair) object;
|
||||
String valueName = pair.getName().getIdentifier();
|
||||
if (valueName != null && valueName.equals("method")) {
|
||||
Expression expression = pair.getValue();
|
||||
methods = ASTUtils.getExpressionValueAsArray(expression, context::addDependency);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (node instanceof SingleMemberAnnotation) {
|
||||
methods = getRequestMethod((SingleMemberAnnotation)node);
|
||||
}
|
||||
|
||||
if (methods == null && node.getParent() instanceof MethodDeclaration) {
|
||||
if (methods == null && ORAstUtils.getParent(node) instanceof MethodDeclaration) {
|
||||
Annotation parentAnnotation = getParentAnnotation(node);
|
||||
if (parentAnnotation != null) {
|
||||
methods = getMethod(parentAnnotation, context);
|
||||
@@ -135,26 +109,25 @@ public class RequestMappingSymbolProvider extends AbstractSymbolProvider {
|
||||
}
|
||||
|
||||
private String[] getPath(Annotation node, SpringIndexerJavaContext context) {
|
||||
if (node.isNormalAnnotation()) {
|
||||
NormalAnnotation normNode = (NormalAnnotation) node;
|
||||
List<?> values = normNode.values();
|
||||
for (Iterator<?> iterator = values.iterator(); iterator.hasNext();) {
|
||||
Object object = iterator.next();
|
||||
if (object instanceof MemberValuePair) {
|
||||
MemberValuePair pair = (MemberValuePair) object;
|
||||
String valueName = pair.getName().getIdentifier();
|
||||
if (valueName != null && (valueName.equals("value") || valueName.equals("path"))) {
|
||||
Expression expression = pair.getValue();
|
||||
return ASTUtils.getExpressionValueAsArray(expression, context::addDependency);
|
||||
|
||||
List<Expression> args = node.getArguments();
|
||||
|
||||
if (args != null) {
|
||||
if (args.size() == 1 && !(args.get(0) instanceof Assignment)) {
|
||||
return ORAstUtils.getExpressionValueAsArray(args.get(0), context::addDependency);
|
||||
} else {
|
||||
for (Expression e : args) {
|
||||
if (e instanceof Assignment) {
|
||||
Assignment assign = (Assignment) e;
|
||||
String varName = assign.getVariable().printTrimmed();
|
||||
if ("value".equals(varName) || "path".equals(varName)) {
|
||||
return ORAstUtils.getExpressionValueAsArray(assign.getAssignment(), context::addDependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (node.isSingleMemberAnnotation()) {
|
||||
SingleMemberAnnotation singleNode = (SingleMemberAnnotation) node;
|
||||
Expression expression = singleNode.getValue();
|
||||
return ASTUtils.getExpressionValueAsArray(expression, context::addDependency);
|
||||
}
|
||||
|
||||
|
||||
return new String[] { "" };
|
||||
}
|
||||
|
||||
@@ -164,26 +137,14 @@ public class RequestMappingSymbolProvider extends AbstractSymbolProvider {
|
||||
}
|
||||
|
||||
private Annotation getParentAnnotation(Annotation node) {
|
||||
ASTNode parent = node.getParent() != null ? node.getParent().getParent() : null;
|
||||
while (parent != null && !(parent instanceof TypeDeclaration)) {
|
||||
parent = parent.getParent();
|
||||
}
|
||||
|
||||
if (parent != null) {
|
||||
TypeDeclaration type = (TypeDeclaration) parent;
|
||||
List<?> modifiers = type.modifiers();
|
||||
Iterator<?> iterator = modifiers.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Object modifier = iterator.next();
|
||||
if (modifier instanceof Annotation) {
|
||||
Annotation annotation = (Annotation) modifier;
|
||||
ITypeBinding resolvedType = annotation.resolveTypeBinding();
|
||||
String annotationType = resolvedType.getQualifiedName();
|
||||
if (annotationType != null && Annotations.SPRING_REQUEST_MAPPING.equals(annotationType)) {
|
||||
return annotation;
|
||||
}
|
||||
ClassDeclaration classDecl = ORAstUtils.findNode(node, ClassDeclaration.class);
|
||||
if (classDecl != null) {
|
||||
for (Annotation a : classDecl.getLeadingAnnotations()) {
|
||||
FullyQualified annotationType = TypeUtils.asFullyQualified(a.getType());
|
||||
if (annotationType != null && Annotations.SPRING_REQUEST_MAPPING.equals(annotationType.getFullyQualifiedName())) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -210,40 +171,26 @@ public class RequestMappingSymbolProvider extends AbstractSymbolProvider {
|
||||
}
|
||||
|
||||
private String[] getAcceptTypes(Annotation node, SpringIndexerJavaContext context) {
|
||||
if (node.isNormalAnnotation()) {
|
||||
NormalAnnotation normNode = (NormalAnnotation) node;
|
||||
List<?> values = normNode.values();
|
||||
for (Iterator<?> iterator = values.iterator(); iterator.hasNext();) {
|
||||
Object object = iterator.next();
|
||||
if (object instanceof MemberValuePair) {
|
||||
MemberValuePair pair = (MemberValuePair) object;
|
||||
String valueName = pair.getName().getIdentifier();
|
||||
if (valueName != null && valueName.equals("consumes")) {
|
||||
Expression expression = pair.getValue();
|
||||
return ASTUtils.getExpressionValueAsArray(expression, context::addDependency);
|
||||
}
|
||||
for (Expression e : node.getArguments()) {
|
||||
if (e instanceof Assignment) {
|
||||
Assignment assign = (Assignment) e;
|
||||
if ("consumes".equals(assign.getVariable().printTrimmed())) {
|
||||
return ORAstUtils.getExpressionValueAsArray(assign.getAssignment(), context::addDependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
private String[] getContentTypes(Annotation node, SpringIndexerJavaContext context) {
|
||||
if (node.isNormalAnnotation()) {
|
||||
NormalAnnotation normNode = (NormalAnnotation) node;
|
||||
List<?> values = normNode.values();
|
||||
for (Iterator<?> iterator = values.iterator(); iterator.hasNext();) {
|
||||
Object object = iterator.next();
|
||||
if (object instanceof MemberValuePair) {
|
||||
MemberValuePair pair = (MemberValuePair) object;
|
||||
String valueName = pair.getName().getIdentifier();
|
||||
if (valueName != null && valueName.equals("produces")) {
|
||||
Expression expression = pair.getValue();
|
||||
return ASTUtils.getExpressionValueAsArray(expression, context::addDependency);
|
||||
}
|
||||
for (Expression e : node.getArguments()) {
|
||||
if (e instanceof Assignment) {
|
||||
Assignment assign = (Assignment) e;
|
||||
if ("produces".equals(assign.getVariable().printTrimmed())) {
|
||||
return ORAstUtils.getExpressionValueAsArray(assign.getAssignment(), context::addDependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
|
||||
@@ -13,18 +13,20 @@ package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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.SimpleName;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.java.JavaIsoVisitor;
|
||||
import org.openrewrite.java.tree.J.FieldAccess;
|
||||
import org.openrewrite.java.tree.J.MethodInvocation;
|
||||
import org.openrewrite.java.tree.JavaType.Method;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ORAstUtils;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxAcceptTypeFinder extends ASTVisitor {
|
||||
public class WebfluxAcceptTypeFinder extends JavaIsoVisitor<ExecutionContext> {
|
||||
|
||||
private List<WebfluxRouteElement> acceptTypes;
|
||||
private TextDocument doc;
|
||||
@@ -39,26 +41,28 @@ public class WebfluxAcceptTypeFinder extends ASTVisitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MethodInvocation node) {
|
||||
IMethodBinding methodBinding = node.resolveMethodBinding();
|
||||
|
||||
try {
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_ACCEPT_TYPE_METHOD.equals(name)) {
|
||||
SimpleName nameArgument = WebfluxUtils.extractSimpleNameArgument(node);
|
||||
if (nameArgument != null && nameArgument.getFullyQualifiedName() != null) {
|
||||
Range range = doc.toRange(nameArgument.getStartPosition(), nameArgument.getLength());
|
||||
acceptTypes.add(new WebfluxRouteElement(nameArgument.getFullyQualifiedName().toString(), range));
|
||||
public MethodInvocation visitMethodInvocation(MethodInvocation methodInvocation, ExecutionContext p) {
|
||||
Method method = methodInvocation.getMethodType();
|
||||
if (method != null && WebfluxUtils.isRouteMethodInvocation(method) && method.getDeclaringType() != null) {
|
||||
try {
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(method.getDeclaringType().getFullyQualifiedName())) {
|
||||
String name = method.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_ACCEPT_TYPE_METHOD.equals(name)) {
|
||||
FieldAccess nameArgument = WebfluxUtils.extractArgument(methodInvocation, FieldAccess.class);
|
||||
if (nameArgument != null) {
|
||||
org.openrewrite.marker.Range r = ORAstUtils.getRange(nameArgument);
|
||||
Range range = doc.toRange(r.getStart().getOffset(), r.length());
|
||||
acceptTypes.add(new WebfluxRouteElement(nameArgument.getSimpleName(), range));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return !WebfluxUtils.isRouteMethodInvocation(methodBinding);
|
||||
return super.visitMethodInvocation(methodInvocation, p);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* Copyright (c) 2018, 2022 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
|
||||
@@ -13,18 +13,20 @@ package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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.SimpleName;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.java.JavaIsoVisitor;
|
||||
import org.openrewrite.java.tree.J.FieldAccess;
|
||||
import org.openrewrite.java.tree.J.MethodInvocation;
|
||||
import org.openrewrite.java.tree.JavaType.Method;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ORAstUtils;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxContentTypeFinder extends ASTVisitor {
|
||||
public class WebfluxContentTypeFinder extends JavaIsoVisitor<ExecutionContext> {
|
||||
|
||||
private List<WebfluxRouteElement> contentTypes;
|
||||
private TextDocument doc;
|
||||
@@ -39,26 +41,28 @@ public class WebfluxContentTypeFinder extends ASTVisitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MethodInvocation node) {
|
||||
IMethodBinding methodBinding = node.resolveMethodBinding();
|
||||
|
||||
try {
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_CONTENT_TYPE_METHOD.equals(name)) {
|
||||
SimpleName nameArgument = WebfluxUtils.extractSimpleNameArgument(node);
|
||||
if (nameArgument != null && nameArgument.getFullyQualifiedName() != null) {
|
||||
Range range = doc.toRange(nameArgument.getStartPosition(), nameArgument.getLength());
|
||||
contentTypes.add(new WebfluxRouteElement(nameArgument.getFullyQualifiedName().toString(), range));
|
||||
public MethodInvocation visitMethodInvocation(MethodInvocation methodInvocation, ExecutionContext p) {
|
||||
Method method = methodInvocation.getMethodType();
|
||||
if (method != null && WebfluxUtils.isRouteMethodInvocation(method)) {
|
||||
try {
|
||||
if (method.getDeclaringType() != null && WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(method.getDeclaringType().getFullyQualifiedName())) {
|
||||
String name = method.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_CONTENT_TYPE_METHOD.equals(name)) {
|
||||
FieldAccess nameArgument = WebfluxUtils.extractArgument(methodInvocation, FieldAccess.class);
|
||||
if (nameArgument != null && nameArgument.getTarget() != null) {
|
||||
org.openrewrite.marker.Range r = ORAstUtils.getRange(nameArgument);
|
||||
Range range = doc.toRange(r.getStart().getOffset(), r.length());
|
||||
contentTypes.add(new WebfluxRouteElement(nameArgument.getSimpleName(), range));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
// ignore
|
||||
}
|
||||
return methodInvocation;
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return !WebfluxUtils.isRouteMethodInvocation(methodBinding);
|
||||
return super.visitMethodInvocation(methodInvocation, p);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -13,25 +13,27 @@ package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
import java.util.ArrayList;
|
||||
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;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.java.JavaIsoVisitor;
|
||||
import org.openrewrite.java.tree.J;
|
||||
import org.openrewrite.java.tree.J.FieldAccess;
|
||||
import org.openrewrite.java.tree.J.MethodInvocation;
|
||||
import org.openrewrite.java.tree.JavaType.Method;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ORAstUtils;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxMethodFinder extends ASTVisitor {
|
||||
public class WebfluxMethodFinder extends JavaIsoVisitor<ExecutionContext> {
|
||||
|
||||
private List<WebfluxRouteElement> methods;
|
||||
private ASTNode root;
|
||||
private J root;
|
||||
private TextDocument doc;
|
||||
|
||||
public WebfluxMethodFinder(ASTNode root, TextDocument doc) {
|
||||
public WebfluxMethodFinder(J root, TextDocument doc) {
|
||||
this.root = root;
|
||||
this.doc = doc;
|
||||
this.methods = new ArrayList<>();
|
||||
@@ -42,23 +44,24 @@ public class WebfluxMethodFinder extends ASTVisitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MethodInvocation node) {
|
||||
public MethodInvocation visitMethodInvocation(MethodInvocation methodInvocation, ExecutionContext p) {
|
||||
boolean visitChildren = true;
|
||||
|
||||
if (node != this.root) {
|
||||
IMethodBinding methodBinding = node.resolveMethodBinding();
|
||||
|
||||
if (methodInvocation != this.root) {
|
||||
Method method = methodInvocation.getMethodType();
|
||||
try {
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (method != null && method.getDeclaringType() != null && WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(method.getDeclaringType().getFullyQualifiedName())) {
|
||||
String name = method.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_HTTPMETHOD_METHODS.contains(name)) {
|
||||
Range range = doc.toRange(node.getStartPosition(), node.getLength());
|
||||
org.openrewrite.marker.Range r = ORAstUtils.getRange(methodInvocation);
|
||||
Range range = doc.toRange(r.getStart().getOffset(), r.length());
|
||||
methods.add(new WebfluxRouteElement(name, range));
|
||||
}
|
||||
else if (name != null && WebfluxUtils.REQUEST_PREDICATE_METHOD_METHOD.equals(name)) {
|
||||
QualifiedName qualifiedName = WebfluxUtils.extractQualifiedNameArgument(node);
|
||||
if (qualifiedName.getName() != null) {
|
||||
Range range = doc.toRange(qualifiedName.getStartPosition(), qualifiedName.getLength());
|
||||
FieldAccess qualifiedName = WebfluxUtils.extractArgument(methodInvocation, FieldAccess.class);
|
||||
if (qualifiedName != null) {
|
||||
org.openrewrite.marker.Range r = ORAstUtils.getRange(qualifiedName);
|
||||
Range range = doc.toRange(r.getStart().getOffset(), r.length());
|
||||
methods.add(new WebfluxRouteElement(qualifiedName.getName().toString(), range));
|
||||
}
|
||||
}
|
||||
@@ -68,11 +71,11 @@ public class WebfluxMethodFinder extends ASTVisitor {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (WebfluxUtils.isRouteMethodInvocation(methodBinding)) {
|
||||
if (WebfluxUtils.isRouteMethodInvocation(method)) {
|
||||
visitChildren = false;
|
||||
}
|
||||
}
|
||||
return visitChildren;
|
||||
return visitChildren ? super.visitMethodInvocation(methodInvocation, p) : methodInvocation;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* Copyright (c) 2018, 2022 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
|
||||
@@ -13,25 +13,27 @@ package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
import java.util.ArrayList;
|
||||
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.StringLiteral;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.java.JavaIsoVisitor;
|
||||
import org.openrewrite.java.tree.J;
|
||||
import org.openrewrite.java.tree.J.Literal;
|
||||
import org.openrewrite.java.tree.J.MethodInvocation;
|
||||
import org.openrewrite.java.tree.JavaType.Method;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ORAstUtils;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxPathFinder extends ASTVisitor {
|
||||
public class WebfluxPathFinder extends JavaIsoVisitor<ExecutionContext> {
|
||||
|
||||
private List<WebfluxRouteElement> path;
|
||||
private ASTNode root;
|
||||
private J root;
|
||||
private TextDocument doc;
|
||||
|
||||
public WebfluxPathFinder(ASTNode root, TextDocument doc) {
|
||||
public WebfluxPathFinder(J root, TextDocument doc) {
|
||||
this.root = root;
|
||||
this.doc = doc;
|
||||
this.path = new ArrayList<>();
|
||||
@@ -40,24 +42,25 @@ public class WebfluxPathFinder extends ASTVisitor {
|
||||
public List<WebfluxRouteElement> getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean visit(MethodInvocation node) {
|
||||
public MethodInvocation visitMethodInvocation(MethodInvocation methodInvocation, ExecutionContext p) {
|
||||
boolean visitChildren = true;
|
||||
|
||||
if (node != this.root) {
|
||||
IMethodBinding methodBinding = node.resolveMethodBinding();
|
||||
if (methodInvocation != this.root) {
|
||||
Method method = methodInvocation.getMethodType();
|
||||
|
||||
try {
|
||||
if (methodBinding != null && methodBinding.getDeclaringClass() != null
|
||||
&& WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
if (method != null && method.getDeclaringType() != null
|
||||
&& WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(method.getDeclaringType().getFullyQualifiedName())) {
|
||||
|
||||
String name = methodBinding.getName();
|
||||
String name = method.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_ALL_PATH_METHODS.contains(name)) {
|
||||
StringLiteral stringLiteral = WebfluxUtils.extractStringLiteralArgument(node);
|
||||
Literal stringLiteral = WebfluxUtils.extractArgument(methodInvocation, Literal.class);
|
||||
if (stringLiteral != null) {
|
||||
Range range = doc.toRange(stringLiteral.getStartPosition(), stringLiteral.getLength());
|
||||
path.add(new WebfluxRouteElement(stringLiteral.getLiteralValue(), range));
|
||||
org.openrewrite.marker.Range r = ORAstUtils.getRange(stringLiteral);
|
||||
Range range = doc.toRange(r.getStart().getOffset(), r.length());
|
||||
path.add(new WebfluxRouteElement(ORAstUtils.getLiteralValue(stringLiteral), range));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,12 +69,14 @@ public class WebfluxPathFinder extends ASTVisitor {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (WebfluxUtils.isRouteMethodInvocation(methodBinding)) {
|
||||
if (WebfluxUtils.isRouteMethodInvocation(method)) {
|
||||
visitChildren = false;
|
||||
}
|
||||
|
||||
}
|
||||
return visitChildren;
|
||||
|
||||
return visitChildren ? super.visitMethodInvocation(methodInvocation, p) : methodInvocation;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018, 2019 Pivotal, Inc.
|
||||
* Copyright (c) 2018, 2022 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
|
||||
@@ -15,25 +15,28 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
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.QualifiedName;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
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;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.InMemoryExecutionContext;
|
||||
import org.openrewrite.java.JavaIsoVisitor;
|
||||
import org.openrewrite.java.tree.Expression;
|
||||
import org.openrewrite.java.tree.J;
|
||||
import org.openrewrite.java.tree.J.Block;
|
||||
import org.openrewrite.java.tree.J.ClassDeclaration;
|
||||
import org.openrewrite.java.tree.J.FieldAccess;
|
||||
import org.openrewrite.java.tree.J.Literal;
|
||||
import org.openrewrite.java.tree.J.MethodDeclaration;
|
||||
import org.openrewrite.java.tree.J.MethodInvocation;
|
||||
import org.openrewrite.java.tree.JavaType;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified;
|
||||
import org.openrewrite.java.tree.JavaType.Method;
|
||||
import org.openrewrite.java.tree.TypeUtils;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.AbstractSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ORAstUtils;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJava.SCAN_PASS;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
@@ -46,15 +49,15 @@ public class WebfluxRouterSymbolProvider extends AbstractSymbolProvider {
|
||||
|
||||
@Override
|
||||
public void addSymbols(MethodDeclaration methodDeclaration, SpringIndexerJavaContext context, TextDocument doc) {
|
||||
Type returnType = methodDeclaration.getReturnType2();
|
||||
JavaType returnType = methodDeclaration.getMethodType().getReturnType();
|
||||
if (returnType != null) {
|
||||
|
||||
ITypeBinding resolvedBinding = returnType.resolveBinding();
|
||||
FullyQualified fqType = TypeUtils.asFullyQualified(returnType);
|
||||
|
||||
if (resolvedBinding != null && WebfluxUtils.ROUTER_FUNCTION_TYPE.equals(resolvedBinding.getBinaryName())) {
|
||||
if (fqType != null && WebfluxUtils.ROUTER_FUNCTION_TYPE.equals(fqType.getFullyQualifiedName())) {
|
||||
|
||||
Block methodBody = methodDeclaration.getBody();
|
||||
if (methodBody != null && methodBody.statements() != null && methodBody.statements().size() > 0) {
|
||||
if (methodBody != null && methodBody.getStatements() != null && methodBody.getStatements().size() > 0) {
|
||||
addSymbolsForRouterFunction(methodBody, context, doc);
|
||||
}
|
||||
else if (SCAN_PASS.ONE.equals(context.getPass())) {
|
||||
@@ -66,20 +69,15 @@ public class WebfluxRouterSymbolProvider extends AbstractSymbolProvider {
|
||||
}
|
||||
|
||||
private void addSymbolsForRouterFunction(Block methodBody, SpringIndexerJavaContext context, TextDocument doc) {
|
||||
methodBody.accept(new ASTVisitor() {
|
||||
|
||||
@Override
|
||||
public boolean visit(MethodInvocation node) {
|
||||
IMethodBinding methodBinding = node.resolveMethodBinding();
|
||||
|
||||
if (methodBinding != null && WebfluxUtils.isRouteMethodInvocation(methodBinding)) {
|
||||
extractMappingSymbol(node, doc, context);
|
||||
new JavaIsoVisitor<ExecutionContext>() {
|
||||
public MethodInvocation visitMethodInvocation(MethodInvocation method, ExecutionContext p) {
|
||||
Method m = method.getMethodType();
|
||||
if (m != null && WebfluxUtils.isRouteMethodInvocation(m)) {
|
||||
extractMappingSymbol(method, doc, context);
|
||||
}
|
||||
|
||||
return super.visit(node);
|
||||
return super.visitMethodInvocation(method, p);
|
||||
}
|
||||
|
||||
});
|
||||
}.visitNonNull(methodBody, new InMemoryExecutionContext());
|
||||
}
|
||||
|
||||
protected void extractMappingSymbol(MethodInvocation node, TextDocument doc, SpringIndexerJavaContext context) {
|
||||
@@ -88,8 +86,10 @@ public class WebfluxRouterSymbolProvider extends AbstractSymbolProvider {
|
||||
WebfluxRouteElement[] contentTypes = extractContentTypes(node, doc);
|
||||
WebfluxRouteElement[] acceptTypes = extractAcceptTypes(node, doc);
|
||||
|
||||
int methodNameStart = node.getName().getStartPosition();
|
||||
int invocationStart = node.getStartPosition();
|
||||
org.openrewrite.marker.Range methodInvocationRange = ORAstUtils.getRange(node);
|
||||
org.openrewrite.marker.Range methodNameRange = ORAstUtils.getRange(node.getName());
|
||||
int methodNameStart = methodInvocationRange.getStart().getOffset();
|
||||
int invocationStart = methodNameRange.getStart().getOffset();
|
||||
|
||||
StringBuilder pathBuilder = new StringBuilder();
|
||||
for (WebfluxRouteElement pathElement : pathElements) {
|
||||
@@ -101,7 +101,7 @@ public class WebfluxRouterSymbolProvider extends AbstractSymbolProvider {
|
||||
if (path.length() > 0) {
|
||||
try {
|
||||
|
||||
Location location = new Location(doc.getUri(), doc.toRange(methodNameStart, node.getLength() - (methodNameStart - invocationStart)));
|
||||
Location location = new Location(doc.getUri(), doc.toRange(methodNameStart, methodInvocationRange.length() - (methodNameStart - invocationStart)));
|
||||
WebfluxHandlerInformation handler = extractHandlerInformation(node, path, httpMethods, contentTypes, acceptTypes);
|
||||
WebfluxElementsInformation elements = extractElementsInformation(pathElements, httpMethods, contentTypes, acceptTypes);
|
||||
|
||||
@@ -136,24 +136,25 @@ public class WebfluxRouterSymbolProvider extends AbstractSymbolProvider {
|
||||
|
||||
private WebfluxRouteElement[] extractPath(MethodInvocation routerInvocation, TextDocument doc) {
|
||||
WebfluxPathFinder pathFinder = new WebfluxPathFinder(routerInvocation, doc);
|
||||
List<?> arguments = routerInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument != null && argument instanceof ASTNode) {
|
||||
((ASTNode)argument).accept(pathFinder);
|
||||
InMemoryExecutionContext ctx = new InMemoryExecutionContext();
|
||||
for (Expression argument : routerInvocation.getArguments()) {
|
||||
if (argument != null) {
|
||||
pathFinder.visitNonNull(argument, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
List<WebfluxRouteElement> path = pathFinder.getPath();
|
||||
|
||||
extractNestedValue(routerInvocation, path, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
Method method = methodInvocation.getMethodType();
|
||||
|
||||
try {
|
||||
if (methodBinding != null && WebfluxUtils.REQUEST_PREDICATE_PATH_METHOD.equals(methodBinding.getName())) {
|
||||
StringLiteral stringLiteral = WebfluxUtils.extractStringLiteralArgument(methodInvocation);
|
||||
if (method != null && WebfluxUtils.REQUEST_PREDICATE_PATH_METHOD.equals(method.getName())) {
|
||||
Literal stringLiteral = WebfluxUtils.extractArgument(methodInvocation, Literal.class);
|
||||
if (stringLiteral != null) {
|
||||
Range range = doc.toRange(stringLiteral.getStartPosition(), stringLiteral.getLength());
|
||||
return new WebfluxRouteElement(stringLiteral.getLiteralValue(), range);
|
||||
org.openrewrite.marker.Range r = ORAstUtils.getRange(stringLiteral);
|
||||
Range range = doc.toRange(r.getStart().getOffset(), r.length());
|
||||
return new WebfluxRouteElement(ORAstUtils.getLiteralValue(stringLiteral), range);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,23 +169,24 @@ public class WebfluxRouterSymbolProvider extends AbstractSymbolProvider {
|
||||
|
||||
private WebfluxRouteElement[] extractMethods(MethodInvocation routerInvocation, TextDocument doc) {
|
||||
WebfluxMethodFinder methodFinder = new WebfluxMethodFinder(routerInvocation, doc);
|
||||
List<?> arguments = routerInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument != null && argument instanceof ASTNode) {
|
||||
((ASTNode)argument).accept(methodFinder);
|
||||
InMemoryExecutionContext ctx = new InMemoryExecutionContext();
|
||||
for (Expression argument : routerInvocation.getArguments()) {
|
||||
if (argument != null) {
|
||||
methodFinder.visitNonNull(argument, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
final List<WebfluxRouteElement> methods = methodFinder.getMethods();
|
||||
|
||||
extractNestedValue(routerInvocation, methods, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
Method method = methodInvocation.getMethodType();
|
||||
|
||||
try {
|
||||
if (methodBinding != null && WebfluxUtils.REQUEST_PREDICATE_METHOD_METHOD.equals(methodBinding.getName())) {
|
||||
QualifiedName qualifiedName = WebfluxUtils.extractQualifiedNameArgument(methodInvocation);
|
||||
if (qualifiedName.getName() != null) {
|
||||
Range range = doc.toRange(qualifiedName.getStartPosition(), qualifiedName.getLength());
|
||||
if (method != null && WebfluxUtils.REQUEST_PREDICATE_METHOD_METHOD.equals(method.getName())) {
|
||||
FieldAccess qualifiedName = WebfluxUtils.extractArgument(methodInvocation, FieldAccess.class);
|
||||
if (qualifiedName != null) {
|
||||
org.openrewrite.marker.Range r = ORAstUtils.getRange(qualifiedName);
|
||||
Range range = doc.toRange(r.getStart().getOffset(), r.length());
|
||||
return new WebfluxRouteElement(qualifiedName.getName().toString(), range);
|
||||
}
|
||||
}
|
||||
@@ -201,24 +203,25 @@ public class WebfluxRouterSymbolProvider extends AbstractSymbolProvider {
|
||||
|
||||
private WebfluxRouteElement[] extractAcceptTypes(MethodInvocation routerInvocation, TextDocument doc) {
|
||||
WebfluxAcceptTypeFinder typeFinder = new WebfluxAcceptTypeFinder(doc);
|
||||
List<?> arguments = routerInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument != null && argument instanceof ASTNode) {
|
||||
((ASTNode)argument).accept(typeFinder);
|
||||
InMemoryExecutionContext ctx = new InMemoryExecutionContext();
|
||||
for (Expression argument : routerInvocation.getArguments()) {
|
||||
if (argument != null) {
|
||||
typeFinder.visitNonNull(argument, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
final List<WebfluxRouteElement> acceptTypes = typeFinder.getAcceptTypes();
|
||||
|
||||
extractNestedValue(routerInvocation, acceptTypes, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
Method methodBinding = methodInvocation.getMethodType();
|
||||
|
||||
try {
|
||||
if (methodBinding != null && WebfluxUtils.REQUEST_PREDICATE_ACCEPT_TYPE_METHOD.equals(methodBinding.getName())) {
|
||||
SimpleName nameArgument = WebfluxUtils.extractSimpleNameArgument(methodInvocation);
|
||||
if (nameArgument != null && nameArgument.getFullyQualifiedName() != null) {
|
||||
Range range = doc.toRange(nameArgument.getStartPosition(), nameArgument.getLength());
|
||||
return new WebfluxRouteElement(nameArgument.getFullyQualifiedName().toString(), range);
|
||||
FieldAccess nameArgument = WebfluxUtils.extractArgument(methodInvocation, FieldAccess.class);
|
||||
if (nameArgument != null) {
|
||||
org.openrewrite.marker.Range r = ORAstUtils.getRange(nameArgument);
|
||||
Range range = doc.toRange(r.getStart().getOffset(), r.length());
|
||||
return new WebfluxRouteElement(nameArgument.getSimpleName(), range);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -234,24 +237,27 @@ public class WebfluxRouterSymbolProvider extends AbstractSymbolProvider {
|
||||
|
||||
private WebfluxRouteElement[] extractContentTypes(MethodInvocation routerInvocation, TextDocument doc) {
|
||||
WebfluxContentTypeFinder contentTypeFinder = new WebfluxContentTypeFinder(doc);
|
||||
List<?> arguments = routerInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument != null && argument instanceof ASTNode) {
|
||||
((ASTNode)argument).accept(contentTypeFinder);
|
||||
InMemoryExecutionContext ctx = new InMemoryExecutionContext();
|
||||
for (Expression argument : routerInvocation.getArguments()) {
|
||||
if (argument != null) {
|
||||
contentTypeFinder.visitNonNull(argument, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
final List<WebfluxRouteElement> contentTypes = contentTypeFinder.getContentTypes();
|
||||
|
||||
extractNestedValue(routerInvocation, contentTypes, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
Method methodBinding = methodInvocation.getMethodType();
|
||||
|
||||
try {
|
||||
if (methodBinding != null && WebfluxUtils.REQUEST_PREDICATE_CONTENT_TYPE_METHOD.equals(methodBinding.getName())) {
|
||||
SimpleName nameArgument = WebfluxUtils.extractSimpleNameArgument(methodInvocation);
|
||||
if (nameArgument != null && nameArgument.getFullyQualifiedName() != null) {
|
||||
Range range = doc.toRange(nameArgument.getStartPosition(), nameArgument.getLength());
|
||||
return new WebfluxRouteElement(nameArgument.getFullyQualifiedName().toString(), range);
|
||||
// TODO: OR AST FieldAcess? So we need FQ name of something? See above a lot of similar places
|
||||
|
||||
FieldAccess nameArgument = WebfluxUtils.extractArgument(methodInvocation, FieldAccess.class);
|
||||
if (nameArgument != null) {
|
||||
org.openrewrite.marker.Range r = ORAstUtils.getRange(nameArgument);
|
||||
Range range = doc.toRange(r.getStart().getOffset(), r.length());
|
||||
return new WebfluxRouteElement(nameArgument.getSimpleName(), range);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,22 +271,21 @@ public class WebfluxRouterSymbolProvider extends AbstractSymbolProvider {
|
||||
return (WebfluxRouteElement[]) contentTypes.toArray(new WebfluxRouteElement[contentTypes.size()]);
|
||||
}
|
||||
|
||||
private void extractNestedValue(ASTNode node, Collection<WebfluxRouteElement> values, Function<MethodInvocation, WebfluxRouteElement> extractor) {
|
||||
if (node == null || node instanceof TypeDeclaration) {
|
||||
private void extractNestedValue(J node, Collection<WebfluxRouteElement> values, Function<MethodInvocation, WebfluxRouteElement> extractor) {
|
||||
if (node == null || node instanceof ClassDeclaration) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node instanceof MethodInvocation) {
|
||||
MethodInvocation methodInvocation = (MethodInvocation) node;
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
Method method = methodInvocation.getMethodType();
|
||||
|
||||
if (methodBinding != null && methodBinding.getDeclaringClass() != null
|
||||
&& WebfluxUtils.ROUTER_FUNCTIONS_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
if (method != null && method.getDeclaringType() != null
|
||||
&& WebfluxUtils.ROUTER_FUNCTIONS_TYPE.equals(method.getDeclaringType().getFullyQualifiedName())) {
|
||||
|
||||
String name = methodBinding.getName();
|
||||
String name = method.getName();
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_NEST_METHOD.equals(name)) {
|
||||
List<?> arguments = methodInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
for (Expression argument : methodInvocation.getArguments()) {
|
||||
if (argument instanceof MethodInvocation) {
|
||||
MethodInvocation nestedMethod = (MethodInvocation) argument;
|
||||
WebfluxRouteElement value = extractor.apply(nestedMethod);
|
||||
@@ -293,32 +298,30 @@ public class WebfluxRouterSymbolProvider extends AbstractSymbolProvider {
|
||||
}
|
||||
}
|
||||
|
||||
extractNestedValue(node.getParent(), values, extractor);
|
||||
extractNestedValue(ORAstUtils.getParent(node), values, extractor);
|
||||
}
|
||||
|
||||
private WebfluxHandlerInformation extractHandlerInformation(MethodInvocation node, String path, WebfluxRouteElement[] httpMethods,
|
||||
WebfluxRouteElement[] contentTypes, WebfluxRouteElement[] acceptTypes) {
|
||||
|
||||
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) {
|
||||
String handlerClass = methodBinding.getDeclaringClass().getBinaryName();
|
||||
if (handlerClass != null) handlerClass = handlerClass.trim();
|
||||
|
||||
String handlerMethod = methodBinding.getMethodDeclaration().toString();
|
||||
if (handlerMethod != null) handlerMethod = handlerMethod.trim();
|
||||
|
||||
return new WebfluxHandlerInformation(handlerClass, handlerMethod, path, getElementStrings(httpMethods), getElementStrings(contentTypes), getElementStrings(acceptTypes));
|
||||
}
|
||||
}
|
||||
for (Expression e : node.getArguments()) {
|
||||
// TODO: OR AST Method references!!!
|
||||
|
||||
// if (argument instanceof ExpressionMethodReference) {
|
||||
// ExpressionMethodReference methodReference = (ExpressionMethodReference) argument;
|
||||
// IMethodBinding methodBinding = methodReference.resolveMethodBinding();
|
||||
//
|
||||
// if (methodBinding != null && methodBinding.getDeclaringClass() != null && methodBinding.getMethodDeclaration() != null) {
|
||||
// String handlerClass = methodBinding.getDeclaringClass().getBinaryName();
|
||||
// if (handlerClass != null) handlerClass = handlerClass.trim();
|
||||
//
|
||||
// String handlerMethod = methodBinding.getMethodDeclaration().toString();
|
||||
// if (handlerMethod != null) handlerMethod = handlerMethod.trim();
|
||||
//
|
||||
// return new WebfluxHandlerInformation(handlerClass, handlerMethod, path, getElementStrings(httpMethods), getElementStrings(contentTypes), getElementStrings(acceptTypes));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,10 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.QualifiedName;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.openrewrite.java.tree.Expression;
|
||||
import org.openrewrite.java.tree.J.Literal;
|
||||
import org.openrewrite.java.tree.J.MethodInvocation;
|
||||
import org.openrewrite.java.tree.JavaType.Method;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
@@ -41,53 +40,30 @@ public class WebfluxUtils {
|
||||
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 StringLiteral extractStringLiteralArgument(MethodInvocation node) {
|
||||
List<?> arguments = node.arguments();
|
||||
if (arguments != null && arguments.size() > 0) {
|
||||
Object object = arguments.get(0);
|
||||
if (object instanceof StringLiteral) {
|
||||
return (StringLiteral) object;
|
||||
public static <T> T extractArgument(MethodInvocation node, Class<T> clazz) {
|
||||
if (node.getArguments() != null) {
|
||||
for (Expression e : node.getArguments()) {
|
||||
if (clazz.isInstance(e)) {
|
||||
return clazz.cast(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static QualifiedName extractQualifiedNameArgument(MethodInvocation node) {
|
||||
List<?> arguments = node.arguments();
|
||||
if (arguments != null && arguments.size() > 0) {
|
||||
Object object = arguments.get(0);
|
||||
if (object instanceof QualifiedName) {
|
||||
return (QualifiedName) object;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static SimpleName extractSimpleNameArgument(MethodInvocation node) {
|
||||
List<?> arguments = node.arguments();
|
||||
if (arguments != null && arguments.size() > 0) {
|
||||
Object object = arguments.get(0);
|
||||
if (object instanceof SimpleName) {
|
||||
return (SimpleName) object;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isRouteMethodInvocation(IMethodBinding methodBinding) {
|
||||
if (ROUTER_FUNCTIONS_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if ("route".equals(name)) {
|
||||
public static boolean isRouteMethodInvocation(Method method) {
|
||||
switch (method.getDeclaringType().getFullyQualifiedName()) {
|
||||
case ROUTER_FUNCTIONS_TYPE:
|
||||
if ("route".equals(method.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (ROUTER_FUNCTION_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if ("andRoute".equals(name)) {
|
||||
break;
|
||||
case ROUTER_FUNCTION_TYPE:
|
||||
if ("andRoute".equals(method.getName())) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* Copyright (c) 2018, 2022 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
|
||||
@@ -10,14 +10,14 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.utils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.Modifier;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.openrewrite.java.tree.J.ClassDeclaration;
|
||||
import org.openrewrite.java.tree.J.Modifier;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified;
|
||||
import org.openrewrite.java.tree.JavaType.FullyQualified.Kind;
|
||||
import org.springframework.ide.vscode.boot.java.beans.BeanUtils;
|
||||
import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
@@ -34,10 +34,10 @@ public class FunctionUtils {
|
||||
public static final String FUNCTION_CONSUMER_TYPE = Consumer.class.getName();
|
||||
public static final String FUNCTION_SUPPLIER_TYPE = Supplier.class.getName();
|
||||
|
||||
public static Tuple3<String, String, DocumentRegion> getFunctionBean(TypeDeclaration typeDeclaration, TextDocument doc) {
|
||||
ITypeBinding resolvedType = typeDeclaration.resolveBinding();
|
||||
public static Tuple3<String, String, DocumentRegion> getFunctionBean(ClassDeclaration typeDeclaration, TextDocument doc) {
|
||||
FullyQualified resolvedType = typeDeclaration.getType();
|
||||
|
||||
if (resolvedType != null && !resolvedType.isInterface() && !isAbstractClass(typeDeclaration, resolvedType)) {
|
||||
if (resolvedType != null && resolvedType.getKind() == Kind.Class && !isAbstractClass(typeDeclaration)) {
|
||||
return getFunctionBean(typeDeclaration, doc, resolvedType);
|
||||
}
|
||||
else {
|
||||
@@ -45,24 +45,16 @@ public class FunctionUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static Tuple3<String, String, DocumentRegion> getFunctionBean(TypeDeclaration typeDeclaration, TextDocument doc,
|
||||
ITypeBinding resolvedType) {
|
||||
|
||||
ITypeBinding[] interfaces = resolvedType.getInterfaces();
|
||||
for (ITypeBinding resolvedInterface : interfaces) {
|
||||
String simplifiedType = null;
|
||||
if (resolvedInterface.isParameterizedType()) {
|
||||
simplifiedType = resolvedInterface.getBinaryName();
|
||||
}
|
||||
else {
|
||||
simplifiedType = resolvedType.getQualifiedName();
|
||||
}
|
||||
private static Tuple3<String, String, DocumentRegion> getFunctionBean(ClassDeclaration typeDeclaration, TextDocument doc,
|
||||
FullyQualified resolvedType) {
|
||||
for (FullyQualified resolvedInterface : resolvedType.getInterfaces()) {
|
||||
String simplifiedType = resolvedInterface.getFullyQualifiedName();
|
||||
|
||||
if (FUNCTION_FUNCTION_TYPE.equals(simplifiedType) || FUNCTION_CONSUMER_TYPE.equals(simplifiedType)
|
||||
|| FUNCTION_SUPPLIER_TYPE.equals(simplifiedType)) {
|
||||
String beanName = getBeanName(typeDeclaration);
|
||||
String beanType = resolvedInterface.getName();
|
||||
DocumentRegion region = ASTUtils.nodeRegion(doc, typeDeclaration.getName());
|
||||
String beanType = resolvedInterface.toString();
|
||||
DocumentRegion region = ORAstUtils.nodeRegion(doc, typeDeclaration.getName());
|
||||
|
||||
return Tuples.of(beanName, beanType, region);
|
||||
}
|
||||
@@ -74,7 +66,7 @@ public class FunctionUtils {
|
||||
}
|
||||
}
|
||||
|
||||
ITypeBinding superclass = resolvedType.getSuperclass();
|
||||
FullyQualified superclass = resolvedType.getSupertype();
|
||||
if (superclass != null) {
|
||||
return getFunctionBean(typeDeclaration, doc, superclass);
|
||||
}
|
||||
@@ -83,22 +75,13 @@ public class FunctionUtils {
|
||||
}
|
||||
}
|
||||
|
||||
protected static String getBeanName(TypeDeclaration typeDeclaration) {
|
||||
String beanName = typeDeclaration.getName().toString();
|
||||
protected static String getBeanName(ClassDeclaration typeDeclaration) {
|
||||
String beanName = typeDeclaration.getSimpleName();
|
||||
return BeanUtils.getBeanNameFromType(beanName);
|
||||
}
|
||||
|
||||
protected static boolean isAbstractClass(TypeDeclaration typeDeclaration, ITypeBinding resolvedType) {
|
||||
List<?> modifiers = typeDeclaration.modifiers();
|
||||
for (Object object : modifiers) {
|
||||
if (object instanceof Modifier) {
|
||||
if (((Modifier) object).isAbstract()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
protected static boolean isAbstractClass(ClassDeclaration typeDeclaration) {
|
||||
return Modifier.hasModifier(typeDeclaration.getModifiers(), Modifier.Type.Abstract);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,14 +10,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ArrayInitializer;
|
||||
import org.eclipse.jdt.core.dom.IBinding;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.IVariableBinding;
|
||||
import org.eclipse.jdt.core.dom.Name;
|
||||
import org.eclipse.jdt.core.dom.QualifiedName;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.openrewrite.ExecutionContext;
|
||||
import org.openrewrite.InMemoryExecutionContext;
|
||||
import org.openrewrite.Parser;
|
||||
@@ -49,9 +41,12 @@ import org.openrewrite.marker.Range;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.commons.util.CollectorUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
public class ORAstUtils {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ORAstUtils.class);
|
||||
@@ -402,6 +397,21 @@ public class ORAstUtils {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<Literal> getExpressionValueAsListOfLiterals(Expression exp) {
|
||||
if (exp instanceof NewArray) {
|
||||
NewArray array = (NewArray) exp;
|
||||
return array.getInitializer().stream()
|
||||
.filter(Literal.class::isInstance)
|
||||
.map(Literal.class::cast)
|
||||
.collect(CollectorUtil.toImmutableList());
|
||||
} else if (exp instanceof Literal){
|
||||
return ImmutableList.of((Literal)exp);
|
||||
}
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String getExpressionValueAsString(Expression exp, Consumer<FullyQualified> dependencies) {
|
||||
// TODO: OR AST need to check if there is way to extract constant values from variables
|
||||
@@ -417,6 +427,17 @@ public class ORAstUtils {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static DocumentRegion stringRegion(TextDocument doc, Literal node) {
|
||||
DocumentRegion nodeRegion = nodeRegion(doc, node);
|
||||
if (nodeRegion.startsWith("\"")) {
|
||||
nodeRegion = nodeRegion.subSequence(1);
|
||||
}
|
||||
if (nodeRegion.endsWith("\"")) {
|
||||
nodeRegion = nodeRegion.subSequence(0, nodeRegion.getLength()-1);
|
||||
}
|
||||
return nodeRegion;
|
||||
}
|
||||
|
||||
public static List<CompilationUnit> parse(JavaParser parser, Iterable<Path> sourceFiles) {
|
||||
List<CompilationUnit> cus = parser.parse(sourceFiles, null, new InMemoryExecutionContext());
|
||||
|
||||
@@ -110,12 +110,12 @@ public class SpringIndexerJavaContext {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
public void addDependency(ITypeBinding dependsOn) {
|
||||
if (dependsOn != null && dependsOn.isFromSource()) {
|
||||
String type = dependsOn.getKey();
|
||||
public void addDependency(FullyQualified type) {
|
||||
if (type != null && false/*dependsOn.isFromSource()*/ ) { // TODO: OR AST can't tell if type has a source
|
||||
String fqName = type.getFullyQualifiedName();
|
||||
|
||||
if (type != null && !scannedTypes.contains(type)) {
|
||||
dependencies.add(type);
|
||||
dependencies.add(fqName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2022 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
|
||||
@@ -21,9 +21,9 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.openrewrite.java.tree.J.CompilationUnit;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.springframework.ide.vscode.boot.java.handlers.BootJavaReconcileEngine
|
||||
import org.springframework.ide.vscode.boot.java.links.SourceLinkFactory;
|
||||
import org.springframework.ide.vscode.boot.java.links.SourceLinks;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ORCompilationUnitCache;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SymbolCache;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SymbolCacheVoid;
|
||||
import org.springframework.ide.vscode.boot.metadata.ValueProviderRegistry;
|
||||
@@ -71,7 +72,7 @@ public class ValueSpelExpressionValidationTest {
|
||||
@Autowired private BootLanguageServerHarness harness;
|
||||
@Autowired private IJavaProject testProject;
|
||||
@Autowired private JavaProjectFinder projectFinder;
|
||||
@Autowired private CompilationUnitCache compilationUnitCache;
|
||||
@Autowired private ORCompilationUnitCache compilationUnitCache;
|
||||
@Autowired private SimpleLanguageServer server;
|
||||
|
||||
private File directory;
|
||||
|
||||
Reference in New Issue
Block a user