@@ -8,7 +8,7 @@ struct UnneededThrowsRule: Rule {
8
8
static let description = RuleDescription (
9
9
identifier: " unneeded_throws_rethrows " ,
10
10
name: " Unneeded (re)throws keyword " ,
11
- description: " Non-throwing functions/variables should not be marked as `throws` or `rethrows` " ,
11
+ description: " Non-throwing functions/properties/closures should not be marked as `throws` or `rethrows`. " ,
12
12
kind: . lint,
13
13
nonTriggeringExamples: UnneededThrowsRuleExamples . nonTriggeringExamples,
14
14
triggeringExamples: UnneededThrowsRuleExamples . triggeringExamples,
@@ -24,16 +24,12 @@ private extension UnneededThrowsRule {
24
24
final class Visitor : ViolationsSyntaxVisitor < ConfigurationType > {
25
25
private var scopes = Stack < Scope > ( )
26
26
27
- override func visit( _: ProtocolDeclSyntax ) -> SyntaxVisitorContinueKind {
28
- . skipChildren
29
- }
30
-
31
- override func visit( _: TypeAliasDeclSyntax ) -> SyntaxVisitorContinueKind {
32
- . skipChildren
33
- }
34
-
35
- override func visit( _: EnumCaseDeclSyntax ) -> SyntaxVisitorContinueKind {
36
- . skipChildren
27
+ override var skippableDeclarations : [ any DeclSyntaxProtocol . Type ] {
28
+ [
29
+ ProtocolDeclSyntax . self,
30
+ TypeAliasDeclSyntax . self,
31
+ EnumCaseDeclSyntax . self,
32
+ ]
37
33
}
38
34
39
35
override func visit( _: FunctionParameterClauseSyntax ) -> SyntaxVisitorContinueKind {
@@ -47,9 +43,9 @@ private extension UnneededThrowsRule {
47
43
48
44
override func visitPost( _: InitializerDeclSyntax ) {
49
45
if let closedScope = scopes. closeScope ( ) {
50
- validateScope (
51
- closedScope,
52
- reason: " The initializer does not throw any error"
46
+ validate (
47
+ scope : closedScope,
48
+ reason: " initializer does not throw any error "
53
49
)
54
50
}
55
51
}
@@ -61,9 +57,9 @@ private extension UnneededThrowsRule {
61
57
62
58
override func visitPost( _: AccessorDeclSyntax ) {
63
59
if let closedScope = scopes. closeScope ( ) {
64
- validateScope (
65
- closedScope,
66
- reason: " The accessor does not throw any error"
60
+ validate (
61
+ scope : closedScope,
62
+ reason: " accessor does not throw any error "
67
63
)
68
64
}
69
65
}
@@ -75,9 +71,9 @@ private extension UnneededThrowsRule {
75
71
76
72
override func visitPost( _: FunctionDeclSyntax ) {
77
73
if let closedScope = scopes. closeScope ( ) {
78
- validateScope (
79
- closedScope,
80
- reason: " The body of this function does not throw any error"
74
+ validate (
75
+ scope : closedScope,
76
+ reason: " body of this function does not throw any error "
81
77
)
82
78
}
83
79
}
@@ -91,9 +87,9 @@ private extension UnneededThrowsRule {
91
87
92
88
override func visitPost( _: FunctionTypeSyntax ) {
93
89
if let closedScope = scopes. closeScope ( ) {
94
- validateScope (
95
- closedScope,
96
- reason: " The closure type does not throw any error"
90
+ validate (
91
+ scope : closedScope,
92
+ reason: " closure type does not throw any error "
97
93
)
98
94
}
99
95
}
@@ -123,19 +119,17 @@ private extension UnneededThrowsRule {
123
119
}
124
120
125
121
override func visitPost( _ node: DoStmtSyntax ) {
126
- let doesNotContainCatchClauseWithoutPattern = !node. catchClauses. contains { catchClause in
127
- catchClause. catchItems. isEmpty
128
- }
129
- if doesNotContainCatchClauseWithoutPattern {
130
- scopes. markCurrentScopeAsThrowing ( )
122
+ if node. catchClauses. contains ( where: { $0. catchItems. isEmpty } ) {
123
+ // All errors will be caught.
124
+ return
131
125
}
126
+ scopes. markCurrentScopeAsThrowing ( )
132
127
}
133
128
134
- override func visit ( _ node: ForStmtSyntax ) -> SyntaxVisitorContinueKind {
129
+ override func visitPost ( _ node: ForStmtSyntax ) {
135
130
if node. tryKeyword != nil {
136
131
scopes. markCurrentScopeAsThrowing ( )
137
132
}
138
- return . visitChildren
139
133
}
140
134
141
135
override func visitPost( _ node: TryExprSyntax ) {
@@ -148,12 +142,12 @@ private extension UnneededThrowsRule {
148
142
scopes. markCurrentScopeAsThrowing ( )
149
143
}
150
144
151
- private func validateScope ( _ scope: Scope , reason: String ) {
145
+ private func validate ( scope: Scope , reason: String ) {
152
146
guard let throwsToken = scope. throwsClause? . throwsSpecifier else { return }
153
147
violations. append (
154
148
ReasonedRuleViolation (
155
149
position: throwsToken. positionAfterSkippingLeadingTrivia,
156
- reason: reason,
150
+ reason: " Superfluous 'throws'; " + reason,
157
151
correction: ReasonedRuleViolation . ViolationCorrection (
158
152
start: throwsToken. positionAfterSkippingLeadingTrivia,
159
153
end: throwsToken. endPosition,
@@ -192,9 +186,7 @@ private extension FunctionCallExprSyntax {
192
186
193
187
private extension PatternBindingSyntax {
194
188
var containsInitializerClause : Bool {
195
- children ( viewMode: . sourceAccurate) . contains { child in
196
- child. is ( InitializerClauseSyntax . self)
197
- }
189
+ initializer != nil
198
190
}
199
191
200
192
var functionTypeSyntax : FunctionTypeSyntax ? {
0 commit comments