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 36268a04f..a9eec832d 100644 Binary files a/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.snap and b/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.snap differ 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 994497e2d..bcb305497 100644 Binary files a/test/lib/linter/snapshots/linter.ts.snap and b/test/lib/linter/snapshots/linter.ts.snap differ