Skip to content

Commit f42d4f2

Browse files
authored
Merge pull request #765 from harlanhaskins/hhaskins/retro-activity
Add lint warning for retroactive conformances
2 parents 6fadf64 + e99495c commit f42d4f2

File tree

7 files changed

+77
-0
lines changed

7 files changed

+77
-0
lines changed

Documentation/RuleDocumentation.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Here's the list of available rules:
1414
- [AlwaysUseLiteralForEmptyCollectionInit](#AlwaysUseLiteralForEmptyCollectionInit)
1515
- [AlwaysUseLowerCamelCase](#AlwaysUseLowerCamelCase)
1616
- [AmbiguousTrailingClosureOverload](#AmbiguousTrailingClosureOverload)
17+
- [AvoidRetroactiveConformances](#AvoidRetroactiveConformances)
1718
- [BeginDocumentationCommentWithOneLineSummary](#BeginDocumentationCommentWithOneLineSummary)
1819
- [DoNotUseSemicolons](#DoNotUseSemicolons)
1920
- [DontRepeatTypeInStaticProperties](#DontRepeatTypeInStaticProperties)
@@ -93,6 +94,14 @@ Lint: If two overloaded functions with one closure parameter appear in the same
9394

9495
`AmbiguousTrailingClosureOverload` is a linter-only rule.
9596

97+
### AvoidRetroactiveConformances
98+
99+
`@retroactive` conformances are forbidden.
100+
101+
Lint: Using `@retroactive` results in a lint error.
102+
103+
`AvoidRetroactiveConformances` is a linter-only rule.
104+
96105
### BeginDocumentationCommentWithOneLineSummary
97106

98107
All documentation comments must begin with a one-line summary of the declaration.

Sources/SwiftFormat/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ add_library(SwiftFormat
5757
Rules/AlwaysUseLiteralForEmptyCollectionInit.swift
5858
Rules/AlwaysUseLowerCamelCase.swift
5959
Rules/AmbiguousTrailingClosureOverload.swift
60+
Rules/AvoidRetroactiveConformances.swift
6061
Rules/BeginDocumentationCommentWithOneLineSummary.swift
6162
Rules/DoNotUseSemicolons.swift
6263
Rules/DontRepeatTypeInStaticProperties.swift

Sources/SwiftFormat/Core/Pipelines+Generated.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ class LintPipeline: SyntaxVisitor {
6464
onVisitPost(rule: TypeNamesShouldBeCapitalized.self, for: node)
6565
}
6666

67+
override func visit(_ node: AttributeSyntax) -> SyntaxVisitorContinueKind {
68+
visitIfEnabled(AvoidRetroactiveConformances.visit, for: node)
69+
return .visitChildren
70+
}
71+
override func visitPost(_ node: AttributeSyntax) {
72+
onVisitPost(rule: AvoidRetroactiveConformances.self, for: node)
73+
}
74+
6775
override func visit(_ node: ClassDeclSyntax) -> SyntaxVisitorContinueKind {
6876
visitIfEnabled(AllPublicDeclarationsHaveDocumentation.visit, for: node)
6977
visitIfEnabled(AlwaysUseLowerCamelCase.visit, for: node)
@@ -193,12 +201,14 @@ class LintPipeline: SyntaxVisitor {
193201
}
194202

195203
override func visit(_ node: ExtensionDeclSyntax) -> SyntaxVisitorContinueKind {
204+
visitIfEnabled(AvoidRetroactiveConformances.visit, for: node)
196205
visitIfEnabled(DontRepeatTypeInStaticProperties.visit, for: node)
197206
visitIfEnabled(NoAccessLevelOnExtensionDeclaration.visit, for: node)
198207
visitIfEnabled(UseTripleSlashForDocumentationComments.visit, for: node)
199208
return .visitChildren
200209
}
201210
override func visitPost(_ node: ExtensionDeclSyntax) {
211+
onVisitPost(rule: AvoidRetroactiveConformances.self, for: node)
202212
onVisitPost(rule: DontRepeatTypeInStaticProperties.self, for: node)
203213
onVisitPost(rule: NoAccessLevelOnExtensionDeclaration.self, for: node)
204214
onVisitPost(rule: UseTripleSlashForDocumentationComments.self, for: node)

Sources/SwiftFormat/Core/RuleNameCache+Generated.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public let ruleNameCache: [ObjectIdentifier: String] = [
1919
ObjectIdentifier(AlwaysUseLiteralForEmptyCollectionInit.self): "AlwaysUseLiteralForEmptyCollectionInit",
2020
ObjectIdentifier(AlwaysUseLowerCamelCase.self): "AlwaysUseLowerCamelCase",
2121
ObjectIdentifier(AmbiguousTrailingClosureOverload.self): "AmbiguousTrailingClosureOverload",
22+
ObjectIdentifier(AvoidRetroactiveConformances.self): "AvoidRetroactiveConformances",
2223
ObjectIdentifier(BeginDocumentationCommentWithOneLineSummary.self): "BeginDocumentationCommentWithOneLineSummary",
2324
ObjectIdentifier(DoNotUseSemicolons.self): "DoNotUseSemicolons",
2425
ObjectIdentifier(DontRepeatTypeInStaticProperties.self): "DontRepeatTypeInStaticProperties",

Sources/SwiftFormat/Core/RuleRegistry+Generated.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"AlwaysUseLiteralForEmptyCollectionInit": false,
1919
"AlwaysUseLowerCamelCase": true,
2020
"AmbiguousTrailingClosureOverload": true,
21+
"AvoidRetroactiveConformances": true,
2122
"BeginDocumentationCommentWithOneLineSummary": false,
2223
"DoNotUseSemicolons": true,
2324
"DontRepeatTypeInStaticProperties": true,
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SwiftSyntax
14+
15+
/// `@retroactive` conformances are forbidden.
16+
///
17+
/// Lint: Using `@retroactive` results in a lint error.
18+
@_spi(Rules)
19+
public final class AvoidRetroactiveConformances: SyntaxLintRule {
20+
public override func visit(_ node: ExtensionDeclSyntax) -> SyntaxVisitorContinueKind {
21+
if let inheritanceClause = node.inheritanceClause {
22+
walk(inheritanceClause)
23+
}
24+
return .skipChildren
25+
}
26+
public override func visit(_ type: AttributeSyntax) -> SyntaxVisitorContinueKind {
27+
if let identifier = type.attributeName.as(IdentifierTypeSyntax.self) {
28+
if identifier.name.text == "retroactive" {
29+
diagnose(.doNotUseRetroactive, on: type)
30+
}
31+
}
32+
return .skipChildren
33+
}
34+
}
35+
36+
extension Finding.Message {
37+
fileprivate static let doNotUseRetroactive: Finding.Message = "do not declare retroactive conformances"
38+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import _SwiftFormatTestSupport
2+
3+
@_spi(Rules) import SwiftFormat
4+
5+
final class AvoidRetroactiveConformancesTests: LintOrFormatRuleTestCase {
6+
func testRetroactiveConformanceIsDiagnosed() {
7+
assertLint(
8+
AvoidRetroactiveConformances.self,
9+
"""
10+
extension Int: 1️⃣@retroactive Identifiable {}
11+
""",
12+
findings: [
13+
FindingSpec("1️⃣", message: "do not declare retroactive conformances"),
14+
]
15+
)
16+
}
17+
}

0 commit comments

Comments
 (0)