Skip to content

Commit f96b32b

Browse files
committed
GH-1463: support for concatenated strings for more reference providers
1 parent 4d767eb commit f96b32b

File tree

5 files changed

+85
-30
lines changed

5 files changed

+85
-30
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,8 @@ protected ReferencesHandler createReferenceHandler(SimpleLanguageServer server,
323323
specificProviders.put(Annotations.VALUE, new ValuePropertyReferencesProvider(projectFinder, index));
324324
specificProviders.put(Annotations.CONDITIONAL_ON_PROPERTY, new ValuePropertyReferencesProvider(projectFinder, index));
325325
specificProviders.put(Annotations.QUALIFIER, new QualifierReferencesProvider(index));
326-
specificProviders.put(Annotations.NAMED_JAKARTA, new NamedReferencesProvider(index, symbolIndex));
327-
specificProviders.put(Annotations.NAMED_JAVAX, new NamedReferencesProvider(index, symbolIndex));
326+
specificProviders.put(Annotations.NAMED_JAKARTA, new NamedReferencesProvider(index));
327+
specificProviders.put(Annotations.NAMED_JAVAX, new NamedReferencesProvider(index));
328328
specificProviders.put(Annotations.PROFILE, new ProfileReferencesProvider(index));
329329

330330
List<ReferenceProvider> unspecificProviders = new ArrayList<>();

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

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616

1717
import org.eclipse.jdt.core.dom.ASTNode;
1818
import org.eclipse.jdt.core.dom.Annotation;
19+
import org.eclipse.jdt.core.dom.Expression;
1920
import org.eclipse.jdt.core.dom.ITypeBinding;
2021
import org.eclipse.jdt.core.dom.MemberValuePair;
21-
import org.eclipse.jdt.core.dom.StringLiteral;
2222
import org.eclipse.lsp4j.Location;
2323
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
24-
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
24+
import org.slf4j.Logger;
25+
import org.slf4j.LoggerFactory;
2526
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
2627
import org.springframework.ide.vscode.boot.java.Annotations;
2728
import org.springframework.ide.vscode.boot.java.handlers.ReferenceProvider;
@@ -35,12 +36,12 @@
3536
*/
3637
public class NamedReferencesProvider implements ReferenceProvider {
3738

39+
private static final Logger log = LoggerFactory.getLogger(NamedReferencesProvider.class);
40+
3841
private final SpringMetamodelIndex springIndex;
39-
private final SpringSymbolIndex symbolIndex;
4042

41-
public NamedReferencesProvider(SpringMetamodelIndex springIndex, SpringSymbolIndex symbolIndex) {
43+
public NamedReferencesProvider(SpringMetamodelIndex springIndex) {
4244
this.springIndex = springIndex;
43-
this.symbolIndex = symbolIndex;
4445
}
4546

4647
@Override
@@ -49,22 +50,22 @@ public List<? extends Location> provideReferences(CancelChecker cancelToken, IJa
4950
cancelToken.checkCanceled();
5051

5152
try {
53+
while (node != null && !(node.getParent() instanceof Annotation) && !(node.getParent() instanceof MemberValuePair)) {
54+
node = node.getParent();
55+
}
56+
5257
// case: @Value("prefix<*>")
53-
if (node instanceof StringLiteral && node.getParent() instanceof Annotation) {
54-
if (node.toString().startsWith("\"") && node.toString().endsWith("\"")) {
55-
return provideReferences(project, ASTUtils.getLiteralValue((StringLiteral) node));
56-
}
58+
if (node instanceof Expression expression && node.getParent() instanceof Annotation) {
59+
return provideReferences(project, ASTUtils.getExpressionValueAsString(expression, v -> {}));
5760
}
5861
// case: @Value(value="prefix<*>")
59-
else if (node instanceof StringLiteral && node.getParent() instanceof MemberValuePair
62+
else if (node instanceof Expression expression && node.getParent() instanceof MemberValuePair
6063
&& "value".equals(((MemberValuePair)node.getParent()).getName().toString())) {
61-
if (node.toString().startsWith("\"") && node.toString().endsWith("\"")) {
62-
return provideReferences(project, ASTUtils.getLiteralValue((StringLiteral) node));
63-
}
64+
return provideReferences(project, ASTUtils.getExpressionValueAsString(expression, v -> {}));
6465
}
6566
}
6667
catch (Exception e) {
67-
e.printStackTrace();
68+
log.error("error finding references for named annotatio value", e);
6869
}
6970

7071
return null;

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

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
import org.eclipse.jdt.core.dom.ASTNode;
1818
import org.eclipse.jdt.core.dom.Annotation;
1919
import org.eclipse.jdt.core.dom.ArrayInitializer;
20+
import org.eclipse.jdt.core.dom.Expression;
2021
import org.eclipse.jdt.core.dom.ITypeBinding;
2122
import org.eclipse.jdt.core.dom.MemberValuePair;
22-
import org.eclipse.jdt.core.dom.StringLiteral;
2323
import org.eclipse.lsp4j.Location;
2424
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
25+
import org.slf4j.Logger;
26+
import org.slf4j.LoggerFactory;
2527
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
2628
import org.springframework.ide.vscode.boot.java.Annotations;
2729
import org.springframework.ide.vscode.boot.java.handlers.ReferenceProvider;
@@ -35,6 +37,8 @@
3537
*/
3638
public class ProfileReferencesProvider implements ReferenceProvider {
3739

40+
private static final Logger log = LoggerFactory.getLogger(ProfileReferencesProvider.class);
41+
3842
private final SpringMetamodelIndex springIndex;
3943

4044
public ProfileReferencesProvider(SpringMetamodelIndex springIndex) {
@@ -47,28 +51,29 @@ public List<? extends Location> provideReferences(CancelChecker cancelToken, IJa
4751
cancelToken.checkCanceled();
4852

4953
try {
54+
while (node != null
55+
&& !(node.getParent() instanceof Annotation)
56+
&& !(node.getParent() instanceof MemberValuePair)
57+
&& !(node.getParent() instanceof ArrayInitializer)) {
58+
node = node.getParent();
59+
}
60+
5061
// case: @Value("prefix<*>")
51-
if (node instanceof StringLiteral && node.getParent() instanceof Annotation) {
52-
if (node.toString().startsWith("\"") && node.toString().endsWith("\"")) {
53-
return provideReferences(project, ASTUtils.getLiteralValue((StringLiteral) node));
54-
}
62+
if (node instanceof Expression expression && node.getParent() instanceof Annotation) {
63+
return provideReferences(project, ASTUtils.getExpressionValueAsString(expression, v -> {}));
5564
}
5665
// case: @Value(value="prefix<*>")
57-
else if (node instanceof StringLiteral && node.getParent() instanceof MemberValuePair
66+
else if (node instanceof Expression expression && node.getParent() instanceof MemberValuePair
5867
&& "value".equals(((MemberValuePair)node.getParent()).getName().toString())) {
59-
if (node.toString().startsWith("\"") && node.toString().endsWith("\"")) {
60-
return provideReferences(project, ASTUtils.getLiteralValue((StringLiteral) node));
61-
}
68+
return provideReferences(project, ASTUtils.getExpressionValueAsString(expression, v -> {}));
6269
}
6370
// case: @Qualifier({"prefix<*>"})
64-
else if (node instanceof StringLiteral && node.getParent() instanceof ArrayInitializer) {
65-
if (node.toString().startsWith("\"") && node.toString().endsWith("\"")) {
66-
return provideReferences(project, ASTUtils.getLiteralValue((StringLiteral) node));
67-
}
71+
else if (node instanceof Expression expression && node.getParent() instanceof ArrayInitializer) {
72+
return provideReferences(project, ASTUtils.getExpressionValueAsString(expression, v -> {}));
6873
}
6974
}
7075
catch (Exception e) {
71-
e.printStackTrace();
76+
log.error("error finding references for profile", e);
7277
}
7378

7479
return null;

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,24 @@ public class TestDependsOnClass {
120120
assertEquals(locationNamedAnnotation1, foundLocation);
121121
}
122122

123+
@Test
124+
public void testNamedRefersToNamedBeanWithConcatenatedString() throws Exception {
125+
Editor editor = harness.newEditor(LanguageId.JAVA, """
126+
package org.test;
127+
128+
import jakarta.inject.Named;
129+
130+
@Named("na" + "m<*>ed1")
131+
public class TestDependsOnClass {
132+
}""", tempJavaDocUri);
133+
134+
List<? extends Location> references = editor.getReferences();
135+
assertEquals(1, references.size());
136+
137+
Location foundLocation = references.get(0);
138+
assertEquals(locationNamedAnnotation1, foundLocation);
139+
}
140+
123141
@Test
124142
public void testNamedNotRefersToPureSpringBean() throws Exception {
125143
Editor editor = harness.newEditor(LanguageId.JAVA, """

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,37 @@ public class TestDependsOnClass {
9595
assertTrue(references.contains(expectedLocation2));
9696
}
9797

98+
@Test
99+
public void testProfileRefersToOtherProfilesWithConcatenatedString() throws Exception {
100+
String tempJavaDocUri = directory.toPath().resolve("src/main/java/org/test/TempClass.java").toUri().toString();
101+
102+
Editor editor = harness.newEditor(LanguageId.JAVA, """
103+
package org.test;
104+
105+
import org.springframework.stereotype.Component;
106+
import org.springframework.context.annotation.Profile;
107+
108+
@Component
109+
@Profile("pro" + "f<*>ile1")
110+
public class TestDependsOnClass {
111+
}""", tempJavaDocUri);
112+
113+
List<? extends Location> references = editor.getReferences();
114+
assertEquals(2, references.size());
115+
116+
String expectedDefinitionUri1 = directory.toPath().resolve("src/main/java/org/test/profiles/ProfilesClass1.java").toUri().toString();
117+
Location expectedLocation1 = new Location(expectedDefinitionUri1,
118+
new Range(new Position(6, 9), new Position(6, 19)));
119+
120+
assertTrue(references.contains(expectedLocation1));
121+
122+
String expectedDefinitionUri2 = directory.toPath().resolve("src/main/java/org/test/profiles/ProfilesClassWithArray.java").toUri().toString();
123+
Location expectedLocation2 = new Location(expectedDefinitionUri2,
124+
new Range(new Position(6, 18), new Position(6, 28)));
125+
126+
assertTrue(references.contains(expectedLocation2));
127+
}
128+
98129
@Test
99130
public void testProfileWithinArrayRefersToOtherProfiles() throws Exception {
100131
String tempJavaDocUri = directory.toPath().resolve("src/main/java/org/test/TempClass.java").toUri().toString();

0 commit comments

Comments
 (0)