Skip to content

Commit ec4920d

Browse files
committed
support record types when indexing nodes for stereotypes
1 parent 81daf09 commit ec4920d

File tree

6 files changed

+78
-2
lines changed

6 files changed

+78
-2
lines changed

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/SymbolProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.eclipse.jdt.core.dom.ITypeBinding;
1717
import org.eclipse.jdt.core.dom.MethodDeclaration;
1818
import org.eclipse.jdt.core.dom.PackageDeclaration;
19+
import org.eclipse.jdt.core.dom.RecordDeclaration;
1920
import org.eclipse.jdt.core.dom.TypeDeclaration;
2021
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext;
2122
import org.springframework.ide.vscode.commons.util.text.TextDocument;
@@ -28,6 +29,7 @@ public interface SymbolProvider {
2829

2930
default void addSymbols(Annotation node, ITypeBinding typeBinding, Collection<ITypeBinding> metaAnnotations, SpringIndexerJavaContext context, TextDocument doc) {};
3031
default void addSymbols(TypeDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) {};
32+
default void addSymbols(RecordDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) {};
3133
default void addSymbols(MethodDeclaration methodDeclaration, SpringIndexerJavaContext context, TextDocument doc) {};
3234
default void addSymbols(PackageDeclaration packageDeclaration, SpringIndexerJavaContext context, TextDocument doc) {};
3335

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/stereotypes/StereotypesIndexer.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@
1919
import java.util.stream.Stream;
2020

2121
import org.eclipse.jdt.core.dom.ASTNode;
22+
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
2223
import org.eclipse.jdt.core.dom.Annotation;
2324
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
2425
import org.eclipse.jdt.core.dom.IAnnotationBinding;
2526
import org.eclipse.jdt.core.dom.IPackageBinding;
2627
import org.eclipse.jdt.core.dom.ITypeBinding;
2728
import org.eclipse.jdt.core.dom.MethodDeclaration;
2829
import org.eclipse.jdt.core.dom.PackageDeclaration;
30+
import org.eclipse.jdt.core.dom.RecordDeclaration;
2931
import org.eclipse.jdt.core.dom.SimpleName;
3032
import org.eclipse.jdt.core.dom.TypeDeclaration;
3133
import org.eclipse.lsp4j.Location;
@@ -74,6 +76,16 @@ public void addSymbols(MethodDeclaration methodDeclaration, SpringIndexerJavaCon
7476
// TODO
7577
}
7678

79+
@Override
80+
public void addSymbols(RecordDeclaration recordDeclaration, SpringIndexerJavaContext context, TextDocument doc) {
81+
try {
82+
createStereotypeElementForType(recordDeclaration, context, doc);
83+
}
84+
catch (BadLocationException e) {
85+
log.error("error identifying location of type declaration", e);
86+
}
87+
}
88+
7789
@Override
7890
public void addSymbols(PackageDeclaration packageDeclaration, SpringIndexerJavaContext context, TextDocument doc) {
7991
if (!context.getDocURI().endsWith("package-info.java")) {
@@ -108,14 +120,14 @@ public void addSymbols(TypeDeclaration typeDeclaration, SpringIndexerJavaContext
108120
}
109121
}
110122

111-
private void createStereotypeElementForType(TypeDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) throws BadLocationException {
123+
private void createStereotypeElementForType(AbstractTypeDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) throws BadLocationException {
112124
ITypeBinding typeBinding = typeDeclaration.resolveBinding();
113125
if (typeBinding == null) {
114126
return;
115127
}
116128

117129
// identify stereotype definitions themselves
118-
if (typeDeclaration.isInterface()) {
130+
if (typeDeclaration instanceof TypeDeclaration && ((TypeDeclaration) typeDeclaration).isInterface()) {
119131
Collection<Annotation> annotations = ASTUtils.getAnnotations(typeDeclaration);
120132
boolean isStereotypeAnnotated = annotations.stream()
121133
.anyMatch(annotation -> annotation.resolveTypeBinding().getQualifiedName().equals(Annotations.JMOLECULES_STEREOTYPE));

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJava.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.eclipse.jdt.core.dom.MethodDeclaration;
4848
import org.eclipse.jdt.core.dom.NormalAnnotation;
4949
import org.eclipse.jdt.core.dom.PackageDeclaration;
50+
import org.eclipse.jdt.core.dom.RecordDeclaration;
5051
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
5152
import org.eclipse.jdt.core.dom.TypeDeclaration;
5253
import org.eclipse.lsp4j.Diagnostic;
@@ -751,6 +752,22 @@ public boolean visit(TypeDeclaration node) {
751752
return super.visit(node);
752753
}
753754

755+
@Override
756+
public boolean visit(RecordDeclaration node) {
757+
try {
758+
context.addScannedType(node.resolveBinding());
759+
extractSymbolInformation(node, context);
760+
}
761+
catch (RequiredCompleteAstException e) {
762+
throw e;
763+
}
764+
catch (Exception e) {
765+
log.error("error extracting symbol information in project '" + context.getProject().getElementName() + "' - for docURI '" + context.getDocURI() + "' - on node: " + node.toString(), e);
766+
}
767+
768+
return super.visit(node);
769+
}
770+
754771
@Override
755772
public boolean visit(MethodDeclaration node) {
756773
try {
@@ -898,6 +915,16 @@ private void extractSymbolInformation(TypeDeclaration typeDeclaration, final Spr
898915
}
899916
}
900917

918+
private void extractSymbolInformation(RecordDeclaration typeDeclaration, final SpringIndexerJavaContext context) throws Exception {
919+
Collection<SymbolProvider> providers = symbolProviders.getAll();
920+
if (!providers.isEmpty()) {
921+
TextDocument doc = DocumentUtils.getTempTextDocument(context.getDocURI(), context.getDocRef(), context.getContent());
922+
for (SymbolProvider provider : providers) {
923+
provider.addSymbols(typeDeclaration, context, doc);
924+
}
925+
}
926+
}
927+
901928
private void extractSymbolInformation(MethodDeclaration methodDeclaration, final SpringIndexerJavaContext context) throws Exception {
902929
Collection<SymbolProvider> providers = symbolProviders.getAll();
903930
if (!providers.isEmpty()) {

headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/stereotypes/StereotypesIndexerTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,27 @@ void testInnerClassElements() throws Exception {
108108
assertTrue(list.contains("example.application.TypeWithInnerClass$InnerClass$InnerClassInInnerClass"));
109109
}
110110

111+
@Test
112+
void testInnerRecordElements() throws Exception {
113+
List<StereotypeClassElement> stereotypeNodes = springIndex.getNodesOfType(StereotypeClassElement.class);
114+
115+
List<String> list = stereotypeNodes.stream()
116+
.filter(node -> node.getType().startsWith("example.application.ClassWithInnerRecordImplementingInterface"))
117+
.map(node -> node.getType())
118+
.toList();
119+
120+
assertEquals(2, list.size());
121+
assertTrue(list.contains("example.application.ClassWithInnerRecordImplementingInterface"));
122+
assertTrue(list.contains("example.application.ClassWithInnerRecordImplementingInterface$InnerRecord"));
123+
124+
StereotypeClassElement recordElement = stereotypeNodes.stream()
125+
.filter(node -> node.getType().startsWith("example.application.ClassWithInnerRecordImplementingInterface$InnerRecord"))
126+
.findAny().get();
127+
128+
assertNotNull(recordElement);
129+
assertTrue(recordElement.doesImplement("example.application.RandomInterface"));
130+
}
131+
111132
@Test
112133
void testLocationInformationForTypeElement() throws Exception {
113134
String docUri = directory.toPath().resolve("src/main/java/example/application/SampleController.java").toUri().toString();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package example.application;
2+
3+
public class ClassWithInnerRecordImplementingInterface {
4+
5+
public record InnerRecord(String someProp) implements RandomInterface {
6+
7+
}
8+
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package example.application;
2+
3+
public interface RandomInterface {
4+
5+
}

0 commit comments

Comments
 (0)