Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: swiftlang/swift-format
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: swiftlang/swift-format
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: release/6.2
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.
  • 12 commits
  • 7 files changed
  • 3 contributors

Commits on Apr 9, 2025

  1. Change default release version for GitHub action releases to 602.0.0

    ahoppen committed Apr 9, 2025
    Copy the full SHA
    6cda49a View commit details
  2. Change code owners for 6.2 to release managers

    ahoppen committed Apr 9, 2025
    Copy the full SHA
    5fe8b61 View commit details
  3. Merge pull request #985 from ahoppen/6.2/release-manager

    [6.2] Change code owners for 6.2 to release managers
    ahoppen authored Apr 9, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    b5b58a2 View commit details
  4. Merge pull request #983 from ahoppen/6.2/default-release-version

    [6.2] Change default release version for GitHub action releases to 602.0.0
    ahoppen authored Apr 9, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    986cbb5 View commit details

Commits on Apr 10, 2025

  1. Merge branch 'main' into merge-main-6.2-2025-04-10

    ahoppen committed Apr 10, 2025
    Copy the full SHA
    adb01db View commit details
  2. Change swift-syntax dependency to release/6.2 (#992)

    ahoppen authored Apr 10, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    101b3aa View commit details

Commits on Apr 11, 2025

  1. Merge pull request #990 from ahoppen/merge-main-6.2-2025-04-10

    Merge `main` into `release/6.2`
    ahoppen authored Apr 11, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    6242861 View commit details

Commits on Apr 18, 2025

  1. Merge pull request #1000 from swiftlang/automerge/merge-main-2025-04-…

    …18_21-03
    
    Merge `main` into `release/6.2`
    ahoppen authored Apr 18, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    4d6bad1 View commit details

Commits on Apr 29, 2025

  1. Merge pull request #1008 from swiftlang/automerge/merge-main-2025-04-…

    …28_09-29
    
    Merge `main` into `release/6.2`
    bnbarham authored Apr 29, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    b1858e8 View commit details

Commits on May 19, 2025

  1. Revert "OrderedImports should create separate group for @_implementat…

    …ionOnly … (#1013)"
    
    This reverts commit ae522f2. Adding
    separate groups can impact a lot of code, let's skip for 6.2 for now.
    bnbarham committed May 19, 2025
    Copy the full SHA
    c2d7ede View commit details
  2. Revert "Merge pull request #1020 from ahoppen/remove-code-owner"

    This reverts commit 42c9826, reversing
    changes made to 7156f95. Codeowner is
    branch managers on 6.2.
    bnbarham committed May 19, 2025
    Copy the full SHA
    009925c View commit details

Commits on May 20, 2025

  1. Merge pull request #1022 from swiftlang/automerge/merge-main-2025-05-…

    …19_09-01
    
    Merge `main` into `release/6.2`
    bnbarham authored May 20, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    2a8349e View commit details
4 changes: 2 additions & 2 deletions .github/workflows/publish_release.yml
Original file line number Diff line number Diff line change
@@ -11,13 +11,13 @@ on:
required: true
swift_format_version:
type: string
default: 603.0.0
default: 602.0.0
description: "swift-format version"
# The version of swift-format to tag. If this is a prerelease, `-prerelease-<date>` is added to this version.
required: true
swift_syntax_tag:
type: string
default: 603.0.0
default: 602.0.0
description: "swift-syntax version"
# The swift-syntax version to depend on. If this is a prerelease, the latest swift-syntax prerelease tag for this version is used.
required: true
16 changes: 2 additions & 14 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,14 +1,2 @@
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2024 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 Swift project authors
#

* @allevato @bnbarham @shawnhyam

.github/ @bnbarham @shahmishal
.swiftci/ @bnbarham @shahmishal
# For the release branch @swiftlang/swift-branch-managers needs to approve the changes
* @swiftlang/swift-branch-managers
6 changes: 3 additions & 3 deletions Documentation/RuleDocumentation.md
Original file line number Diff line number Diff line change
@@ -407,9 +407,9 @@ Lint: If a function call with a trailing closure also contains a non-trailing cl
### OrderedImports

Imports must be lexicographically ordered and logically grouped at the top of each source file.
The order of the import groups is 1) regular imports, 2) declaration imports, 3) @_implementationOnly
imports, and 4) @testable imports. These groups are separated by a single blank line. Blank lines in
between the import declarations are removed.
The order of the import groups is 1) regular imports, 2) declaration imports, and 3) @testable
imports. These groups are separated by a single blank line. Blank lines in between the import
declarations are removed.

