Skip to content

Commit

Permalink
Add new file_content_type for PreviewProvider subclasses for SwiftUI …
Browse files Browse the repository at this point in the history
…support

Fixes #2860.
  • Loading branch information
Jeehut committed Feb 1, 2020
1 parent ed54fd6 commit 432b418
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 6 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
grouping it with initializers.
[Steven Magdy](https://github.com/StevenMagdy)

* Add case `preview_provider` to the order list of `file_types_order` to fix
an issue with false positives for `PreviewProvider` subclasses in SwiftUI.
[Cihat Gündüz](https://github.com/Jeehut)
[#2860](https://github.com/realm/SwiftLint/issues/2860)

#### Bug Fixes

* Fix `discarded_notification_center_observer` false positives when
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ enum FileType: String {
case supportingType = "supporting_type"
case mainType = "main_type"
case `extension` = "extension"
case previewProvider = "preview_provider"
}

public struct FileTypesOrderConfiguration: RuleConfiguration, Equatable {
private(set) var severityConfiguration = SeverityConfiguration(.warning)
private(set) var order: [[FileType]] = [
[.supportingType],
[.mainType],
[.extension]
[.extension],
[.previewProvider]
]

public var consoleDescription: String {
Expand Down
19 changes: 17 additions & 2 deletions Source/SwiftLintFramework/Rules/Style/FileTypesOrderRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public struct FileTypesOrderRule: ConfigurationProviderRule, OptInRule {
mainTypeSubstructure: mainTypeSubstructure
)

let previewProviderSubstructures = self.previewProviderSubstructures(in: file)

let mainTypeOffset: [FileTypeOffset] = [(.mainType, mainTypeSubstuctureOffset)]
let extensionOffsets: [FileTypeOffset] = extensionsSubstructures.compactMap { substructure in
guard let offset = substructure.offset else { return nil }
Expand All @@ -43,10 +45,14 @@ public struct FileTypesOrderRule: ConfigurationProviderRule, OptInRule {
return (.supportingType, offset)
}

let orderedFileTypeOffsets = (mainTypeOffset + extensionOffsets + supportingTypeOffsets).sorted { lhs, rhs in
return lhs.offset < rhs.offset
let previewProviderOffsets: [FileTypeOffset] = previewProviderSubstructures.compactMap { substructure in
guard let offset = substructure.offset else { return nil }
return (.previewProvider, offset)
}

let allOffsets: [FileTypeOffset] = mainTypeOffset + extensionOffsets + supportingTypeOffsets + previewProviderOffsets
let orderedFileTypeOffsets = allOffsets.sorted { lhs, rhs in lhs.offset < rhs.offset }

var violations = [StyleViolation]()

var lastMatchingIndex = -1
Expand Down Expand Up @@ -106,12 +112,19 @@ public struct FileTypesOrderRule: ConfigurationProviderRule, OptInRule {
let dict = file.structureDictionary
return dict.substructure.filter { substructure in
guard let declarationKind = substructure.declarationKind else { return false }
guard !substructure.inheritedTypes.contains("PreviewProvider") else { return false }

return substructure.offset != mainTypeSubstructure.offset &&
supportingTypeKinds.contains(declarationKind)
}
}

private func previewProviderSubstructures(in file: SwiftLintFile) -> [SourceKittenDictionary] {
return file.structureDictionary.substructure.filter { substructure in
return substructure.inheritedTypes.contains("PreviewProvider")
}
}

private func mainTypeSubstructure(in file: SwiftLintFile) -> SourceKittenDictionary? {
let dict = file.structureDictionary

Expand All @@ -133,6 +146,8 @@ public struct FileTypesOrderRule: ConfigurationProviderRule, OptInRule {

let priorityKindSubstructures = dict.substructure.filter { substructure in
guard let kind = substructure.declarationKind else { return false }
guard !substructure.inheritedTypes.contains("PreviewProvider") else { return false }

return priorityKinds.contains(kind)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@ internal struct FileTypesOrderRuleExamples {
extension Foo {}
extension Bar {
}
""",
"""
struct ContentView: View {
var body: some View {
Text("Hello, World!")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View { ContentView() }
}
"""
]

Expand Down Expand Up @@ -198,6 +209,19 @@ internal struct FileTypesOrderRuleExamples {
return UITableViewCell()
}
}
""",
"""
// Preview Provider
↓struct ContentView_Previews: PreviewProvider {
static var previews: some View { ContentView() }
}
// Main Type
struct ContentView: View {
var body: some View {
Text("Hello, World!")
}
}
"""
]
}
17 changes: 14 additions & 3 deletions Tests/SwiftLintFrameworkTests/FileTypesOrderRuleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class FileTypesOrderRuleTests: XCTestCase {
verifyRule(FileTypesOrderRule.description)
}

func testFileTypesOrderReversedOrder() {
func testFileTypesOrderReversedOrder() {
// Test with reversed `order` entries
let nonTriggeringExamples = [
FileTypesOrderRuleExamples.defaultOrderParts.reversed().joined(separator: "\n\n")
Expand Down Expand Up @@ -49,6 +49,17 @@ class FileTypesOrderRuleTests: XCTestCase {
protocol TestViewControllerDelegate {
func didPressTrackedButton()
}
""",
"""
↓struct ContentView: View {
var body: some View {
Text("Hello, World!")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View { ContentView() }
}
"""
]

Expand All @@ -59,7 +70,7 @@ class FileTypesOrderRuleTests: XCTestCase {
verifyRule(
reversedOrderDescription,
ruleConfiguration: [
"order": ["extension", "main_type", "supporting_type"]
"order": ["preview_provider", "extension", "main_type", "supporting_type"]
]
)
}
Expand Down Expand Up @@ -125,7 +136,7 @@ class FileTypesOrderRuleTests: XCTestCase {
verifyRule(
groupedOrderDescription,
ruleConfiguration: [
"order": ["main_type", ["extension", "supporting_type"]]
"order": ["main_type", ["extension", "supporting_type"], "preview_provider"]
]
)
}
Expand Down

0 comments on commit 432b418

Please # to comment.