Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

organizeDeclarations custom naming & ordering #1736

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from

Conversation

oiuhr
Copy link
Contributor

@oiuhr oiuhr commented Jun 18, 2024

This PR adds an ability to parametrize order inside organizeDeclarations categories & their respective marks.

I'm not sure about the design so it's up to discussion, but long story short:

We have 6 visibility categories (plus 2 for airbnb conventions, but i guess this number can increase without any major changes) and ~15 type groups. By providing parameters --visibilityorder we sort visibility categories (the same goes for the typeorder), and by --mode parameter we tell which category will be respected as primary sorting group. Each group either take a default mark comment value or custom parametrized with parameters --visibilitymark & --typemark, if provided.

Copy link

codecov bot commented Jun 18, 2024

Codecov Report

Attention: Patch coverage is 94.50549% with 20 lines in your changes missing coverage. Please review.

Project coverage is 95.21%. Comparing base (a9c61c1) to head (79518d3).

Files Patch % Lines
Sources/OptionDescriptor.swift 80.95% 16 Missing ⚠️
Sources/FormattingHelpers.swift 98.46% 4 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1736      +/-   ##
===========================================
- Coverage    95.49%   95.21%   -0.29%     
===========================================
  Files           20       20              
  Lines        23386    23580     +194     
===========================================
+ Hits         22332    22451     +119     
- Misses        1054     1129      +75     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@oiuhr
Copy link
Contributor Author

oiuhr commented Jun 18, 2024

Current questions:

  • Is it okay if we cant filter out custom marks? For example: we were using default mark for instance lifecycle group, which was given an // MARK: Lifecycle mark. Then we change up to custom mark, smth like // MARK: Init and // MARK: Lifecycle is replaced. But if we jump from custom to default formatter simply have nothing to compare and just place // MARK: Lifecycle under previously used custom mark. Should we add something like --potentialCategoryMarks to filter them out if needed?
  • I couldn't find the way to somehow validate provided parameters. For example --visibilityorder clearly should have 6+ entries in it, all of which should be unique and valid 💀

Comment on lines 1293 to 1302
[
beforeMarks,
instanceLifecycle,
open,
public,
package,
internal,
fileprivate,
private
]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I assume the argument itself doesn't allow the [ and ] characters, maybe we should omit them from the default example?

Suggested change
[
beforeMarks,
instanceLifecycle,
open,
public,
package,
internal,
fileprivate,
private
]
beforeMarks,
instanceLifecycle,
open,
public,
package,
internal,
fileprivate,
private

@calda
Copy link
Collaborator

calda commented Jun 18, 2024

Is it okay if we cant filter out custom marks? For example: we were using default mark for instance lifecycle group, which was given an // MARK: Lifecycle mark. Then we change up to custom mark, smth like // MARK: Init and // MARK: Lifecycle is replaced. But if we jump from custom to default formatter simply have nothing to compare and just place // MARK: Lifecycle under previously used custom mark. Should we add something like --potentialCategoryMarks to filter them out if needed?

To me it seems fine to leave this as-is.

Copy link
Collaborator

@calda calda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really cool, nice work! The implementation is really simple. Great to see how this builds on top of #1678.

I left some minor comments but otherwise this looks great to me!

The most important point is probably this discussion related to generating the DeclarationType for each declaration: #1736 (comment)

Sources/FormattingHelpers.swift Outdated Show resolved Hide resolved
Sources/Examples.swift Outdated Show resolved Hide resolved
Sources/FormattingHelpers.swift Show resolved Hide resolved
Sources/OptionDescriptor.swift Outdated Show resolved Hide resolved
Sources/OptionDescriptor.swift Outdated Show resolved Hide resolved
Sources/Options.swift Outdated Show resolved Hide resolved
Sources/Options.swift Outdated Show resolved Hide resolved
Tests/RulesTests+Organization.swift Show resolved Hide resolved
@nicklockwood nicklockwood force-pushed the develop branch 3 times, most recently from c6722bc to c9f9e8b Compare June 23, 2024 07:50
@nicklockwood nicklockwood force-pushed the develop branch 3 times, most recently from 610e36b to 15531fd Compare June 29, 2024 08:21
@nicklockwood nicklockwood force-pushed the develop branch 2 times, most recently from 0bcca90 to a9c61c1 Compare July 10, 2024 19:07
@oiuhr oiuhr force-pushed the organizeDeclarations-custom-order branch from eb89782 to 48c9120 Compare July 17, 2024 02:17
Copy link
Collaborator

@calda calda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is REALLY AWESOME! Nice work! I really like the way you implemented the validation. Great idea!

I left a few minor comments, but otherwise this is looking really good!!

@@ -1291,6 +1291,18 @@ private struct Examples {
"""

let organizeDeclarations = """
Default value for `--visibilityorder`:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice!

Rules.md Outdated

<details>
<summary>Examples</summary>

Default value for `--visibilityorder`:
`["beforeMarks", "instanceLifecycle", "open", "public", "package", "internal", "fileprivate", "private"]`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we format these defaults in a way that would be accepted by the --visibilityorder argument?

So, instead, maybe:

Suggested change
`["beforeMarks", "instanceLifecycle", "open", "public", "package", "internal", "fileprivate", "private"]`
`beforeMarks, instanceLifecycle, open, public, package, internal, fileprivate, private`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, thanks! this looks much better

let essentials = Formatter.VisibilityType.essentialCases.map(\.rawValue)
for type in essentials {
guard order.contains(type) else {
throw FormatError.options("--visibilityorder expects \(type) to be included")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea!

guard let match = type.bestMatches(in: essentials).first else {
throw FormatError.options(errorMessage)
}
throw FormatError.options(errorMessage + ". Did you mean '\(match)?'")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great UX here!

@@ -262,7 +262,7 @@ class CommandLineTests: XCTestCase {
func testHelpLineLength() {
CLI.print = { message, _ in
for line in message.components(separatedBy: "\n") {
XCTAssertLessThanOrEqual(line.count, 80, line)
XCTAssertLessThanOrEqual(line.count, 100, line)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't change this

Suggested change
XCTAssertLessThanOrEqual(line.count, 100, line)
XCTAssertLessThanOrEqual(line.count, 80, line)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sry, rolled back

Sources/FormattingHelpers.swift Show resolved Hide resolved
switch self {
case .beforeMarks:
return "Before Marks"
"Before Marks"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need to include the explicit return here since SwiftFormat supports old Swift versions without this newer feature

Suggested change
"Before Marks"
return "Before Marks"

case .keyword("let"), .keyword("var"),
.keyword("operator"), .keyword("precedencegroup"):

if isOverriddenDeclaration && availableTypes.contains(.overriddenProperty) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! This looks great

let customVisibilityMarks = options.customVisibilityMarks
let customTypeMarks = options.customTypeMarks

func parseMarks<T: RawRepresentable>(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this could put put somewhere else in the file rather than being nested in the categoryOrder method?

let parsedVisibilityMarks: ParsedVisibilityMarks = parseMarks(for: customVisibilityMarks)
let parsedTypeMarks: ParsedTypeMarks = parseMarks(for: customTypeMarks)

func flatten<C1: Collection, C2: Collection>(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for this helper, maybe it doesn't need to be nested in this categoryOrder method

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants