@@ -27,10 +27,10 @@ extension LintPipeline {
2727 /// - node: The syntax node on which the rule will be applied. This lets us check whether the
2828 /// rule is enabled for the particular source range where the node occurs.
2929 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
3131 ) {
3232 guard context. isRuleEnabled ( Rule . self. ruleName, node: Syntax ( node) ) else { return }
33- let rule = Rule ( context : context )
33+ let rule = self . rule ( Rule . self )
3434 _ = visitor ( rule) ( node)
3535 }
3636
@@ -44,14 +44,30 @@ extension LintPipeline {
4444 /// - node: The syntax node on which the rule will be applied. This lets us check whether the
4545 /// rule is enabled for the particular source range where the node occurs.
4646 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
4848 ) {
4949 // Note that visitor function type is expressed as `Any` because we ignore the return value, but
5050 // more importantly because the `visit` methods return protocol refinements of `Syntax` that
5151 // cannot currently be expressed as constraints without duplicating this function for each of
5252 // them individually.
5353 guard context. isRuleEnabled ( Rule . self. ruleName, node: Syntax ( node) ) else { return }
54- let rule = Rule ( context : context )
54+ let rule = self . rule ( Rule . self )
5555 _ = visitor ( rule) ( node)
5656 }
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+ }
5773}
0 commit comments