Skip to content

Commit 0e03915

Browse files
authored
Merge pull request #659 from thunderseethe/main
Respect SyntaxVisitorContinueKind of rules when run in Pipeline
2 parents b87fa64 + d881cd1 commit 0e03915

File tree

4 files changed

+306
-1
lines changed

4 files changed

+306
-1
lines changed

Sources/SwiftFormat/Core/LintPipeline.swift

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,13 @@ extension LintPipeline {
2929
_ visitor: (Rule) -> (Node) -> SyntaxVisitorContinueKind, for node: Node
3030
) {
3131
guard context.isRuleEnabled(Rule.self, node: Syntax(node)) else { return }
32+
let ruleId = ObjectIdentifier(Rule.self)
33+
guard self.shouldSkipChildren[ruleId] == nil else { return }
3234
let rule = self.rule(Rule.self)
33-
_ = visitor(rule)(node)
35+
let continueKind = visitor(rule)(node)
36+
if case .skipChildren = continueKind {
37+
self.shouldSkipChildren[ruleId] = node
38+
}
3439
}
3540

3641
/// Calls the `visit` method of a rule for the given node if that rule is enabled for the node.
@@ -50,10 +55,27 @@ extension LintPipeline {
5055
// cannot currently be expressed as constraints without duplicating this function for each of
5156
// them individually.
5257
guard context.isRuleEnabled(Rule.self, node: Syntax(node)) else { return }
58+
guard self.shouldSkipChildren[ObjectIdentifier(Rule.self)] == nil else { return }
5359
let rule = self.rule(Rule.self)
5460
_ = visitor(rule)(node)
5561
}
5662

63+
/// Cleans up any state associated with `rule` when we leave syntax node `node`
64+
///
65+
/// - Parameters:
66+
/// - rule: The type of the syntax rule we're cleaning up.
67+
/// - node: The syntax node htat our traversal has left.
68+
func onVisitPost<R: Rule, Node: SyntaxProtocol>(
69+
rule: R.Type, for node: Node
70+
) {
71+
let rule = ObjectIdentifier(rule)
72+
if case .some(let skipNode) = self.shouldSkipChildren[rule] {
73+
if node.id == skipNode.id {
74+
self.shouldSkipChildren.removeValue(forKey: rule)
75+
}
76+
}
77+
}
78+
5779
/// Retrieves an instance of a lint or format rule based on its type.
5880
///
5981
/// There is at most 1 instance of each rule allocated per `LintPipeline`. This method will

0 commit comments

Comments
 (0)