Lint: If an import appears anywhere other than the beginning of the file it resides in,
not lexicographically ordered, or not in the appropriate import group, a lint error is
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -198,7 +198,7 @@ var dependencies: [Package.Dependency] {
return [
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.2"),
.package(url: "https://github.com/apple/swift-markdown.git", from: "0.2.0"),
.package(url: "https://github.com/swiftlang/swift-syntax.git", branch: "main"),
.package(url: "https://github.com/swiftlang/swift-syntax.git", branch: "release/6.2"),
]
}
}
58 changes: 11 additions & 47 deletions Sources/SwiftFormat/Rules/OrderedImports.swift
Original file line number Diff line number Diff line change
@@ -13,9 +13,9 @@
import SwiftSyntax

/// Imports must be lexicographically ordered and logically grouped at the top of each source file.
/// The order of the import groups is 1) regular imports, 2) declaration imports, 3) @_implementationOnly
/// imports, and 4) @testable imports. These groups are separated by a single blank line. Blank lines in
/// between the import declarations are removed.
/// The order of the import groups is 1) regular imports, 2) declaration imports, and 3) @testable
/// imports. These groups are separated by a single blank line. Blank lines in between the import
/// declarations are removed.
///
/// Lint: If an import appears anywhere other than the beginning of the file it resides in,
/// not lexicographically ordered, or not in the appropriate import group, a lint error is
@@ -34,7 +34,6 @@ public final class OrderedImports: SyntaxFormatRule {

var regularImports: [Line] = []
var declImports: [Line] = []
var implementationOnlyImports: [Line] = []
var testableImports: [Line] = []
var codeBlocks: [Line] = []
var fileHeader: [Line] = []
@@ -53,23 +52,14 @@ public final class OrderedImports: SyntaxFormatRule {

regularImports = formatImports(regularImports)
declImports = formatImports(declImports)
implementationOnlyImports = formatImports(implementationOnlyImports)
testableImports = formatImports(testableImports)
formatCodeblocks(&codeBlocks)

let joined = joinLines(
fileHeader,
regularImports,
declImports,
implementationOnlyImports,
testableImports,
codeBlocks
)
let joined = joinLines(fileHeader, regularImports, declImports, testableImports, codeBlocks)
formattedLines.append(contentsOf: joined)

regularImports = []
declImports = []
implementationOnlyImports = []
testableImports = []
codeBlocks = []
fileHeader = []
@@ -125,11 +115,6 @@ public final class OrderedImports: SyntaxFormatRule {
regularImports.append(line)
commentBuffer = []

case .implementationOnlyImport:
implementationOnlyImports.append(contentsOf: commentBuffer)
implementationOnlyImports.append(line)
commentBuffer = []

case .testableImport:
testableImports.append(contentsOf: commentBuffer)
testableImports.append(line)
@@ -163,7 +148,6 @@ public final class OrderedImports: SyntaxFormatRule {
/// statements do not appear at the top of the file.
private func checkGrouping<C: Collection>(_ lines: C) where C.Element == Line {
var declGroup = false
var implementationOnlyGroup = false
var testableGroup = false
var codeGroup = false

@@ -173,8 +157,6 @@ public final class OrderedImports: SyntaxFormatRule {
switch lineType {
case .declImport:
declGroup = true
case .implementationOnlyImport:
implementationOnlyGroup = true
case .testableImport:
testableGroup = true
case .codeBlock:
@@ -184,28 +166,17 @@ public final class OrderedImports: SyntaxFormatRule {

if codeGroup {
switch lineType {
case .regularImport, .declImport, .implementationOnlyImport, .testableImport:
case .regularImport, .declImport, .testableImport:
diagnose(.placeAtTopOfFile, on: line.firstToken)
default: ()
}
}

if testableGroup {
switch lineType {
case .regularImport, .declImport, .implementationOnlyImport:
diagnose(
.groupImports(before: lineType, after: LineType.testableImport),
on: line.firstToken
)
default: ()
}
}

if implementationOnlyGroup {
switch lineType {
case .regularImport, .declImport:
diagnose(
.groupImports(before: lineType, after: LineType.implementationOnlyImport),
.groupImports(before: lineType, after: LineType.testableImport),
on: line.firstToken
)
default: ()
@@ -237,7 +208,7 @@ public final class OrderedImports: SyntaxFormatRule {

for line in imports {
switch line.type {
case .regularImport, .declImport, .implementationOnlyImport, .testableImport:
case .regularImport, .declImport, .testableImport:
let fullyQualifiedImport = line.fullyQualifiedImport
// Check for duplicate imports and potentially remove them.
if let previousMatchingImportIndex = visitedImports[fullyQualifiedImport] {
@@ -419,7 +390,6 @@ fileprivate func convertToCodeBlockItems(lines: [Line]) -> [CodeBlockItemSyntax]
public enum LineType: CustomStringConvertible {
case regularImport
case declImport
case implementationOnlyImport
case testableImport
case codeBlock
case comment
@@ -431,8 +401,6 @@ public enum LineType: CustomStringConvertible {
return "regular"
case .declImport:
return "declaration"
case .implementationOnlyImport:
return "implementationOnly"
case .testableImport:
return "testable"
case .codeBlock:
@@ -547,16 +515,12 @@ fileprivate class Line {

/// Returns a `LineType` the represents the type of import from the given import decl.
private func importType(of importDecl: ImportDeclSyntax) -> LineType {

let importIdentifierTypes = importDecl.attributes.compactMap { $0.as(AttributeSyntax.self)?.attributeName }
let importAttributeNames = importIdentifierTypes.compactMap { $0.as(IdentifierTypeSyntax.self)?.name.text }

if importAttributeNames.contains("testable") {
if let attr = importDecl.attributes.firstToken(viewMode: .sourceAccurate),
attr.tokenKind == .atSign,
attr.nextToken(viewMode: .sourceAccurate)?.text == "testable"
{
return .testableImport
}
if importAttributeNames.contains("_implementationOnly") {
return .implementationOnlyImport
}
if importDecl.importKindSpecifier != nil {
return .declImport
}
78 changes: 10 additions & 68 deletions Tests/SwiftFormatTests/Rules/OrderedImportsTests.swift
Original file line number Diff line number Diff line change
@@ -27,17 +27,14 @@ final class OrderedImportsTests: LintOrFormatRuleTestCase {
import UIKit
@testable import SwiftFormat
🔟import enum Darwin.D.isatty
8️⃣import enum Darwin.D.isatty
// Starts Test
3️⃣@testable import MyModuleUnderTest
// Starts Ind
2️⃣8️⃣import func Darwin.C.isatty
// Starts ImplementationOnly
9️⃣@_implementationOnly import InternalModule
2️⃣7️⃣import func Darwin.C.isatty
let a = 3
4️⃣5️⃣6️⃣7️⃣import SwiftSyntax
4️⃣5️⃣6️⃣import SwiftSyntax
""",
expected: """
// Starts Imports
@@ -51,9 +48,6 @@ final class OrderedImportsTests: LintOrFormatRuleTestCase {
import func Darwin.C.isatty
import enum Darwin.D.isatty
// Starts ImplementationOnly
@_implementationOnly import InternalModule
// Starts Test
@testable import MyModuleUnderTest
@testable import SwiftFormat
@@ -66,11 +60,9 @@ final class OrderedImportsTests: LintOrFormatRuleTestCase {
FindingSpec("3️⃣", message: "sort import statements lexicographically"),
FindingSpec("4️⃣", message: "place imports at the top of the file"),
FindingSpec("5️⃣", message: "place regular imports before testable imports"),
FindingSpec("6️⃣", message: "place regular imports before implementationOnly imports"),
FindingSpec("7️⃣", message: "place regular imports before declaration imports"),
FindingSpec("8️⃣", message: "sort import statements lexicographically"),
FindingSpec("9️⃣", message: "place implementationOnly imports before testable imports"),
FindingSpec("🔟", message: "place declaration imports before testable imports"),
FindingSpec("6️⃣", message: "place regular imports before declaration imports"),
FindingSpec("7️⃣", message: "sort import statements lexicographically"),
FindingSpec("8️⃣", message: "place declaration imports before testable imports"),
]
)
}
@@ -104,50 +96,6 @@ final class OrderedImportsTests: LintOrFormatRuleTestCase {
)
}

func testImportsWithAttributes() {
assertFormatting(
OrderedImports.self,
input: """
import Foundation
1️⃣@preconcurrency import AVFoundation
@preconcurrency @_implementationOnly import InternalModuleC
2️⃣@_implementationOnly import InternalModuleA
3️⃣import Core
@testable @preconcurrency import TestServiceB
4️⃣@preconcurrency @testable import TestServiceA
5️⃣@_implementationOnly @preconcurrency import InternalModuleB
let a = 3
""",
expected: """
@preconcurrency import AVFoundation
import Core
import Foundation
@_implementationOnly import InternalModuleA
@_implementationOnly @preconcurrency import InternalModuleB
@preconcurrency @_implementationOnly import InternalModuleC
@preconcurrency @testable import TestServiceA
@testable @preconcurrency import TestServiceB
let a = 3
""",
findings: [
FindingSpec("1️⃣", message: "sort import statements lexicographically"),
FindingSpec("2️⃣", message: "sort import statements lexicographically"),
FindingSpec("3️⃣", message: "place regular imports before implementationOnly imports"),
FindingSpec("4️⃣", message: "sort import statements lexicographically"),
FindingSpec("5️⃣", message: "place implementationOnly imports before testable imports"),
]
)
}

func testImportsOrderWithDocComment() {
assertFormatting(
OrderedImports.self,
@@ -198,9 +146,6 @@ final class OrderedImportsTests: LintOrFormatRuleTestCase {
import func Darwin.C.isatty
@_implementationOnly import InternalModuleA
@preconcurrency @_implementationOnly import InternalModuleB
@testable import MyModuleUnderTest
""",
expected: """
@@ -211,9 +156,6 @@ final class OrderedImportsTests: LintOrFormatRuleTestCase {
import func Darwin.C.isatty
@_implementationOnly import InternalModuleA
@preconcurrency @_implementationOnly import InternalModuleB
@testable import MyModuleUnderTest
""",
findings: []
@@ -382,7 +324,7 @@ final class OrderedImportsTests: LintOrFormatRuleTestCase {
@testable import testZ // trailing comment about testZ
3️⃣@testable import testC
// swift-format-ignore
@_implementationOnly import testB
@testable import testB
// Comment about Bar
import enum Bar
@@ -408,7 +350,7 @@ final class OrderedImportsTests: LintOrFormatRuleTestCase {
@testable import testZ // trailing comment about testZ
// swift-format-ignore
@_implementationOnly import testB
@testable import testB
// Comment about Bar
import enum Bar
@@ -571,7 +513,7 @@ final class OrderedImportsTests: LintOrFormatRuleTestCase {
input: """
// exported import of bar
@_exported import bar
@preconcurrency import bar
@_implementationOnly import bar
import bar
import foo
// second import of foo
@@ -589,7 +531,7 @@ final class OrderedImportsTests: LintOrFormatRuleTestCase {
expected: """
// exported import of bar
@_exported import bar
@preconcurrency import bar
@_implementationOnly import bar
import bar
// second import of foo
import foo
1 change: 0 additions & 1 deletion api-breakages.txt
Original file line number Diff line number Diff line change
@@ -18,4 +18,3 @@ API breakage: func Configuration.MultilineStringReflowBehavior.hash(into:) has b
API breakage: func Configuration.MultilineStringReflowBehavior.encode(to:) has been removed
API breakage: var Configuration.MultilineStringReflowBehavior.hashValue has been removed
API breakage: constructor Configuration.MultilineStringReflowBehavior.init(from:) has been removed
API breakage: enumelement LineType.implementationOnlyImport has been added as a new enum case