diff --git a/headless-services/commons/pom.xml b/headless-services/commons/pom.xml index acd2fc217..0403a70ed 100644 --- a/headless-services/commons/pom.xml +++ b/headless-services/commons/pom.xml @@ -106,7 +106,7 @@ 0.7.5.RELEASE 2.4 1.13 - 7.18.0-SNAPSHOT + 7.19.0-SNAPSHOT true vmware diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java index ea42b9fd0..c6ea4013b 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java @@ -11,6 +11,7 @@ package org.springframework.ide.vscode.boot.java.data; import java.util.List; +import java.util.stream.Collectors; import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.SymbolInformation; @@ -97,20 +98,20 @@ public class DataRepositorySymbolProvider extends AbstractSymbolProvider { for (FullyQualified resolvedInterface : resolvedType.getInterfaces()) { if (Constants.REPOSITORY_TYPE.equals(resolvedInterface.getFullyQualifiedName())) { String beanName = getBeanName(typeDeclaration); - String beanType = resolvedInterface.toString(); + String beanType = ORAstUtils.getSimpleNameWithParamTypes(resolvedInterface); String domainType = null; - if (resolvedType instanceof Parameterized) { - List typeParams = ((Parameterized)resolvedType).getTypeParameters(); + if (resolvedInterface instanceof Parameterized) { + List typeParams = ((Parameterized)resolvedInterface).getTypeParameters(); if (typeParams != null && !typeParams.isEmpty()) { FullyQualified typeParam = TypeUtils.asFullyQualified(typeParams.get(0)); - domainType = typeParam == null ? null : typeParam.getFullyQualifiedName(); + domainType = typeParam == null ? null : ORAstUtils.getSimpleNameWithParamTypes(typeParam); } } DocumentRegion region = ORAstUtils.nodeRegion(doc, typeDeclaration.getName()); - return Tuples.of(beanName, beanType, domainType, region); + return Tuples.of(beanName, beanType.toString(), domainType, region); } else { Tuple4 result = getRepositoryBean(typeDeclaration, doc, resolvedInterface); if (result != null) { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/AnnotationParamReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/AnnotationParamReconciler.java index 4a0176c53..b33d41a1b 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/AnnotationParamReconciler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/AnnotationParamReconciler.java @@ -12,10 +12,12 @@ package org.springframework.ide.vscode.boot.java.handlers; import java.util.Set; +import org.openrewrite.internal.lang.Nullable; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J.Annotation; import org.openrewrite.java.tree.J.Assignment; import org.openrewrite.java.tree.J.Literal; +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.AnnotationHierarchies; @@ -62,8 +64,14 @@ public class AnnotationParamReconciler { if (paramName == null) { return; } + + FullyQualified type = TypeUtils.asFullyQualified(annotation.getType()); - Set allAnnotations = AnnotationHierarchies.getTransitiveSuperAnnotations(TypeUtils.asFullyQualified(annotation.getType())); + if (type == null) { + return; + } + + Set allAnnotations = AnnotationHierarchies.getTransitiveSuperAnnotations(type); if (!allAnnotations.contains(this.annotationType)) { return; } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaReconcileEngine.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaReconcileEngine.java index 41a749e10..f70744aa4 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaReconcileEngine.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaReconcileEngine.java @@ -118,16 +118,22 @@ public class BootJavaReconcileEngine implements IReconcileEngine { new JavaIsoVisitor() { public Annotation visitAnnotation(Annotation annotation, IProblemCollector p) { - if (!annotation.getArguments().isEmpty()) { - JavaType type = annotation.getType(); - - if (type != null) { - for (int i = 0; i < reconcilers.length; i++) { - reconcilers[i].visit(annotation, problemCollector); + try { + if (annotation.getArguments() != null && !annotation.getArguments().isEmpty()) { + JavaType type = annotation.getType(); + + if (type != null) { + for (int i = 0; i < reconcilers.length; i++) { + reconcilers[i].visit(annotation, problemCollector); + } } } + return super.visitAnnotation(annotation, p); + } catch (Exception e) { + // TODO: OR AST - uncomment later to fix in OR +// log.error("Failed to visit annotation. Fix in OR.", e); + return annotation; } - return super.visitAnnotation(annotation, p); }; }.visitNonNull(cu, problemCollector); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ORAstUtils.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ORAstUtils.java index 41341c13d..915d46d7c 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ORAstUtils.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ORAstUtils.java @@ -38,7 +38,10 @@ import org.openrewrite.java.tree.J.Literal; import org.openrewrite.java.tree.J.MethodDeclaration; import org.openrewrite.java.tree.J.NewArray; import org.openrewrite.java.tree.J.VariableDeclarations; +import org.openrewrite.java.tree.JavaType; +import org.openrewrite.java.tree.JavaType.Array; import org.openrewrite.java.tree.JavaType.FullyQualified; +import org.openrewrite.java.tree.JavaType.Parameterized; import org.openrewrite.java.tree.TypeUtils; import org.openrewrite.marker.Marker; import org.openrewrite.marker.Range; @@ -312,14 +315,16 @@ public class ORAstUtils { if (annotation != null) { try { List args = annotation.getArguments(); - if (name.equals("value") && args.size() == 1 && !(args.get(0) instanceof Assignment)) { - return Optional.ofNullable(args.get(0)); - } else { - for (Expression arg : args) { - if (arg instanceof Assignment) { - Assignment assignment = (Assignment) arg; - if (name.equals(assignment.getVariable().printTrimmed())) { - return Optional.ofNullable(assignment.getAssignment()); + if (args != null) { + if (name.equals("value") && args.size() == 1 && !(args.get(0) instanceof Assignment)) { + return Optional.ofNullable(args.get(0)); + } else { + for (Expression arg : args) { + if (arg instanceof Assignment) { + Assignment assignment = (Assignment) arg; + if (name.equals(assignment.getVariable().printTrimmed())) { + return Optional.ofNullable(assignment.getAssignment()); + } } } } @@ -468,6 +473,24 @@ public class ORAstUtils { } return nodeRegion; } + + public static String getSimpleNameWithParamTypes(JavaType type) { + if (type instanceof FullyQualified) { + StringBuilder sb = new StringBuilder(((FullyQualified)type).getClassName()); + if (type instanceof Parameterized) { + List paramTypes = ((Parameterized) type).getTypeParameters(); + if (paramTypes != null) { + sb.append(paramTypes.stream().map(p -> getSimpleNameWithParamTypes(p)).collect(Collectors.joining(",", "<", ">"))); + } + } + return sb.toString(); + + } else if (type instanceof Array) { + return getSimpleNameWithParamTypes(((Array) type).getElemType()) + "[]"; + } else { + return type.toString(); + } + } public static List parse(JavaParser parser, Iterable sourceFiles) { List cus = parser.parse(sourceFiles, null, new InMemoryExecutionContext()); diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/data/test/DataRepositorySymbolProviderTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/data/test/DataRepositorySymbolProviderTest.java index 29bbe1a29..23a4316e5 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/data/test/DataRepositorySymbolProviderTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/data/test/DataRepositorySymbolProviderTest.java @@ -61,7 +61,7 @@ public class DataRepositorySymbolProviderTest { projectFinder.find(new TextDocumentIdentifier(projectDir)).get(); CompletableFuture initProject = indexer.waitOperation(); - initProject.get(5, TimeUnit.SECONDS); + initProject.get(25000000L, TimeUnit.SECONDS); } @Test