Skip to content

Commit

Permalink
Add '--retain-codable-properties' option
Browse files Browse the repository at this point in the history
  • Loading branch information
ileitch committed Jan 2, 2024
1 parent 6aa51bd commit 8f5d47e
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- Add experimental unused import analysis.
- The option `--external-encodable-protocols` is deprecated, use `--external-codable-protocols` instead.
- Assign-only properties on structs with synthesized initializers are now detected.
- Added the `--retain-codable-properties` option to retain all properties on Codable types.

##### 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 @@ -84,6 +84,9 @@ struct ScanCommand: FrontendCommand {
@Flag(help: "Retain SwiftUI previews")
var retainSwiftUIPreviews: Bool = defaultConfiguration.$retainSwiftUIPreviews.defaultValue

@Flag(help: "Retain properties on Codable types")
var retainCodableProperties: Bool = defaultConfiguration.$retainCodableProperties.defaultValue

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

Expand Down Expand Up @@ -150,6 +153,7 @@ struct ScanCommand: FrontendCommand {
configuration.apply(\.$cleanBuild, cleanBuild)
configuration.apply(\.$buildArguments, buildArguments)
configuration.apply(\.$relativeResults, relativeResults)
configuration.apply(\.$retainCodableProperties, retainCodableProperties)

try scanBehavior.main { project in
try Scan().perform(project: project)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Foundation
import Shared

final class CodablePropertyRetainer: SourceGraphMutator {
private let graph: SourceGraph
private let configuration: Configuration

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

func mutate() {
guard configuration.retainCodableProperties else { return }

for decl in graph.declarations(ofKinds: Declaration.Kind.discreteConformableKinds) {
guard graph.isCodable(decl) else { continue }

for decl in decl.declarations {
guard decl.kind == .varInstance else { continue }
graph.markRetained(decl)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public final class SourceGraphMutatorRunner {
PropertyWrapperRetainer.self,
ResultBuilderRetainer.self,
CapitalSelfFunctionCallRetainer.self,
CodablePropertyRetainer.self,

AncestralReferenceEliminator.self,
AssignOnlyPropertyReferenceEliminator.self,
Expand Down
10 changes: 10 additions & 0 deletions Sources/Shared/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ public final class Configuration {
@Setting(key: "enable_unused_import_analysis", defaultValue: false)
public var enableUnusedImportsAnalysis: Bool

@Setting(key: "retain_codable_properties", defaultValue: false)
public var retainCodableProperties: Bool

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

Expand Down Expand Up @@ -230,6 +233,10 @@ public final class Configuration {
config[$relativeResults.key] = relativeResults
}

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

return try Yams.dump(object: config)
}

Expand Down Expand Up @@ -309,6 +316,8 @@ public final class Configuration {
$buildArguments.assign(value)
case $relativeResults.key:
$relativeResults.assign(value)
case $retainCodableProperties.key:
$retainCodableProperties.assign(value)
default:
logger.warn("\(path.string): invalid key '\(key)'")
}
Expand Down Expand Up @@ -346,6 +355,7 @@ public final class Configuration {
$cleanBuild.reset()
$buildArguments.reset()
$relativeResults.reset()
$retainCodableProperties.reset()
}

// MARK: - Helpers
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Foundation

public struct FixtureStruct14: Codable {
let unused: Int

init(unused: Int) {
self.unused = unused
}
}
22 changes: 22 additions & 0 deletions Tests/PeripheryTests/RetentionTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,28 @@ final class RetentionTest: FixtureSourceGraphTestCase {
}
}

func testRetainsCodableProperties() {
configuration.retainCodableProperties = false
configuration.retainAssignOnlyProperties = false

analyze(retainPublic: true) {
assertReferenced(.struct("FixtureStruct14")) {
self.assertNotReferenced(.functionConstructor("init(unused:)"))
self.assertAssignOnlyProperty(.varInstance("unused"))
}
}

configuration.retainCodableProperties = true

analyze(retainPublic: true) {
assertReferenced(.struct("FixtureStruct14")) {
self.assertNotReferenced(.functionConstructor("init(unused:)"))
self.assertReferenced(.varInstance("unused"))
self.assertNotAssignOnlyProperty(.varInstance("unused"))
}
}
}

// MARK: - Assign-only properties

func testStructImplicitInitializer() {
Expand Down

0 comments on commit 8f5d47e

Please sign in to comment.