@@ -68,36 +68,36 @@ module Impl {
68
68
* where `definingNode` is the entire `Either::Left(x) | Either::Right(x)`
69
69
* pattern.
70
70
*/
71
+ cached
71
72
private predicate variableDecl ( AstNode definingNode , Name name , string text ) {
72
- (
73
- exists ( SelfParam sp |
74
- name = sp .getName ( ) and
75
- definingNode = name and
76
- text = name .getText ( ) and
77
- // exclude self parameters from functions without a body as these are
78
- // trait method declarations without implementations
79
- not exists ( Function f | not f .hasBody ( ) and f .getParamList ( ) .getSelfParam ( ) = sp )
80
- )
81
- or
82
- exists ( IdentPat pat |
83
- name = pat .getName ( ) and
84
- (
85
- definingNode = getOutermostEnclosingOrPat ( pat )
86
- or
87
- not exists ( getOutermostEnclosingOrPat ( pat ) ) and definingNode = name
88
- ) and
89
- text = name .getText ( ) and
90
- // exclude for now anything starting with an uppercase character, which may be a reference to
91
- // an enum constant (e.g. `None`). This excludes static and constant variables (UPPERCASE),
92
- // which we don't appear to recognize yet anyway. This also assumes programmers follow the
93
- // naming guidelines, which they generally do, but they're not enforced.
94
- not text .charAt ( 0 ) .isUppercase ( ) and
95
- // exclude parameters from functions without a body as these are trait method declarations
96
- // without implementations
97
- not exists ( Function f | not f .hasBody ( ) and f .getParamList ( ) .getAParam ( ) .getPat ( ) = pat ) and
98
- // exclude parameters from function pointer types (e.g. `x` in `fn(x: i32) -> i32`)
99
- not exists ( FnPtrTypeRepr fp | fp .getParamList ( ) .getParam ( _) .getPat ( ) = pat )
100
- )
73
+ Cached:: ref ( ) and
74
+ exists ( SelfParam sp |
75
+ name = sp .getName ( ) and
76
+ definingNode = name and
77
+ text = name .getText ( ) and
78
+ // exclude self parameters from functions without a body as these are
79
+ // trait method declarations without implementations
80
+ not exists ( Function f | not f .hasBody ( ) and f .getParamList ( ) .getSelfParam ( ) = sp )
81
+ )
82
+ or
83
+ exists ( IdentPat pat |
84
+ name = pat .getName ( ) and
85
+ (
86
+ definingNode = getOutermostEnclosingOrPat ( pat )
87
+ or
88
+ not exists ( getOutermostEnclosingOrPat ( pat ) ) and definingNode = name
89
+ ) and
90
+ text = name .getText ( ) and
91
+ // exclude for now anything starting with an uppercase character, which may be a reference to
92
+ // an enum constant (e.g. `None`). This excludes static and constant variables (UPPERCASE),
93
+ // which we don't appear to recognize yet anyway. This also assumes programmers follow the
94
+ // naming guidelines, which they generally do, but they're not enforced.
95
+ not text .charAt ( 0 ) .isUppercase ( ) and
96
+ // exclude parameters from functions without a body as these are trait method declarations
97
+ // without implementations
98
+ not exists ( Function f | not f .hasBody ( ) and f .getParamList ( ) .getAParam ( ) .getPat ( ) = pat ) and
99
+ // exclude parameters from function pointer types (e.g. `x` in `fn(x: i32) -> i32`)
100
+ not exists ( FnPtrTypeRepr fp | fp .getParamList ( ) .getParam ( _) .getPat ( ) = pat )
101
101
)
102
102
}
103
103
@@ -156,8 +156,12 @@ module Impl {
156
156
predicate isCaptured ( ) { this .getAnAccess ( ) .isCapture ( ) }
157
157
158
158
/** Gets the parameter that introduces this variable, if any. */
159
+ cached
159
160
ParamBase getParameter ( ) {
160
- result = this .getSelfParam ( ) or result .( Param ) .getPat ( ) = getAVariablePatAncestor ( this )
161
+ Cached:: ref ( ) and
162
+ result = this .getSelfParam ( )
163
+ or
164
+ result .( Param ) .getPat ( ) = getAVariablePatAncestor ( this )
161
165
}
162
166
163
167
/** Hold is this variable is mutable. */
@@ -614,12 +618,18 @@ module Impl {
614
618
615
619
/** A variable write. */
616
620
class VariableWriteAccess extends VariableAccess {
617
- VariableWriteAccess ( ) { assignmentExprDescendant ( this ) }
621
+ cached
622
+ VariableWriteAccess ( ) {
623
+ Cached:: ref ( ) and
624
+ assignmentExprDescendant ( this )
625
+ }
618
626
}
619
627
620
628
/** A variable read. */
621
629
class VariableReadAccess extends VariableAccess {
630
+ cached
622
631
VariableReadAccess ( ) {
632
+ Cached:: ref ( ) and
623
633
not this instanceof VariableWriteAccess and
624
634
not this = any ( RefExpr re ) .getExpr ( ) and
625
635
not this = any ( CompoundAssignmentExpr cae ) .getLhs ( )
@@ -638,6 +648,22 @@ module Impl {
638
648
639
649
cached
640
650
private module Cached {
651
+ cached
652
+ predicate ref ( ) { 1 = 1 }
653
+
654
+ cached
655
+ predicate backref ( ) {
656
+ 1 = 1
657
+ or
658
+ variableDecl ( _, _, _)
659
+ or
660
+ exists ( VariableReadAccess a )
661
+ or
662
+ exists ( VariableWriteAccess a )
663
+ or
664
+ exists ( any ( Variable v ) .getParameter ( ) )
665
+ }
666
+
641
667
cached
642
668
newtype TVariable =
643
669
MkVariable ( AstNode definingNode , string name ) { variableDecl ( definingNode , _, name ) }
0 commit comments