Skip to content

Commit 2608eaa

Browse files
committed
add location information to stereotype nodes
1 parent 2d816e0 commit 2608eaa

File tree

5 files changed

+81
-26
lines changed

5 files changed

+81
-26
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public Collection<StereotypeMethodElement> extractMethods(StereotypeClassElement
4545

4646
static class SimpleApplicationModulesStructureProvider extends ApplicationModulesStructureProvider implements SimpleStructureProvider<ApplicationModules, StereotypePackageElement, StereotypeClassElement, StereotypeMethodElement> {
4747

48-
SimpleApplicationModulesStructureProvider(IJavaProject project, SpringMetamodelIndex springIndex) {
48+
SimpleApplicationModulesStructureProvider(IJavaProject project, CachedSpringMetamodelIndex springIndex) {
4949
super(project, springIndex);
5050
}
5151

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

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.ide.vscode.boot.java.commands;
1818

19+
import java.net.URISyntaxException;
20+
import java.net.URL;
1921
import java.util.ArrayList;
2022
import java.util.Arrays;
2123
import java.util.Collections;
@@ -27,6 +29,8 @@
2729

2830
import org.eclipse.lsp4j.DocumentSymbol;
2931
import org.eclipse.lsp4j.Location;
32+
import org.eclipse.lsp4j.Position;
33+
import org.eclipse.lsp4j.Range;
3034
import org.jmolecules.stereotype.api.Stereotype;
3135
import org.jmolecules.stereotype.catalog.StereotypeCatalog;
3236
import org.jmolecules.stereotype.tooling.LabelProvider;
@@ -75,14 +79,38 @@ public JsonNodeHandler(LabelProvider<A, StereotypePackageElement, StereotypeClas
7579
@Override
7680
public void handleStereotype(Stereotype stereotype, NodeContext context) {
7781

78-
// var definition = catalog.getDefinition(stereotype);
79-
// var sources = definition.getSources();
80-
81-
addChild(node -> node
82-
.withAttribute(TEXT, labels.getStereotypeLabel(stereotype))
83-
.withAttribute(ICON, StereotypeIcons.getIcon(stereotype))
84-
.withAttribute(HOVER, "<stereotype catalog source coming soon...>")
85-
);
82+
if (stereotype.getIdentifier().equals("org.jmolecules.misc.Other")) {
83+
addChild(node -> node
84+
.withAttribute(TEXT, labels.getStereotypeLabel(stereotype))
85+
.withAttribute(ICON, StereotypeIcons.getIcon(stereotype))
86+
);
87+
} else {
88+
var definition = catalog.getDefinition(stereotype);
89+
var sources = definition.getSources();
90+
91+
Location location = null;
92+
for (Object source : sources) {
93+
if (source instanceof URL) {
94+
try {
95+
String uri = ((URL)source).toURI().toString();
96+
location = new Location(uri, new Range(new Position(0, 0), new Position(0, 0)));
97+
} catch (URISyntaxException e) {
98+
// ignore
99+
}
100+
}
101+
else if (source instanceof Location) {
102+
location = ((Location) source);
103+
}
104+
}
105+
106+
final Location finalLocation = location;
107+
addChild(node -> node
108+
.withAttribute(TEXT, labels.getStereotypeLabel(stereotype))
109+
.withAttribute(ICON, StereotypeIcons.getIcon(stereotype))
110+
.withAttribute(HOVER, "defined in: " + sources.toString())
111+
.withAttribute(LOCATION, finalLocation)
112+
);
113+
}
86114
}
87115

88116
@Override

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,9 @@ private void registerStereotype(StereotypeDefinitionElement element) {
136136
var stereotype = element.createStereotype();
137137
var type = element.getType();
138138
var assignment = element.getAssignment();
139-
140-
catalog.getOrRegister(stereotype, Assignment.of(type, assignment), type).getStereotype();
139+
var location = element.getLocation();
140+
141+
catalog.getOrRegister(stereotype, Assignment.of(type, assignment), location).getStereotype();
141142
}
142143

143144
}

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*******************************************************************************/
1111
package org.springframework.ide.vscode.boot.java.stereotypes;
1212

13+
import org.eclipse.lsp4j.Location;
1314
import org.jmolecules.stereotype.api.Stereotype;
1415
import org.jmolecules.stereotype.catalog.StereotypeDefinition.Assignment.Type;
1516
import org.jmolecules.stereotype.support.StringBasedStereotype;
@@ -23,12 +24,16 @@ public class StereotypeDefinitionElement extends AbstractSpringIndexElement {
2324
private final String[] groups;
2425
private final Type assignment;
2526

26-
public StereotypeDefinitionElement(String type, int priority, String displayName, String[] groups, Type assignment) {
27+
private final Location location;
28+
29+
public StereotypeDefinitionElement(String type, int priority, String displayName, String[] groups, Type assignment,
30+
Location location) {
2731
this.type = type;
2832
this.priority = priority;
2933
this.displayName = displayName;
3034
this.groups = groups;
3135
this.assignment = assignment;
36+
this.location = location;
3237
}
3338

3439
public String getType() {
@@ -39,6 +44,10 @@ public Type getAssignment() {
3944
return this.assignment;
4045
}
4146

47+
public Location getLocation() {
48+
return location;
49+
}
50+
4251
public Stereotype createStereotype() {
4352
var stereotype = StringBasedStereotype.of(type, priority);
4453

@@ -54,5 +63,5 @@ public Stereotype createStereotype() {
5463

5564
return stereotype;
5665
}
57-
66+
5867
}

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

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,30 @@ public class StereotypesIndexer implements SymbolProvider {
6262
public void addSymbols(Annotation node, ITypeBinding typeBinding, Collection<ITypeBinding> metaAnnotations, SpringIndexerJavaContext context, TextDocument doc) {
6363
ASTNode parent = node.getParent();
6464

65-
if (parent instanceof AnnotationTypeDeclaration) {
66-
AnnotationTypeDeclaration annotationType = (AnnotationTypeDeclaration) parent;
67-
ITypeBinding annotationBinding = annotationType.resolveBinding();
68-
69-
StereotypeDefinitionElement stereotypeDefinitionElement = createDefinitionElement(annotationBinding.getQualifiedName(), Type.IS_ANNOTATED, node, doc);
70-
context.getBeans().add(new CachedBean(context.getDocURI(), stereotypeDefinitionElement));
65+
try {
66+
if (parent instanceof AnnotationTypeDeclaration) {
67+
AnnotationTypeDeclaration annotationType = (AnnotationTypeDeclaration) parent;
68+
ITypeBinding annotationBinding = annotationType.resolveBinding();
69+
70+
StereotypeDefinitionElement stereotypeDefinitionElement = createDefinitionElement((AbstractTypeDeclaration) parent,
71+
annotationBinding.getQualifiedName(), Type.IS_ANNOTATED, node, doc);
72+
73+
context.getBeans().add(new CachedBean(context.getDocURI(), stereotypeDefinitionElement));
74+
}
75+
else if (parent instanceof TypeDeclaration && ((TypeDeclaration) parent).isInterface()) {
76+
ITypeBinding interfaceType = ((TypeDeclaration) parent).resolveBinding();
77+
78+
StereotypeDefinitionElement stereotypeDefinitionElement = createDefinitionElement((AbstractTypeDeclaration) parent,
79+
interfaceType.getQualifiedName(), Type.IMPLEMENTS, node, doc);
80+
81+
context.getBeans().add(new CachedBean(context.getDocURI(), stereotypeDefinitionElement));
82+
}
7183
}
72-
else if (parent instanceof TypeDeclaration && ((TypeDeclaration) parent).isInterface()) {
73-
ITypeBinding interfaceType = ((TypeDeclaration) parent).resolveBinding();
74-
75-
StereotypeDefinitionElement stereotypeDefinitionElement = createDefinitionElement(interfaceType.getQualifiedName(), Type.IMPLEMENTS, node, doc);
76-
context.getBeans().add(new CachedBean(context.getDocURI(), stereotypeDefinitionElement));
84+
catch (BadLocationException e) {
85+
log.error("error identifying location of type declaration for: " + parent.toString(), e);
86+
}
87+
catch (NullPointerException e) {
88+
log.error("error creating stereotype definition element for: " + parent.toString(), e);
7789
}
7890
}
7991

@@ -226,7 +238,9 @@ private Collection<IAnnotationBinding> getMetaAnnotations(AnnotationHierarchies
226238
return result;
227239
}
228240

229-
private StereotypeDefinitionElement createDefinitionElement(String id, StereotypeDefinition.Assignment.Type assignment, Annotation additionalDetails, TextDocument doc) {
241+
private StereotypeDefinitionElement createDefinitionElement(AbstractTypeDeclaration parent, String id, StereotypeDefinition.Assignment.Type assignment,
242+
Annotation additionalDetails, TextDocument doc) throws BadLocationException, NullPointerException {
243+
230244
int priority = Stereotype.DEFAULT_PRIORITY;
231245
Optional<Expression> attribute = ASTUtils.getAttribute(additionalDetails, "priority");
232246
if (attribute.isPresent()) {
@@ -245,8 +259,11 @@ private StereotypeDefinitionElement createDefinitionElement(String id, Stereotyp
245259
if (groupsAttribute.isPresent()) {
246260
groups = ASTUtils.getExpressionValueAsArray(groupsAttribute.get(), (a) -> {});
247261
}
262+
263+
SimpleName typeName = parent.getName();
264+
Location location = new Location(doc.getUri(), doc.toRange(typeName.getStartPosition(), typeName.getLength()));
248265

249-
return new StereotypeDefinitionElement(id, priority, displayName, groups, assignment);
266+
return new StereotypeDefinitionElement(id, priority, displayName, groups, assignment, location);
250267
}
251268

252269
}

0 commit comments

Comments
 (0)