diff --git a/Sources/SwiftFormat/Core/Pipelines+Generated.swift b/Sources/SwiftFormat/Core/Pipelines+Generated.swift index 286c1f5c8..4e524c56b 100644 --- a/Sources/SwiftFormat/Core/Pipelines+Generated.swift +++ b/Sources/SwiftFormat/Core/Pipelines+Generated.swift @@ -37,10 +37,12 @@ class LintPipeline: SyntaxVisitor { } override func visit(_ node: ActorDeclSyntax) -> SyntaxVisitorContinueKind { + visitIfEnabled(AllPublicDeclarationsHaveDocumentation.visit, for: node) visitIfEnabled(TypeNamesShouldBeCapitalized.visit, for: node) return .visitChildren } override func visitPost(_ node: ActorDeclSyntax) { + onVisitPost(rule: AllPublicDeclarationsHaveDocumentation.self, for: node) onVisitPost(rule: TypeNamesShouldBeCapitalized.self, for: node) } @@ -179,6 +181,7 @@ class LintPipeline: SyntaxVisitor { } override func visit(_ node: EnumDeclSyntax) -> SyntaxVisitorContinueKind { + visitIfEnabled(AllPublicDeclarationsHaveDocumentation.visit, for: node) visitIfEnabled(BeginDocumentationCommentWithOneLineSummary.visit, for: node) visitIfEnabled(FullyIndirectEnum.visit, for: node) visitIfEnabled(NoLeadingUnderscores.visit, for: node) @@ -188,6 +191,7 @@ class LintPipeline: SyntaxVisitor { return .visitChildren } override func visitPost(_ node: EnumDeclSyntax) { + onVisitPost(rule: AllPublicDeclarationsHaveDocumentation.self, for: node) onVisitPost(rule: BeginDocumentationCommentWithOneLineSummary.self, for: node) onVisitPost(rule: FullyIndirectEnum.self, for: node) onVisitPost(rule: NoLeadingUnderscores.self, for: node) diff --git a/Sources/SwiftFormat/Rules/AllPublicDeclarationsHaveDocumentation.swift b/Sources/SwiftFormat/Rules/AllPublicDeclarationsHaveDocumentation.swift index 75d619539..feaa3a550 100644 --- a/Sources/SwiftFormat/Rules/AllPublicDeclarationsHaveDocumentation.swift +++ b/Sources/SwiftFormat/Rules/AllPublicDeclarationsHaveDocumentation.swift @@ -46,7 +46,7 @@ public final class AllPublicDeclarationsHaveDocumentation: SyntaxLintRule { public override func visit(_ node: ClassDeclSyntax) -> SyntaxVisitorContinueKind { diagnoseMissingDocComment(DeclSyntax(node), name: node.name.text, modifiers: node.modifiers) - return .skipChildren + return .visitChildren } public override func visit(_ node: VariableDeclSyntax) -> SyntaxVisitorContinueKind { @@ -57,7 +57,17 @@ public final class AllPublicDeclarationsHaveDocumentation: SyntaxLintRule { public override func visit(_ node: StructDeclSyntax) -> SyntaxVisitorContinueKind { diagnoseMissingDocComment(DeclSyntax(node), name: node.name.text, modifiers: node.modifiers) - return .skipChildren + return .visitChildren + } + + public override func visit(_ node: EnumDeclSyntax) -> SyntaxVisitorContinueKind { + diagnoseMissingDocComment(DeclSyntax(node), name: node.name.text, modifiers: node.modifiers) + return .visitChildren + } + + public override func visit(_ node: ActorDeclSyntax) -> SyntaxVisitorContinueKind { + diagnoseMissingDocComment(DeclSyntax(node), name: node.name.text, modifiers: node.modifiers) + return .visitChildren } public override func visit(_ node: ProtocolDeclSyntax) -> SyntaxVisitorContinueKind { diff --git a/Sources/SwiftFormat/Rules/BeginDocumentationCommentWithOneLineSummary.swift b/Sources/SwiftFormat/Rules/BeginDocumentationCommentWithOneLineSummary.swift index 2195bd796..92fefce8a 100644 --- a/Sources/SwiftFormat/Rules/BeginDocumentationCommentWithOneLineSummary.swift +++ b/Sources/SwiftFormat/Rules/BeginDocumentationCommentWithOneLineSummary.swift @@ -40,7 +40,7 @@ public final class BeginDocumentationCommentWithOneLineSummary: SyntaxLintRule { public override func visit(_ node: EnumDeclSyntax) -> SyntaxVisitorContinueKind { diagnoseDocComments(in: DeclSyntax(node)) - return .skipChildren + return .visitChildren } public override func visit(_ node: InitializerDeclSyntax) -> SyntaxVisitorContinueKind { @@ -60,7 +60,7 @@ public final class BeginDocumentationCommentWithOneLineSummary: SyntaxLintRule { public override func visit(_ node: ClassDeclSyntax) -> SyntaxVisitorContinueKind { diagnoseDocComments(in: DeclSyntax(node)) - return .skipChildren + return .visitChildren } public override func visit(_ node: VariableDeclSyntax) -> SyntaxVisitorContinueKind { @@ -70,7 +70,7 @@ public final class BeginDocumentationCommentWithOneLineSummary: SyntaxLintRule { public override func visit(_ node: StructDeclSyntax) -> SyntaxVisitorContinueKind { diagnoseDocComments(in: DeclSyntax(node)) - return .skipChildren + return .visitChildren } public override func visit(_ node: ProtocolDeclSyntax) -> SyntaxVisitorContinueKind { diff --git a/Sources/SwiftFormat/Rules/UseSynthesizedInitializer.swift b/Sources/SwiftFormat/Rules/UseSynthesizedInitializer.swift index e3d4e2444..43ba2d67d 100644 --- a/Sources/SwiftFormat/Rules/UseSynthesizedInitializer.swift +++ b/Sources/SwiftFormat/Rules/UseSynthesizedInitializer.swift @@ -72,7 +72,7 @@ public final class UseSynthesizedInitializer: SyntaxLintRule { extraneousInitializers.forEach { diagnose(.removeRedundantInitializer, on: $0) } } - return .skipChildren + return .visitChildren } /// Compares the actual access level of an initializer with the access level of a synthesized diff --git a/Tests/SwiftFormatTests/Rules/AllPublicDeclarationsHaveDocumentationTests.swift b/Tests/SwiftFormatTests/Rules/AllPublicDeclarationsHaveDocumentationTests.swift index b32fdb5ff..81965c38c 100644 --- a/Tests/SwiftFormatTests/Rules/AllPublicDeclarationsHaveDocumentationTests.swift +++ b/Tests/SwiftFormatTests/Rules/AllPublicDeclarationsHaveDocumentationTests.swift @@ -7,16 +7,40 @@ final class AllPublicDeclarationsHaveDocumentationTests: LintOrFormatRuleTestCas assertLint( AllPublicDeclarationsHaveDocumentation.self, """ - 1️⃣public func lightswitchRave() { - } + 1️⃣public func lightswitchRave() {} + /// Comment. + public func lightswitchRave() {} + func lightswitchRave() {} - 2️⃣public var isSblounskched: Int { - return 0 - } + 2️⃣public var isSblounskched: Int { return 0 } + /// Comment. + public var isSblounskched: Int { return 0 } + var isSblounskched: Int { return 0 } - /// Everybody to the limit. - public func fhqwhgads() { - } + 3️⃣public struct Foo {} + /// Comment. + public struct Foo {} + struct Foo {} + + 4️⃣public actor Bar {} + /// Comment. + public actor Bar {} + actor Bar {} + + 5️⃣public class Baz {} + /// Comment. + public class Baz {} + class Baz {} + + 6️⃣public enum Qux {} + /// Comment. + public enum Qux {} + enum Qux {} + + 7️⃣public typealias MyType = Int + /// Comment. + public typealias MyType = Int + typealias MyType = Int /** * Determines if an email was delorted. @@ -28,6 +52,138 @@ final class AllPublicDeclarationsHaveDocumentationTests: LintOrFormatRuleTestCas findings: [ FindingSpec("1️⃣", message: "add a documentation comment for 'lightswitchRave()'"), FindingSpec("2️⃣", message: "add a documentation comment for 'isSblounskched'"), + FindingSpec("3️⃣", message: "add a documentation comment for 'Foo'"), + FindingSpec("4️⃣", message: "add a documentation comment for 'Bar'"), + FindingSpec("5️⃣", message: "add a documentation comment for 'Baz'"), + FindingSpec("6️⃣", message: "add a documentation comment for 'Qux'"), + FindingSpec("7️⃣", message: "add a documentation comment for 'MyType'") + ] + ) + } + + func testNestedDecls() { + assertLint( + AllPublicDeclarationsHaveDocumentation.self, + """ + /// Comment. + public struct MyContainer { + 1️⃣public func lightswitchRave() {} + /// Comment. + public func lightswitchRave() {} + func lightswitchRave() {} + + 2️⃣public var isSblounskched: Int { return 0 } + /// Comment. + public var isSblounskched: Int { return 0 } + var isSblounskched: Int { return 0 } + + 3️⃣public struct Foo {} + /// Comment. + public struct Foo {} + struct Foo {} + + 4️⃣public actor Bar {} + /// Comment. + public actor Bar {} + actor Bar {} + + 5️⃣public class Baz {} + /// Comment. + public class Baz {} + class Baz {} + + 6️⃣public enum Qux {} + /// Comment. + public enum Qux {} + enum Qux {} + + 7️⃣public typealias MyType = Int + /// Comment. + public typealias MyType = Int + typealias MyType = Int + + } + """, + findings: [ + FindingSpec("1️⃣", message: "add a documentation comment for 'lightswitchRave()'"), + FindingSpec("2️⃣", message: "add a documentation comment for 'isSblounskched'"), + FindingSpec("3️⃣", message: "add a documentation comment for 'Foo'"), + FindingSpec("4️⃣", message: "add a documentation comment for 'Bar'"), + FindingSpec("5️⃣", message: "add a documentation comment for 'Baz'"), + FindingSpec("6️⃣", message: "add a documentation comment for 'Qux'"), + FindingSpec("7️⃣", message: "add a documentation comment for 'MyType'") + ] + ) + } + + func testNestedInStruct() { + assertLint( + AllPublicDeclarationsHaveDocumentation.self, + """ + /// Comment. + public struct MyContainer { + 1️⃣public typealias MyType = Int + /// Comment. + public typealias MyType = Int + typealias MyType = Int + } + """, + findings: [ + FindingSpec("1️⃣", message: "add a documentation comment for 'MyType'"), + ] + ) + } + + func testNestedInClass() { + assertLint( + AllPublicDeclarationsHaveDocumentation.self, + """ + /// Comment. + public class MyContainer { + 1️⃣public typealias MyType = Int + /// Comment. + public typealias MyType = Int + typealias MyType = Int + } + """, + findings: [ + FindingSpec("1️⃣", message: "add a documentation comment for 'MyType'"), + ] + ) + } + + func testNestedInEnum() { + assertLint( + AllPublicDeclarationsHaveDocumentation.self, + """ + /// Comment. + public enum MyContainer { + 1️⃣public typealias MyType = Int + /// Comment. + public typealias MyType = Int + typealias MyType = Int + } + """, + findings: [ + FindingSpec("1️⃣", message: "add a documentation comment for 'MyType'"), + ] + ) + } + + func testNestedInActor() { + assertLint( + AllPublicDeclarationsHaveDocumentation.self, + """ + /// Comment. + public actor MyContainer { + 1️⃣public typealias MyType = Int + /// Comment. + public typealias MyType = Int + typealias MyType = Int + } + """, + findings: [ + FindingSpec("1️⃣", message: "add a documentation comment for 'MyType'"), ] ) } diff --git a/Tests/SwiftFormatTests/Rules/BeginDocumentationCommentWithOneLineSummaryTests.swift b/Tests/SwiftFormatTests/Rules/BeginDocumentationCommentWithOneLineSummaryTests.swift index cfeaa09dd..6c96f6d8a 100644 --- a/Tests/SwiftFormatTests/Rules/BeginDocumentationCommentWithOneLineSummaryTests.swift +++ b/Tests/SwiftFormatTests/Rules/BeginDocumentationCommentWithOneLineSummaryTests.swift @@ -169,4 +169,69 @@ final class BeginDocumentationCommentWithOneLineSummaryTests: LintOrFormatRuleTe """ ) } + + func testNestedInsideStruct() { + assertLint( + BeginDocumentationCommentWithOneLineSummary.self, + """ + struct MyContainer { + /// This docline should not succeed. + /// There are two sentences without a blank line between them. + 1️⃣struct Test {} + } + """, + findings: [ + FindingSpec("1️⃣", message: #"add a blank comment line after this sentence: "This docline should not succeed.""#) + ] + ) + } + + func testNestedInsideEnum() { + assertLint( + BeginDocumentationCommentWithOneLineSummary.self, + """ + enum MyContainer { + /// This docline should not succeed. + /// There are two sentences without a blank line between them. + 1️⃣struct Test {} + } + """, + findings: [ + FindingSpec("1️⃣", message: #"add a blank comment line after this sentence: "This docline should not succeed.""#) + ] + ) + } + + func testNestedInsideClass() { + assertLint( + BeginDocumentationCommentWithOneLineSummary.self, + """ + class MyContainer { + /// This docline should not succeed. + /// There are two sentences without a blank line between them. + 1️⃣struct Test {} + } + """, + findings: [ + FindingSpec("1️⃣", message: #"add a blank comment line after this sentence: "This docline should not succeed.""#) + ] + ) + } + + func testNestedInsideActor() { + assertLint( + BeginDocumentationCommentWithOneLineSummary.self, + """ + actor MyContainer { + /// This docline should not succeed. + /// There are two sentences without a blank line between them. + 1️⃣struct Test {} + } + """, + findings: [ + FindingSpec("1️⃣", message: #"add a blank comment line after this sentence: "This docline should not succeed.""#) + ] + ) + } + } diff --git a/Tests/SwiftFormatTests/Rules/UseSynthesizedInitializerTests.swift b/Tests/SwiftFormatTests/Rules/UseSynthesizedInitializerTests.swift index fa00858fe..a21c99ba8 100644 --- a/Tests/SwiftFormatTests/Rules/UseSynthesizedInitializerTests.swift +++ b/Tests/SwiftFormatTests/Rules/UseSynthesizedInitializerTests.swift @@ -26,6 +26,26 @@ final class UseSynthesizedInitializerTests: LintOrFormatRuleTestCase { ) } + func testNestedMemberwiseInitializerIsDiagnosed() { + assertLint( + UseSynthesizedInitializer.self, + """ + public struct MyContainer { + public struct Person { + public var name: String + + 1️⃣init(name: String) { + self.name = name + } + } + } + """, + findings: [ + FindingSpec("1️⃣", message: "remove this explicit initializer, which is identical to the compiler-synthesized initializer"), + ] + ) + } + func testInternalMemberwiseInitializerIsDiagnosed() { assertLint( UseSynthesizedInitializer.self,