GH-1498: bean registrars are not bean index eleements anymore, but have a dedicated index element instead
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
/*******************************************************************************
|
||||
* 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.commons.protocol.spring;
|
||||
|
||||
import org.eclipse.lsp4j.DocumentSymbol;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
|
||||
public class BeanRegistrarElement extends AbstractSpringIndexElement implements SymbolElement {
|
||||
|
||||
private final String name;
|
||||
private final String type;
|
||||
private final Location location;
|
||||
|
||||
public BeanRegistrarElement(String name, String type, Location location) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocumentSymbol getDocumentSymbol() {
|
||||
return new DocumentSymbol(
|
||||
name + " (Bean Registrar)",
|
||||
SymbolKind.Class,
|
||||
location.getRange(), location.getRange());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.RecordDeclaration;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
@@ -51,9 +52,11 @@ import org.springframework.ide.vscode.boot.java.utils.DefaultSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext;
|
||||
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.BeanRegistrarElement;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.DefaultValues;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.InjectionPoint;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.SimpleSymbolElement;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.SpringIndexElement;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
@@ -401,7 +404,7 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void indexBeanRegistrarImplementation(Bean bean, TypeDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) {
|
||||
private void indexBeanRegistrarImplementation(SpringIndexElement parentNode, TypeDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) {
|
||||
try {
|
||||
ITypeBinding typeBinding = typeDeclaration.resolveBinding();
|
||||
if (typeBinding == null) return;
|
||||
@@ -416,39 +419,32 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
throw new RequiredCompleteAstException();
|
||||
}
|
||||
|
||||
if (bean == null) { // need to create and register bean element
|
||||
String beanType = typeBinding.getQualifiedName();
|
||||
String beanName = BeanUtils.getBeanNameFromType(typeBinding.getName());
|
||||
if (parentNode == null) { // need to create and register bean element
|
||||
String name = typeBinding.getName();
|
||||
String type = typeBinding.getQualifiedName();
|
||||
|
||||
Location location = new Location(doc.getUri(), doc.toRange(typeDeclaration.getStartPosition(), typeDeclaration.getLength()));
|
||||
SimpleName typeNameNode = typeDeclaration.getName();
|
||||
Location location = new Location(doc.getUri(), doc.toRange(typeNameNode.getStartPosition(), typeNameNode.getLength()));
|
||||
|
||||
WorkspaceSymbol symbol = new WorkspaceSymbol(
|
||||
beanLabel("+", null, null, beanName, beanType),
|
||||
SymbolKind.Class,
|
||||
name + " (Bean Registrar)",
|
||||
SymbolKind.Interface,
|
||||
Either.forLeft(location));
|
||||
|
||||
InjectionPoint[] injectionPoints = ASTUtils.findInjectionPoints(typeDeclaration, doc);
|
||||
|
||||
Set<String> supertypes = new HashSet<>();
|
||||
ASTUtils.findSupertypes(typeBinding, supertypes);
|
||||
|
||||
Collection<Annotation> annotationsOnMethod = ASTUtils.getAnnotations(typeDeclaration);
|
||||
AnnotationMetadata[] annotations = ASTUtils.getAnnotationsMetadata(annotationsOnMethod, doc);
|
||||
|
||||
bean = new Bean(beanName, beanType, location, injectionPoints, supertypes, annotations, false, symbol.getName());
|
||||
parentNode = new BeanRegistrarElement(name, type, location);
|
||||
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), symbol));
|
||||
context.getBeans().add(new CachedBean(context.getDocURI(), bean));
|
||||
context.getBeans().add(new CachedBean(context.getDocURI(), parentNode));
|
||||
}
|
||||
|
||||
scanBeanRegistryInvocations(bean, registerMethod.getBody(), context, doc);
|
||||
scanBeanRegistryInvocations(parentNode, registerMethod.getBody(), context, doc);
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
log.error("", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void scanBeanRegistryInvocations(Bean component, Block body, SpringIndexerJavaContext context, TextDocument doc) {
|
||||
private void scanBeanRegistryInvocations(SpringIndexElement parent, Block body, SpringIndexerJavaContext context, TextDocument doc) {
|
||||
if (body == null) {
|
||||
return;
|
||||
}
|
||||
@@ -491,7 +487,7 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
String beanName = BeanUtils.getBeanNameFromType(typeParameters[0].getName());
|
||||
String beanType = typeParamName;
|
||||
|
||||
createBean(component, beanName, beanType, typeParameters[0], methodInvocation, context, doc);
|
||||
createBean(parent, beanName, beanType, typeParameters[0], methodInvocation, context, doc);
|
||||
}
|
||||
}
|
||||
else if (arguments.size() == 2 && "java.lang.String".equals(types.get(0).getQualifiedName()) && "java.lang.Class".equals(types.get(1).getBinaryName())) {
|
||||
@@ -505,7 +501,7 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
String typeParamName = typeParameters[0].getBinaryName();
|
||||
String beanType = typeParamName;
|
||||
|
||||
createBean(component, beanName, beanType, typeParameters[0], methodInvocation, context, doc);
|
||||
createBean(parent, beanName, beanType, typeParameters[0], methodInvocation, context, doc);
|
||||
}
|
||||
}
|
||||
else if (arguments.size() == 2 && "java.lang.Class".equals(types.get(0).getBinaryName()) && "java.util.function.Consumer".equals(types.get(1).getBinaryName())) {
|
||||
@@ -519,7 +515,7 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
String beanName = BeanUtils.getBeanNameFromType(typeParameters[0].getName());
|
||||
String beanType = typeParamName;
|
||||
|
||||
createBean(component, beanName, beanType, typeParameters[0], methodInvocation, context, doc);
|
||||
createBean(parent, beanName, beanType, typeParameters[0], methodInvocation, context, doc);
|
||||
}
|
||||
}
|
||||
else if (arguments.size() == 3 && "java.lang.String".equals(types.get(0).getQualifiedName())
|
||||
@@ -534,7 +530,7 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
String typeParamName = typeParameters[0].getBinaryName();
|
||||
String beanType = typeParamName;
|
||||
|
||||
createBean(component, beanName, beanType, typeParameters[0], methodInvocation, context, doc);
|
||||
createBean(parent, beanName, beanType, typeParameters[0], methodInvocation, context, doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -548,7 +544,7 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
});
|
||||
}
|
||||
|
||||
public void createBean(Bean parentBean, String beanName, String beanType, ITypeBinding beanTypeBinding, ASTNode node, SpringIndexerJavaContext context, TextDocument doc) throws BadLocationException {
|
||||
public void createBean(SpringIndexElement parentNode, String beanName, String beanType, ITypeBinding beanTypeBinding, ASTNode node, SpringIndexerJavaContext context, TextDocument doc) throws BadLocationException {
|
||||
Location location = new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()));
|
||||
|
||||
WorkspaceSymbol symbol = new WorkspaceSymbol(
|
||||
@@ -564,7 +560,7 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
AnnotationMetadata[] annotations = DefaultValues.EMPTY_ANNOTATIONS;
|
||||
|
||||
Bean bean = new Bean(beanName, beanType, location, injectionPoints, supertypes, annotations, false, symbol.getName());
|
||||
parentBean.addChild(bean);
|
||||
parentNode.addChild(bean);
|
||||
}
|
||||
|
||||
public static String beanLabel(String searchPrefix, String annotationTypeName, Collection<String> metaAnnotationNames, String beanName, String beanType) {
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixRe
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.BeanRegistrarElement;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.SpringIndexElement;
|
||||
import org.springframework.ide.vscode.commons.rewrite.config.RecipeScope;
|
||||
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
|
||||
@@ -168,10 +169,11 @@ public class BeanRegistrarDeclarationReconciler implements JdtAstReconciler {
|
||||
|
||||
Set<String> importedTypesDelta = getImportAnnotationTypesDelta(createdIndexElements, previuosIndexElements);
|
||||
|
||||
Arrays.stream(springIndex.getBeans())
|
||||
.filter(bean -> bean.isTypeCompatibleWith(Annotations.BEAN_REGISTRAR_INTERFACE))
|
||||
.filter(bean -> importedTypesDelta.contains(bean.getType()))
|
||||
.map(bean -> bean.getLocation().getUri())
|
||||
List<BeanRegistrarElement> registrarElements = springIndex.getNodesOfType(BeanRegistrarElement.class);
|
||||
|
||||
registrarElements.stream()
|
||||
.filter(registrar -> importedTypesDelta.contains(registrar.getType()))
|
||||
.map(registrar -> registrar.getLocation().getUri())
|
||||
.map(docURI -> UriUtil.toFileString(docURI))
|
||||
.forEach(file -> context.markForAffetcedFilesIndexing(file));
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ public class SpringIndexerJava implements SpringIndexer {
|
||||
|
||||
// whenever the implementation of the indexer changes in a way that the stored data in the cache is no longer valid,
|
||||
// we need to change the generation - this will result in a re-indexing due to no up-to-date cache data being found
|
||||
private static final String GENERATION = "GEN-17";
|
||||
private static final String GENERATION = "GEN-18";
|
||||
private static final String INDEX_FILES_TASK_ID = "index-java-source-files-task-";
|
||||
|
||||
private static final String SYMBOL_KEY = "symbols";
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.index.test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@@ -31,8 +32,9 @@ import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf;
|
||||
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
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.BeanRegistrarElement;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.DocumentElement;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.SpringIndexElement;
|
||||
import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
|
||||
@@ -72,15 +74,17 @@ public class SpringIndexerBeanRegistrarTest {
|
||||
void testSimpleBeanRegistration() throws Exception {
|
||||
String docUri = directory.toPath().resolve("src/main/java/com/example/MyBeanRegistrar.java").toUri().toString();
|
||||
|
||||
Bean[] beans = springIndex.getBeansOfDocument(docUri);
|
||||
assertEquals(5, beans.length);
|
||||
Bean[] beansOfDoc = springIndex.getBeansOfDocument(docUri);
|
||||
assertFalse(Arrays.stream(beansOfDoc).anyMatch(bean -> bean.getName().equals("myBeanRegistrar")));
|
||||
|
||||
Bean beanRegistrarBean = Arrays.stream(beans).filter(bean -> bean.getName().equals("myBeanRegistrar")).findFirst().get();
|
||||
assertEquals("com.example.MyBeanRegistrar", beanRegistrarBean.getType());
|
||||
DocumentElement document = springIndex.getDocument(docUri);
|
||||
List<SpringIndexElement> docChildren = document.getChildren();
|
||||
assertEquals(1, docChildren.size());
|
||||
assertTrue(docChildren.get(0) instanceof BeanRegistrarElement);
|
||||
|
||||
List<SpringIndexElement> children = beanRegistrarBean.getChildren();
|
||||
List<SpringIndexElement> children = docChildren.get(0).getChildren();
|
||||
assertEquals(4, children.size());
|
||||
|
||||
|
||||
Bean fooFoo = (Bean) children.get(0);
|
||||
assertEquals("fooFoo", fooFoo.getName());
|
||||
assertEquals("com.example.FooFoo", fooFoo.getType());
|
||||
|
||||
@@ -31,7 +31,6 @@ 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.boot.index.SpringMetamodelIndex;
|
||||
import org.springframework.ide.vscode.boot.java.Boot4JavaProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.utils.test.TestFileScanListener;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
@@ -51,7 +50,6 @@ public class BeanRegistrarAdvancedReconcilingTest {
|
||||
@Autowired private BootLanguageServerHarness harness;
|
||||
@Autowired private JavaProjectFinder projectFinder;
|
||||
@Autowired private SpringSymbolIndex indexer;
|
||||
@Autowired private SpringMetamodelIndex springIndex;
|
||||
|
||||
private File directory;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user