@@ -6,6 +6,7 @@ import * as crypto from 'crypto';
66import { documentationLinkMap , getPremiumCertLink } from './util/documentation' ;
77import { runCommand } from './util/scripts' ;
88import { looksLikePath , resolvePath , findWorkspaceRoot } from './util/path' ;
9+ import { diagnosticsUnion } from './util/diagnostics' ;
910
1011// To keep track of document changes we save hashed versions of their content to this record
1112let documentHashMemory : Record < string , string > = { } ;
@@ -349,7 +350,6 @@ async function runCppcheckOnFileXML(
349350
350351 const errors = result . results ?. errors ?. [ 0 ] ?. error || [ ] ;
351352 const diagnostics : Record < string , vscode . Diagnostic [ ] > = { } ;
352- console . log ( 'errors from file' , document . fileName , errors ) ;
353353 for ( const e of errors ) {
354354 const isCriticalError = criticalWarningTypes . includes ( e . $ . id ) ;
355355 const locations = e . location || [ ] ;
@@ -358,12 +358,13 @@ async function runCppcheckOnFileXML(
358358 }
359359
360360 const mainLoc = locations [ locations . length - 1 ] . $ ;
361-
362361 // If main location is not current file, we are not using a project file and warning is not critical then skip displaying warning
363362 if ( ! isCriticalError && usingProjectFile && ! filePath . endsWith ( mainLoc . file ) ) {
364363 continue ;
365364 }
366365
366+ const mainLocDocument = await vscode . workspace . openTextDocument ( mainLoc . file ) ;
367+
367368 // Cppcheck line number is 1-indexed, while VS Code uses 0-indexing
368369 let line = Number ( mainLoc . line ) - 1 ;
369370 // Invalid line number usually means non-analysis output
@@ -377,7 +378,7 @@ async function runCppcheckOnFileXML(
377378
378379 // Cppcheck col number is 1-indexed, while VS Code uses 0-indexing
379380 let col = Number ( mainLoc . column ) - 1 ;
380- if ( isNaN ( col ) || col < 0 ) {
381+ if ( isNaN ( col ) || col < 0 || col > mainLocDocument . lineAt ( line ) . text . length ) {
381382 col = 0 ;
382383 }
383384
@@ -386,7 +387,7 @@ async function runCppcheckOnFileXML(
386387 continue ;
387388 }
388389
389- const range = new vscode . Range ( line , col , line , document . lineAt ( line ) . text . length ) ;
390+ const range = new vscode . Range ( line , col , line , mainLocDocument . lineAt ( line ) . text . length ) ;
390391 const diagnostic = new vscode . Diagnostic ( range , e . $ . msg , severity ) ;
391392 diagnostic . source = "cppcheck" ;
392393 // If we have a link to documentation, include it
@@ -405,28 +406,25 @@ async function runCppcheckOnFileXML(
405406 const loc = locations [ locations . length - i ] . $ ;
406407 const msg = loc . info ;
407408 const lLine = Number ( loc . line ) - 1 ;
408- var lCol = Number ( loc . col ) - 1 ;
409+ const lCol = Number ( loc . col ) - 1 ;
409410
410411 if ( msg === null || msg === undefined || isNaN ( lLine ) || lLine < 0 || lLine >= document . lineCount ) {
411412 continue ;
412413 }
413414
414- if ( isNaN ( lCol ) || lCol < 0 ) {
415- lCol = 0 ;
416- }
417-
415+ const relatedDocument = await vscode . workspace . openTextDocument ( loc . file ) ;
418416 const relatedRange = new vscode . Range (
419417 lLine , lCol ,
420- lLine , document . lineAt ( lLine ) . text . length
418+ lLine , relatedDocument . lineAt ( lLine ) . text . length
421419 ) ;
422- const relatedDocument = await vscode . workspace . openTextDocument ( loc . file ) ;
423420 relatedInfos . push (
424421 new vscode . DiagnosticRelatedInformation (
425422 new vscode . Location ( relatedDocument ?. uri ?? '' , relatedRange ) ,
426423 msg
427424 )
428425 ) ;
429426 }
427+
430428 if ( relatedInfos . length > 0 ) {
431429 diagnostic . relatedInformation = relatedInfos ;
432430 }
@@ -448,24 +446,11 @@ async function runCppcheckOnFileXML(
448446 }
449447 const sourceDocumentUri = document . uri . toString ( ) ;
450448 for ( const uri of Object . keys ( diagnostics ) ) {
451- const existingDiagnostics =
452- diagnosticCollection . get ( vscode . Uri . parse ( uri ) ) ;
449+ var newDiagnostics = diagnostics [ uri ] ;
453450 // If file has existing diagnostics from analyzing other files we do not want to overwrite those
454- const newDiagnostics = diagnostics [ uri ] ;
455-
451+ const existingDiagnostics = diagnosticCollection . get ( vscode . Uri . parse ( uri ) ) ;
456452 if ( existingDiagnostics ) {
457- // Compare existing diagnostics to new diagnostics (error code & range) to only push unique ones
458- for ( const diagnostic of existingDiagnostics ) {
459- if ( ! newDiagnostics . some ( ( d ) => {
460- if ( typeof ( diagnostic ?. code ) === "object" && typeof ( diagnostic ?. code ) !== null && typeof ( d ?. code ) === "object" && typeof ( d ?. code ) !== null ) {
461- return diagnostic . code . value === d . code . value && diagnostic . range . isEqual ( d . range ) ;
462- } else {
463- return diagnostic . code === d . code && diagnostic . range . isEqual ( d . range ) ;
464- }
465- } ) ) {
466- newDiagnostics . push ( diagnostic ) ;
467- }
468- }
453+ newDiagnostics = diagnosticsUnion ( newDiagnostics , existingDiagnostics . flat ( ) ) ;
469454 }
470455 diagnosticCollection . set ( vscode . Uri . parse ( uri ) , newDiagnostics ) ;
471456 if ( fileRelationMap [ uri ] === null || fileRelationMap [ uri ] === undefined ) {
0 commit comments