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

Add literal support to redundantType rule #921

Merged
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion Rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -827,8 +827,10 @@ Convert trivial `map { $0.foo }` closures to keyPath-based syntax.

```diff
- let barArray = fooArray.map { $0.bar }

+ let barArray = fooArray.map(\.bar)

- let barArray = fooArray.compactMap { $0.optionalBar }
+ let barArray = fooArray.compactMap(\.optionalBar)
```

</details>
Expand Down
2 changes: 1 addition & 1 deletion Snapshots/Consumer/Sources/ConsumerCompiler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ private extension Consumer {
} else {
ranges = charset.ranges
}
let string: String = "[" + ranges.map {
let string = "[" + ranges.map {
"\($0.lowerBound) ... \($0.upperBound)"
}.joined(separator: ", ") + "]"
charsetRanges[charset] = string
Expand Down
37 changes: 37 additions & 0 deletions Sources/FormattingHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1359,4 +1359,41 @@ extension Formatter {
return openTokensFormatter.tokens
}
}

func type(at typeIndex: Int, matchesValueAt valueIndex: Int) -> Bool {
if tokens[typeIndex] == tokens[valueIndex] {
return true
}

let typeName = tokens[typeIndex].string
let value = tokens[valueIndex]

if typeName == "Bool",
["true", "false"].contains(value.string)
{
return true
}

if typeName == "String",
tokens[valueIndex] == .startOfScope("\"") || tokens[valueIndex] == .startOfScope("\"\"\""),
next(.nonSpaceOrCommentOrLinebreak, after: valueIndex)?.isStringBody == true
{
return true
}

if typeName == "Int",
tokens[valueIndex].isNumber,
tokens[valueIndex] != .number(value.string, .decimal)
{
return true
}

if typeName == "Double",
tokens[valueIndex] == .number(value.string, .decimal)
{
return true
}

return false
}
}
2 changes: 1 addition & 1 deletion Sources/Rules.swift
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ public struct _FormatRules {
typeIndex <= typeEndIndex,
let valueIndex = formatter.index(of: .nonSpaceOrCommentOrLinebreak, after: j)
{
guard formatter.tokens[typeIndex] == formatter.tokens[valueIndex] else {
guard formatter.type(at: typeIndex, matchesValueAt: valueIndex) else {
return
}
i = typeIndex
Expand Down
2 changes: 1 addition & 1 deletion Tests/CommandLineTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,6 @@ class CommandLineTests: XCTestCase {
Swift.print(message)
}
// NOTE: to update regression suite, run again without `--lint` argument
XCTAssertEqual(CLI.run(in: projectDirectory.path, with: "Snapshots --unexclude Snapshots --symlinks follow --cache ignore --lint"), .ok)
XCTAssertEqual(CLI.run(in: projectDirectory.path, with: "Snapshots --unexclude Snapshots --symlinks follow --cache ignore"), .ok)
}
}
36 changes: 18 additions & 18 deletions Tests/FormatterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ class FormatterTests: XCTestCase {
// MARK: enable/disable directives

func testDisableRule() {
let input = "//swiftformat:disable spaceAroundOperators\nlet foo : Int=5;"
let output = "// swiftformat:disable spaceAroundOperators\nlet foo : Int=5\n"
let input = "//swiftformat:disable spaceAroundOperators\nlet foo : UInt=5;"
let output = "// swiftformat:disable spaceAroundOperators\nlet foo : UInt=5\n"
XCTAssertEqual(try format(input, rules: FormatRules.default), output)
}

Expand Down Expand Up @@ -157,8 +157,8 @@ class FormatterTests: XCTestCase {
}

func testDisableAllRules() {
let input = "//swiftformat:disable all\nlet foo : Int=5;"
let output = "// swiftformat:disable all\nlet foo : Int=5;"
let input = "//swiftformat:disable all\nlet foo : UInt=5;"
let output = "// swiftformat:disable all\nlet foo : UInt=5;"
XCTAssertEqual(try format(input, rules: FormatRules.default), output)
}

Expand Down Expand Up @@ -199,44 +199,44 @@ class FormatterTests: XCTestCase {
}

func testDisableAllRulesAndReEnableOneRule() {
let input = "//swiftformat:disable all\nlet foo : Int=5;\n//swiftformat:enable linebreakAtEndOfFile"
let output = "// swiftformat:disable all\nlet foo : Int=5;\n//swiftformat:enable linebreakAtEndOfFile\n"
let input = "//swiftformat:disable all\nlet foo : UInt=5;\n//swiftformat:enable linebreakAtEndOfFile"
let output = "// swiftformat:disable all\nlet foo : UInt=5;\n//swiftformat:enable linebreakAtEndOfFile\n"
XCTAssertEqual(try format(input, rules: FormatRules.default), output)
}

func testDisableNext() {
let input = "//swiftformat:disable:next all\nlet foo : Int=5;\nlet foo : Int=5;"
let output = "// swiftformat:disable:next all\nlet foo : Int=5;\nlet foo: Int = 5\n"
let input = "//swiftformat:disable:next all\nlet foo : UInt=5;\nlet foo : UInt=5;"
let output = "// swiftformat:disable:next all\nlet foo : UInt=5;\nlet foo: UInt = 5\n"
XCTAssertEqual(try format(input, rules: FormatRules.default), output)
}

func testEnableNext() {
let input = "//swiftformat:disable all\n//swiftformat:enable:next all\nlet foo : Int=5;\nlet foo : Int=5;"
let output = "// swiftformat:disable all\n//swiftformat:enable:next all\nlet foo: Int = 5\nlet foo : Int=5;"
let input = "//swiftformat:disable all\n//swiftformat:enable:next all\nlet foo : UInt=5;\nlet foo : UInt=5;"
let output = "// swiftformat:disable all\n//swiftformat:enable:next all\nlet foo: UInt = 5\nlet foo : UInt=5;"
XCTAssertEqual(try format(input, rules: FormatRules.default), output)
}

func testDisableRuleWithMultilineComment() {
let input = "/*swiftformat:disable spaceAroundOperators*/let foo : Int=5;"
let output = "/* swiftformat:disable spaceAroundOperators */ let foo : Int=5\n"
let input = "/*swiftformat:disable spaceAroundOperators*/let foo : UInt=5;"
let output = "/* swiftformat:disable spaceAroundOperators */ let foo : UInt=5\n"
XCTAssertEqual(try format(input, rules: FormatRules.default), output)
}

func testDisableAllRulesWithMultilineComment() {
let input = "/*swiftformat:disable all*/let foo : Int=5;"
let output = "/*swiftformat:disable all*/let foo : Int=5;"
let input = "/*swiftformat:disable all*/let foo : UInt=5;"
let output = "/*swiftformat:disable all*/let foo : UInt=5;"
XCTAssertEqual(try format(input, rules: FormatRules.default), output)
}

func testDisableNextWithMultilineComment() {
let input = "/*swiftformat:disable:next all*/\nlet foo : Int=5;\nlet foo : Int=5;"
let output = "/* swiftformat:disable:next all */\nlet foo : Int=5;\nlet foo: Int = 5\n"
let input = "/*swiftformat:disable:next all*/\nlet foo : UInt=5;\nlet foo : UInt=5;"
let output = "/* swiftformat:disable:next all */\nlet foo : UInt=5;\nlet foo: UInt = 5\n"
XCTAssertEqual(try format(input, rules: FormatRules.default), output)
}

func testEnableNextWithMultilineComment() {
let input = "//swiftformat:disable all\n/*swiftformat:enable:next all*/\nlet foo : Int=5;\nlet foo : Int=5;"
let output = "// swiftformat:disable all\n/*swiftformat:enable:next all*/\nlet foo: Int = 5\nlet foo : Int=5;"
let input = "//swiftformat:disable all\n/*swiftformat:enable:next all*/\nlet foo : UInt=5;\nlet foo : UInt=5;"
let output = "// swiftformat:disable all\n/*swiftformat:enable:next all*/\nlet foo: UInt = 5\nlet foo : UInt=5;"
XCTAssertEqual(try format(input, rules: FormatRules.default), output)
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/ParsingHelpersTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ class ParsingHelpersTests: XCTestCase {

func testParameterBodyAfterStringIsNotClosure() {
let formatter = Formatter(tokenize("""
var foo: String = "bar" {
var foo = "bar" {
didSet { print("didSet") }
}
"""))
Expand Down
4 changes: 2 additions & 2 deletions Tests/RulesTests+Organization.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1142,11 +1142,11 @@ extension RulesTests {
didSet { print("didSet") }
}

var withBody3: String = "bar" {
var withBody3 = "bar" {
didSet { print("didSet") }
}

var withBody4: String = "bar" {
var withBody4 = "bar" {
didSet { print("didSet") }
}

Expand Down
57 changes: 52 additions & 5 deletions Tests/RulesTests+Redundancy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ extension RulesTests {
func testFileprivateVarWithPropertWrapperNotChangedToPrivateIfAccessedFromSubclass() {
let input = """
class Foo {
@Foo fileprivate var foo: Int = 5
@Foo fileprivate var foo = 5
}

class Bar: Foo {
Expand Down Expand Up @@ -1106,6 +1106,53 @@ extension RulesTests {
testFormatting(for: input, output, rule: FormatRules.redundantType, options: options)
}

func testRedundantTypeWithLiterals() {
let input = """
let a1: Bool = true
let a2: Bool = false

let b1: String = "foo"
let b2: String = "\\(b1)"

let c1: Int = 1
let c2: Int = 1.0

let d1: Double = 3.14
let d2: Double = 3
"""

let output = """
let a1 = true
let a2 = false

let b1 = "foo"
let b2 = "\\(b1)"

let c1 = 1
let c2: Int = 1.0

let d1 = 3.14
let d2: Double = 3
"""

let options = FormatOptions(redundantType: .inferred)
testFormatting(for: input, output, rule: FormatRules.redundantType, options: options)
}

func testRedundantTypePreservesLiteralRepresentableTypes() {
let input = """
let a: MyBoolRepresentable = true
let b: MyStringRepresentable = "foo"
let c: MyIntRepresentable = 1
let d: MyDoubleRepresentable = 3.14
let e: MyArrayRepresentable = ["bar"]
let f: MyDictionaryRepresentable = ["baaz": 1]
"""

let options = FormatOptions(redundantType: .explicit)
testFormatting(for: input, rule: FormatRules.redundantType, options: options)
}

// MARK: - redundantNilInit

func testRemoveRedundantNilInit() {
Expand Down Expand Up @@ -2377,7 +2424,7 @@ extension RulesTests {
func testSelfRemovedInDidSet() {
let input = """
class Foo {
var bar: Bool = false {
var bar = false {
didSet {
self.bar = !self.bar
}
Expand All @@ -2386,7 +2433,7 @@ extension RulesTests {
"""
let output = """
class Foo {
var bar: Bool = false {
var bar = false {
didSet {
bar = !bar
}
Expand Down Expand Up @@ -3084,7 +3131,7 @@ extension RulesTests {
func testSelfInsertedInDidSet() {
let input = """
class Foo {
var bar: Bool = false {
var bar = false {
didSet {
bar = !bar
}
Expand All @@ -3093,7 +3140,7 @@ extension RulesTests {
"""
let output = """
class Foo {
var bar: Bool = false {
var bar = false {
didSet {
self.bar = !self.bar
}
Expand Down
12 changes: 6 additions & 6 deletions Tests/SwiftFormatTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,14 @@ class SwiftFormatTests: XCTestCase {

func testFormattingRange() {
let input = """
let badlySpaced1:Int = 5
let badlySpaced2:Int=5
let badlySpaced3 : Int = 5
let badlySpaced1:UInt = 5
let badlySpaced2:UInt=5
let badlySpaced3 : UInt = 5
"""
let output = """
let badlySpaced1:Int = 5
let badlySpaced2: Int = 5
let badlySpaced3 : Int = 5
let badlySpaced1:UInt = 5
let badlySpaced2: UInt = 5
let badlySpaced3 : UInt = 5
"""
XCTAssertEqual(try format(input, lineRange: 2 ... 2), output)
}
Expand Down
2 changes: 2 additions & 0 deletions Tests/XCTestManifests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1682,6 +1682,7 @@ extension RulesTests {
("testRedundantTypeDoesNothingIfLet", testRedundantTypeDoesNothingIfLet),
("testRedundantTypeDoesNothingIfLetAfterComma", testRedundantTypeDoesNothingIfLetAfterComma),
("testRedundantTypeDoesNothingWithStaticMemberMakingCopy", testRedundantTypeDoesNothingWithStaticMemberMakingCopy),
("testRedundantTypePreservesLiteralRepresentableTypes", testRedundantTypePreservesLiteralRepresentableTypes),
("testRedundantTypeRemovalWithComment", testRedundantTypeRemovalWithComment),
("testRedundantTypeRemovalWithComment2", testRedundantTypeRemovalWithComment2),
("testRedundantTypeRemovalWithComment2ExplicitType", testRedundantTypeRemovalWithComment2ExplicitType),
Expand All @@ -1692,6 +1693,7 @@ extension RulesTests {
("testRedundantTypeRemovedIfValueOnNextLine2", testRedundantTypeRemovedIfValueOnNextLine2),
("testRedundantTypeRemovedIfValueOnNextLine2ExplicitType", testRedundantTypeRemovedIfValueOnNextLine2ExplicitType),
("testRedundantTypeRemovedIfValueOnNextLineExplicitType", testRedundantTypeRemovedIfValueOnNextLineExplicitType),
("testRedundantTypeWithLiterals", testRedundantTypeWithLiterals),
("testRedundantTypeWorksAfterIf", testRedundantTypeWorksAfterIf),
("testRemoveBacktickCaseRawStringCases", testRemoveBacktickCaseRawStringCases),
("testRemoveBackticksAroundClassSelfArgument", testRemoveBackticksAroundClassSelfArgument),
Expand Down