adjusted handling of named annotation to not take beans without named annotatin into account
This commit is contained in:
@@ -39,9 +39,7 @@ public class NamedCompletionProvider implements AnnotationAttributeCompletionPro
|
||||
|
||||
Bean[] beans = this.springIndex.getBeansOfProject(project.getElementName());
|
||||
|
||||
return Stream.concat(
|
||||
findAllNamedValues(beans),
|
||||
Arrays.stream(beans).map(bean -> bean.getName()))
|
||||
return findAllNamedValues(beans)
|
||||
.distinct()
|
||||
.map(beanName -> new AnnotationAttributeProposal(beanName))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -14,12 +14,14 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.IAnnotationBinding;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.LocationLink;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
@@ -64,12 +66,18 @@ public class NamedDefinitionProvider implements IJavaDefinitionProvider {
|
||||
}
|
||||
|
||||
private List<LocationLink> findBeansWithName(IJavaProject project, String beanName) {
|
||||
Bean[] beans = this.springIndex.getBeansWithName(project.getElementName(), beanName);
|
||||
Bean[] beans = this.springIndex.getBeansOfProject(project.getElementName());
|
||||
|
||||
return Arrays.stream(beans)
|
||||
.map(bean -> {
|
||||
return new LocationLink(bean.getLocation().getUri(), bean.getLocation().getRange(), bean.getLocation().getRange());
|
||||
})
|
||||
Stream<Location> namedLocationFromBeans = Arrays.stream(beans)
|
||||
// annotations from beans themselves
|
||||
.flatMap(bean -> Arrays.stream(bean.getAnnotations()))
|
||||
.filter(annotation -> Annotations.NAMED_ANNOTATIONS.contains(annotation.getAnnotationType()))
|
||||
.filter(annotation -> annotation.getAttributes() != null && annotation.getAttributes().containsKey("value") && annotation.getAttributes().get("value").length == 1)
|
||||
.filter(annotation -> annotation.getAttributes().get("value")[0].getName().equals(beanName))
|
||||
.map(annotation -> annotation.getAttributes().get("value")[0].getLocation());
|
||||
|
||||
return namedLocationFromBeans
|
||||
.map(location -> new LocationLink(location.getUri(), location.getRange(), location.getRange()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@@ -71,11 +71,6 @@ public class NamedReferencesProvider implements ReferenceProvider {
|
||||
private List<? extends Location> provideReferences(IJavaProject project, String value) {
|
||||
Bean[] beans = this.springIndex.getBeansOfProject(project.getElementName());
|
||||
|
||||
// beans with name
|
||||
Stream<Location> beanLocations = Arrays.stream(beans)
|
||||
.filter(bean -> bean.getName().equals(value))
|
||||
.map(bean -> bean.getLocation());
|
||||
|
||||
Stream<Location> namedLocationFromBeans = Arrays.stream(beans)
|
||||
// annotations from beans themselves
|
||||
.flatMap(bean -> Arrays.stream(bean.getAnnotations()))
|
||||
@@ -95,7 +90,7 @@ public class NamedReferencesProvider implements ReferenceProvider {
|
||||
.filter(annotation -> annotation.getAttributes().get("value")[0].getName().equals(value))
|
||||
.map(annotation -> annotation.getAttributes().get("value")[0].getLocation());
|
||||
|
||||
return Stream.concat(beanLocations, Stream.concat(namedLocationFromBeans, namedLocationsFromInjectionPoints)).toList();
|
||||
return Stream.concat(namedLocationFromBeans, namedLocationsFromInjectionPoints).toList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -95,53 +95,53 @@ public class NamedCompletionProviderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQualifierCompletionWithoutQuotesWithoutPrefix() throws Exception {
|
||||
assertCompletions("@Named(<*>)", new String[] {"named1", "named2", "bean1", "bean2"}, 0, "@Named(\"named1\"<*>)");
|
||||
public void testNamedCompletionWithoutQuotesWithoutPrefix() throws Exception {
|
||||
assertCompletions("@Named(<*>)", new String[] {"named1", "named2"}, 0, "@Named(\"named1\"<*>)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQualifierCompletionWithoutQuotesWithPrefix() throws Exception {
|
||||
assertCompletions("@Named(be<*>)", 2, "@Named(\"bean1\"<*>)");
|
||||
public void testNamedCompletionWithoutQuotesWithPrefix() throws Exception {
|
||||
assertCompletions("@Named(be<*>)", 0, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQualifierCompletionWithoutQuotesWithPrefixFromExistingQualifier() throws Exception {
|
||||
public void testNamedCompletionWithoutQuotesWithPrefixFromExistingQualifier() throws Exception {
|
||||
assertCompletions("@Named(na<*>)", new String[] {"named1", "named2"}, 0, "@Named(\"named1\"<*>)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQualifierCompletionWithoutQuotesWithAttributeName() throws Exception {
|
||||
assertCompletions("@Named(value=<*>)", 4, "@Named(value=\"named1\"<*>)");
|
||||
public void testNamedCompletionWithoutQuotesWithAttributeName() throws Exception {
|
||||
assertCompletions("@Named(value=<*>)", 2, "@Named(value=\"named1\"<*>)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQualifierCompletionInsideOfQuotesWithoutPrefix() throws Exception {
|
||||
assertCompletions("@Named(\"<*>\")", 4, "@Named(\"named1<*>\")");
|
||||
public void testNamedCompletionInsideOfQuotesWithoutPrefix() throws Exception {
|
||||
assertCompletions("@Named(\"<*>\")", 2, "@Named(\"named1<*>\")");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQualifierCompletionInsideOfQuotesWithPrefix() throws Exception {
|
||||
assertCompletions("@Named(\"be<*>\")", 2, "@Named(\"bean1<*>\")");
|
||||
public void testNAmedCompletionInsideOfQuotesWithPrefix() throws Exception {
|
||||
assertCompletions("@Named(\"na<*>\")", 2, "@Named(\"named1<*>\")");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQualifierCompletionInsideOfQuotesWithPrefixButWithoutMatches() throws Exception {
|
||||
public void testNamedCompletionInsideOfQuotesWithPrefixButWithoutMatches() throws Exception {
|
||||
assertCompletions("@Named(\"XXX<*>\")", 0, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQualifierCompletionOutsideOfAnnotation1() throws Exception {
|
||||
public void testNamedCompletionOutsideOfAnnotation1() throws Exception {
|
||||
assertCompletions("@Named(\"XXX\")<*>", 0, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQualifierCompletionOutsideOfAnnotation2() throws Exception {
|
||||
public void testNamedCompletionOutsideOfAnnotation2() throws Exception {
|
||||
assertCompletions("@Named<*>(\"XXX\")", 0, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQualifierCompletionInsideOfQuotesWithPrefixAndReplacedPostfix() throws Exception {
|
||||
assertCompletions("@Named(\"be<*>xxx\")", 2, "@Named(\"bean1<*>\")");
|
||||
public void testNamedCompletionInsideOfQuotesWithPrefixAndReplacedPostfix() throws Exception {
|
||||
assertCompletions("@Named(\"na<*>xxx\")", 2, "@Named(\"named1<*>\")");
|
||||
}
|
||||
|
||||
private void assertCompletions(String completionLine, int noOfExpectedCompletions, String expectedCompletedLine) throws Exception {
|
||||
|
||||
@@ -10,10 +10,9 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.beans.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -33,6 +32,7 @@ import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf;
|
||||
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.AnnotationAttributeValue;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.AnnotationMetadata;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
@@ -62,6 +62,8 @@ public class NamedDefinitionProviderTest {
|
||||
private String tempJavaDocUri1;
|
||||
private String tempJavaDocUri2;
|
||||
private String tempJavaDocUri;
|
||||
private Location locationNamedAnnotation1;
|
||||
private Location locationNamedAnnotation2;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
@@ -79,8 +81,14 @@ public class NamedDefinitionProviderTest {
|
||||
tempJavaDocUri1 = directory.toPath().resolve("src/main/java/org/test/TempClass1.java").toUri().toString();
|
||||
tempJavaDocUri2 = directory.toPath().resolve("src/main/java/org/test/TempClass2.java").toUri().toString();
|
||||
|
||||
bean1 = new Bean("bean1", "type1", new Location(tempJavaDocUri1, new Range(new Position(1,1), new Position(1, 20))), null, null, new AnnotationMetadata[] {});
|
||||
bean2 = new Bean("bean2", "type2", new Location(tempJavaDocUri2, new Range(new Position(1,1), new Position(1, 20))), null, null, new AnnotationMetadata[] {});
|
||||
locationNamedAnnotation1 = new Location(tempJavaDocUri1, new Range(new Position(1, 10), new Position(1, 20)));
|
||||
locationNamedAnnotation2 = new Location(tempJavaDocUri2, new Range(new Position(2, 10), new Position(2, 20)));
|
||||
|
||||
AnnotationMetadata annotationBean1 = new AnnotationMetadata("jakarta.inject.Named", false, null, Map.of("value", new AnnotationAttributeValue[] {new AnnotationAttributeValue("named1", locationNamedAnnotation1)}));
|
||||
AnnotationMetadata annotationBean2 = new AnnotationMetadata("jakarta.inject.Named", false, null, Map.of("value", new AnnotationAttributeValue[] {new AnnotationAttributeValue("named2", locationNamedAnnotation2)}));
|
||||
|
||||
bean1 = new Bean("bean1", "type1", new Location(tempJavaDocUri1, new Range(new Position(1,1), new Position(1, 20))), null, null, new AnnotationMetadata[] {annotationBean1});
|
||||
bean2 = new Bean("bean2", "type2", new Location(tempJavaDocUri2, new Range(new Position(1,1), new Position(1, 20))), null, null, new AnnotationMetadata[] {annotationBean2});
|
||||
|
||||
springIndex.updateBeans(project.getElementName(), new Bean[] {bean1, bean2});
|
||||
}
|
||||
@@ -92,18 +100,15 @@ public class NamedDefinitionProviderTest {
|
||||
|
||||
import jakarta.inject.Named;
|
||||
|
||||
@Named("bean1")
|
||||
@Named("named1")
|
||||
public class TestDependsOnClass {
|
||||
}""", tempJavaDocUri);
|
||||
|
||||
Bean[] beans = springIndex.getBeansWithName(project.getElementName(), "bean1");
|
||||
assertEquals(1, beans.length);
|
||||
|
||||
LocationLink expectedLocation = new LocationLink(tempJavaDocUri1,
|
||||
beans[0].getLocation().getRange(), beans[0].getLocation().getRange(),
|
||||
LocationLink expectedLocation = new LocationLink(locationNamedAnnotation1.getUri(),
|
||||
locationNamedAnnotation1.getRange(), locationNamedAnnotation1.getRange(),
|
||||
null);
|
||||
|
||||
editor.assertLinkTargets("bean1", List.of(expectedLocation));
|
||||
editor.assertLinkTargets("named1", List.of(expectedLocation));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -117,19 +122,16 @@ public class NamedDefinitionProviderTest {
|
||||
@Component
|
||||
public class TestDependsOnClass {
|
||||
|
||||
public void setDependency(@Named("bean1") Object bean) {
|
||||
public void setDependency(@Named("named1") Object bean) {
|
||||
}
|
||||
|
||||
}""", tempJavaDocUri);
|
||||
|
||||
Bean[] beans = springIndex.getBeansWithName(project.getElementName(), "bean1");
|
||||
assertEquals(1, beans.length);
|
||||
|
||||
LocationLink expectedLocation = new LocationLink(tempJavaDocUri1,
|
||||
beans[0].getLocation().getRange(), beans[0].getLocation().getRange(),
|
||||
LocationLink expectedLocation = new LocationLink(locationNamedAnnotation1.getUri(),
|
||||
locationNamedAnnotation1.getRange(), locationNamedAnnotation1.getRange(),
|
||||
null);
|
||||
|
||||
editor.assertLinkTargets("bean1", List.of(expectedLocation));
|
||||
editor.assertLinkTargets("named1", List.of(expectedLocation));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -143,12 +145,12 @@ public class NamedDefinitionProviderTest {
|
||||
@Component
|
||||
public class TestDependsOnClass {
|
||||
|
||||
public void setDependency(@Named("XXX") Object bean1) {
|
||||
public void setDependency(@Named("bean1") Object bean1) {
|
||||
}
|
||||
|
||||
}""", tempJavaDocUri1);
|
||||
|
||||
editor.assertNoLinkTargets("XXX");
|
||||
editor.assertNoLinkTargets("bean1");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,14 +11,15 @@
|
||||
package org.springframework.ide.vscode.boot.java.beans.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
@@ -34,8 +35,10 @@ import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf;
|
||||
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.AnnotationAttributeValue;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.AnnotationMetadata;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.InjectionPoint;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.Editor;
|
||||
import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness;
|
||||
@@ -61,6 +64,11 @@ public class NamedReferencesProviderTest {
|
||||
|
||||
private String tempJavaDocUri1;
|
||||
private String tempJavaDocUri;
|
||||
private String tempJavaDocUri2;
|
||||
private Location locationNamedAnnotation1;
|
||||
private Location locationNamedAnnotation2;
|
||||
private Bean bean2;
|
||||
private Location point1NamedAnnotationLocation;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
@@ -74,17 +82,47 @@ public class NamedReferencesProviderTest {
|
||||
CompletableFuture<Void> initProject = indexer.waitOperation();
|
||||
initProject.get(5, TimeUnit.SECONDS);
|
||||
|
||||
tempJavaDocUri = directory.toPath().resolve("src/main/java/org/test/TestDependsOnClass.java").toUri().toString();
|
||||
tempJavaDocUri = directory.toPath().resolve("src/main/java/org/test/TestDependsOnClass.java").toUri().toString();
|
||||
tempJavaDocUri1 = directory.toPath().resolve("src/main/java/org/test/TempClass1.java").toUri().toString();
|
||||
tempJavaDocUri2 = directory.toPath().resolve("src/main/java/org/test/TempClass2.java").toUri().toString();
|
||||
|
||||
bean1 = new Bean("bean1", "type1", new Location(tempJavaDocUri1, new Range(new Position(1,1), new Position(1, 20))), null, null, new AnnotationMetadata[] {});
|
||||
locationNamedAnnotation1 = new Location(tempJavaDocUri1, new Range(new Position(1, 10), new Position(1, 20)));
|
||||
locationNamedAnnotation2 = new Location(tempJavaDocUri2, new Range(new Position(2, 10), new Position(2, 20)));
|
||||
|
||||
Bean[] beans = ArrayUtils.add(springIndex.getBeansOfProject(project.getElementName()), bean1);
|
||||
springIndex.updateBeans(project.getElementName(), beans);
|
||||
AnnotationMetadata annotationBean1 = new AnnotationMetadata("jakarta.inject.Named", false, null, Map.of("value", new AnnotationAttributeValue[] {new AnnotationAttributeValue("named1", locationNamedAnnotation1)}));
|
||||
AnnotationMetadata annotationBean2 = new AnnotationMetadata("jakarta.inject.Named", false, null, Map.of("value", new AnnotationAttributeValue[] {new AnnotationAttributeValue("named2", locationNamedAnnotation2)}));
|
||||
|
||||
point1NamedAnnotationLocation = new Location(tempJavaDocUri1, new Range(new Position(20, 10), new Position(20, 20)));
|
||||
AnnotationMetadata point1Metadata = new AnnotationMetadata("jakarta.inject.Named", false, null, Map.of("value", new AnnotationAttributeValue[] {new AnnotationAttributeValue("namedAtPoint1", point1NamedAnnotationLocation)}));
|
||||
|
||||
InjectionPoint point1 = new InjectionPoint("point1", "type1", null, new AnnotationMetadata[] {point1Metadata});
|
||||
|
||||
bean1 = new Bean("bean1", "type1", new Location(tempJavaDocUri1, new Range(new Position(1,1), new Position(1, 20))), new InjectionPoint[] {point1}, null, new AnnotationMetadata[] {annotationBean1});
|
||||
bean2 = new Bean("bean2", "type2", new Location(tempJavaDocUri2, new Range(new Position(1,1), new Position(1, 20))), null, null, new AnnotationMetadata[] {annotationBean2});
|
||||
|
||||
springIndex.updateBeans(project.getElementName(), new Bean[] {bean1, bean2});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNamedRefersToBean() throws Exception {
|
||||
public void testNamedRefersToNamedBean() throws Exception {
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA, """
|
||||
package org.test;
|
||||
|
||||
import jakarta.inject.Named;
|
||||
|
||||
@Named("na<*>med1")
|
||||
public class TestDependsOnClass {
|
||||
}""", tempJavaDocUri);
|
||||
|
||||
List<? extends Location> references = editor.getReferences();
|
||||
assertEquals(1, references.size());
|
||||
|
||||
Location foundLocation = references.get(0);
|
||||
assertEquals(locationNamedAnnotation1, foundLocation);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNamedNotRefersToPureSpringBean() throws Exception {
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA, """
|
||||
package org.test;
|
||||
|
||||
@@ -94,43 +132,26 @@ public class NamedReferencesProviderTest {
|
||||
public class TestDependsOnClass {
|
||||
}""", tempJavaDocUri);
|
||||
|
||||
Bean[] beans = springIndex.getBeansWithName(project.getElementName(), "bean1");
|
||||
assertEquals(1, beans.length);
|
||||
|
||||
Location expectedLocation = new Location(tempJavaDocUri1,
|
||||
beans[0].getLocation().getRange());
|
||||
|
||||
List<? extends Location> references = editor.getReferences();
|
||||
assertEquals(1, references.size());
|
||||
|
||||
Location foundLocation = references.get(0);
|
||||
assertEquals(expectedLocation, foundLocation);
|
||||
assertNull(references);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNamedRefersToOtherNamedValues() throws Exception {
|
||||
public void testNamedRefersToNamedInjectionPoints() throws Exception {
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA, """
|
||||
package org.test;
|
||||
|
||||
import jakarta.inject.Named;
|
||||
|
||||
@Named("specificFin<*>der")
|
||||
@Named("namedAt<*>Point1")
|
||||
public class TestDependsOnClass {
|
||||
}""", tempJavaDocUri);
|
||||
|
||||
String expectedDefinitionUri1 = directory.toPath().resolve("src/main/java/org/test/jakarta/SimpleMovieLister.java").toUri().toString();
|
||||
Location expectedLocation1 = new Location(expectedDefinitionUri1,
|
||||
new Range(new Position(27, 45), new Position(27, 61)));
|
||||
|
||||
String expectedDefinitionUri2 = directory.toPath().resolve("src/main/java/org/test/javax/SimpleMovieLister.java").toUri().toString();
|
||||
Location expectedLocation2 = new Location(expectedDefinitionUri2,
|
||||
new Range(new Position(27, 45), new Position(27, 61)));
|
||||
|
||||
List<? extends Location> references = editor.getReferences();
|
||||
assertEquals(2, references.size());
|
||||
assertEquals(1, references.size());
|
||||
|
||||
assertTrue(references.contains(expectedLocation1));
|
||||
assertTrue(references.contains(expectedLocation2));
|
||||
Location foundLocation = references.get(0);
|
||||
assertEquals(point1NamedAnnotationLocation, foundLocation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user