Skip to content

Cherrypick recent changes into swift-5.2-branch. #171

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

Merged
merged 6 commits into from
Apr 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/apple/swift-syntax", from: "0.50200.0"),
.package(url: "https://github.com/apple/swift-tools-support-core.git", from: "0.0.1"),
.package(url: "https://github.com/apple/swift-argument-parser.git", .upToNextMinor(from: "0.0.4")),
],
targets: [
Expand Down Expand Up @@ -62,12 +61,11 @@ let package = Package(
.target(
name: "swift-format",
dependencies: [
"ArgumentParser",
"SwiftFormat",
"SwiftFormatConfiguration",
"SwiftFormatCore",
"SwiftSyntax",
"SwiftToolsSupport-auto",
"ArgumentParser",
]
),
.testTarget(
Expand Down
16 changes: 12 additions & 4 deletions Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -533,11 +533,19 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
override func visit(_ node: RepeatWhileStmtSyntax) -> SyntaxVisitorContinueKind {
arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements)

let whilePrecedingBreak = config.lineBreakBeforeControlFlowKeywords
? Token.break(.same) : Token.space
before(node.whileKeyword, tokens: whilePrecedingBreak)
if config.lineBreakBeforeControlFlowKeywords {
before(node.whileKeyword, tokens: .break(.same), .open)
after(node.condition.lastToken, tokens: .close)
} else {
// The length of the condition needs to force the breaks around the braces of the repeat
// stmt's body, so that there's always a break before the right brace when the while &
// condition is too long to be on one line.
before(node.whileKeyword, tokens: .space)
// The `open` token occurs after the ending tokens for the braced `body` node.
before(node.body.rightBrace, tokens: .open)
after(node.condition.lastToken, tokens: .close)
}
after(node.whileKeyword, tokens: .space)

return .visitChildren
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftFormatRules/OrderedImports.swift
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ fileprivate class Line {
else {
return ""
}
return importDecl.path.description.trimmingCharacters(in: .whitespaces)
return importDecl.path.description.trimmingCharacters(in: .whitespacesAndNewlines)
}

/// Returns the first `TokenSyntax` in the code block(s) from this Line, or nil when this Line
Expand Down
2 changes: 0 additions & 2 deletions Sources/swift-format/Subcommands/DumpConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
import ArgumentParser
import Foundation
import SwiftFormatConfiguration
import TSCBasic
import TSCUtility

extension SwiftFormatCommand {
/// Dumps the tool's default configuration in JSON format to standard output.
Expand Down
27 changes: 11 additions & 16 deletions Sources/swift-format/Subcommands/Format.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import Foundation
import SwiftFormat
import SwiftFormatConfiguration
import SwiftSyntax
import TSCBasic

extension SwiftFormatCommand {
/// Formats one or more files containing Swift code.
Expand Down Expand Up @@ -89,31 +88,29 @@ private func formatMain(
// fixed anyway.
let formatter = SwiftFormatter(configuration: configuration, diagnosticEngine: nil)
formatter.debugOptions = debugOptions
let assumingFileURL = URL(fileURLWithPath: assumingFilename ?? "<stdin>")

let path = assumingFilename ?? "<stdin>"
let assumingFileURL = URL(fileURLWithPath: path)

guard let source = readSource(from: sourceFile) else {
diagnosticEngine.diagnose(
Diagnostic.Message(
.error, "Unable to read source for formatting from \(assumingFileURL.path)."))
Diagnostic.Message(.error, "Unable to read source for formatting from \(path)."))
return
}

var stdoutStream = FileHandle.standardOutput
do {
if inPlace {
let cwd = FileManager.default.currentDirectoryPath
var buffer = BufferedOutputByteStream()
var buffer = ""
try formatter.format(source: source, assumingFileURL: assumingFileURL, to: &buffer)
buffer.flush()
try localFileSystem.writeFileContents(
AbsolutePath(assumingFileURL.path, relativeTo: AbsolutePath(cwd)),
bytes: buffer.bytes
)

let bufferData = buffer.data(using: .utf8)! // Conversion to UTF-8 cannot fail
try bufferData.write(to: assumingFileURL, options: .atomic)
} else {
try formatter.format(source: source, assumingFileURL: assumingFileURL, to: &stdoutStream)
stdoutStream.flush()
stdoutStream.synchronizeFile()
}
} catch SwiftFormatError.fileNotReadable {
let path = assumingFileURL.path
diagnosticEngine.diagnose(
Diagnostic.Message(
.error, "Unable to format \(path): file is not readable or does not exist."))
Expand All @@ -125,17 +122,15 @@ private func formatMain(
return
}
stdoutStream.write(source)
stdoutStream.flush()
stdoutStream.synchronizeFile()
return
}
let path = assumingFileURL.path
let location = SourceLocationConverter(file: path, source: source).location(for: position)
diagnosticEngine.diagnose(
Diagnostic.Message(.error, "file contains invalid or unrecognized Swift syntax."),
location: location)
return
} catch {
let path = assumingFileURL.path
diagnosticEngine.diagnose(Diagnostic.Message(.error, "Unable to format \(path): \(error)"))
return
}
Expand Down
1 change: 0 additions & 1 deletion Sources/swift-format/Subcommands/LegacyMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import SwiftFormat
import SwiftFormatConfiguration
import SwiftFormatCore
import SwiftSyntax
import TSCBasic

extension SwiftFormatCommand {
/// Keep the legacy `-m/--mode` flag working temporarily when no other subcommand is specified.
Expand Down
1 change: 0 additions & 1 deletion Sources/swift-format/Subcommands/Lint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import Foundation
import SwiftFormat
import SwiftFormatConfiguration
import SwiftSyntax
import TSCBasic

extension SwiftFormatCommand {
/// Emits style diagnostics for one or more files containing Swift code.
Expand Down
19 changes: 19 additions & 0 deletions Sources/swift-format/Utilities/FileHandle+TextOutputStream.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import Foundation

extension FileHandle: TextOutputStream {
public func write(_ string: String) {
self.write(string.data(using: .utf8)!) // Conversion to UTF-8 cannot fail
}
}
1 change: 0 additions & 1 deletion Sources/swift-format/Utilities/Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import SwiftFormat
import SwiftFormatConfiguration
import SwiftFormatCore
import SwiftSyntax
import TSCBasic

/// Throws an error that causes the current command to exit the process with a failure exit code if
/// any of the preceding operations emitted diagnostics.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ final class DifferentiationAttributeTests: PrettyPrintTestCase {
assertPrettyPrintEqual(input: input, expected: expected, linelength: 43)
}

#if HAS_DERIVATIVE_REGISTRATION_ATTRIBUTE
func testDerivative() {
func testDerivative() {
#if HAS_DERIVATIVE_REGISTRATION_ATTRIBUTE
let input =
"""
@derivative(of: foo, wrt: x)
Expand Down Expand Up @@ -78,9 +78,11 @@ final class DifferentiationAttributeTests: PrettyPrintTestCase {
"""

assertPrettyPrintEqual(input: input, expected: expected, linelength: 28)
}
#endif
}

func testTranspose() {
func testTranspose() {
#if HAS_DERIVATIVE_REGISTRATION_ATTRIBUTE
let input =
"""
@transpose(of: foo, wrt: 0)
Expand Down Expand Up @@ -114,6 +116,6 @@ final class DifferentiationAttributeTests: PrettyPrintTestCase {
"""

assertPrettyPrintEqual(input: input, expected: expected, linelength: 27)
}
#endif
#endif
}
}
25 changes: 25 additions & 0 deletions Tests/SwiftFormatPrettyPrintTests/RepeatStmtTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ final class RepeatStmtTests: PrettyPrintTestCase {
while x
repeat { foo() }
while longcondition
repeat { f() }
while long.condition
repeat { f() } while long.condition
repeat { f() } while long.condition.that.ison.many.lines
repeat {
let a = 123
var b = "abc"
Expand All @@ -29,6 +33,16 @@ final class RepeatStmtTests: PrettyPrintTestCase {
repeat {
foo()
} while longcondition
repeat {
f()
} while long.condition
repeat {
f()
} while long.condition
repeat {
f()
} while long.condition
.that.ison.many.lines
repeat {
let a = 123
var b = "abc"
Expand All @@ -50,6 +64,10 @@ final class RepeatStmtTests: PrettyPrintTestCase {
repeat {} while x
repeat { f() } while x
repeat { foo() } while longcondition
repeat { f() }
while long.condition
repeat { f() } while long.condition
repeat { f() } while long.condition.that.ison.many.lines
repeat {
let a = 123
var b = "abc"
Expand All @@ -68,6 +86,13 @@ final class RepeatStmtTests: PrettyPrintTestCase {
repeat { f() } while x
repeat { foo() }
while longcondition
repeat { f() }
while long.condition
repeat { f() }
while long.condition
repeat { f() }
while long.condition.that
.ison.many.lines
repeat {
let a = 123
var b = "abc"
Expand Down
100 changes: 100 additions & 0 deletions Tests/SwiftFormatRulesTests/OrderedImportsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,30 @@ final class OrderedImportsTests: LintOrFormatRuleTestCase {
)
}

func testImportsContainingNewlines() {
let input =
"""
import
zeta
import Zeta
import
Alpha
import Beta
"""

let expected =
"""
import
Alpha
import Beta
import Zeta
import
zeta
"""

XCTAssertFormatting(OrderedImports.self, input: input, expected: expected)
}

func testRemovesDuplicateImports() {
let input =
"""
Expand Down Expand Up @@ -541,4 +565,80 @@ final class OrderedImportsTests: LintOrFormatRuleTestCase {

XCTAssertFormatting(OrderedImports.self, input: input, expected: expected)
}

func testConditionalImports() {
let input =
"""
import Zebras
import Apples
#if canImport(Darwin)
import Darwin
#elseif canImport(Glibc)
import Glibc
#endif
import Aardvarks

foo()
bar()
baz()
"""

let expected =
"""
import Aardvarks
import Apples
import Zebras

#if canImport(Darwin)
import Darwin
#elseif canImport(Glibc)
import Glibc
#endif

foo()
bar()
baz()
"""

XCTAssertFormatting(OrderedImports.self, input: input, expected: expected)
}

func testIgnoredConditionalImports() {
let input =
"""
import Zebras
import Apples
#if canImport(Darwin)
import Darwin
#elseif canImport(Glibc)
import Glibc
#endif
// swift-format-ignore
import Aardvarks

foo()
bar()
baz()
"""

let expected =
"""
import Apples
import Zebras

#if canImport(Darwin)
import Darwin
#elseif canImport(Glibc)
import Glibc
#endif
// swift-format-ignore
import Aardvarks

foo()
bar()
baz()
"""

XCTAssertFormatting(OrderedImports.self, input: input, expected: expected)
}
}
Loading