@@ -150,22 +150,14 @@ module Rbi {
150150 class ProcCall extends RbiType , SignatureCall , MethodCallAgainstT {
151151 ProcCall ( ) { this .getMethodName ( ) = "proc" }
152152
153- private ProcReturnsTypeCall getReturnsTypeCall ( ) { result . getProcCall ( ) = this }
154-
155- private ProcParamsCall getParamsCall ( ) { result . getProcCall ( ) = this }
153+ override ReturnsTypeCall getReturnsTypeCall ( ) {
154+ result . ( ProcReturnsTypeCall ) . getProcCall ( ) = this
155+ }
156156
157- /**
158- * Gets the return type of this type signature.
159- */
160- override ReturnType getReturnType ( ) { result = this .getReturnsTypeCall ( ) .getReturnType ( ) }
157+ override ProcParamsCall getParamsCall ( ) { result .getProcCall ( ) = this }
161158
162- /**
163- * Gets the type of a parameter of this type signature.
164- */
165- override ParameterType getAParameterType ( ) {
166- result = this .getParamsCall ( ) .getAParameterType ( )
167- }
168- // TODO: get associated method to which this can be passed
159+ // TODO: widen type for procs/blocks
160+ override MethodBase getAssociatedMethod ( ) { none ( ) }
169161 }
170162 }
171163
@@ -207,15 +199,11 @@ module Rbi {
207199 * A call that defines a type signature for a method or proc.
208200 */
209201 abstract class SignatureCall extends MethodCall {
210- /**
211- * Gets the return type of this type signature.
212- */
213- abstract ReturnType getReturnType ( ) ;
202+ abstract ParamsCall getParamsCall ( ) ;
214203
215- /**
216- * Gets the type of a parameter of this type signature.
217- */
218- abstract ParameterType getAParameterType ( ) ;
204+ abstract ReturnsTypeCall getReturnsTypeCall ( ) ;
205+
206+ abstract MethodBase getAssociatedMethod ( ) ;
219207 }
220208
221209 private predicate isMethodSignatureCallNode ( CfgNode n ) {
@@ -240,20 +228,35 @@ module Rbi {
240228 )
241229 }
242230
231+ /**
232+ * A call to a method named `attr_reader` or `attr_accessor`, used to define
233+ * attribute reader methods for a named attribute.
234+ */
235+ class AttrReaderMethodCall extends MethodCall {
236+ AttrReaderMethodCall ( ) { this .getMethodName ( ) = [ "attr_reader" , "attr_accessor" ] }
237+
238+ /** Gets a name of an attribute defined by this call. */
239+ string getAnAttributeName ( ) {
240+ result = this .getAnArgument ( ) .getConstantValue ( ) .getStringlikeValue ( )
241+ }
242+ }
243+
243244 /** A call to `sig` to define the type signature of a method. */
244245 class MethodSignatureCall extends SignatureCall {
245246 MethodSignatureCall ( ) { this .getMethodName ( ) = "sig" }
246247
247- private MethodReturnsTypeCall getReturnsTypeCall ( ) { result .getMethodSignatureCall ( ) = this }
248+ override ReturnsTypeCall getReturnsTypeCall ( ) {
249+ result .( MethodReturnsTypeCall ) .getMethodSignatureCall ( ) = this
250+ }
248251
249- private MethodParamsCall getParamsCall ( ) { result .getMethodSignatureCall ( ) = this }
252+ override MethodParamsCall getParamsCall ( ) { result .getMethodSignatureCall ( ) = this }
250253
251254 private ExprCfgNode getCfgNode ( ) { result .getExpr ( ) = this }
252255
253256 /**
254257 * Gets the method whose type signature is defined by this call.
255258 */
256- MethodBase getAssociatedMethod ( ) {
259+ override MethodBase getAssociatedMethod ( ) {
257260 result =
258261 min ( ExprCfgNode methodCfgNode , int i |
259262 methodSignatureSuccessorNodeRanked ( this .getCfgNode ( ) , methodCfgNode , i ) and
@@ -267,10 +270,10 @@ module Rbi {
267270 * Gets a call to `attr_reader` or `attr_accessor` where the return type of
268271 * the generated method is described by this call.
269272 */
270- MethodCall getAssociatedAttrReaderCall ( ) {
273+ AttrReaderMethodCall getAssociatedAttrReaderCall ( ) {
271274 result =
272275 min ( ExprNodes:: MethodCallCfgNode c , int i |
273- c .getExpr ( ) . getMethodName ( ) = [ "attr_reader" , "attr_accessor" ] and
276+ c .getExpr ( ) instanceof AttrReaderMethodCall and
274277 methodSignatureSuccessorNodeRanked ( this .getCfgNode ( ) , c , i )
275278 |
276279 c order by i
@@ -280,12 +283,7 @@ module Rbi {
280283 /**
281284 * Gets the return type of this type signature.
282285 */
283- override ReturnType getReturnType ( ) { result = this .getReturnsTypeCall ( ) .getReturnType ( ) }
284-
285- /**
286- * Gets the type of a parameter of this type signature.
287- */
288- override ParameterType getAParameterType ( ) { result = this .getParamsCall ( ) .getAParameterType ( ) }
286+ ReturnType getReturnType ( ) { result = this .getReturnsTypeCall ( ) .getReturnType ( ) }
289287 }
290288
291289 /**
@@ -320,12 +318,54 @@ module Rbi {
320318 ParamsCall ( ) { this .getMethodName ( ) = "params" }
321319
322320 /**
323- * Gets the type of a parameter defined by this call.
321+ * Gets the type of a positional parameter defined by this call.
324322 */
325- ParameterType getAParameterType ( ) { result = this .getArgument ( _) }
323+ ParameterType getPositionalParameterType ( int i ) {
324+ result = this .getArgument ( i ) and
325+ // explicitly exclude keyword parameters
326+ not this .getAssociatedParameter ( result .getName ( ) ) instanceof KeywordParameter and
327+ // and exclude block arguments
328+ not this .getAssociatedParameter ( result .getName ( ) ) instanceof BlockParameter
329+ }
330+
331+ /** Gets the type of the keyword parameter named `keyword`. */
332+ ParameterType getKeywordParameterType ( string keyword ) {
333+ exists ( KeywordParameter kp |
334+ kp = this .getAssociatedParameter ( keyword ) and
335+ kp .getName ( ) = keyword and
336+ result .getType ( ) = this .getKeywordArgument ( keyword )
337+ )
338+ }
339+
340+ /** Gets the type of the block parameter to the associated method. */
341+ ParameterType getBlockParameterType ( ) {
342+ this .getAssociatedParameter ( result .getName ( ) ) instanceof BlockParameter and
343+ result = this .getArgument ( _)
344+ }
345+
346+ /** Gets the parameter with the given name. */
347+ NamedParameter getAssociatedParameter ( string name ) {
348+ result = this .getSignatureCall ( ) .getAssociatedMethod ( ) .getAParameter ( ) and
349+ result .getName ( ) = name
350+ }
351+
352+ /** Gets the signature call which this params call belongs to. */
353+ SignatureCall getSignatureCall ( ) { this = result .getParamsCall ( ) }
354+
355+ /** Gets a parameter type associated with this call */
356+ ParameterType getAParameterType ( ) {
357+ result = this .getPositionalParameterType ( _) or
358+ result = this .getKeywordParameterType ( _) or
359+ result = this .getBlockParameterType ( )
360+ }
326361 }
327362
363+ /**
364+ * A call that defines a return type for an associated method.
365+ * The return type is either a specific type, or the void type (i.e. "don't care").
366+ */
328367 abstract class ReturnsTypeCall extends MethodCall {
368+ /** Get the `ReturnType` corresponding to this call. */
329369 abstract ReturnType getReturnType ( ) ;
330370 }
331371
@@ -391,6 +431,7 @@ module Rbi {
391431 abstract class ProcReturnsTypeCall extends ReturnsTypeCall , ProcSignatureDefiningCall { }
392432
393433 /** A call that defines the parameter types of a proc or block. */
434+ // TODO: there is currently no way to map from this to parameter types with actual associated parameters
394435 class ProcParamsCall extends ParamsCall , ProcSignatureDefiningCall { }
395436
396437 /** A call that defines the return type of a non-void proc or block. */
@@ -408,25 +449,30 @@ module Rbi {
408449
409450 /**
410451 * A pair defining the type of a parameter to a method.
452+ *
453+ * This is an argument to some call to `params`.
411454 */
412455 class ParameterType extends Pair {
413- private RbiType t ;
456+ private ParamsCall paramsCall ;
414457
415- ParameterType ( ) { t = this . getValue ( ) }
458+ ParameterType ( ) { paramsCall . getAnArgument ( ) = this }
416459
417- /** Gets the `RbiType` of this parameter. */
418- RbiType getType ( ) { result = t }
419-
420- private SignatureCall getOuterMethodSignatureCall ( ) { this = result .getAParameterType ( ) }
460+ private SignatureCall getMethodSignatureCall ( ) { paramsCall = result .getParamsCall ( ) }
421461
422462 private MethodBase getAssociatedMethod ( ) {
423- result = this .getOuterMethodSignatureCall ( ) .( MethodSignatureCall ) .getAssociatedMethod ( )
463+ result = this .getMethodSignatureCall ( ) .( MethodSignatureCall ) .getAssociatedMethod ( )
424464 }
425465
426- /** Gets the parameter to which this type applies. */
466+ /** Gets the `RbiType` of this parameter. */
467+ RbiType getType ( ) { result = this .getValue ( ) }
468+
469+ /** Gets the name of this parameter. */
470+ string getName ( ) { result = this .getKey ( ) .getConstantValue ( ) .getStringlikeValue ( ) }
471+
472+ /** Gets the `NamedParameter` to which this type applies. */
427473 NamedParameter getParameter ( ) {
428474 result = this .getAssociatedMethod ( ) .getAParameter ( ) and
429- result .getName ( ) = this .getKey ( ) . getConstantValue ( ) . getStringlikeValue ( )
475+ result .getName ( ) = this .getName ( )
430476 }
431477 }
432478}
0 commit comments