GH-1348: find references from listeners to publishers and vice versa now works
Fixes GH-1348
This commit is contained in:
@@ -14,6 +14,7 @@ import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@@ -33,6 +34,7 @@ import org.springframework.ide.vscode.boot.java.beans.QualifierReferencesProvide
|
||||
import org.springframework.ide.vscode.boot.java.conditionals.ConditionalsLiveHoverProvider;
|
||||
import org.springframework.ide.vscode.boot.java.copilot.CopilotAgentCommandHandler;
|
||||
import org.springframework.ide.vscode.boot.java.copilot.util.ResponseModifier;
|
||||
import org.springframework.ide.vscode.boot.java.events.EventReferenceProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.BootJavaCodeActionProvider;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.BootJavaCodeLensEngine;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.BootJavaDocumentHighlightEngine;
|
||||
@@ -316,16 +318,19 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
|
||||
protected ReferencesHandler createReferenceHandler(SimpleLanguageServer server, JavaProjectFinder projectFinder,
|
||||
SpringMetamodelIndex index, SpringSymbolIndex symbolIndex, CompilationUnitCache cuCache) {
|
||||
|
||||
Map<String, ReferenceProvider> providers = new HashMap<>();
|
||||
Map<String, ReferenceProvider> specificProviders = new HashMap<>();
|
||||
|
||||
providers.put(Annotations.VALUE, new ValuePropertyReferencesProvider(projectFinder, index));
|
||||
providers.put(Annotations.CONDITIONAL_ON_PROPERTY, new ValuePropertyReferencesProvider(projectFinder, index));
|
||||
providers.put(Annotations.QUALIFIER, new QualifierReferencesProvider(index));
|
||||
providers.put(Annotations.NAMED_JAKARTA, new NamedReferencesProvider(index, symbolIndex));
|
||||
providers.put(Annotations.NAMED_JAVAX, new NamedReferencesProvider(index, symbolIndex));
|
||||
providers.put(Annotations.PROFILE, new ProfileReferencesProvider(index));
|
||||
specificProviders.put(Annotations.VALUE, new ValuePropertyReferencesProvider(projectFinder, index));
|
||||
specificProviders.put(Annotations.CONDITIONAL_ON_PROPERTY, new ValuePropertyReferencesProvider(projectFinder, index));
|
||||
specificProviders.put(Annotations.QUALIFIER, new QualifierReferencesProvider(index));
|
||||
specificProviders.put(Annotations.NAMED_JAKARTA, new NamedReferencesProvider(index, symbolIndex));
|
||||
specificProviders.put(Annotations.NAMED_JAVAX, new NamedReferencesProvider(index, symbolIndex));
|
||||
specificProviders.put(Annotations.PROFILE, new ProfileReferencesProvider(index));
|
||||
|
||||
List<ReferenceProvider> unspecificProviders = new ArrayList<>();
|
||||
unspecificProviders.add(new EventReferenceProvider(index));
|
||||
|
||||
return new BootJavaReferencesHandler(this, cuCache, projectFinder, providers);
|
||||
return new BootJavaReferencesHandler(this, cuCache, projectFinder, specificProviders, unspecificProviders);
|
||||
}
|
||||
|
||||
protected BootJavaCodeLensEngine createCodeLensEngine(SpringMetamodelIndex springIndex, JavaProjectFinder projectFinder, SimpleLanguageServer server, SpelSemanticTokens spelSemanticTokens) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2024 Broadcom
|
||||
* Copyright (c) 2024, 2025 Broadcom
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -28,6 +28,7 @@ import org.springframework.ide.vscode.boot.java.handlers.ReferenceProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
@@ -69,6 +70,11 @@ public class NamedReferencesProvider implements ReferenceProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Location> provideReferences(CancelChecker cancelToken, IJavaProject project, TextDocument doc, ASTNode node, int offset) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<? extends Location> provideReferences(IJavaProject project, String value) {
|
||||
Bean[] beans = this.springIndex.getBeansOfProject(project.getElementName());
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2024 Broadcom
|
||||
* Copyright (c) 2024, 2025 Broadcom
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -28,6 +28,7 @@ import org.springframework.ide.vscode.boot.java.handlers.ReferenceProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
@@ -73,6 +74,11 @@ public class ProfileReferencesProvider implements ReferenceProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Location> provideReferences(CancelChecker cancelToken, IJavaProject project, TextDocument doc, ASTNode node, int offset) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<? extends Location> provideReferences(IJavaProject project, String value) {
|
||||
Bean[] beans = this.springIndex.getBeans();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2024 Broadcom
|
||||
* Copyright (c) 2024, 2025 Broadcom
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -27,6 +27,7 @@ import org.springframework.ide.vscode.boot.java.handlers.ReferenceProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
@@ -66,6 +67,11 @@ public class QualifierReferencesProvider implements ReferenceProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Location> provideReferences(CancelChecker cancelToken, IJavaProject project, TextDocument doc, ASTNode node, int offset) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<? extends Location> provideReferences(IJavaProject project, String value) {
|
||||
Bean[] beans = this.springIndex.getBeans();
|
||||
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2025 Broadcom
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.events;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.ReferenceProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class EventReferenceProvider implements ReferenceProvider {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(EventReferenceProvider.class);
|
||||
|
||||
private final SpringMetamodelIndex index;
|
||||
|
||||
public EventReferenceProvider(SpringMetamodelIndex index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Location> provideReferences(CancelChecker cancelToken, IJavaProject project, ASTNode node,
|
||||
Annotation annotation, ITypeBinding type, int offset) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Location> provideReferences(CancelChecker cancelToken, IJavaProject project, TextDocument doc, ASTNode node, int offset) {
|
||||
try {
|
||||
Position position = doc.toPosition(offset);
|
||||
|
||||
Bean[] beans = index.getBeans();
|
||||
|
||||
// when offset is inside an event listener, find the respective event type
|
||||
Optional<String> listenerEventType = Arrays.stream(beans)
|
||||
.filter(bean -> bean.getLocation().getUri().equals(doc.getUri()))
|
||||
.flatMap(bean -> bean.getChildren().stream())
|
||||
.filter(element -> element instanceof EventListenerIndexElement)
|
||||
.map(element -> (EventListenerIndexElement) element)
|
||||
.filter(eventListener -> isPositionInside(position, eventListener.getLocation()))
|
||||
.map(eventListener -> eventListener.getEventType())
|
||||
.findAny();
|
||||
|
||||
if (listenerEventType.isPresent()) {
|
||||
// use the listener event type to look for publishers for that type
|
||||
String eventType = listenerEventType.get();
|
||||
|
||||
List<Location> foundLocations = Arrays.stream(beans)
|
||||
.flatMap(bean -> bean.getChildren().stream())
|
||||
.filter(element -> element instanceof EventPublisherIndexElement)
|
||||
.map(element -> (EventPublisherIndexElement) element)
|
||||
.filter(publisher -> publisher.getEventType().equals(eventType))
|
||||
.map(publisher -> publisher.getLocation())
|
||||
.toList();
|
||||
|
||||
if (foundLocations.size() > 0) {
|
||||
return foundLocations;
|
||||
}
|
||||
}
|
||||
|
||||
// when offset is inside an event publisher, find the respective event type
|
||||
else {
|
||||
Optional<String> publisherEventType = Arrays.stream(beans)
|
||||
.filter(bean -> bean.getLocation().getUri().equals(doc.getUri()))
|
||||
.flatMap(bean -> bean.getChildren().stream())
|
||||
.filter(element -> element instanceof EventPublisherIndexElement)
|
||||
.map(element -> (EventPublisherIndexElement) element)
|
||||
.filter(eventListener -> isPositionInside(position, eventListener.getLocation()))
|
||||
.map(eventListener -> eventListener.getEventType())
|
||||
.findAny();
|
||||
|
||||
if (publisherEventType.isPresent()) {
|
||||
// use the listener event type to look for publishers for that type
|
||||
String eventType = publisherEventType.get();
|
||||
|
||||
List<Location> foundLocations = Arrays.stream(beans)
|
||||
.flatMap(bean -> bean.getChildren().stream())
|
||||
.filter(element -> element instanceof EventListenerIndexElement)
|
||||
.map(element -> (EventListenerIndexElement) element)
|
||||
.filter(listener -> listener.getEventType().equals(eventType))
|
||||
.map(listener-> listener.getLocation())
|
||||
.toList();
|
||||
|
||||
if (foundLocations.size() > 0) {
|
||||
return foundLocations;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
log.error("", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isPositionInside(Position position, Location location) {
|
||||
boolean afterStart = position.getLine() > location.getRange().getStart().getLine()
|
||||
|| (position.getLine() == location.getRange().getStart().getLine() && position.getCharacter() >= location.getRange().getStart().getCharacter());
|
||||
|
||||
boolean beforeEnd = position.getLine() < location.getRange().getEnd().getLine()
|
||||
|| (position.getLine() == location.getRange().getEnd().getLine() && position.getCharacter() <= location.getRange().getEnd().getCharacter());
|
||||
|
||||
return afterStart && beforeEnd;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2024 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2025 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -11,6 +11,8 @@
|
||||
package org.springframework.ide.vscode.boot.java.handlers;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -22,7 +24,6 @@ import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.NodeFinder;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.ReferenceParams;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
|
||||
@@ -39,14 +40,17 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
|
||||
private final JavaProjectFinder projectFinder;
|
||||
private final BootJavaLanguageServerComponents server;
|
||||
private final Map<String, ReferenceProvider> referenceProviders;
|
||||
private final Map<String, ReferenceProvider> annotationSpecificReferenceProviders;
|
||||
private final List<ReferenceProvider> unspecificProviders;
|
||||
private final CompilationUnitCache cuCache;
|
||||
|
||||
public BootJavaReferencesHandler(BootJavaLanguageServerComponents server, CompilationUnitCache cuCache, JavaProjectFinder projectFinder, Map<String, ReferenceProvider> specificProviders) {
|
||||
public BootJavaReferencesHandler(BootJavaLanguageServerComponents server, CompilationUnitCache cuCache, JavaProjectFinder projectFinder,
|
||||
Map<String, ReferenceProvider> specificProviders, List<ReferenceProvider> unspecificProviders) {
|
||||
this.server = server;
|
||||
this.cuCache = cuCache;
|
||||
this.projectFinder = projectFinder;
|
||||
this.referenceProviders = specificProviders;
|
||||
this.annotationSpecificReferenceProviders = specificProviders;
|
||||
this.unspecificProviders = unspecificProviders;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,7 +66,7 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
|
||||
cancelToken.checkCanceled();
|
||||
|
||||
List<? extends Location> referencesResult = provideReferences(cancelToken, doc.getId(), offset);
|
||||
List<? extends Location> referencesResult = provideReferences(cancelToken, doc, offset);
|
||||
if (referencesResult != null) {
|
||||
return referencesResult;
|
||||
}
|
||||
@@ -78,20 +82,32 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
return SimpleTextDocumentService.NO_REFERENCES;
|
||||
}
|
||||
|
||||
private List<? extends Location> provideReferences(CancelChecker cancelToken, TextDocumentIdentifier docID, int offset) throws Exception {
|
||||
Optional<IJavaProject> projectOptional = projectFinder.find(docID);
|
||||
private List<? extends Location> provideReferences(CancelChecker cancelToken, TextDocument doc, int offset) throws Exception {
|
||||
Optional<IJavaProject> projectOptional = projectFinder.find(doc.getId());
|
||||
|
||||
if (projectOptional.isPresent()) {
|
||||
IJavaProject project = projectOptional.get();
|
||||
|
||||
URI docUri = URI.create(docID.getUri());
|
||||
URI docUri = URI.create(doc.getUri());
|
||||
|
||||
return cuCache.withCompilationUnit(project, docUri, cu -> {
|
||||
cancelToken.checkCanceled();
|
||||
|
||||
ASTNode node = NodeFinder.perform(cu, offset, 0);
|
||||
if (node != null) {
|
||||
return provideReferencesForAnnotation(cancelToken, project, node, offset);
|
||||
List<Location> result = new ArrayList<>();
|
||||
|
||||
List<? extends Location> referencesForAnnotation = provideReferencesForAnnotation(cancelToken, project, node, offset);
|
||||
if (referencesForAnnotation != null) {
|
||||
result.addAll(referencesForAnnotation);
|
||||
}
|
||||
|
||||
List<? extends Location> otherReferences = provideUnspecificReferences(cancelToken, project, doc, node, offset);
|
||||
if (otherReferences != null) {
|
||||
result.addAll(otherReferences);
|
||||
}
|
||||
|
||||
return result.size() > 0 ? result : null;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
@@ -102,6 +118,21 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<? extends Location> provideUnspecificReferences(CancelChecker cancelToken, IJavaProject project, TextDocument doc, ASTNode node, int offset) {
|
||||
List<Location> result = new ArrayList<>();
|
||||
|
||||
for (Iterator<ReferenceProvider> iterator = unspecificProviders.iterator(); iterator.hasNext();) {
|
||||
ReferenceProvider referenceProvider = iterator.next();
|
||||
|
||||
List<? extends Location> references = referenceProvider.provideReferences(cancelToken, project, doc, node, offset);
|
||||
if (references != null) {
|
||||
result.addAll(references);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<? extends Location> provideReferencesForAnnotation(CancelChecker cancelToken, IJavaProject project, ASTNode node, int offset) {
|
||||
Annotation annotation = null;
|
||||
|
||||
@@ -119,7 +150,7 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
String qualifiedName = type.getQualifiedName();
|
||||
|
||||
if (qualifiedName != null) {
|
||||
ReferenceProvider provider = this.referenceProviders.get(qualifiedName);
|
||||
ReferenceProvider provider = this.annotationSpecificReferenceProviders.get(qualifiedName);
|
||||
|
||||
if (provider != null) {
|
||||
return provider.provideReferences(cancelToken, project, node, annotation, type, offset);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2024 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2025 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -18,13 +18,14 @@ import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public interface ReferenceProvider {
|
||||
|
||||
List<? extends Location> provideReferences(CancelChecker cancelToken, IJavaProject project, ASTNode node, Annotation annotation,
|
||||
ITypeBinding type, int offset);
|
||||
List<? extends Location> provideReferences(CancelChecker cancelToken, IJavaProject project, ASTNode node, Annotation annotation, ITypeBinding type, int offset);
|
||||
List<? extends Location> provideReferences(CancelChecker cancelToken, IJavaProject project, TextDocument doc, ASTNode node, int offset);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2024 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2025 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -101,6 +101,11 @@ public class ValuePropertyReferencesProvider implements ReferenceProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Location> provideReferences(CancelChecker cancelToken, IJavaProject project, TextDocument doc, ASTNode node, int offset) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<? extends Location> findReferencesToPropertyKey(String propertyKey) {
|
||||
List<? extends Location> fromPropertyFiles = findReferencesFromPropertyFiles(propertyKey);
|
||||
List<? extends Location> fromAnnotations = findReferencesFromAnnotations(propertyKey);
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2025 Broadcom
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.events.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
|
||||
import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest;
|
||||
import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
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;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@BootLanguageServerTest
|
||||
@Import(SymbolProviderTestConf.class)
|
||||
public class EventsReferencesProviderTest {
|
||||
|
||||
@Autowired private BootLanguageServerHarness harness;
|
||||
@Autowired private JavaProjectFinder projectFinder;
|
||||
@Autowired private SpringSymbolIndex indexer;
|
||||
|
||||
private File directory;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
harness.intialize(null);
|
||||
|
||||
directory = new File(ProjectsHarness.class.getResource("/test-projects/test-events-indexing/").toURI());
|
||||
|
||||
String projectDir = directory.toURI().toString();
|
||||
projectFinder.find(new TextDocumentIdentifier(projectDir)).get();
|
||||
|
||||
CompletableFuture<Void> initProject = indexer.waitOperation();
|
||||
initProject.get(5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEventListenerFindsAllPublishers() throws Exception {
|
||||
String tempJavaDocUri = directory.toPath().resolve("src/main/java/com/example/events/demo/CustomEventListener.java").toUri().toString();
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA, """
|
||||
package com.example.events.demo;
|
||||
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class CustomEventListener {
|
||||
|
||||
@EventListener
|
||||
public void handle<*>Event(CustomEvent event) {
|
||||
System.out.println(event);
|
||||
}
|
||||
}""", tempJavaDocUri);
|
||||
|
||||
List<? extends Location> references = editor.getReferences();
|
||||
assertEquals(1, references.size());
|
||||
|
||||
String expectedDefinitionUri1 = directory.toPath().resolve("src/main/java/com/example/events/demo/CustomEventPublisher.java").toUri().toString();
|
||||
Location expectedLocation1 = new Location(expectedDefinitionUri1, new Range(new Position(15, 2), new Position(15, 48)));
|
||||
|
||||
assertTrue(references.contains(expectedLocation1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEventPublisherFindsAllListeners() throws Exception {
|
||||
String tempJavaDocUri = directory.toPath().resolve("src/main/java/com/example/events/demo/CustomEventPublisher.java").toUri().toString();
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA, """
|
||||
package com.example.events.demo;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class CustomEventPublisher {
|
||||
|
||||
private ApplicationEventPublisher publisher;
|
||||
|
||||
public CustomEventPublisher(ApplicationEventPublisher publisher) {
|
||||
this.publisher = publisher;
|
||||
}
|
||||
|
||||
public void foo() {
|
||||
this.publisher.pu<*>blishEvent(new CustomEvent());
|
||||
}
|
||||
}""", tempJavaDocUri);
|
||||
|
||||
List<? extends Location> references = editor.getReferences();
|
||||
assertEquals(1, references.size());
|
||||
|
||||
String expectedDefinitionUri1 = directory.toPath().resolve("src/main/java/com/example/events/demo/CustomEventListener.java").toUri().toString();
|
||||
Location expectedLocation1 = new Location(expectedDefinitionUri1, new Range(new Position(9, 13), new Position(9, 24)));
|
||||
|
||||
assertTrue(references.contains(expectedLocation1));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
* Contributors:
|
||||
* Broadcom - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.beans.test;
|
||||
package org.springframework.ide.vscode.boot.java.events.test;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@@ -33,6 +33,7 @@ import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
|
||||
import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest;
|
||||
import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf;
|
||||
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
|
||||
import org.springframework.ide.vscode.boot.java.beans.test.SpringIndexerHarness;
|
||||
import org.springframework.ide.vscode.boot.java.events.EventListenerIndexElement;
|
||||
import org.springframework.ide.vscode.boot.java.events.EventPublisherIndexElement;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.example.events.demo;
|
||||
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class CustomEventListener {
|
||||
|
||||
@EventListener
|
||||
public void handleEvent(CustomEvent event) {
|
||||
System.out.println(event);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user