Skip to content

Commit

Permalink
Fix removal of @_exported imports
Browse files Browse the repository at this point in the history
  • Loading branch information
nicklockwood committed Oct 12, 2022
1 parent 852199c commit d208709
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 3 deletions.
8 changes: 6 additions & 2 deletions Sources/ParsingHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,11 @@ extension Formatter {
struct ImportRange: Comparable {
var module: String
var range: Range<Int>
var isTestable: Bool
var attributes: [String]

var isTestable: Bool {
attributes.contains("@testable")
}

static func < (lhs: ImportRange, rhs: ImportRange) -> Bool {
let la = lhs.module.lowercased()
Expand Down Expand Up @@ -1218,7 +1222,7 @@ extension Formatter {
importRanges.append(ImportRange(
module: name,
range: range,
isTestable: tokens[range].contains(.keyword("@testable"))
attributes: tokens[range].compactMap { $0.isAttribute ? $0.string : nil }
))
} else {
// Error
Expand Down
3 changes: 2 additions & 1 deletion Sources/Rules.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4887,6 +4887,7 @@ public struct _FormatRules {
return ranges.sorted { $0.module.count < $1.module.count }
}
// Group @testable imports at the top or bottom
// TODO: need more general solution for handling other import attributes
return ranges.sorted {
// If both have a @testable keyword, or neither has one, just sort alphabetically
guard $0.isTestable != $1.isTestable else {
Expand Down Expand Up @@ -4927,7 +4928,7 @@ public struct _FormatRules {
continue
}
let range2 = importRanges[j]
if !range.isTestable || range2.isTestable {
if Set(range.attributes).isSubset(of: range2.attributes) {
formatter.removeTokens(in: range.range)
continue
}
Expand Down
12 changes: 12 additions & 0 deletions Tests/RulesTests+Redundancy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4780,6 +4780,18 @@ class RedundancyTests: RulesTests {
testFormatting(for: input, output, rule: FormatRules.duplicateImports)
}

func testNoRemoveExportedDuplicateImport() {
let input = "import Foo\n@_exported import Foo"
let output = "\n@_exported import Foo"
testFormatting(for: input, output, rule: FormatRules.duplicateImports)
}

func testNoRemoveExportedDuplicateImport2() {
let input = "@_exported import Foo\nimport Foo"
let output = "@_exported import Foo"
testFormatting(for: input, output, rule: FormatRules.duplicateImports)
}

// MARK: - unusedArguments

// closures
Expand Down

0 comments on commit d208709

Please sign in to comment.