From 9040f6cb7e47f244700a3b622b69b1b521511cad Mon Sep 17 00:00:00 2001 From: Tony Allevato Date: Tue, 13 Sep 2022 09:14:03 -0700 Subject: [PATCH 1/9] Update package and version number for 0.50700.0 release. --- Package.swift | 6 +++--- Sources/swift-format/VersionOptions.swift | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Package.swift b/Package.swift index 9ab3fa332..8156ccfa2 100644 --- a/Package.swift +++ b/Package.swift @@ -215,15 +215,15 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil { package.dependencies += [ .package( url: "https://github.com/apple/swift-argument-parser.git", - branch: "main" + .upToNextMinor(from: "1.1.4") ), .package( url: "https://github.com/apple/swift-syntax.git", - branch: "main" + branch: "swift-5.7-RELEASE" ), .package( url: "https://github.com/apple/swift-tools-support-core.git", - branch: "main" + .upToNextMinor(from: "0.2.7") ), ] } else { diff --git a/Sources/swift-format/VersionOptions.swift b/Sources/swift-format/VersionOptions.swift index 8ac851fdc..93f6e9703 100644 --- a/Sources/swift-format/VersionOptions.swift +++ b/Sources/swift-format/VersionOptions.swift @@ -20,7 +20,7 @@ struct VersionOptions: ParsableArguments { func validate() throws { if version { // TODO: Automate updates to this somehow. - print("0.50500.0") + print("0.50700.0") throw ExitCode.success } } From b1e746d5f8609f9bf06023f6070a5683834a6364 Mon Sep 17 00:00:00 2001 From: Tony Allevato Date: Tue, 20 Sep 2022 09:05:20 -0700 Subject: [PATCH 2/9] Update swift-syntax dependency to 0.50700.0. --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 8156ccfa2..522633896 100644 --- a/Package.swift +++ b/Package.swift @@ -219,7 +219,7 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil { ), .package( url: "https://github.com/apple/swift-syntax.git", - branch: "swift-5.7-RELEASE" + .upToNextMinor(from: "0.50700.0") ), .package( url: "https://github.com/apple/swift-tools-support-core.git", From 217377bdbf6481ccc544ac19b5a17462a40f155c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 12 Dec 2022 16:37:56 -0800 Subject: [PATCH 3/9] Add an option to allow space around range formation operators. Fixes #457 --- Documentation/Configuration.md | 3 ++ .../Configuration.swift | 10 +++++ .../TokenStreamCreator.swift | 12 ++++-- .../BinaryOperatorExprTests.swift | 37 ++++++++++++++++++- 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/Documentation/Configuration.md b/Documentation/Configuration.md index a0afbd65d..6f1092103 100644 --- a/Documentation/Configuration.md +++ b/Documentation/Configuration.md @@ -79,6 +79,9 @@ top-level keys and values: true, a line break is forced before the "." of the component and after the component's closing delimiter (i.e. right paren, right bracket, right brace, etc.). +* `spacesAroundRangeFormationOperators` _(boolean)_: Determines whether whitespace should be forced + before and after the range formation operators `...` and `..<`. + > TODO: Add support for enabling/disabling specific syntax transformations in > the pipeline. diff --git a/Sources/SwiftFormatConfiguration/Configuration.swift b/Sources/SwiftFormatConfiguration/Configuration.swift index 3648f6973..f698a3982 100644 --- a/Sources/SwiftFormatConfiguration/Configuration.swift +++ b/Sources/SwiftFormatConfiguration/Configuration.swift @@ -35,6 +35,7 @@ public struct Configuration: Codable, Equatable { case fileScopedDeclarationPrivacy case indentSwitchCaseLabels case rules + case spacesAroundRangeFormationOperators } /// The version of this configuration. @@ -142,6 +143,10 @@ public struct Configuration: Codable, Equatable { ///``` public var indentSwitchCaseLabels = false + /// Determines whether whitespace should be forced before and after the range formation operators + /// `...` and `..<`. + public var spacesAroundRangeFormationOperators = false + /// Constructs a Configuration with all default values. public init() { self.version = highestSupportedConfigurationVersion @@ -194,6 +199,9 @@ public struct Configuration: Codable, Equatable { self.lineBreakAroundMultilineExpressionChainComponents = try container.decodeIfPresent( Bool.self, forKey: .lineBreakAroundMultilineExpressionChainComponents) ?? false + self.spacesAroundRangeFormationOperators = + try container.decodeIfPresent( + Bool.self, forKey: .spacesAroundRangeFormationOperators) ?? false self.fileScopedDeclarationPrivacy = try container.decodeIfPresent( FileScopedDeclarationPrivacyConfiguration.self, forKey: .fileScopedDeclarationPrivacy) @@ -226,6 +234,8 @@ public struct Configuration: Codable, Equatable { try container.encode( lineBreakAroundMultilineExpressionChainComponents, forKey: .lineBreakAroundMultilineExpressionChainComponents) + try container.encode( + spacesAroundRangeFormationOperators, forKey: .spacesAroundRangeFormationOperators) try container.encode(fileScopedDeclarationPrivacy, forKey: .fileScopedDeclarationPrivacy) try container.encode(indentSwitchCaseLabels, forKey: .indentSwitchCaseLabels) try container.encode(rules, forKey: .rules) diff --git a/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift b/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift index 857f5bc31..0e4747122 100644 --- a/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift +++ b/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift @@ -3296,20 +3296,24 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { return nil } - /// Returns a value indicating whether whitespace should be required around the given operator. + /// Returns a value indicating whether whitespace should be required around the given operator, + /// for the given configuration. /// /// If spaces are not required (for example, range operators), then the formatter will also forbid /// breaks around the operator. This is to prevent situations where a break could occur before an /// unspaced operator (e.g., turning `0...10` into `0...10`), which would be a breaking /// change because it would treat it as a prefix operator `...10` instead of an infix operator. - private func shouldRequireWhitespace(around operatorExpr: ExprSyntax) -> Bool { + private func shouldRequireWhitespace( + around operatorExpr: ExprSyntax, configuration: Configuration) -> Bool + { // Note that we look at the operator itself to make this determination, not the token kind. // The token kind (spaced or unspaced operator) represents how the *user* wrote it, and we want // to ignore that and apply our own rules. if let binaryOperator = operatorExpr.as(BinaryOperatorExprSyntax.self) { let token = binaryOperator.operatorToken - if let binOp = operatorTable.infixOperator(named: token.text), - let precedenceGroup = binOp.precedenceGroup, precedenceGroup == "RangeFormationPrecedence" + if !config.spacesAroundRangeFormationOperators, + let binOp = operatorTable.infixOperator(named: token.text), + let precedenceGroup = binOp.precedenceGroup, precedenceGroup == "RangeFormationPrecedence" { // We want to omit whitespace around range formation operators if possible. We can't do this // if the token is either preceded by a postfix operator, followed by a prefix operator, or diff --git a/Tests/SwiftFormatPrettyPrintTests/BinaryOperatorExprTests.swift b/Tests/SwiftFormatPrettyPrintTests/BinaryOperatorExprTests.swift index 5c37caf70..1a97cd76e 100644 --- a/Tests/SwiftFormatPrettyPrintTests/BinaryOperatorExprTests.swift +++ b/Tests/SwiftFormatPrettyPrintTests/BinaryOperatorExprTests.swift @@ -1,3 +1,5 @@ +import SwiftFormatConfiguration + final class BinaryOperatorExprTests: PrettyPrintTestCase { func testNonRangeFormationOperatorsAreSurroundedByBreaks() { let input = @@ -26,7 +28,7 @@ final class BinaryOperatorExprTests: PrettyPrintTestCase { assertPrettyPrintEqual(input: input, expected: expected10, linelength: 10) } - func testRangeFormationOperatorsAreCompactedWhenPossible() { + func testRangeFormationOperatorCompaction_noSpacesAroundRangeFormation() { let input = """ x = 1...100 @@ -48,7 +50,38 @@ final class BinaryOperatorExprTests: PrettyPrintTestCase { """ - assertPrettyPrintEqual(input: input, expected: expected, linelength: 80) + var configuration = Configuration() + configuration.spacesAroundRangeFormationOperators = false + assertPrettyPrintEqual( + input: input, expected: expected, linelength: 80, configuration: configuration) + } + + func testRangeFormationOperatorCompaction_spacesAroundRangeFormation() { + let input = + """ + x = 1...100 + x = 1..<100 + x = (1++)...(-100) + x = 1 ... 100 + x = 1 ..< 100 + x = (1++) ... (-100) + """ + + let expected = + """ + x = 1 ... 100 + x = 1 ..< 100 + x = (1++) ... (-100) + x = 1 ... 100 + x = 1 ..< 100 + x = (1++) ... (-100) + + """ + + var configuration = Configuration() + configuration.spacesAroundRangeFormationOperators = true + assertPrettyPrintEqual( + input: input, expected: expected, linelength: 80, configuration: configuration) } func testRangeFormationOperatorsAreNotCompactedWhenFollowingAPostfixOperator() { From 58be9def9fa2a01866d4f384772ca18735df61a2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 12 Dec 2022 16:46:17 -0800 Subject: [PATCH 4/9] Attempt to rebase. --- Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift b/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift index 0e4747122..535cad3df 100644 --- a/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift +++ b/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift @@ -1777,7 +1777,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { let wrapsBeforeOperator = !isAssigningOperator(binOp) - if shouldRequireWhitespace(around: binOp) { + if shouldRequireWhitespace(around: binOp, configuration: config) { if isAssigningOperator(binOp) { var beforeTokens: [Token] From 59fad250f8dce9eb12784755d1fb92e98fc31744 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 12 Dec 2022 16:57:49 -0800 Subject: [PATCH 5/9] Update to swift-syntax main branch --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 522633896..3c2bb3408 100644 --- a/Package.swift +++ b/Package.swift @@ -219,7 +219,7 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil { ), .package( url: "https://github.com/apple/swift-syntax.git", - .upToNextMinor(from: "0.50700.0") + branch: "main" ), .package( url: "https://github.com/apple/swift-tools-support-core.git", From 49f15a9b2ff6c459e987f1053f9fd3daf06ba6b2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 13 Dec 2022 07:59:49 -0800 Subject: [PATCH 6/9] Remove needless parameter --- Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift b/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift index 535cad3df..fa592e4cf 100644 --- a/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift +++ b/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift @@ -1777,7 +1777,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { let wrapsBeforeOperator = !isAssigningOperator(binOp) - if shouldRequireWhitespace(around: binOp, configuration: config) { + if shouldRequireWhitespace(around: binOp) { if isAssigningOperator(binOp) { var beforeTokens: [Token] @@ -3303,9 +3303,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { /// breaks around the operator. This is to prevent situations where a break could occur before an /// unspaced operator (e.g., turning `0...10` into `0...10`), which would be a breaking /// change because it would treat it as a prefix operator `...10` instead of an infix operator. - private func shouldRequireWhitespace( - around operatorExpr: ExprSyntax, configuration: Configuration) -> Bool - { + private func shouldRequireWhitespace(around operatorExpr: ExprSyntax) -> Bool { // Note that we look at the operator itself to make this determination, not the token kind. // The token kind (spaced or unspaced operator) represents how the *user* wrote it, and we want // to ignore that and apply our own rules. From cf4384bd878e0ddd19dfe96342fd28df8c2d0a1c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 13 Dec 2022 08:00:50 -0800 Subject: [PATCH 7/9] Leave branches pinned to main --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 3c2bb3408..842bad6a8 100644 --- a/Package.swift +++ b/Package.swift @@ -215,7 +215,7 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil { package.dependencies += [ .package( url: "https://github.com/apple/swift-argument-parser.git", - .upToNextMinor(from: "1.1.4") + branch: "main" ), .package( url: "https://github.com/apple/swift-syntax.git", From f419f40766a728e352f71c426e7416eddf2e45a3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 13 Dec 2022 08:01:22 -0800 Subject: [PATCH 8/9] Drop version options change per request. --- Sources/swift-format/VersionOptions.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/swift-format/VersionOptions.swift b/Sources/swift-format/VersionOptions.swift index 93f6e9703..8ac851fdc 100644 --- a/Sources/swift-format/VersionOptions.swift +++ b/Sources/swift-format/VersionOptions.swift @@ -20,7 +20,7 @@ struct VersionOptions: ParsableArguments { func validate() throws { if version { // TODO: Automate updates to this somehow. - print("0.50700.0") + print("0.50500.0") throw ExitCode.success } } From 2d6e458a59baf7d334870bc0d75b649d8ba8fc6e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 13 Dec 2022 09:22:11 -0800 Subject: [PATCH 9/9] Revert another package change --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 842bad6a8..9ab3fa332 100644 --- a/Package.swift +++ b/Package.swift @@ -223,7 +223,7 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil { ), .package( url: "https://github.com/apple/swift-tools-support-core.git", - .upToNextMinor(from: "0.2.7") + branch: "main" ), ] } else {