Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@

### Enhancements

* None.
* Add `legacy_uigraphics_functions` rule to encourage the use of modern
UIGraphicsImageRenderer instead of legacy UIGraphics{Begin|End}ImageContext.
The modern replacement is safer, cleaner, Retina-aware and more performant.
Comment on lines +31 to +33
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Add `legacy_uigraphics_functions` rule to encourage the use of modern
UIGraphicsImageRenderer instead of legacy UIGraphics{Begin|End}ImageContext.
The modern replacement is safer, cleaner, Retina-aware and more performant.
* Add `legacy_uigraphics_functions` rule to encourage the use of modern
`UIGraphicsImageRenderer `instead of legacy `UIGraphics{Begin|End}ImageContext`.
The modern replacement is safer, cleaner, Retina-aware and more performant.

[Dimitri Dupuis-Latour](https://github.com/DimDL)
[#6268](https://github.com/realm/SwiftLint/issues/6268)

### Bug Fixes

Expand Down
1 change: 1 addition & 0 deletions Source/SwiftLintBuiltInRules/Models/BuiltInRules.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ public let builtInRules: [any Rule.Type] = [
LegacyNSGeometryFunctionsRule.self,
LegacyObjcTypeRule.self,
LegacyRandomRule.self,
LegacyUIGraphicsFunctionsRule.self,
LetVarWhitespaceRule.self,
LineLengthRule.self,
LiteralExpressionEndIndentationRule.self,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import SwiftSyntax

@SwiftSyntaxRule
struct LegacyUIGraphicsFunctionsRule: Rule {
var configuration = SeverityConfiguration<Self>(.warning)

static let description = RuleDescription(
identifier: "legacy_uigraphics_functions",
name: "Legacy UIGraphics Functions",
description: "Prefer using `UIGraphicsImageRenderer` over legacy functions",
rationale: "The modern replacement is safer, cleaner, Retina-aware and more performant",
kind: .idiomatic,
nonTriggeringExamples: [
Example("""
let renderer = UIGraphicsImageRenderer(size: bounds.size)
let screenshot = renderer.image { _ in
myUIView.drawHierarchy(in: bounds, afterScreenUpdates: true)
}
"""),

Check failure on line 20 in Source/SwiftLintBuiltInRules/Rules/Lint/LegacyUIGraphicsFunctionsRule.swift

View workflow job for this annotation

GitHub Actions / Swift

Lines should not have trailing whitespace (trailing_whitespace)
Example("""
let renderer = UIGraphicsImageRenderer(size: newSize)
let combined = renderer.image { _ in
background.draw(in: CGRect(origin: .zero, size: newSize))
watermark.draw(in: CGRect(origin: .zero, size: watermarkSize))
}
"""),

Check failure on line 28 in Source/SwiftLintBuiltInRules/Rules/Lint/LegacyUIGraphicsFunctionsRule.swift

View workflow job for this annotation

GitHub Actions / Swift

Lines should not have trailing whitespace (trailing_whitespace)
Example("""
let format = UIGraphicsImageRendererFormat()
format.scale = 1.0
format.opaque = true

Check failure on line 33 in Source/SwiftLintBuiltInRules/Rules/Lint/LegacyUIGraphicsFunctionsRule.swift

View workflow job for this annotation

GitHub Actions / Swift

Lines should not have trailing whitespace (trailing_whitespace)
let renderer = UIGraphicsImageRenderer(size: newSize, format: format)
return renderer.image { _ in
image.draw(in: CGRect(origin: .zero, size: newSize))
}
"""),
],
triggeringExamples: [
Example("""
↓UIGraphicsBeginImageContext(newSize)
myUIView.drawHierarchy(in: bounds, afterScreenUpdates: false)
let optionalScreenshot = ↓UIGraphicsGetImageFromCurrentImageContext()
↓UIGraphicsEndImageContext()
"""),

Check failure on line 47 in Source/SwiftLintBuiltInRules/Rules/Lint/LegacyUIGraphicsFunctionsRule.swift

View workflow job for this annotation

GitHub Actions / Swift

Lines should not have trailing whitespace (trailing_whitespace)
Example("""
↓UIGraphicsBeginImageContext(newSize)
background.draw(in: CGRect(origin: .zero, size: newSize))
watermark.draw(in: CGRect(origin: .zero, size: watermarkSize))
let optionalOutput = ↓UIGraphicsGetImageFromCurrentImageContext()
↓UIGraphicsEndImageContext()
"""),

Check failure on line 55 in Source/SwiftLintBuiltInRules/Rules/Lint/LegacyUIGraphicsFunctionsRule.swift

View workflow job for this annotation

GitHub Actions / Swift

Lines should not have trailing whitespace (trailing_whitespace)
Example("""
↓UIGraphicsBeginImageContextWithOptions(newSize, true, 1.0)
image.draw(in: CGRect(origin: .zero, size: newSize))
let optionalOutput = ↓UIGraphicsGetImageFromCurrentImageContext()
↓UIGraphicsEndImageContext()
"""),
]
)
}

private extension LegacyUIGraphicsFunctionsRule {
final class Visitor: ViolationsSyntaxVisitor<ConfigurationType> {
private static let legacyUIGraphicsFunctions: Set<String> = [
"UIGraphicsBeginImageContext",
"UIGraphicsBeginImageContextWithOptions",
"UIGraphicsGetImageFromCurrentImageContext",
"UIGraphicsEndImageContext",
]

override func visitPost(_ node: FunctionCallExprSyntax) {
if let function = node.calledExpression.as(DeclReferenceExprSyntax.self)?.baseName.text,
Self.legacyUIGraphicsFunctions.contains(function) {
violations.append(node.positionAfterSkippingLeadingTrivia)
}
}
}
}
12 changes: 6 additions & 6 deletions Tests/GeneratedTests/GeneratedTests_05.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ final class LegacyRandomRuleGeneratedTests: SwiftLintTestCase {
}
}

final class LegacyUIGraphicsFunctionsRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(LegacyUIGraphicsFunctionsRule.description)
}
}

