@@ -65,6 +65,61 @@ private boolean isGenerated(string provenance) {
6565 provenance != "generated" and result = false
6666}
6767
68+ private predicate relatedArgSpec ( Callable c , string spec ) {
69+ exists (
70+ string namespace , string type , boolean subtypes , string name , string signature , string ext
71+ |
72+ summaryModel ( namespace , type , subtypes , name , signature , ext , spec , _, _, _) or
73+ summaryModel ( namespace , type , subtypes , name , signature , ext , _, spec , _, _) or
74+ sourceModel ( namespace , type , subtypes , name , signature , ext , spec , _, _) or
75+ sinkModel ( namespace , type , subtypes , name , signature , ext , spec , _, _)
76+ |
77+ c = interpretElement ( namespace , type , subtypes , name , signature , ext )
78+ )
79+ }
80+
81+ /**
82+ * Holds if `defaultsCallable` is a Kotlin default-parameter proxy for `originalCallable`, and
83+ * `originalCallable` has a model, and `defaultsArgSpec` is `originalArgSpec` adjusted to account
84+ * for the additional dispatch receiver parameter that occurs in the default-parameter proxy's argument
85+ * list. When no adjustment is required (e.g. for constructors, or non-argument-based specs), `defaultArgsSpec`
86+ * equals `originalArgSpec`.
87+ */
88+ private predicate correspondingKotlinParameterDefaultsArgSpec (
89+ Callable originalCallable , Callable defaultsCallable , string originalArgSpec ,
90+ string defaultsArgSpec
91+ ) {
92+ relatedArgSpec ( originalCallable , originalArgSpec ) and
93+ defaultsCallable = originalCallable .getKotlinParameterDefaultsProxy ( ) and
94+ (
95+ originalCallable instanceof Constructor and originalArgSpec = defaultsArgSpec
96+ or
97+ originalCallable instanceof Method and
98+ exists ( string regex |
99+ // Note I use a regex and not AccessPathToken because this feeds summaryElement et al,
100+ // which would introduce mutual recursion with the definition of AccessPathToken.
101+ regex = "Argument\\[([0-9]+)\\](.*)" and
102+ (
103+ exists ( string oldArgNumber , string rest , int paramOffset |
104+ oldArgNumber = originalArgSpec .regexpCapture ( regex , 1 ) and
105+ rest = originalArgSpec .regexpCapture ( regex , 2 ) and
106+ paramOffset =
107+ (
108+ defaultsCallable .getNumberOfParameters ( ) -
109+ ( originalCallable .getNumberOfParameters ( ) + 2 )
110+ ) and
111+ if ktExtensionFunctions ( originalCallable , _, _) and oldArgNumber = "0"
112+ then defaultsArgSpec = originalArgSpec
113+ else defaultsArgSpec = "Argument[" + ( oldArgNumber .toInt ( ) + paramOffset ) + "]" + rest
114+ )
115+ or
116+ not originalArgSpec .regexpMatch ( regex ) and
117+ defaultsArgSpec = originalArgSpec
118+ )
119+ )
120+ )
121+ }
122+
68123/**
69124 * Holds if an external flow summary exists for `c` with input specification
70125 * `input`, output specification `output`, kind `kind`, and a flag `generated`
@@ -75,11 +130,19 @@ predicate summaryElement(
75130) {
76131 exists (
77132 string namespace , string type , boolean subtypes , string name , string signature , string ext ,
78- string provenance
133+ string provenance , string originalInput , string originalOutput , Callable baseCallable
79134 |
80- summaryModel ( namespace , type , subtypes , name , signature , ext , input , output , kind , provenance ) and
135+ summaryModel ( namespace , type , subtypes , name , signature , ext , originalInput , originalOutput ,
136+ kind , provenance ) and
81137 generated = isGenerated ( provenance ) and
82- c .asCallable ( ) = interpretElement ( namespace , type , subtypes , name , signature , ext )
138+ baseCallable = interpretElement ( namespace , type , subtypes , name , signature , ext ) and
139+ (
140+ c .asCallable ( ) = baseCallable and input = originalInput and output = originalOutput
141+ or
142+ correspondingKotlinParameterDefaultsArgSpec ( baseCallable , c .asCallable ( ) , originalInput , input ) and
143+ correspondingKotlinParameterDefaultsArgSpec ( baseCallable , c .asCallable ( ) , originalOutput ,
144+ output )
145+ )
83146 )
84147}
85148
@@ -149,11 +212,16 @@ class SourceOrSinkElement = Top;
149212predicate sourceElement ( SourceOrSinkElement e , string output , string kind , boolean generated ) {
150213 exists (
151214 string namespace , string type , boolean subtypes , string name , string signature , string ext ,
152- string provenance
215+ string provenance , SourceOrSinkElement baseSource , string originalOutput
153216 |
154- sourceModel ( namespace , type , subtypes , name , signature , ext , output , kind , provenance ) and
217+ sourceModel ( namespace , type , subtypes , name , signature , ext , originalOutput , kind , provenance ) and
155218 generated = isGenerated ( provenance ) and
156- e = interpretElement ( namespace , type , subtypes , name , signature , ext )
219+ baseSource = interpretElement ( namespace , type , subtypes , name , signature , ext ) and
220+ (
221+ e = baseSource and output = originalOutput
222+ or
223+ correspondingKotlinParameterDefaultsArgSpec ( baseSource , e , originalOutput , output )
224+ )
157225 )
158226}
159227
@@ -165,11 +233,16 @@ predicate sourceElement(SourceOrSinkElement e, string output, string kind, boole
165233predicate sinkElement ( SourceOrSinkElement e , string input , string kind , boolean generated ) {
166234 exists (
167235 string namespace , string type , boolean subtypes , string name , string signature , string ext ,
168- string provenance
236+ string provenance , SourceOrSinkElement baseSink , string originalInput
169237 |
170- sinkModel ( namespace , type , subtypes , name , signature , ext , input , kind , provenance ) and
238+ sinkModel ( namespace , type , subtypes , name , signature , ext , originalInput , kind , provenance ) and
171239 generated = isGenerated ( provenance ) and
172- e = interpretElement ( namespace , type , subtypes , name , signature , ext )
240+ baseSink = interpretElement ( namespace , type , subtypes , name , signature , ext ) and
241+ (
242+ e = baseSink and originalInput = input
243+ or
244+ correspondingKotlinParameterDefaultsArgSpec ( baseSink , e , originalInput , input )
245+ )
173246 )
174247}
175248
0 commit comments