@@ -64,6 +64,15 @@ abstract class AttrRef extends Node {
64
64
abstract class AttrWrite extends AttrRef {
65
65
/** Gets the data flow node corresponding to the value that is written to the attribute. */
66
66
abstract Node getValue ( ) ;
67
+
68
+ /**
69
+ * Holds if this attribute write writes the attribute named `attrName` on object `object` with
70
+ * value `value`.
71
+ */
72
+ predicate writes ( Node object , string attrName , Node value ) {
73
+ this .accesses ( object , attrName ) and
74
+ this .getValue ( ) = value
75
+ }
67
76
}
68
77
69
78
/**
@@ -225,7 +234,14 @@ private class ClassDefinitionAsAttrWrite extends AttrWrite, CfgNode {
225
234
* - Dynamic attribute reads using `getattr`: `getattr(object, attr)`
226
235
* - Qualified imports: `from module import attr as name`
227
236
*/
228
- abstract class AttrRead extends AttrRef , Node , LocalSourceNode { }
237
+ abstract class AttrRead extends AttrRef , Node , LocalSourceNode {
238
+
239
+ /** Holds if this attribute read reads the attribute named `attrName` on the object `object`. */
240
+ predicate reads ( Node object , string attrName ) {
241
+ this .accesses ( object , attrName )
242
+ }
243
+
244
+ }
229
245
230
246
/** A simple attribute read, e.g. `object.attr` */
231
247
private class AttributeReadAsAttrRead extends AttrRead , CfgNode {
0 commit comments