From 62d709afb3fa9ef8c0a1f5d720892768634743f6 Mon Sep 17 00:00:00 2001 From: Matthias Osswald Date: Wed, 13 Mar 2024 17:36:14 +0100 Subject: [PATCH] fix: Remove duplicate messages Some findings are reported as usage of deprecated API but also as usage of global variables. This change removes the duplicate messages and keeps the one about the deprecated API as it provides more information. --- src/detectors/Reporter.ts | 51 ++++++++++++++---- .../rules/snapshots/NoDeprecatedApi.ts.md | 10 +--- .../rules/snapshots/NoDeprecatedApi.ts.snap | Bin 4447 -> 4393 bytes test/lib/linter/snapshots/linter.ts.md | 30 ++--------- test/lib/linter/snapshots/linter.ts.snap | Bin 7516 -> 7340 bytes 5 files changed, 46 insertions(+), 45 deletions(-) diff --git a/src/detectors/Reporter.ts b/src/detectors/Reporter.ts index e2b62263c..0474006b7 100644 --- a/src/detectors/Reporter.ts +++ b/src/detectors/Reporter.ts @@ -148,19 +148,52 @@ export default class Reporter implements BaseReporter { let errorCount = 0; let warningCount = 0; let fatalErrorCount = 0; - for (const {severity, fatal} of this.#messages) { - if (severity === LintMessageSeverity.Error) { - errorCount++; - if (fatal) { - fatalErrorCount++; - } - } else { - warningCount++; + const lineColumnMessagesMap = new Map(); + const messages: LintMessage[] = []; + for (const message of this.#messages) { + // Group messages by line/column so that we can deduplicate them + if (!message.line || !message.column) { + // If there is no line or column, we cannot group/deduplicate + messages.push(message); + continue; + } + const lineColumnKey = `${message.line}:${message.column}`; + let lineColumnMessages = lineColumnMessagesMap.get(lineColumnKey); + if (!lineColumnMessages) { + lineColumnMessages = []; + lineColumnMessagesMap.set(lineColumnKey, lineColumnMessages); } + lineColumnMessages.push(message); + } + + // Add deduplicated messages to the result + for (const lineColumnMessages of lineColumnMessagesMap.values()) { + // If there are multiple messages for the same line/column, + // and at least one of them is NOT a "no-globals-js" message, + // we can deduplicate the "no-globals-js" messages. + const deduplicateGlobalMessages = lineColumnMessages.length > 1 && + lineColumnMessages.some((message) => message.ruleId !== "ui5-linter-no-globals-js"); + + lineColumnMessages.forEach((message) => { + if (deduplicateGlobalMessages && message.ruleId === "ui5-linter-no-globals-js") { + // Skip global messages if there are other messages for the same line/column + return; + } + if (message.severity === LintMessageSeverity.Error) { + errorCount++; + if (message.fatal) { + fatalErrorCount++; + } + } else { + warningCount++; + } + messages.push(message); + }); } + return { filePath: this.#getFileName(), - messages: this.#messages, + messages, coverageInfo: this.#coverageInfo, errorCount, warningCount, diff --git a/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md b/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md index 4e5cc8f9d..d02a5430f 100644 --- a/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md +++ b/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md @@ -796,7 +796,7 @@ Generated by [AVA](https://avajs.dev). [ { coverageInfo: [], - errorCount: 2, + errorCount: 1, fatalErrorCount: 0, filePath: 'sap.ui.jsview.js', messages: [ @@ -809,14 +809,6 @@ Generated by [AVA](https://avajs.dev). ruleId: 'ui5-linter-no-deprecated-api', severity: 2, }, - { - column: 1, - fatal: undefined, - line: 1, - message: 'Access of global variable \'sap\' (sap.ui.jsview)', - ruleId: 'ui5-linter-no-globals-js', - severity: 2, - }, ], warningCount: 0, }, diff --git a/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.snap b/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.snap index 36268a04f44c0d2b045cf0ea49af88a0045deea3..a9eec832d8752f16b361b85132e7bb018dbbcfd7 100644 GIT binary patch literal 4393 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 literal 4447 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 diff --git a/test/lib/linter/snapshots/linter.ts.md b/test/lib/linter/snapshots/linter.ts.md index 21aee1ef0..1581208cb 100644 --- a/test/lib/linter/snapshots/linter.ts.md +++ b/test/lib/linter/snapshots/linter.ts.md @@ -555,7 +555,7 @@ Generated by [AVA](https://avajs.dev). }, { coverageInfo: [], - errorCount: 3, + errorCount: 2, fatalErrorCount: 0, filePath: 'webapp/test/integration/opaTests.qunit.js', messages: [ @@ -577,14 +577,6 @@ Generated by [AVA](https://avajs.dev). ruleId: 'ui5-linter-no-deprecated-api', severity: 2, }, - { - column: 1, - fatal: undefined, - line: 4, - message: 'Access of global variable \'sap\' (sap.ui.getCore)', - ruleId: 'ui5-linter-no-globals-js', - severity: 2, - }, ], warningCount: 0, }, @@ -678,7 +670,7 @@ Generated by [AVA](https://avajs.dev). }, { coverageInfo: [], - errorCount: 3, + errorCount: 2, fatalErrorCount: 0, filePath: 'webapp/test/unit/unitTests.qunit.js', messages: [ @@ -700,14 +692,6 @@ Generated by [AVA](https://avajs.dev). ruleId: 'ui5-linter-no-deprecated-api', severity: 2, }, - { - column: 1, - fatal: undefined, - line: 6, - message: 'Access of global variable \'sap\' (sap.ui.getCore)', - ruleId: 'ui5-linter-no-globals-js', - severity: 2, - }, ], warningCount: 0, }, @@ -923,7 +907,7 @@ Generated by [AVA](https://avajs.dev). }, { coverageInfo: [], - errorCount: 3, + errorCount: 2, fatalErrorCount: 0, filePath: 'src/main/js/library.js', messages: [ @@ -945,14 +929,6 @@ Generated by [AVA](https://avajs.dev). ruleId: 'ui5-linter-no-deprecated-api', severity: 2, }, - { - column: 2, - fatal: undefined, - line: 15, - message: 'Access of global variable \'sap\' (sap.ui.getCore)', - ruleId: 'ui5-linter-no-globals-js', - severity: 2, - }, ], warningCount: 0, }, diff --git a/test/lib/linter/snapshots/linter.ts.snap b/test/lib/linter/snapshots/linter.ts.snap index 994497e2d5de3e102d9f30e29181fbd8527857e5..bcb3054973e9552a2a50131ea0651f4202371dac 100644 GIT binary patch literal 7340 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