From 58ca923f9970693fdfba266ab6839e42ff3f2adb Mon Sep 17 00:00:00 2001 From: Sophio Japharidze Date: Fri, 27 Dec 2024 14:48:48 +0100 Subject: [PATCH 1/2] SLVSCODE-966 improve UX with taint vulnerabilities on file change --- src/extension.ts | 24 +++++++++++++++++++++++- src/hotspot/hotspotsTreeDataProvider.ts | 4 ++-- src/lsp/protocol.ts | 8 ++++++-- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 462ef956b..5d1791589 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -9,7 +9,7 @@ import * as ChildProcess from 'child_process'; import { DateTime } from 'luxon'; import * as Path from 'path'; import * as VSCode from 'vscode'; -import { LanguageClientOptions, StreamInfo } from 'vscode-languageclient/node'; +import { DiagnosticSeverity, LanguageClientOptions, StreamInfo } from 'vscode-languageclient/node'; import { configureCompilationDatabase, notifyMissingCompileCommands } from './cfamily/cfamily'; import { AutoBindingService } from './connected/autobinding'; import { assistCreatingConnection } from './connected/assistCreatingConnection'; @@ -92,6 +92,7 @@ let hotspotsTreeDataProvider: AllHotspotsTreeDataProvider; let allHotspotsView: VSCode.TreeView; let helpAndFeedbackTreeDataProvider: HelpAndFeedbackTreeDataProvider; let helpAndFeedbackView: VSCode.TreeView; +let diagnosticCollection: VSCode.DiagnosticCollection; function runJavaServer(context: VSCode.ExtensionContext): Promise { return resolveRequirements(context) @@ -221,6 +222,9 @@ export async function activate(context: VSCode.ExtensionContext) { await languageClient.start(); + diagnosticCollection = VSCode.languages.createDiagnosticCollection('SonarQube Taint Vulnerabilities'); + context.subscriptions.push(diagnosticCollection); + ConnectionSettingsService.init(context, languageClient); NewCodeDefinitionService.init(context); FileSystemServiceImpl.init(); @@ -623,6 +627,24 @@ function installCustomRequestHandlers(context: VSCode.ExtensionContext) { await hotspotsTreeDataProvider.refresh(hotspotsPerFile); updateSonarLintViewContainerBadge(); }); + languageClient.onNotification(protocol.PublishTaintVulnerabilitiesForFile.type, async taintVulnerabilitiesPerFile => { + const diagnostics = taintVulnerabilitiesPerFile.diagnostics.map(diagnostic => { + const d = new VSCode.Diagnostic( + new VSCode.Range( + new VSCode.Position(diagnostic.range.start.line, diagnostic.range.start.character), + new VSCode.Position(diagnostic.range.end.line, diagnostic.range.end.character) + ), + diagnostic.message, + DiagnosticSeverity.Error + ); + d.source = diagnostic.source; + d.code = diagnostic.code; + d['data'] = diagnostic.data; + return d; + }); + diagnosticCollection.set(VSCode.Uri.parse(taintVulnerabilitiesPerFile.uri), diagnostics); + }); + languageClient.onRequest( protocol.AssistBinding.type, async params => await BindingService.instance.assistBinding(params) diff --git a/src/hotspot/hotspotsTreeDataProvider.ts b/src/hotspot/hotspotsTreeDataProvider.ts index 7f8d4fdbc..c88853da0 100644 --- a/src/hotspot/hotspotsTreeDataProvider.ts +++ b/src/hotspot/hotspotsTreeDataProvider.ts @@ -9,7 +9,7 @@ import Timeout = NodeJS.Timeout; import * as VSCode from 'vscode'; import { ProviderResult, TextDocument, ThemeColor, ThemeIcon } from 'vscode'; -import { Diagnostic, PublishHotspotsForFileParams } from '../lsp/protocol'; +import { Diagnostic, PublishDiagnosticsParams } from '../lsp/protocol'; import { ConnectionSettingsService } from '../settings/connectionsettings'; import { Commands } from '../util/commands'; import { getFileNameFromFullPath, getRelativePathFromFullPath, protocol2CodeConverter } from '../util/uri'; @@ -126,7 +126,7 @@ export class AllHotspotsTreeDataProvider implements VSCode.TreeDataProvider 0) { this.fileHotspotsCache.set(hotspotsPerFile.uri, hotspotsPerFile.diagnostics); diff --git a/src/lsp/protocol.ts b/src/lsp/protocol.ts index bda15c6ef..9a460e112 100644 --- a/src/lsp/protocol.ts +++ b/src/lsp/protocol.ts @@ -460,13 +460,17 @@ export interface Diagnostic extends lsp.Diagnostic { flows: Flow[]; } -export interface PublishHotspotsForFileParams { +export interface PublishDiagnosticsParams { uri: string; diagnostics: Diagnostic[]; } export namespace PublishHotspotsForFile { - export const type = new lsp.NotificationType('sonarlint/publishSecurityHotspots'); + export const type = new lsp.NotificationType('sonarlint/publishSecurityHotspots'); +} + +export namespace PublishTaintVulnerabilitiesForFile { + export const type = new lsp.NotificationType('sonarlint/publishTaintVulnerabilities'); } export interface ShowHotspotLocationsParams { From 5f8d265af41b43015897dfe1c2d5a80dcdabdbe7 Mon Sep 17 00:00:00 2001 From: Sophio Japharidze Date: Mon, 6 Jan 2025 13:39:33 +0100 Subject: [PATCH 2/2] SLVSCODE-966 apply review comments --- scripts/dependencies.json | 2 +- src/extension.ts | 14 +++++++------- src/util/util.ts | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/scripts/dependencies.json b/scripts/dependencies.json index 4237ec0bb..e55f5a781 100644 --- a/scripts/dependencies.json +++ b/scripts/dependencies.json @@ -2,7 +2,7 @@ { "groupId": "org.sonarsource.sonarlint.ls", "artifactId": "sonarlint-language-server", - "version": "3.15.0.75823", + "version": "3.15.0.75834", "output": "server/sonarlint-ls.jar" }, { diff --git a/src/extension.ts b/src/extension.ts index 5d1791589..e9ad8d7be 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -9,7 +9,7 @@ import * as ChildProcess from 'child_process'; import { DateTime } from 'luxon'; import * as Path from 'path'; import * as VSCode from 'vscode'; -import { DiagnosticSeverity, LanguageClientOptions, StreamInfo } from 'vscode-languageclient/node'; +import { LanguageClientOptions, StreamInfo } from 'vscode-languageclient/node'; import { configureCompilationDatabase, notifyMissingCompileCommands } from './cfamily/cfamily'; import { AutoBindingService } from './connected/autobinding'; import { assistCreatingConnection } from './connected/assistCreatingConnection'; @@ -60,7 +60,7 @@ import { getPlatform } from './util/platform'; import { installManagedJre, JAVA_HOME_CONFIG, resolveRequirements } from './util/requirements'; import { code2ProtocolConverter, protocol2CodeConverter } from './util/uri'; import * as util from './util/util'; -import { filterOutFilesIgnoredForAnalysis, shouldAnalyseFile } from './util/util'; +import { filterOutFilesIgnoredForAnalysis, getSeverity, shouldAnalyseFile } from './util/util'; import { resolveIssueMultiStepInput } from './issue/resolveIssue'; import { IssueService } from './issue/issue'; import { CAN_SHOW_MISSING_REQUIREMENT_NOTIF, showSslCertificateConfirmationDialog } from './util/showMessage'; @@ -92,7 +92,7 @@ let hotspotsTreeDataProvider: AllHotspotsTreeDataProvider; let allHotspotsView: VSCode.TreeView; let helpAndFeedbackTreeDataProvider: HelpAndFeedbackTreeDataProvider; let helpAndFeedbackView: VSCode.TreeView; -let diagnosticCollection: VSCode.DiagnosticCollection; +let taintVulnerabilityCollection: VSCode.DiagnosticCollection; function runJavaServer(context: VSCode.ExtensionContext): Promise { return resolveRequirements(context) @@ -222,8 +222,8 @@ export async function activate(context: VSCode.ExtensionContext) { await languageClient.start(); - diagnosticCollection = VSCode.languages.createDiagnosticCollection('SonarQube Taint Vulnerabilities'); - context.subscriptions.push(diagnosticCollection); + taintVulnerabilityCollection = VSCode.languages.createDiagnosticCollection('SonarQube Taint Vulnerabilities'); + context.subscriptions.push(taintVulnerabilityCollection); ConnectionSettingsService.init(context, languageClient); NewCodeDefinitionService.init(context); @@ -635,14 +635,14 @@ function installCustomRequestHandlers(context: VSCode.ExtensionContext) { new VSCode.Position(diagnostic.range.end.line, diagnostic.range.end.character) ), diagnostic.message, - DiagnosticSeverity.Error + getSeverity(diagnostic.severity) ); d.source = diagnostic.source; d.code = diagnostic.code; d['data'] = diagnostic.data; return d; }); - diagnosticCollection.set(VSCode.Uri.parse(taintVulnerabilitiesPerFile.uri), diagnostics); + taintVulnerabilityCollection.set(VSCode.Uri.parse(taintVulnerabilitiesPerFile.uri), diagnostics); }); languageClient.onRequest( diff --git a/src/util/util.ts b/src/util/util.ts index 5ac601181..b6eb23d69 100644 --- a/src/util/util.ts +++ b/src/util/util.ts @@ -300,3 +300,22 @@ function isOpenInEditor(fileUri: string) { const notebookDocumentIsOpen = vscode.workspace.notebookDocuments.some(d => d.uri.toString(false) === codeFileUri); return textDocumentIsOpen || notebookDocumentIsOpen; } + +export function getSeverity(severity: number): vscode.DiagnosticSeverity { + const SEVERITY_ERROR = 1; + const SEVERITY_WARNING = 2; + const SEVERITY_INFORMATION = 3; + const SEVERITY_HINT = 4; + switch (severity) { + case SEVERITY_ERROR: + return vscode.DiagnosticSeverity.Error; + case SEVERITY_WARNING: + return vscode.DiagnosticSeverity.Warning; + case SEVERITY_INFORMATION: + return vscode.DiagnosticSeverity.Information; + case SEVERITY_HINT: + return vscode.DiagnosticSeverity.Hint; + default: + return vscode.DiagnosticSeverity.Warning; + } +}