swiftlang / swift-format

Formatting technology for Swift source code
Apache License 2.0
2.38k stars 216 forks source link

Add a rule to disallow `public` extensions while allowing `private` and `fileprivate` ones #715

Open Matejkob opened 2 months ago

Matejkob commented 2 months ago

Currently, the NoAccessLevelOnExtensionDeclaration rule removes access level attributes from all extensions, regardless of the specific access level. However, there is a valid use case for allowing private and fileprivate extensions while disallowing public extensions.

When an extension is marked as private or fileprivate, it provides a clear indication that the extension and its members are not intended to be accessed from outside the current file or declaration scope. This can help prevent unintended leakage of implementation details and maintain encapsulation.

On the other hand, public extensions can be a source of unintended behavior and may not always align with the intended visibility of the extension members.

func testDisallowPublicExtension() {
  assertFormatting(
    NewRule???.self,
    input: """
        public extension Foo {
            var bar: String { "" }
        }

        private extension Foo {
            var baz: String { "" }
        }
        """,
    expected: """
        extension Foo {
            public var bar: String { "" }
        }

        private extension Foo {
            var baz: String { "" }
        }
        """,
    findings: [
      // TODO: Add findings
    ]
  )
}

Originated from: https://github.com/apple/swift-syntax/pull/2602#issuecomment-2052549838

Matejkob commented 2 months ago

It may be worth considering allowing users to have more customization options and define which access levels should be moved and which should not. This would provide more flexibility and cater to different project requirements and coding styles.

allevato commented 2 months ago

It seems reasonable to add a configuration setting for this.

Rather than focusing on public specifically, I wonder if we should draw the line between access levels that are visible outside the module vs. access levels visible only inside? In other words, ban public/package extension but allow internal/fileprivate/private extension.

ahoppen commented 2 months ago

Tracked in Apple’s issue tracker as rdar://126948459