Skip to content

Commit

Permalink
Merge pull request realm#2885 from realm/mf-flatmap
Browse files Browse the repository at this point in the history
Add `flatmap_over_map_reduce` opt-in rule
  • Loading branch information
marcelofabri authored Sep 26, 2019
2 parents 539629a + d4ef1f0 commit f211694
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 0 deletions.
1 change: 1 addition & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ opt_in_rules:
- file_header
- file_name
- first_where
- flatmap_over_map_reduce
- identical_operands
- joined_default_parameter
- legacy_random
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
[nvanfleet](https://github.com/nvanfleet)
[#2866](https://github.com/realm/SwiftLint/issues/2866)

* Add `flatmap_over_map_reduce` opt-in rule to prefer
using `flatMap` over `map { ... }.reduce([], +)`.
[Marcelo Fabri](https://github.com/marcelofabri)
[#2883](https://github.com/realm/SwiftLint/issues/2883)

#### Bug Fixes

* None.
Expand Down
34 changes: 34 additions & 0 deletions Rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
* [File Name](#file-name)
* [File Types Order](#file-types-order)
* [First Where](#first-where)
* [FlatMap over map and reduce](#flatmap-over-map-and-reduce)
* [For Where](#for-where)
* [Force Cast](#force-cast)
* [Force Try](#force-try)
Expand Down Expand Up @@ -8429,6 +8430,39 @@ if let pause = timeTracker.pauses.filter("beginDate < %@", beginDate).first { pr



## FlatMap over map and reduce

Identifier | Enabled by default | Supports autocorrection | Kind | Analyzer | Minimum Swift Compiler Version
--- | --- | --- | --- | --- | ---
`flatmap_over_map_reduce` | Disabled | No | performance | No | 3.0.0

Prefer `flatMap` over `map` followed by `reduce([], +)`.

### Examples

<details>
<summary>Non Triggering Examples</summary>

```swift
let foo = bar.map { $0.count }.reduce(0, +)
```

```swift
let foo = bar.flatMap { $0.array }
```

</details>
<details>
<summary>Triggering Examples</summary>

```swift
let foo = ↓bar.map { $0.array }.reduce([], +)
```

</details>



## For Where

Identifier | Enabled by default | Supports autocorrection | Kind | Analyzer | Minimum Swift Compiler Version
Expand Down
1 change: 1 addition & 0 deletions Source/SwiftLintFramework/Models/MasterRuleList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public let masterRuleList = RuleList(rules: [
FileNameRule.self,
FileTypesOrderRule.self,
FirstWhereRule.self,
FlatMapOverMapReduceRule.self,
ForWhereRule.self,
ForceCastRule.self,
ForceTryRule.self,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import SourceKittenFramework

public struct FlatMapOverMapReduceRule: CallPairRule, OptInRule, ConfigurationProviderRule, AutomaticTestableRule {
public var configuration = SeverityConfiguration(.warning)

public init() {}

public static let description = RuleDescription(
identifier: "flatmap_over_map_reduce",
name: "FlatMap over map and reduce",
description: "Prefer `flatMap` over `map` followed by `reduce([], +)`.",
kind: .performance,
nonTriggeringExamples: [
"let foo = bar.map { $0.count }.reduce(0, +)",
"let foo = bar.flatMap { $0.array }"
],
triggeringExamples: [
"let foo = ↓bar.map { $0.array }.reduce([], +)"
]
)

public func validate(file: File) -> [StyleViolation] {
let pattern = "[\\}\\)]\\s*\\.reduce\\s*\\(\\[\\s*\\],\\s*\\+\\s*\\)"
return validate(file: file, pattern: pattern, patternSyntaxKinds: [.identifier],
callNameSuffix: ".map", severity: configuration.severity)
}
}
4 changes: 4 additions & 0 deletions SwiftLint.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@
D45255C81F0932F8003C9B56 /* RuleDescription+Examples.swift in Sources */ = {isa = PBXBuildFile; fileRef = D45255C71F0932F8003C9B56 /* RuleDescription+Examples.swift */; };
D462021F1E15F52D0027AAD1 /* NumberSeparatorRuleExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = D462021E1E15F52D0027AAD1 /* NumberSeparatorRuleExamples.swift */; };
D46252541DF63FB200BE2CA1 /* NumberSeparatorRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D46252531DF63FB200BE2CA1 /* NumberSeparatorRule.swift */; };
D466B620233D229F0068190B /* FlatMapOverMapReduceRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D466B61F233D229F0068190B /* FlatMapOverMapReduceRule.swift */; };
D46A317F1F1CEDCD00AF914A /* UnneededParenthesesInClosureArgumentRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D46A317E1F1CEDCD00AF914A /* UnneededParenthesesInClosureArgumentRule.swift */; };
D46E041D1DE3712C00728374 /* TrailingCommaRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D46E041C1DE3712C00728374 /* TrailingCommaRule.swift */; };
D47079A71DFCEB2D00027086 /* EmptyParenthesesWithTrailingClosureRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D47079A61DFCEB2D00027086 /* EmptyParenthesesWithTrailingClosureRule.swift */; };
Expand Down Expand Up @@ -779,6 +780,7 @@
D45255C71F0932F8003C9B56 /* RuleDescription+Examples.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "RuleDescription+Examples.swift"; sourceTree = "<group>"; };
D462021E1E15F52D0027AAD1 /* NumberSeparatorRuleExamples.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumberSeparatorRuleExamples.swift; sourceTree = "<group>"; };
D46252531DF63FB200BE2CA1 /* NumberSeparatorRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumberSeparatorRule.swift; sourceTree = "<group>"; };
D466B61F233D229F0068190B /* FlatMapOverMapReduceRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlatMapOverMapReduceRule.swift; sourceTree = "<group>"; };
D46A317E1F1CEDCD00AF914A /* UnneededParenthesesInClosureArgumentRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnneededParenthesesInClosureArgumentRule.swift; sourceTree = "<group>"; };
D46E041C1DE3712C00728374 /* TrailingCommaRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrailingCommaRule.swift; sourceTree = "<group>"; };
D47079A61DFCEB2D00027086 /* EmptyParenthesesWithTrailingClosureRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmptyParenthesesWithTrailingClosureRule.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1088,6 +1090,7 @@
E847F0A81BFBBABD00EA9363 /* EmptyCountRule.swift */,
740DF1AF203F5AFC0081F694 /* EmptyStringRule.swift */,
D42D2B371E09CC0D00CD7A2E /* FirstWhereRule.swift */,
D466B61F233D229F0068190B /* FlatMapOverMapReduceRule.swift */,
D414D6AD21D22FF500960935 /* LastWhereRule.swift */,
756C0777222EA49400A111F4 /* ReduceIntoRule.swift */,
429644B41FB0A99E00D75128 /* SortedFirstLastRule.swift */,
Expand Down Expand Up @@ -2197,6 +2200,7 @@
4A9A3A3A1DC1D75F00DF5183 /* HTMLReporter.swift in Sources */,
D40F83881DE9179200524C62 /* TrailingCommaConfiguration.swift in Sources */,
827169B31F488181003FB9AF /* ExplicitEnumRawValueRule.swift in Sources */,
D466B620233D229F0068190B /* FlatMapOverMapReduceRule.swift in Sources */,
D41985E921FAB62F003BE2B7 /* DeploymentTargetRule.swift in Sources */,
62FE5D32200CABDD00F68793 /* DiscouragedOptionalCollectionExamples.swift in Sources */,
D49896F12026B36C00814A83 /* RedundantSetAccessControlRule.swift in Sources */,
Expand Down
7 changes: 7 additions & 0 deletions Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,12 @@ extension FirstWhereRuleTests {
]
}

extension FlatMapOverMapReduceRuleTests {
static var allTests: [(String, (FlatMapOverMapReduceRuleTests) -> () throws -> Void)] = [
("testWithDefaultConfiguration", testWithDefaultConfiguration)
]
}

extension ForWhereRuleTests {
static var allTests: [(String, (ForWhereRuleTests) -> () throws -> Void)] = [
("testWithDefaultConfiguration", testWithDefaultConfiguration)
Expand Down Expand Up @@ -1624,6 +1630,7 @@ XCTMain([
testCase(FileNameRuleTests.allTests),
testCase(FileTypesOrderRuleTests.allTests),
testCase(FirstWhereRuleTests.allTests),
testCase(FlatMapOverMapReduceRuleTests.allTests),
testCase(ForWhereRuleTests.allTests),
testCase(ForceCastRuleTests.allTests),
testCase(ForceTryRuleTests.allTests),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,12 @@ class FirstWhereRuleTests: XCTestCase {
}
}

class FlatMapOverMapReduceRuleTests: XCTestCase {
func testWithDefaultConfiguration() {
verifyRule(FlatMapOverMapReduceRule.description)
}
}

class ForWhereRuleTests: XCTestCase {
func testWithDefaultConfiguration() {
verifyRule(ForWhereRule.description)
Expand Down

0 comments on commit f211694

Please sign in to comment.