From 5ce59c4e82505e412e518466030b71fc29d93682 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Mar 2026 03:56:32 +0000 Subject: [PATCH] Fix redundantPublic rule to handle nested types like Foo.Bar via fullyQualifiedName prefix matching Co-authored-by: calda <1811727+calda@users.noreply.github.com> --- Sources/Rules/RedundantPublic.swift | 3 ++- Tests/Rules/RedundantPublicTests.swift | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Sources/Rules/RedundantPublic.swift b/Sources/Rules/RedundantPublic.swift index 4dd47a5d..6ff73014 100644 --- a/Sources/Rules/RedundantPublic.swift +++ b/Sources/Rules/RedundantPublic.swift @@ -59,7 +59,8 @@ public extension FormatRule { // Inside an extension where the extended type is internal, any `public` modifier has no effect. // We can only handle this case if the extension and type are defined in the same file. if let extendedTypeName = parentType.name, - internalTypes.contains(extendedTypeName) + internalTypes.contains(extendedTypeName) || + internalTypes.contains(where: { extendedTypeName.hasPrefix($0 + ".") }) { declaration.removeVisibility(.public) } diff --git a/Tests/Rules/RedundantPublicTests.swift b/Tests/Rules/RedundantPublicTests.swift index 48fa0caa..b4c783a0 100644 --- a/Tests/Rules/RedundantPublicTests.swift +++ b/Tests/Rules/RedundantPublicTests.swift @@ -195,6 +195,29 @@ final class RedundantPublicTests: XCTestCase { testFormatting(for: input, [output], rules: [.redundantPublic]) } + func testRemovesPublicInExtensionOfPublicNestedTypeInInternalType() { + let input = """ + struct Foo { + public struct Bar {} + } + + extension Foo.Bar { + public func test() {} + } + """ + + let output = """ + struct Foo { + struct Bar {} + } + + extension Foo.Bar { + func test() {} + } + """ + testFormatting(for: input, output, rule: .redundantPublic, exclude: [.enumNamespaces]) + } + func testRemovesPublicInExtensionOfNestedInternalType() { let input = """ enum OuterType {