@@ -69,6 +69,9 @@ class DataFlowCallable extends TDataFlowCallable {
6969cached
7070newtype TDataFlowCall =
7171 TNormalCall ( ApplyExprCfgNode call ) or
72+ TPropertyGetterCall ( PropertyGetterCfgNode getter ) or
73+ TPropertySetterCall ( PropertySetterCfgNode setter ) or
74+ TPropertyObserverCall ( PropertyObserverCfgNode obserer ) or
7275 TSummaryCall ( FlowSummaryImpl:: Public:: SummarizedCallable c , Node receiver ) {
7376 FlowSummaryImpl:: Private:: summaryCallbackRange ( c , receiver )
7477 }
@@ -84,6 +87,14 @@ class DataFlowCall extends TDataFlowCall {
8487 /** Gets the underlying source code call, if any. */
8588 ApplyExprCfgNode asCall ( ) { none ( ) }
8689
90+ /**
91+ * Gets the i'th argument of call.class
92+ * The qualifier is considered to have index `-1`.
93+ */
94+ CfgNode getArgument ( int i ) { none ( ) }
95+
96+ final CfgNode getAnArgument ( ) { result = this .getArgument ( _) }
97+
8798 /** Gets a textual representation of this call. */
8899 string toString ( ) { none ( ) }
89100
@@ -111,13 +122,92 @@ private class NormalCall extends DataFlowCall, TNormalCall {
111122
112123 override ApplyExprCfgNode asCall ( ) { result = apply }
113124
125+ override CfgNode getArgument ( int i ) {
126+ i = - 1 and
127+ result = apply .getQualifier ( )
128+ or
129+ result = apply .getArgument ( i )
130+ }
131+
114132 override DataFlowCallable getEnclosingCallable ( ) { result = TDataFlowFunc ( apply .getScope ( ) ) }
115133
116134 override string toString ( ) { result = apply .toString ( ) }
117135
118136 override Location getLocation ( ) { result = apply .getLocation ( ) }
119137}
120138
139+ class PropertyGetterCall extends DataFlowCall , TPropertyGetterCall {
140+ private PropertyGetterCfgNode getter ;
141+
142+ PropertyGetterCall ( ) { this = TPropertyGetterCall ( getter ) }
143+
144+ override CfgNode getArgument ( int i ) {
145+ i = - 1 and
146+ result = getter .getBase ( )
147+ }
148+
149+ override DataFlowCallable getEnclosingCallable ( ) { result = TDataFlowFunc ( getter .getScope ( ) ) }
150+
151+ PropertyGetterCfgNode getGetter ( ) { result = getter }
152+
153+ override string toString ( ) { result = getter .toString ( ) }
154+
155+ override Location getLocation ( ) { result = getter .getLocation ( ) }
156+
157+ AccessorDecl getAccessorDecl ( ) { result = getter .getAccessorDecl ( ) }
158+ }
159+
160+ class PropertySetterCall extends DataFlowCall , TPropertySetterCall {
161+ private PropertySetterCfgNode setter ;
162+
163+ PropertySetterCall ( ) { this = TPropertySetterCall ( setter ) }
164+
165+ override CfgNode getArgument ( int i ) {
166+ i = - 1 and
167+ result = setter .getBase ( )
168+ or
169+ i = 0 and
170+ result = setter .getSource ( )
171+ }
172+
173+ override DataFlowCallable getEnclosingCallable ( ) { result = TDataFlowFunc ( setter .getScope ( ) ) }
174+
175+ PropertySetterCfgNode getSetter ( ) { result = setter }
176+
177+ override string toString ( ) { result = setter .toString ( ) }
178+
179+ override Location getLocation ( ) { result = setter .getLocation ( ) }
180+
181+ AccessorDecl getAccessorDecl ( ) { result = setter .getAccessorDecl ( ) }
182+ }
183+
184+ class PropertyObserverCall extends DataFlowCall , TPropertyObserverCall {
185+ private PropertyObserverCfgNode observer ;
186+
187+ PropertyObserverCall ( ) { this = TPropertyObserverCall ( observer ) }
188+
189+ override CfgNode getArgument ( int i ) {
190+ i = - 1 and
191+ result = observer .getBase ( )
192+ or
193+ // TODO: This is correct for `willSet` (which takes a `newValue` parameter),
194+ // but for `didSet` (which takes an `oldValue` paramter) we need an rvalue
195+ // for `getBase()`.
196+ i = 0 and
197+ result = observer .getSource ( )
198+ }
199+
200+ override DataFlowCallable getEnclosingCallable ( ) { result = TDataFlowFunc ( observer .getScope ( ) ) }
201+
202+ PropertyObserverCfgNode getObserver ( ) { result = observer }
203+
204+ override string toString ( ) { result = observer .toString ( ) }
205+
206+ override Location getLocation ( ) { result = observer .getLocation ( ) }
207+
208+ AccessorDecl getAccessorDecl ( ) { result = observer .getAccessorDecl ( ) }
209+ }
210+
121211class SummaryCall extends DataFlowCall , TSummaryCall {
122212 private FlowSummaryImpl:: Public:: SummarizedCallable c ;
123213 private Node receiver ;
@@ -145,6 +235,12 @@ private module Cached {
145235 cached
146236 DataFlowCallable viableCallable ( DataFlowCall call ) {
147237 result = TDataFlowFunc ( call .asCall ( ) .getStaticTarget ( ) )
238+ or
239+ result = TDataFlowFunc ( call .( PropertyGetterCall ) .getAccessorDecl ( ) )
240+ or
241+ result = TDataFlowFunc ( call .( PropertySetterCall ) .getAccessorDecl ( ) )
242+ or
243+ result = TDataFlowFunc ( call .( PropertyObserverCall ) .getAccessorDecl ( ) )
148244 }
149245
150246 cached
0 commit comments