From 88ae9318ed31f091ea39f5a51ba6109551ae717b Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Thu, 4 Apr 2024 17:21:12 +0200 Subject: [PATCH] GH-1219: another small optimization to avoid converting supertype sets and arrays all the time + reusing common sets instead of creating new set objects all the time --- .../vscode/commons/protocol/spring/Bean.java | 19 ++++++++++++------ .../protocol/spring/DefaultValues.java | 10 ++++++++-- .../boot/index/cache/IndexCacheOnDisc.java | 6 +++--- .../boot/java/beans/BeansSymbolProvider.java | 4 ++-- .../java/beans/ComponentSymbolProvider.java | 4 ++-- .../java/beans/FeignClientSymbolProvider.java | 4 ++-- .../data/DataRepositorySymbolProvider.java | 4 ++-- .../index/test/SpringMetamodelIndexTest.java | 20 ++++++++++--------- 8 files changed, 43 insertions(+), 28 deletions(-) diff --git a/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/Bean.java b/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/Bean.java index 3d76da77a..4a934aab1 100644 --- a/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/Bean.java +++ b/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/Bean.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023 VMware, Inc. + * Copyright (c) 2023, 2024 VMware, 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 @@ -10,8 +10,6 @@ *******************************************************************************/ package org.springframework.ide.vscode.commons.protocol.spring; -import java.util.Arrays; -import java.util.HashSet; import java.util.Set; import org.eclipse.lsp4j.Location; @@ -27,10 +25,11 @@ public class Bean { private final Set supertypes; private final String[] annotations; - public Bean(String name, String type, Location location, InjectionPoint[] injectionPoints, String[] supertypes, String[] annotations) { + public Bean(String name, String type, Location location, InjectionPoint[] injectionPoints, Set supertypes, String[] annotations) { this.name = name; this.type = type; this.location = location; + this.annotations = annotations; if (injectionPoints != null && injectionPoints.length == 0) { this.injectionPoints = DefaultValues.EMPTY_INJECTION_POINTS; @@ -38,9 +37,17 @@ public class Bean { else { this.injectionPoints = injectionPoints; } + + if (supertypes != null && supertypes.size() == 0) { + this.supertypes = DefaultValues.EMPTY_SUPERTYPES; + } + else if (supertypes != null && supertypes.size() == 1 && supertypes.contains("java.lang.Object")) { + this.supertypes = DefaultValues.OBJECT_SUPERTYPE; + } + else { + this.supertypes = supertypes; + } - this.supertypes = new HashSet<>(Arrays.asList(supertypes)); - this.annotations = annotations; } public String getName() { diff --git a/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/DefaultValues.java b/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/DefaultValues.java index 40c912747..1a1588775 100644 --- a/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/DefaultValues.java +++ b/headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/DefaultValues.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023 VMware, Inc. + * Copyright (c) 2023, 2024 VMware, 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 @@ -10,8 +10,14 @@ *******************************************************************************/ package org.springframework.ide.vscode.commons.protocol.spring; +import java.util.HashSet; +import java.util.Set; + public class DefaultValues { - public static InjectionPoint[] EMPTY_INJECTION_POINTS = new InjectionPoint[0]; + public static final Set EMPTY_SUPERTYPES = new HashSet<>(); + public static final Set OBJECT_SUPERTYPE = Set.of("java.lang.Object"); + + public static final InjectionPoint[] EMPTY_INJECTION_POINTS = new InjectionPoint[0]; } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/index/cache/IndexCacheOnDisc.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/index/cache/IndexCacheOnDisc.java index 9f897b2e1..10ecf148e 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/index/cache/IndexCacheOnDisc.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/index/cache/IndexCacheOnDisc.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2023 Pivotal, Inc. + * Copyright (c) 2019, 2024 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 @@ -451,7 +451,7 @@ public class IndexCacheOnDisc implements IndexCache { } /** - * gson adapter to store subtype information for symbol addon informations + * gson adapter to store subtype information for beans */ private static class BeanJsonAdapter implements JsonDeserializer { @@ -469,7 +469,7 @@ public class IndexCacheOnDisc implements IndexCache { InjectionPoint[] injectionPoints = context.deserialize(injectionPointObject, InjectionPoint[].class); JsonElement supertypesObject = parsedObject.get("supertypes"); - String[] supertypes = context.deserialize(supertypesObject, String[].class); + Set supertypes = context.deserialize(supertypesObject, Set.class); JsonElement annotationsObject = parsedObject.get("annotations"); String[] annotations = annotationsObject == null? new String[0] : context.deserialize(annotationsObject, String[].class); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java index d5aa32a67..84707ee7e 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2023 Pivotal, Inc. + * Copyright (c) 2017, 2024 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 @@ -99,7 +99,7 @@ public class BeansSymbolProvider extends AbstractSymbolProvider { .findTransitiveSuperAnnotationBindings(node.resolveAnnotationBinding()) .map(t -> t.getAnnotationType().getQualifiedName()).toArray(String[]::new); - Bean beanDefinition = new Bean(nameAndRegion.getT1(), beanType.getQualifiedName(), location, injectionPoints, (String[]) supertypes.toArray(new String[supertypes.size()]), annotations); + Bean beanDefinition = new Bean(nameAndRegion.getT1(), beanType.getQualifiedName(), location, injectionPoints, supertypes, annotations); context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol)); context.getBeans().add(new CachedBean(context.getDocURI(), beanDefinition)); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java index f3df493fd..6f3c40875 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2023 Pivotal, Inc. + * Copyright (c) 2017, 2024 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 @@ -96,7 +96,7 @@ public class ComponentSymbolProvider extends AbstractSymbolProvider { String[] annotations = Stream.concat(Stream.of(annotationType), metaAnnotations.stream()).map(t -> t.getQualifiedName()).toArray(String[]::new); - Bean beanDefinition = new Bean(beanName, beanType.getQualifiedName(), location, injectionPoints, (String[]) supertypes.toArray(new String[supertypes.size()]), annotations); + Bean beanDefinition = new Bean(beanName, beanType.getQualifiedName(), location, injectionPoints, supertypes, annotations); return Tuple.two(new EnhancedSymbolInformation(symbol, addon), beanDefinition); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/FeignClientSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/FeignClientSymbolProvider.java index c80f42839..db8fb08d1 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/FeignClientSymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/FeignClientSymbolProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023 VMware, Inc. + * Copyright (c) 2023, 2024 VMware, 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 @@ -94,7 +94,7 @@ public class FeignClientSymbolProvider extends AbstractSymbolProvider { String[] annotations = Stream.concat(Stream.of(annotationType), metaAnnotations.stream()).map(t -> t.getQualifiedName()).toArray(String[]::new); - Bean beanDefinition = new Bean(beanName, beanType == null ? "" : beanType.getQualifiedName(), location, injectionPoints, (String[]) supertypes.toArray(new String[supertypes.size()]), annotations); + Bean beanDefinition = new Bean(beanName, beanType == null ? "" : beanType.getQualifiedName(), location, injectionPoints, supertypes, annotations); return Tuple.two(new EnhancedSymbolInformation(symbol, addon), beanDefinition); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java index fd0e2f949..4c52d9a5d 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018, 2023 Pivotal, Inc. + * Copyright (c) 2018, 2024 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 @@ -73,7 +73,7 @@ public class DataRepositorySymbolProvider extends AbstractSymbolProvider { ASTUtils.findSupertypes(concreteBeanTypeBindung, supertypes); String concreteRepoType = concreteBeanTypeBindung.getQualifiedName(); - Bean beanDefinition = new Bean(beanName, concreteRepoType, location, injectionPoints, (String[]) supertypes.toArray(new String[supertypes.size()]), new String[0]); + Bean beanDefinition = new Bean(beanName, concreteRepoType, location, injectionPoints, supertypes, new String[0]); context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol)); context.getBeans().add(new CachedBean(context.getDocURI(), beanDefinition)); diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/index/test/SpringMetamodelIndexTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/index/test/SpringMetamodelIndexTest.java index 99a67e37f..3deb2c521 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/index/test/SpringMetamodelIndexTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/index/test/SpringMetamodelIndexTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023 VMware, Inc. + * Copyright (c) 2023, 2024 VMware, 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 @@ -17,7 +17,9 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.assertj.core.util.Arrays; import org.eclipse.lsp4j.Location; @@ -35,7 +37,7 @@ import com.google.gson.Gson; public class SpringMetamodelIndexTest { private InjectionPoint[] emptyInjectionPoints = new InjectionPoint[0]; - private String[] emptySupertypes = new String[0]; + private Set emptySupertypes = new HashSet<>(); private String[] emptyAnnotations = new String[0]; private Location locationForDoc1 = new Location("docURI1", new Range(new Position(1, 1), new Position(1, 10))); @@ -221,7 +223,7 @@ public class SpringMetamodelIndexTest { InjectionPoint point1 = new InjectionPoint("point1", "point1-type", locationForDoc2); InjectionPoint point2 = new InjectionPoint("point2", "point2-type", locationForDoc1); - Bean bean1 = new Bean("beanName1", "beanType", locationForDoc1, new InjectionPoint[] {point1, point2}, new String[] {"supertype1", "supertype2"}, emptyAnnotations); + Bean bean1 = new Bean("beanName1", "beanType", locationForDoc1, new InjectionPoint[] {point1, point2}, Set.of("supertype1", "supertype2"), emptyAnnotations); String serialized = bean1.toString(); Gson gson = IndexCacheOnDisc.createGson(); @@ -286,8 +288,8 @@ public class SpringMetamodelIndexTest { @Test void testFindMatchingBeansWithOneProject() { SpringMetamodelIndex index = new SpringMetamodelIndex(); - Bean bean1 = new Bean("beanName1", "beanType1", locationForDoc1, emptyInjectionPoints, new String[] {"supertype1", "supertype2"}, emptyAnnotations); - Bean bean2 = new Bean("beanName2", "beanType2", locationForDoc1, emptyInjectionPoints, new String[] {"supertype3", "supertype4", "supertype5"}, emptyAnnotations); + Bean bean1 = new Bean("beanName1", "beanType1", locationForDoc1, emptyInjectionPoints, Set.of("supertype1", "supertype2"), emptyAnnotations); + Bean bean2 = new Bean("beanName2", "beanType2", locationForDoc1, emptyInjectionPoints, Set.of("supertype3", "supertype4", "supertype5"), emptyAnnotations); index.updateBeans("someProject", new Bean[] {bean1, bean2}); @@ -313,11 +315,11 @@ public class SpringMetamodelIndexTest { @Test void testFindMatchingBeansWithMultipleProjects() { SpringMetamodelIndex index = new SpringMetamodelIndex(); - Bean bean1 = new Bean("beanName1", "beanType1", locationForDoc1, emptyInjectionPoints, new String[] {"supertype1", "supertype2"}, emptyAnnotations); - Bean bean2 = new Bean("beanName2", "beanType2", locationForDoc1, emptyInjectionPoints, new String[] {"supertype3", "supertype4, supertype5"}, emptyAnnotations); + Bean bean1 = new Bean("beanName1", "beanType1", locationForDoc1, emptyInjectionPoints, Set.of("supertype1", "supertype2"), emptyAnnotations); + Bean bean2 = new Bean("beanName2", "beanType2", locationForDoc1, emptyInjectionPoints, Set.of("supertype3", "supertype4, supertype5"), emptyAnnotations); - Bean bean3 = new Bean("beanName3", "beanType1", locationForDoc1, emptyInjectionPoints, new String[] {"supertype1", "supertype2"}, emptyAnnotations); - Bean bean4 = new Bean("beanName4", "beanType2", locationForDoc1, emptyInjectionPoints, new String[] {"supertype3", "supertype4, supertype5"}, emptyAnnotations); + Bean bean3 = new Bean("beanName3", "beanType1", locationForDoc1, emptyInjectionPoints, Set.of("supertype1", "supertype2"), emptyAnnotations); + Bean bean4 = new Bean("beanName4", "beanType2", locationForDoc1, emptyInjectionPoints, Set.of("supertype3", "supertype4, supertype5"), emptyAnnotations); index.updateBeans("projectA", new Bean[] {bean1, bean2}); index.updateBeans("projectB", new Bean[] {bean3, bean4});