diff --git a/CHANGELOG.md b/CHANGELOG.md index 85241e63325..4e3497a35d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,11 @@ [Juozas Valancius](https://github.com/juozasvalancius) [#3840](https://github.com/realm/SwiftLint/issues/3840) +* Don't skip autocorrect on files that have parser warnings. Only files with + errors reported by the Swift parser will be skipped. + [Marcelo Fabri](https://github.com/marcelofabri) + [#3343](https://github.com/realm/SwiftLint/issues/3343) + #### Bug Fixes * Fix false positives in `unused_closure_parameter` when using parameters with diff --git a/Source/SwiftLintFramework/Models/Linter.swift b/Source/SwiftLintFramework/Models/Linter.swift index d5ce3cb0cc0..42dd51fe640 100644 --- a/Source/SwiftLintFramework/Models/Linter.swift +++ b/Source/SwiftLintFramework/Models/Linter.swift @@ -280,11 +280,17 @@ public struct CollectedLinter { } if let parserDiagnostics = file.parserDiagnostics { - queuedPrintError( - "Skipping correcting file because it produced Swift parser diagnostics: \(file.path ?? "")" - ) - queuedPrintError(toJSON(["diagnostics": parserDiagnostics])) - return [] + let errorDiagnostics = parserDiagnostics.filter { diagnostic in + diagnostic["key.severity"] as? String == "source.diagnostic.severity.error" + } + + if errorDiagnostics.isNotEmpty { + queuedPrintError( + "Skipping correcting file because it produced Swift parser errors: \(file.path ?? "")" + ) + queuedPrintError(toJSON(["diagnostics": errorDiagnostics])) + return [] + } } var corrections = [Correction]() diff --git a/Tests/SwiftLintFrameworkTests/ParserDiagnosticsTests.swift b/Tests/SwiftLintFrameworkTests/ParserDiagnosticsTests.swift index ac5bc0e3a43..f906112e1df 100644 --- a/Tests/SwiftLintFrameworkTests/ParserDiagnosticsTests.swift +++ b/Tests/SwiftLintFrameworkTests/ParserDiagnosticsTests.swift @@ -2,11 +2,47 @@ import XCTest final class ParserDiagnosticsTests: XCTestCase { - func testFileWithParserDiagnostics() { + func testFileWithParserErrorDiagnostics() { parserDiagnosticsDisabledForTests = false XCTAssertNotNil(SwiftLintFile(contents: "importz Foundation").parserDiagnostics) } + func testFileWithParserErrorDiagnosticsDoesntAutocorrect() throws { + let contents = """ + importz Foundation + print(CGPointZero) + """ + XCTAssertNotNil(SwiftLintFile(contents: contents).parserDiagnostics) + + let ruleDescription = LegacyConstantRule.description + .with(corrections: [Example(contents): Example(contents)]) + + let config = try XCTUnwrap(makeConfig(nil, ruleDescription.identifier, skipDisableCommandTests: true)) + verifyCorrections(ruleDescription, config: config, disableCommands: [], + testMultiByteOffsets: false, parserDiagnosticsDisabledForTests: false) + } + + func testFileWithParserWarningDiagnostics() throws { + parserDiagnosticsDisabledForTests = false + // extraneous duplicate parameter name; 'bar' already has an argument label + let original = """ + func foo(bar bar: String) -> Int { 0 } + """ + + let corrected = """ + func foo(bar bar: String) -> Int { 0 } + """ + + XCTAssertNotNil(SwiftLintFile(contents: original).parserDiagnostics) + + let ruleDescription = ReturnArrowWhitespaceRule.description + .with(corrections: [Example(original): Example(corrected)]) + + let config = try XCTUnwrap(makeConfig(nil, ruleDescription.identifier, skipDisableCommandTests: true)) + verifyCorrections(ruleDescription, config: config, disableCommands: [], + testMultiByteOffsets: false, parserDiagnosticsDisabledForTests: false) + } + func testFileWithoutParserDiagnostics() { parserDiagnosticsDisabledForTests = false XCTAssertNil(SwiftLintFile(contents: "import Foundation").parserDiagnostics) diff --git a/Tests/SwiftLintFrameworkTests/TestHelpers.swift b/Tests/SwiftLintFrameworkTests/TestHelpers.swift index ace7b930267..7307f718155 100644 --- a/Tests/SwiftLintFrameworkTests/TestHelpers.swift +++ b/Tests/SwiftLintFrameworkTests/TestHelpers.swift @@ -400,10 +400,11 @@ extension XCTestCase { } func verifyCorrections(_ ruleDescription: RuleDescription, config: Configuration, - disableCommands: [String], testMultiByteOffsets: Bool) { + disableCommands: [String], testMultiByteOffsets: Bool, + parserDiagnosticsDisabledForTests: Bool = true) { let ruleDescription = ruleDescription.focused() - parserDiagnosticsDisabledForTests = true + SwiftLintFramework.parserDiagnosticsDisabledForTests = parserDiagnosticsDisabledForTests // corrections ruleDescription.corrections.forEach {