From d27739d284d0e737b51500af66d50fda28a72a96 Mon Sep 17 00:00:00 2001 From: Sophio Japharidze Date: Tue, 26 Nov 2024 13:08:49 +0100 Subject: [PATCH] SLLS-280 exclude analysis of files not open in editor --- .../ls/SonarLintExtendedLanguageClient.java | 28 ++------------- .../sonarlint/ls/SonarLintLanguageServer.java | 34 +++++++++++-------- .../AbstractLanguageServerMediumTests.java | 18 ++++------ .../LanguageServerMediumTests.java | 17 ---------- .../LanguageServerWithFoldersMediumTests.java | 16 +++++++++ 5 files changed, 46 insertions(+), 67 deletions(-) diff --git a/src/main/java/org/sonarsource/sonarlint/ls/SonarLintExtendedLanguageClient.java b/src/main/java/org/sonarsource/sonarlint/ls/SonarLintExtendedLanguageClient.java index ca7736906..e037b9ab5 100644 --- a/src/main/java/org/sonarsource/sonarlint/ls/SonarLintExtendedLanguageClient.java +++ b/src/main/java/org/sonarsource/sonarlint/ls/SonarLintExtendedLanguageClient.java @@ -234,31 +234,6 @@ public String getFixRecommendations() { @JsonNotification("sonarlint/showIssueOrHotspot") void showIssueOrHotspot(ShowAllLocationsCommand.Param params); - @JsonRequest("sonarlint/isIgnoredByScm") - CompletableFuture isIgnoredByScm(String fileUri); - - class ShouldAnalyseFileCheckResult { - boolean shouldBeAnalysed; - String reason; - - public ShouldAnalyseFileCheckResult(boolean shouldBeAnalysed, @Nullable String reason) { - this.shouldBeAnalysed = shouldBeAnalysed; - this.reason = reason; - } - - public boolean isShouldBeAnalysed() { - return shouldBeAnalysed; - } - - @CheckForNull - public String getReason() { - return reason; - } - } - - @JsonRequest("sonarlint/shouldAnalyseFile") - CompletableFuture shouldAnalyseFile(SonarLintExtendedLanguageServer.UriParams fileUri); - class FileUrisParams { Collection fileUris; @@ -796,6 +771,9 @@ public String getReason() { @JsonNotification("sonarlint/readyForTests") void readyForTests(); + @JsonRequest("sonarlint/isOpenInEditor") + CompletableFuture isOpenInEditor(String fileUri); + class SslCertificateConfirmationParams { @Expose diff --git a/src/main/java/org/sonarsource/sonarlint/ls/SonarLintLanguageServer.java b/src/main/java/org/sonarsource/sonarlint/ls/SonarLintLanguageServer.java index 705d5c89c..f5913efc9 100644 --- a/src/main/java/org/sonarsource/sonarlint/ls/SonarLintLanguageServer.java +++ b/src/main/java/org/sonarsource/sonarlint/ls/SonarLintLanguageServer.java @@ -447,22 +447,28 @@ public CompletableFuture>> codeAction(CodeActio @Override public void didOpen(DidOpenTextDocumentParams params) { var uri = create(params.getTextDocument().getUri()); - if (openNotebooksCache.isNotebook(uri)) { - lsLogOutput.debug(String.format("Skipping text document analysis of notebook \"%s\"", uri)); - return; - } - var file = openFilesCache.didOpen(uri, params.getTextDocument().getLanguageId(), params.getTextDocument().getText(), params.getTextDocument().getVersion()); - CompletableFutures.computeAsync(cancelChecker -> { - String configScopeId; - moduleEventsProcessor.notifyBackendWithFileLanguageAndContent(file); - var maybeWorkspaceFolder = workspaceFoldersManager.findFolderForFile(uri); - if (maybeWorkspaceFolder.isPresent()) { - configScopeId = maybeWorkspaceFolder.get().getUri().toString(); + client.isOpenInEditor(uri.toString()).thenAccept(isOpen -> { + if (Boolean.TRUE.equals(isOpen)) { + if (openNotebooksCache.isNotebook(uri)) { + lsLogOutput.debug(String.format("Skipping text document analysis of notebook \"%s\"", uri)); + return; + } + var file = openFilesCache.didOpen(uri, params.getTextDocument().getLanguageId(), params.getTextDocument().getText(), params.getTextDocument().getVersion()); + CompletableFutures.computeAsync(cancelChecker -> { + String configScopeId; + moduleEventsProcessor.notifyBackendWithFileLanguageAndContent(file); + var maybeWorkspaceFolder = workspaceFoldersManager.findFolderForFile(uri); + if (maybeWorkspaceFolder.isPresent()) { + configScopeId = maybeWorkspaceFolder.get().getUri().toString(); + } else { + configScopeId = ROOT_CONFIGURATION_SCOPE; + } + backendServiceFacade.getBackendService().didOpenFile(configScopeId, uri); + return null; + }); } else { - configScopeId = ROOT_CONFIGURATION_SCOPE; + lsLogOutput.debug(String.format("Skipping analysis of file not open in the editor: \"%s\"", uri)); } - backendServiceFacade.getBackendService().didOpenFile(configScopeId, uri); - return null; }); } diff --git a/src/test/java/org/sonarsource/sonarlint/ls/mediumtests/AbstractLanguageServerMediumTests.java b/src/test/java/org/sonarsource/sonarlint/ls/mediumtests/AbstractLanguageServerMediumTests.java index 12a097f86..229589efd 100644 --- a/src/test/java/org/sonarsource/sonarlint/ls/mediumtests/AbstractLanguageServerMediumTests.java +++ b/src/test/java/org/sonarsource/sonarlint/ls/mediumtests/AbstractLanguageServerMediumTests.java @@ -355,6 +355,7 @@ protected static class FakeLanguageClient implements SonarLintExtendedLanguageCl ShowRuleDescriptionParams ruleDesc; boolean isIgnoredByScm = false; boolean shouldAnalyseFile = true; + boolean isOpenInEditor = true; final AtomicInteger needCompilationDatabaseCalls = new AtomicInteger(); final Set openedLinks = new HashSet<>(); final Set shownMessages = new HashSet<>(); @@ -382,6 +383,7 @@ void clear() { shouldAnalyseFile = true; scopeReadyForAnalysis.clear(); suggestedBindings = null; + isOpenInEditor = true; } @Override @@ -486,6 +488,11 @@ public void readyForTests() { readyForTestsLatch.countDown(); } + @Override + public CompletableFuture isOpenInEditor(String fileUri) { + return CompletableFuture.completedFuture(isOpenInEditor); + } + @Override public CompletableFuture askSslCertificateConfirmation(SslCertificateConfirmationParams params) { return null; @@ -558,17 +565,6 @@ public void showIssue(ShowAllLocationsCommand.Param issue) { public void showIssueOrHotspot(ShowAllLocationsCommand.Param params) { } - @Override - public CompletableFuture isIgnoredByScm(String fileUri) { - return CompletableFutures.computeAsync(cancelToken -> isIgnoredByScm); - } - - @Override - public CompletableFuture shouldAnalyseFile(SonarLintExtendedLanguageServer.UriParams fileUri) { - return CompletableFutures.computeAsync(cancelToken -> new ShouldAnalyseFileCheckResult(shouldAnalyseFile, "reason")); - - } - @Override public CompletableFuture filterOutExcludedFiles(FileUrisParams params) { return CompletableFutures.computeAsync(cancelToken -> new FileUrisResult(params.getFileUris())); diff --git a/src/test/java/org/sonarsource/sonarlint/ls/mediumtests/LanguageServerMediumTests.java b/src/test/java/org/sonarsource/sonarlint/ls/mediumtests/LanguageServerMediumTests.java index 4ae21f70d..dbdcea150 100644 --- a/src/test/java/org/sonarsource/sonarlint/ls/mediumtests/LanguageServerMediumTests.java +++ b/src/test/java/org/sonarsource/sonarlint/ls/mediumtests/LanguageServerMediumTests.java @@ -324,23 +324,6 @@ void analyzeSimplePythonFileOnOpen() throws Exception { tuple(1, 2, 1, 7, "python:PrintStatementUsage", "sonarqube", "Replace print statement by built-in function.", DiagnosticSeverity.Warning))); } - @Test - @Disabled("We lost the ability to exclude preview files") - void doNotAnalyzePythonFileOnPreview() throws Exception { - setShowVerboseLogs(client.globalSettings, true); - notifyConfigurationChangeOnClient(); - - var uri = getUri("analyzeSimplePythonFileOnOpen.py", analysisDir); - - client.shouldAnalyseFile = false; - didOpen(uri, "python", "def foo():\n print 'toto'\n"); - - awaitUntilAsserted(() -> assertThat(client.logs) - .extracting(withoutTimestamp()) - .contains("[Info] reason \"" + uri + "\"")); - assertThat(client.getDiagnostics(uri)).isEmpty(); - } - @Test void analyzeSimplePythonFileWithCustomRuleConfig() throws Exception { var uri = getUri("analyzeSimplePyFileWithCustomRuleConfig.py", analysisDir); diff --git a/src/test/java/org/sonarsource/sonarlint/ls/mediumtests/LanguageServerWithFoldersMediumTests.java b/src/test/java/org/sonarsource/sonarlint/ls/mediumtests/LanguageServerWithFoldersMediumTests.java index 594d406d6..2382612aa 100644 --- a/src/test/java/org/sonarsource/sonarlint/ls/mediumtests/LanguageServerWithFoldersMediumTests.java +++ b/src/test/java/org/sonarsource/sonarlint/ls/mediumtests/LanguageServerWithFoldersMediumTests.java @@ -140,6 +140,22 @@ void analysisShouldUseFolderSettings() throws Exception { assertThat(client.getDiagnostics(uriOutsideFolder)).isEmpty(); } + @Test + void doNotAnalyzePythonFileOnPreview() { + setShowVerboseLogs(client.globalSettings, true); + notifyConfigurationChangeOnClient(); + client.isOpenInEditor = false; + + var uri = folder1BaseDir.resolve("doNotAnalyzePythonFileOnPreview.py").toUri().toString(); + + didOpen(uri, "python", "def foo():\n print 'toto'\n"); + + awaitUntilAsserted(() -> assertThat(client.logs) + .extracting(withoutTimestamp()) + .contains(String.format("[Debug] Skipping analysis of file not open in the editor: \"%s\"", uri))); + assertThat(client.getDiagnostics(uri)).isEmpty(); + } + @Test void shouldBatchAnalysisFromTheSameFolder() { var file1InFolder = folder1BaseDir.resolve("file1.py").toUri().toString();