From d13cea2efe93411393200b8ffa2ccda6c0fc3006 Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Fri, 4 Aug 2023 15:15:40 +0200 Subject: [PATCH] GH-1083: integrate fingerprint of validation settings into diagnostics cache --- .../testharness/LanguageServerHarness.java | 2 +- .../vscode/boot/app/SpringSymbolIndex.java | 31 ++++++++------- .../boot/java/utils/SpringIndexerJava.java | 15 +++++++- ...ringValidationBeanMethodNotPublicTest.java | 38 ++++++++++++++++++- 4 files changed, 68 insertions(+), 18 deletions(-) diff --git a/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java b/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java index 13630917e..afacf4d5d 100644 --- a/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java +++ b/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java @@ -958,7 +958,7 @@ public class LanguageServerHarness { } public void changeConfiguration(Settings settings) { - getServer().getWorkspaceService().didChangeConfiguration(new DidChangeConfigurationParams(settings)); + getServer().getWorkspaceService().didChangeConfiguration(new DidChangeConfigurationParams(settings.getRawSettings())); } public SimpleLanguageServer getServer() { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndex.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndex.java index d958bbe3e..9aad0dd65 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndex.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndex.java @@ -250,7 +250,7 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex { reconcilers.add(new BeanMethodNotPublicReconciler(server.getQuickfixRegistry())); BiFunction, BiConsumer, IProblemCollector> problemCollectorFactory = (docRef, aggregator) -> server.createProblemCollector(docRef, aggregator); - springIndexerJava = new SpringIndexerJava(handler, specificProviders, this.cache, projectFinder(), server.getProgressService(), reconcilers, problemCollectorFactory); + springIndexerJava = new SpringIndexerJava(handler, specificProviders, this.cache, projectFinder(), server.getProgressService(), reconcilers, problemCollectorFactory, config.getJavaValidationSettingsJson()); factoriesIndexer = new SpringFactoriesIndexer(handler, cache); @@ -278,14 +278,12 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex { config.addListener(evt -> { log.info("update settings of spring indexer - start"); - - CompletableFuture.runAsync(() -> - configureIndexer(SymbolIndexConfig.builder() - .scanXml(config.isSpringXMLSupportEnabled()) - .xmlScanFolders(config.xmlBeansFoldersToScan()) - .scanTestJavaSources(config.isScanJavaTestSourcesEnabled()) - .build() - ), this.updateQueue); + + configurationChanged(SymbolIndexConfig.builder() + .scanXml(config.isSpringXMLSupportEnabled()) + .xmlScanFolders(config.xmlBeansFoldersToScan()) + .scanTestJavaSources(config.isScanJavaTestSourcesEnabled()) + .build()); log.info("update settings of spring indexer - done"); }); @@ -309,6 +307,15 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex { }); } + public void configurationChanged(SymbolIndexConfig config) { + CompletableFuture.runAsync(() -> configureIndexer(config), this.updateQueue); + + Collection projects = projectFinder().all(); + for (IJavaProject project : projects) { + initializeProject(project, true); + } + } + public void configureIndexer(SymbolIndexConfig config) { synchronized (this) { if (config.isScanXml() && !(Arrays.asList(this.indexers).contains(springIndexerXML))) { @@ -326,11 +333,7 @@ public class SpringSymbolIndex implements InitializingBean, SpringIndex { } } springIndexerJava.setScanTestJavaSources(config.isScanTestJavaSources()); - } - - Collection projects = projectFinder().all(); - for (IJavaProject project : projects) { - initializeProject(project, true); + springIndexerJava.setValidationSeveritySettings(this.config.getJavaValidationSettingsJson()); } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJava.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJava.java index b8daaaa87..56ce41d3b 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJava.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJava.java @@ -75,6 +75,7 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument; import com.google.common.collect.Multimap; import com.google.common.collect.MultimapBuilder; +import com.google.gson.JsonObject; /** * @author Martin Lippert @@ -104,14 +105,18 @@ public class SpringIndexerJava implements SpringIndexer { private final ProgressService progressService; private boolean scanTestJavaSources = false; + private JsonObject validationSeveritySettings; + private FileScanListener fileScanListener = null; //used by test code only private final SpringIndexerJavaDependencyTracker dependencyTracker = new SpringIndexerJavaDependencyTracker(); private final BiFunction, BiConsumer, IProblemCollector> problemCollectorCreator; + public SpringIndexerJava(SymbolHandler symbolHandler, AnnotationHierarchyAwareLookup symbolProviders, IndexCache cache, JavaProjectFinder projectFimder, ProgressService progressService, List reconcilers, - BiFunction, BiConsumer, IProblemCollector> problemCollectorCreator) { + BiFunction, BiConsumer, IProblemCollector> problemCollectorCreator, + JsonObject validationSeveritySettings) { this.symbolHandler = symbolHandler; this.symbolProviders = symbolProviders; this.reconcilers = reconcilers; @@ -120,6 +125,7 @@ public class SpringIndexerJava implements SpringIndexer { this.progressService = progressService; this.problemCollectorCreator = problemCollectorCreator; + this.validationSeveritySettings = validationSeveritySettings; } public SpringIndexerJavaDependencyTracker getDependencyTracker() { @@ -776,7 +782,8 @@ public class SpringIndexerJava implements SpringIndexer { .map(file -> file.getAbsolutePath() + "#" + file.lastModified()) .collect(Collectors.joining(",")); - return new IndexCacheKey(project.getElementName(), "java", elementType, DigestUtils.md5Hex(GENERATION + "-" + classpathIdentifier).toUpperCase()); +// return new IndexCacheKey(project.getElementName(), "java", elementType, DigestUtils.md5Hex(GENERATION + "-" + classpathIdentifier).toUpperCase()); + return new IndexCacheKey(project.getElementName(), "java", elementType, DigestUtils.md5Hex(GENERATION + "-" + validationSeveritySettings.toString() + "-" + classpathIdentifier).toUpperCase()); } public void setScanTestJavaSources(boolean scanTestJavaSources) { @@ -840,6 +847,10 @@ public class SpringIndexerJava implements SpringIndexer { } } + public void setValidationSeveritySettings(JsonObject javaValidationSettingsJson) { + this.validationSeveritySettings = javaValidationSettingsJson; + } + public void setFileScanListener(FileScanListener fileScanListener) { this.fileScanListener = fileScanListener; } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/reconcilers/test/SpringValidationBeanMethodNotPublicTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/reconcilers/test/SpringValidationBeanMethodNotPublicTest.java index 32e5f2d98..cf34d8b1c 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/reconcilers/test/SpringValidationBeanMethodNotPublicTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/reconcilers/test/SpringValidationBeanMethodNotPublicTest.java @@ -12,7 +12,6 @@ package org.springframework.ide.vscode.boot.java.reconcilers.test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; import java.util.List; @@ -20,6 +19,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import org.eclipse.lsp4j.Diagnostic; +import org.eclipse.lsp4j.DiagnosticSeverity; import org.eclipse.lsp4j.PublishDiagnosticsParams; import org.eclipse.lsp4j.TextDocumentIdentifier; import org.junit.jupiter.api.BeforeEach; @@ -27,16 +27,21 @@ 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.BootJavaConfig; import org.springframework.ide.vscode.boot.app.BootLanguageServerInitializer; 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.java.Boot2JavaProblemType; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; +import org.springframework.ide.vscode.commons.languageserver.util.Settings; import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness; import org.springframework.ide.vscode.project.harness.ProjectsHarness; import org.springframework.test.context.junit.jupiter.SpringExtension; +import com.google.gson.Gson; +import com.google.gson.JsonElement; + /** * @author Martin Lippert */ @@ -46,6 +51,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; public class SpringValidationBeanMethodNotPublicTest { @Autowired private BootLanguageServerHarness harness; + @Autowired private BootJavaConfig config; @Autowired private BootLanguageServerInitializer serverInit; @Autowired private JavaProjectFinder projectFinder; @@ -87,6 +93,36 @@ public class SpringValidationBeanMethodNotPublicTest { assertEquals(1, diagnostics.size()); } + @Test + void testChangingSeverityOfFindPublicBeanMethodInConfigClass() throws Exception { + String docUri = directory.toPath().resolve("src/main/java/org/test/BeanMethodNotPublic.java").toUri().toString(); + + PublishDiagnosticsParams diagnosticsMessage = harness.getDiagnostics(docUri); + List diagnostics = diagnosticsMessage.getDiagnostics(); + + Diagnostic diagnostic = diagnostics.get(0); + assertEquals(Boot2JavaProblemType.JAVA_PUBLIC_BEAN_METHOD.getCode(), diagnostic.getCode().getLeft()); + assertEquals(1, diagnostics.size()); + assertEquals(DiagnosticSeverity.Hint, diagnostic.getSeverity()); + + String changedSettings = "{\"spring-boot\": {\"ls\": {\"problem\": {\"boot2\": {\"JAVA_PUBLIC_BEAN_METHOD\": \"ERROR\"}}}}}"; + JsonElement settingsAsJson = new Gson().fromJson(changedSettings, JsonElement.class); + Settings settings = new Settings(settingsAsJson); + + harness.changeConfiguration(settings); + + CompletableFuture initProject = indexer.waitOperation(); + initProject.get(5, TimeUnit.SECONDS); + + diagnosticsMessage = harness.getDiagnostics(docUri); + diagnostics = diagnosticsMessage.getDiagnostics(); + + diagnostic = diagnostics.get(0); + assertEquals(Boot2JavaProblemType.JAVA_PUBLIC_BEAN_METHOD.getCode(), diagnostic.getCode().getLeft()); + assertEquals(1, diagnostics.size()); + assertEquals(DiagnosticSeverity.Error, diagnostic.getSeverity()); + } + @Test void testPublishEmptyDiagnosticsWhenNoProblemsAreFound() throws Exception { String docUri = directory.toPath().resolve("src/main/java/org/test/BeanClass1.java").toUri().toString();