Skip to content

Commit

Permalink
Don't retain SwiftUI previews by default. Closes #524
Browse files Browse the repository at this point in the history
  • Loading branch information
ileitch committed Sep 26, 2023
1 parent f934646 commit eeeccc2
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 5 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

##### Enhancements

- None.
- SwiftUI previews (`PreviewProvider`) are no longer retained by default. Retain them with `--retain-swift-ui-previews`.

##### Bug Fixes

Expand Down
4 changes: 4 additions & 0 deletions Sources/Frontend/Commands/ScanCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ struct ScanCommand: FrontendCommand {
@Flag(help: "Retain unused protocol function parameters, even if the parameter is unused in all conforming functions")
var retainUnusedProtocolFuncParams: Bool = defaultConfiguration.$retainUnusedProtocolFuncParams.defaultValue

@Flag(help: "Retain SwiftUI previews")
var retainSwiftUIPreviews: Bool = defaultConfiguration.$retainSwiftUIPreviews.defaultValue

@Flag(help: "Clean existing build artifacts before building")
var cleanBuild: Bool = defaultConfiguration.$cleanBuild.defaultValue

Expand Down Expand Up @@ -119,6 +122,7 @@ struct ScanCommand: FrontendCommand {
configuration.apply(\.$retainObjcAccessible, retainObjcAccessible)
configuration.apply(\.$retainObjcAnnotated, retainObjcAnnotated)
configuration.apply(\.$retainUnusedProtocolFuncParams, retainUnusedProtocolFuncParams)
configuration.apply(\.$retainSwiftUIPreviews, retainSwiftUIPreviews)
configuration.apply(\.$disableRedundantPublicAnalysis, disableRedundantPublicAnalysis)
configuration.apply(\.$externalEncodableProtocols, externalEncodableProtocols)
configuration.apply(\.$externalTestCaseClasses, externalTestCaseClasses)
Expand Down
12 changes: 10 additions & 2 deletions Sources/PeripheryKit/SourceGraph/Mutators/SwiftUIRetainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import Shared

final class SwiftUIRetainer: SourceGraphMutator {
private let graph: SourceGraph
private static let specialProtocolNames = ["PreviewProvider", "LibraryContentProvider"]
private let configuration: Configuration
private static let specialProtocolNames = ["LibraryContentProvider"]
private static let applicationDelegateAdaptorStructNames = ["UIApplicationDelegateAdaptor", "NSApplicationDelegateAdaptor"]

required init(graph: SourceGraph, configuration: Configuration) {
self.graph = graph
self.configuration = configuration
}

func mutate() {
Expand All @@ -18,12 +20,18 @@ final class SwiftUIRetainer: SourceGraphMutator {
// MARK: - Private

private func retainSpecialProtocolConformances() {
var names = Self.specialProtocolNames

if configuration.retainSwiftUIPreviews {
names.append("PreviewProvider")
}

graph
.declarations(ofKinds: [.class, .struct, .enum])
.lazy
.filter {
$0.related.contains {
self.graph.isExternal($0) && $0.kind == .protocol && Self.specialProtocolNames.contains($0.name ?? "")
self.graph.isExternal($0) && $0.kind == .protocol && names.contains($0.name ?? "")
}
}
.forEach { graph.markRetained($0) }
Expand Down
10 changes: 10 additions & 0 deletions Sources/Shared/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ public final class Configuration {
@Setting(key: "retain_unused_protocol_func_params", defaultValue: false)
public var retainUnusedProtocolFuncParams: Bool

@Setting(key: "retain_swift_ui_previews", defaultValue: false)
public var retainSwiftUIPreviews: Bool

@Setting(key: "disable_redundant_public_analysis", defaultValue: false)
public var disableRedundantPublicAnalysis: Bool

Expand Down Expand Up @@ -166,6 +169,10 @@ public final class Configuration {
config[$retainUnusedProtocolFuncParams.key] = retainUnusedProtocolFuncParams
}

if $retainSwiftUIPreviews.hasNonDefaultValue {
config[$retainSwiftUIPreviews.key] = retainSwiftUIPreviews
}

if $disableRedundantPublicAnalysis.hasNonDefaultValue {
config[$disableRedundantPublicAnalysis.key] = disableRedundantPublicAnalysis
}
Expand Down Expand Up @@ -252,6 +259,8 @@ public final class Configuration {
$retainObjcAnnotated.assign(value)
case $retainUnusedProtocolFuncParams.key:
$retainUnusedProtocolFuncParams.assign(value)
case $retainSwiftUIPreviews.key:
$retainSwiftUIPreviews.assign(value)
case $disableRedundantPublicAnalysis.key:
$disableRedundantPublicAnalysis.assign(value)
case $verbose.key:
Expand Down Expand Up @@ -292,6 +301,7 @@ public final class Configuration {
$retainObjcAccessible.reset()
$retainObjcAnnotated.reset()
$retainUnusedProtocolFuncParams.reset()
$retainSwiftUIPreviews.reset()
$disableRedundantPublicAnalysis.reset()
$externalEncodableProtocols.reset()
$externalTestCaseClasses.reset()
Expand Down
4 changes: 2 additions & 2 deletions Tests/XcodeTests/SwiftUIProjectTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ class SwiftUIProjectTest: SourceGraphTestCase {
assertReferenced(.struct("SwiftUIProjectApp"))
}

func testRetainsPreviewProvider() {
assertReferenced(.struct("ContentView_Previews"))
func testDoesNotRetainPreviewProvider() {
assertNotReferenced(.struct("ContentView_Previews"))
}

func testRetainsLibraryContentProvider() {
Expand Down

0 comments on commit eeeccc2

Please sign in to comment.