final class LetVarWhitespaceRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(LetVarWhitespaceRule.description)
Expand Down Expand Up @@ -150,9 +156,3 @@ final class NSObjectPreferIsEqualRuleGeneratedTests: SwiftLintTestCase {
verifyRule(NSObjectPreferIsEqualRule.description)
}
}

final class NestingRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(NestingRule.description)
}
}
12 changes: 6 additions & 6 deletions Tests/GeneratedTests/GeneratedTests_06.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
@testable import SwiftLintCore
import TestHelpers

final class NestingRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(NestingRule.description)
}
}

final class NimbleOperatorRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(NimbleOperatorRule.description)
Expand Down Expand Up @@ -150,9 +156,3 @@ final class PreferKeyPathRuleGeneratedTests: SwiftLintTestCase {
verifyRule(PreferKeyPathRule.description)
}
}

final class PreferNimbleRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(PreferNimbleRule.description)
}
}
12 changes: 6 additions & 6 deletions Tests/GeneratedTests/GeneratedTests_07.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
@testable import SwiftLintCore
import TestHelpers

final class PreferNimbleRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(PreferNimbleRule.description)
}
}

final class PreferSelfInStaticReferencesRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(PreferSelfInStaticReferencesRule.description)
Expand Down Expand Up @@ -150,9 +156,3 @@ final class RedundantSelfInClosureRuleGeneratedTests: SwiftLintTestCase {
verifyRule(RedundantSelfInClosureRule.description)
}
}

final class RedundantSendableRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(RedundantSendableRule.description)
}
}
12 changes: 6 additions & 6 deletions Tests/GeneratedTests/GeneratedTests_08.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
@testable import SwiftLintCore
import TestHelpers

final class RedundantSendableRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(RedundantSendableRule.description)
}
}

final class RedundantSetAccessControlRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(RedundantSetAccessControlRule.description)
Expand Down Expand Up @@ -150,9 +156,3 @@ final class SwitchCaseAlignmentRuleGeneratedTests: SwiftLintTestCase {
verifyRule(SwitchCaseAlignmentRule.description)
}
}

final class SwitchCaseOnNewlineRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(SwitchCaseOnNewlineRule.description)
}
}
12 changes: 6 additions & 6 deletions Tests/GeneratedTests/GeneratedTests_09.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
@testable import SwiftLintCore
import TestHelpers

final class SwitchCaseOnNewlineRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(SwitchCaseOnNewlineRule.description)
}
}

final class SyntacticSugarRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(SyntacticSugarRule.description)
Expand Down Expand Up @@ -150,9 +156,3 @@ final class UnusedControlFlowLabelRuleGeneratedTests: SwiftLintTestCase {
verifyRule(UnusedControlFlowLabelRule.description)
}
}

final class UnusedDeclarationRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(UnusedDeclarationRule.description)
}
}
6 changes: 6 additions & 0 deletions Tests/GeneratedTests/GeneratedTests_10.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
@testable import SwiftLintCore
import TestHelpers

final class UnusedDeclarationRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(UnusedDeclarationRule.description)
}
}

final class UnusedEnumeratedRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(UnusedEnumeratedRule.description)
Expand Down
5 changes: 5 additions & 0 deletions Tests/IntegrationTests/default_rule_configurations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,11 @@ legacy_random:
meta:
opt-in: false
correctable: false
legacy_uigraphics_functions:
severity: warning
meta:
opt-in: false
correctable: false
let_var_whitespace:
severity: warning
meta:
Expand Down
Loading