mirror of
https://github.com/realm/SwiftLint.git
synced 2026-05-07 20:12:49 +00:00
Ignore @concurrent functions in async_without_await rule (#6284)
This commit is contained in:
committed by
GitHub
parent
4065fc8437
commit
a0414c919d
@@ -66,6 +66,11 @@
|
||||
[SimplyDanny](https://github.com/SimplyDanny)
|
||||
[#6253](https://github.com/realm/SwiftLint/issues/6235)
|
||||
|
||||
* Exclude `@concurrent` functions from `async_without_await` rule analysis.
|
||||
`@concurrent` functions requires `aysnc` in any case.
|
||||
[nandhinisubbu](https://github.com/nandhinisubbu)
|
||||
[#6283](https://github.com/realm/SwiftLint/issues/6283)
|
||||
|
||||
## 0.61.0: Even Fresher Breeze
|
||||
|
||||
### Breaking
|
||||
|
||||
@@ -30,7 +30,9 @@ private extension AsyncWithoutAwaitRule {
|
||||
return .visitChildren
|
||||
}
|
||||
|
||||
let asyncToken = node.signature.effectSpecifiers?.asyncSpecifier
|
||||
// @concurrent functions require the async keyword even without await calls
|
||||
let asyncToken = node.attributes.contains(attributeNamed: "concurrent")
|
||||
? nil : node.signature.effectSpecifiers?.asyncSpecifier
|
||||
functionScopes.push(.init(asyncToken: asyncToken))
|
||||
|
||||
return .visitChildren
|
||||
@@ -42,8 +44,11 @@ private extension AsyncWithoutAwaitRule {
|
||||
}
|
||||
}
|
||||
|
||||
override func visit(_: ClosureExprSyntax) -> SyntaxVisitorContinueKind {
|
||||
functionScopes.push(.init(asyncToken: pendingAsync))
|
||||
override func visit(_ node: ClosureExprSyntax) -> SyntaxVisitorContinueKind {
|
||||
// @concurrent closures require the async keyword even without await calls
|
||||
let asyncToken = (node.signature?.attributes.contains(attributeNamed: "concurrent") ?? false)
|
||||
? nil : pendingAsync
|
||||
functionScopes.push(.init(asyncToken: asyncToken))
|
||||
pendingAsync = nil
|
||||
return .visitChildren
|
||||
}
|
||||
@@ -78,7 +83,9 @@ private extension AsyncWithoutAwaitRule {
|
||||
return .visitChildren
|
||||
}
|
||||
|
||||
let asyncToken = node.signature.effectSpecifiers?.asyncSpecifier
|
||||
// @concurrent can be applied to initializers
|
||||
let asyncToken = node.attributes.contains(attributeNamed: "concurrent")
|
||||
? nil : node.signature.effectSpecifiers?.asyncSpecifier
|
||||
functionScopes.push(.init(asyncToken: asyncToken))
|
||||
|
||||
return .visitChildren
|
||||
|
||||
@@ -160,6 +160,34 @@ internal struct AsyncWithoutAwaitRuleExamples {
|
||||
}
|
||||
}
|
||||
""", excludeFromDocumentation: true),
|
||||
Example("""
|
||||
@concurrent
|
||||
func concurrentFunction() async {
|
||||
performWork()
|
||||
}
|
||||
"""),
|
||||
Example("""
|
||||
struct S: Sendable {
|
||||
@concurrent
|
||||
func alwaysSwitch() async {
|
||||
// This is valid - @concurrent functions require async even without await
|
||||
}
|
||||
}
|
||||
"""),
|
||||
Example("""
|
||||
struct ConcurrentInitExample {
|
||||
@concurrent
|
||||
init() async {
|
||||
setup()
|
||||
}
|
||||
func setup() {}
|
||||
}
|
||||
"""),
|
||||
Example("""
|
||||
struct ConcurrentClosureExample {
|
||||
let c: () async -> Int = { @concurrent in 1 }
|
||||
}
|
||||
"""),
|
||||
]
|
||||
|
||||
static let triggeringExamples = [
|
||||
|
||||
Reference in New Issue
Block a user