@@ -27,10 +27,10 @@ extension LintPipeline {
27
27
/// - node: The syntax node on which the rule will be applied. This lets us check whether the
28
28
/// rule is enabled for the particular source range where the node occurs.
29
29
func visitIfEnabled< Rule: SyntaxLintRule , Node: SyntaxProtocol > (
30
- _ visitor: ( Rule ) -> ( Node ) -> SyntaxVisitorContinueKind , in context : Context , for node: Node
30
+ _ visitor: ( Rule ) -> ( Node ) -> SyntaxVisitorContinueKind , for node: Node
31
31
) {
32
32
guard context. isRuleEnabled ( Rule . self. ruleName, node: Syntax ( node) ) else { return }
33
- let rule = Rule ( context : context )
33
+ let rule = self . rule ( Rule . self )
34
34
_ = visitor ( rule) ( node)
35
35
}
36
36
@@ -44,14 +44,30 @@ extension LintPipeline {
44
44
/// - node: The syntax node on which the rule will be applied. This lets us check whether the
45
45
/// rule is enabled for the particular source range where the node occurs.
46
46
func visitIfEnabled< Rule: SyntaxFormatRule , Node: SyntaxProtocol > (
47
- _ visitor: ( Rule ) -> ( Node ) -> Any , in context : Context , for node: Node
47
+ _ visitor: ( Rule ) -> ( Node ) -> Any , for node: Node
48
48
) {
49
49
// Note that visitor function type is expressed as `Any` because we ignore the return value, but
50
50
// more importantly because the `visit` methods return protocol refinements of `Syntax` that
51
51
// cannot currently be expressed as constraints without duplicating this function for each of
52
52
// them individually.
53
53
guard context. isRuleEnabled ( Rule . self. ruleName, node: Syntax ( node) ) else { return }
54
- let rule = Rule ( context : context )
54
+ let rule = self . rule ( Rule . self )
55
55
_ = visitor ( rule) ( node)
56
56
}
57
+
58
+ /// Retrieves an instance of a lint or format rule based on its type.
59
+ ///
60
+ /// There is at most 1 instance of each rule allocated per `LintPipeline`. This method will
61
+ /// create that instance as needed, using `ruleCache` to cache rules.
62
+ /// - Parameter type: The type of the rule to retrieve.
63
+ /// - Returns: An instance of the given type.
64
+ private func rule< R: Rule > ( _ type: R . Type ) -> R {
65
+ let identifier = ObjectIdentifier ( type)
66
+ if let cachedRule = ruleCache [ identifier] {
67
+ return cachedRule as! R
68
+ }
69
+ let rule = R ( context: context)
70
+ ruleCache [ identifier] = rule
71
+ return rule
72
+ }
57
73
}
0 commit comments