@@ -185,23 +185,23 @@ module SourceSinkInterpretationInput implements
185185
186186 /**
187187 * Holds if this source or sink element is a method or field that was specified
188- * with the given values for `pkg`, `type` and `subtypes`.
188+ * with the given values for `e`, ` pkg`, `type` and `subtypes`.
189189 */
190- predicate hasTypeInfo ( string pkg , string type , boolean subtypes ) {
191- this = TMethodEntityElement ( _ , pkg , type , subtypes ) or
192- this = TFieldEntityElement ( _ , pkg , type , subtypes )
190+ predicate hasFullInfo ( Entity e , string pkg , string type , boolean subtypes ) {
191+ this = TMethodEntityElement ( e , pkg , type , subtypes ) or
192+ this = TFieldEntityElement ( e , pkg , type , subtypes )
193193 }
194194
195195 /** Gets a textual representation of this source or sink element. */
196196 string toString ( ) {
197- not this . hasTypeInfo ( _ , _ , _ ) and
197+ ( this instanceof TOtherEntityElement or this instanceof TAstElement ) and
198198 result = "element representing " + [ this .asEntity ( ) .toString ( ) , this .asAstNode ( ) .toString ( ) ]
199199 or
200- exists ( string pkg , string name , boolean subtypes |
201- this .hasTypeInfo ( pkg , name , subtypes ) and
200+ exists ( Entity e , string pkg , string name , boolean subtypes |
201+ this .hasFullInfo ( e , pkg , name , subtypes ) and
202202 result =
203- "element representing " + this . asEntity ( ) . toString ( ) + " with receiver type " + pkg + "." +
204- name + " and subtypes=" + subtypes
203+ "element representing " + e . toString ( ) + " with receiver type " + pkg + "." + name +
204+ " and subtypes=" + subtypes
205205 )
206206 }
207207
@@ -249,8 +249,8 @@ module SourceSinkInterpretationInput implements
249249 (
250250 result .asOtherEntity ( ) = callTarget
251251 or
252- result . asMethodEntity ( ) = callTarget and
253- elementAppliesToQualifier ( result , cn .getReceiver ( ) )
252+ callTarget instanceof Method and
253+ result = getElementWithQualifier ( callTarget , cn .getReceiver ( ) )
254254 )
255255 )
256256 }
@@ -278,22 +278,20 @@ module SourceSinkInterpretationInput implements
278278 }
279279
280280 /**
281- * Holds if method or field spec `sse` applies in the context of qualifier `qual`.
281+ * Gets a method or field spec for `e` which applies in the context of
282+ * qualifier `qual`.
282283 *
283- * Note that naively checking `sse.asEntity() `'s qualified name is not correct, because
284- * `Method`s and `Field`s may have multiple qualified names due to embedding. We must instead
285- * check that the specific name given by `sse.hasTypeInfo` refers to either `qual`'s type
286- * or to a type it embeds.
284+ * Note that naively checking `e `'s qualified name is not correct, because
285+ * `Method`s and `Field`s may have multiple qualified names due to embedding.
286+ * We must instead check that the package and type name given by
287+ * `result.hasFullInfo` refer to either `qual`'s type or to a type it embeds.
287288 */
288- bindingset [ sse , qual]
289+ bindingset [ e , qual]
289290 pragma [ inline_late]
290- private predicate elementAppliesToQualifier ( SourceOrSinkElement sse , DataFlow:: Node qual ) {
291- exists (
292- string pkg , string typename , boolean subtypes , Type syntacticQualBaseType , Type targetType
293- |
294- sse .hasTypeInfo ( pkg , typename , subtypes ) and
295- targetType .hasQualifiedName ( pkg , typename ) and
296- syntacticQualBaseType = getSyntacticQualifierBaseType ( qual )
291+ private SourceOrSinkElement getElementWithQualifier ( Entity e , DataFlow:: Node qual ) {
292+ exists ( boolean subtypes , Type syntacticQualBaseType , Type targetType |
293+ syntacticQualBaseType = getSyntacticQualifierBaseType ( qual ) and
294+ result = constructElement ( e , targetType , subtypes )
297295 |
298296 subtypes = [ true , false ] and
299297 syntacticQualBaseType = targetType
@@ -307,12 +305,20 @@ module SourceSinkInterpretationInput implements
307305 or
308306 // `syntacticQualBaseType`'s underlying type might be a struct type and `sse`
309307 // might be a promoted method or field in it.
310- targetType =
311- getIntermediateEmbeddedType ( sse .asMethodEntity ( ) , syntacticQualBaseType .getUnderlyingType ( ) )
308+ targetType = getIntermediateEmbeddedType ( e , syntacticQualBaseType .getUnderlyingType ( ) )
312309 )
313310 )
314311 }
315312
313+ bindingset [ e, targetType, subtypes]
314+ pragma [ inline_late]
315+ private SourceOrSinkElement constructElement ( Entity e , Type targetType , boolean subtypes ) {
316+ exists ( string pkg , string typename |
317+ targetType .hasQualifiedName ( pkg , typename ) and
318+ result .hasFullInfo ( e , pkg , typename , subtypes )
319+ )
320+ }
321+
316322 /**
317323 * Gets the type of an embedded field of `st` which is on the path to `e`,
318324 * which is a promoted method or field of `st`, or its base type if it's a
@@ -388,8 +394,7 @@ module SourceSinkInterpretationInput implements
388394 or
389395 exists ( DataFlow:: FieldReadNode frn | frn = n |
390396 c = "" and
391- frn .getField ( ) = pragma [ only_bind_into ] ( e ) .asFieldEntity ( ) and
392- elementAppliesToQualifier ( pragma [ only_bind_into ] ( e ) , frn .getBase ( ) )
397+ pragma [ only_bind_into ] ( e ) = getElementWithQualifier ( frn .getField ( ) , frn .getBase ( ) )
393398 )
394399 )
395400 }
@@ -410,7 +415,7 @@ module SourceSinkInterpretationInput implements
410415 |
411416 c = "" and
412417 fw .writesField ( base , f , node .asNode ( ) ) and
413- elementAppliesToQualifier ( pragma [ only_bind_into ] ( e ) , base )
418+ pragma [ only_bind_into ] ( e ) = getElementWithQualifier ( f , base )
414419 )
415420 }
416421}
0 commit comments