@@ -150,22 +150,14 @@ module Rbi {
150
150
class ProcCall extends RbiType , SignatureCall , MethodCallAgainstT {
151
151
ProcCall ( ) { this .getMethodName ( ) = "proc" }
152
152
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
+ }
156
156
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 }
161
158
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 ( ) }
169
161
}
170
162
}
171
163
@@ -207,15 +199,11 @@ module Rbi {
207
199
* A call that defines a type signature for a method or proc.
208
200
*/
209
201
abstract class SignatureCall extends MethodCall {
210
- /**
211
- * Gets the return type of this type signature.
212
- */
213
- abstract ReturnType getReturnType ( ) ;
202
+ abstract ParamsCall getParamsCall ( ) ;
214
203
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 ( ) ;
219
207
}
220
208
221
209
private predicate isMethodSignatureCallNode ( CfgNode n ) {
@@ -240,20 +228,35 @@ module Rbi {
240
228
)
241
229
}
242
230
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
+
243
244
/** A call to `sig` to define the type signature of a method. */
244
245
class MethodSignatureCall extends SignatureCall {
245
246
MethodSignatureCall ( ) { this .getMethodName ( ) = "sig" }
246
247
247
- private MethodReturnsTypeCall getReturnsTypeCall ( ) { result .getMethodSignatureCall ( ) = this }
248
+ override ReturnsTypeCall getReturnsTypeCall ( ) {
249
+ result .( MethodReturnsTypeCall ) .getMethodSignatureCall ( ) = this
250
+ }
248
251
249
- private MethodParamsCall getParamsCall ( ) { result .getMethodSignatureCall ( ) = this }
252
+ override MethodParamsCall getParamsCall ( ) { result .getMethodSignatureCall ( ) = this }
250
253
251
254
private ExprCfgNode getCfgNode ( ) { result .getExpr ( ) = this }
252
255
253
256
/**
254
257
* Gets the method whose type signature is defined by this call.
255
258
*/
256
- MethodBase getAssociatedMethod ( ) {
259
+ override MethodBase getAssociatedMethod ( ) {
257
260
result =
258
261
min ( ExprCfgNode methodCfgNode , int i |
259
262
methodSignatureSuccessorNodeRanked ( this .getCfgNode ( ) , methodCfgNode , i ) and
@@ -267,10 +270,10 @@ module Rbi {
267
270
* Gets a call to `attr_reader` or `attr_accessor` where the return type of
268
271
* the generated method is described by this call.
269
272
*/
270
- MethodCall getAssociatedAttrReaderCall ( ) {
273
+ AttrReaderMethodCall getAssociatedAttrReaderCall ( ) {
271
274
result =
272
275
min ( ExprNodes:: MethodCallCfgNode c , int i |
273
- c .getExpr ( ) . getMethodName ( ) = [ "attr_reader" , "attr_accessor" ] and
276
+ c .getExpr ( ) instanceof AttrReaderMethodCall and
274
277
methodSignatureSuccessorNodeRanked ( this .getCfgNode ( ) , c , i )
275
278
|
276
279
c order by i
@@ -280,12 +283,7 @@ module Rbi {
280
283
/**
281
284
* Gets the return type of this type signature.
282
285
*/
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 ( ) }
289
287
}
290
288
291
289
/**
@@ -313,19 +311,64 @@ module Rbi {
313
311
MethodSignatureCall getMethodSignatureCall ( ) { result = sigCall }
314
312
}
315
313
314
+ bindingset [ paramName]
315
+ private predicate isBlockParamName ( string paramName ) { paramName = [ "blk" , "block" ] }
316
+
316
317
/**
317
318
* A call to `params`. This defines the types of parameters to a method or proc.
318
319
*/
319
320
class ParamsCall extends MethodCall {
320
321
ParamsCall ( ) { this .getMethodName ( ) = "params" }
321
322
322
323
/**
323
- * Gets the type of a parameter defined by this call.
324
+ * Gets the type of a positional parameter defined by this call.
324
325
*/
325
- ParameterType getAParameterType ( ) { result = this .getArgument ( _) }
326
+ ParameterType getPositionalParameterType ( int i ) {
327
+ result = this .getArgument ( i ) and
328
+ // explicitly exclude keyword parameters
329
+ not this .getAssociatedParameter ( result .getName ( ) ) instanceof KeywordParameter and
330
+ // and exclude block arguments
331
+ not isBlockParamName ( result .getName ( ) )
332
+ }
333
+
334
+ /** Gets the type of the keyword parameter named `keyword`. */
335
+ ParameterType getKeywordParameterType ( string keyword ) {
336
+ exists ( KeywordParameter kp |
337
+ kp = this .getAssociatedParameter ( keyword ) and
338
+ kp .getName ( ) = keyword and
339
+ result .getType ( ) = this .getKeywordArgument ( keyword )
340
+ )
341
+ }
342
+
343
+ /** Gets the type of the block parameter to the associated method. */
344
+ ParameterType getBlockParameterType ( ) {
345
+ isBlockParamName ( result .getName ( ) ) and
346
+ result = this .getArgument ( _)
347
+ }
348
+
349
+ /** Gets the parameter with the given name. */
350
+ NamedParameter getAssociatedParameter ( string name ) {
351
+ result = this .getSignatureCall ( ) .getAssociatedMethod ( ) .getAParameter ( ) and
352
+ result .getName ( ) = name
353
+ }
354
+
355
+ /** Gets the signature call which this params call belongs to. */
356
+ SignatureCall getSignatureCall ( ) { this = result .getParamsCall ( ) }
357
+
358
+ /** Gets a parameter type associated with this call */
359
+ ParameterType getAParameterType ( ) {
360
+ result = this .getPositionalParameterType ( _) or
361
+ result = this .getKeywordParameterType ( _) or
362
+ result = this .getBlockParameterType ( )
363
+ }
326
364
}
327
365
366
+ /**
367
+ * A call that defines a return type for an associated method.
368
+ * The return type is either a specific type, or the void type (i.e. "don't care").
369
+ */
328
370
abstract class ReturnsTypeCall extends MethodCall {
371
+ /** Get the `ReturnType` corresponding to this call. */
329
372
abstract ReturnType getReturnType ( ) ;
330
373
}
331
374
@@ -391,6 +434,7 @@ module Rbi {
391
434
abstract class ProcReturnsTypeCall extends ReturnsTypeCall , ProcSignatureDefiningCall { }
392
435
393
436
/** A call that defines the parameter types of a proc or block. */
437
+ // TODO: there is currently no way to map from this to parameter types with actual associated parameters
394
438
class ProcParamsCall extends ParamsCall , ProcSignatureDefiningCall { }
395
439
396
440
/** A call that defines the return type of a non-void proc or block. */
@@ -408,25 +452,30 @@ module Rbi {
408
452
409
453
/**
410
454
* A pair defining the type of a parameter to a method.
455
+ *
456
+ * This is an argument to some call to `params`.
411
457
*/
412
458
class ParameterType extends Pair {
413
- private RbiType t ;
459
+ private ParamsCall paramsCall ;
414
460
415
- ParameterType ( ) { t = this . getValue ( ) }
461
+ ParameterType ( ) { paramsCall . getAnArgument ( ) = this }
416
462
417
- /** Gets the `RbiType` of this parameter. */
418
- RbiType getType ( ) { result = t }
419
-
420
- private SignatureCall getOuterMethodSignatureCall ( ) { this = result .getAParameterType ( ) }
463
+ private SignatureCall getMethodSignatureCall ( ) { paramsCall = result .getParamsCall ( ) }
421
464
422
465
private MethodBase getAssociatedMethod ( ) {
423
- result = this .getOuterMethodSignatureCall ( ) .( MethodSignatureCall ) .getAssociatedMethod ( )
466
+ result = this .getMethodSignatureCall ( ) .( MethodSignatureCall ) .getAssociatedMethod ( )
424
467
}
425
468
426
- /** Gets the parameter to which this type applies. */
469
+ /** Gets the `RbiType` of this parameter. */
470
+ RbiType getType ( ) { result = this .getValue ( ) }
471
+
472
+ /** Gets the name of this parameter. */
473
+ string getName ( ) { result = this .getKey ( ) .getConstantValue ( ) .getStringlikeValue ( ) }
474
+
475
+ /** Gets the `NamedParameter` to which this type applies. */
427
476
NamedParameter getParameter ( ) {
428
477
result = this .getAssociatedMethod ( ) .getAParameter ( ) and
429
- result .getName ( ) = this .getKey ( ) . getConstantValue ( ) . getStringlikeValue ( )
478
+ result .getName ( ) = this .getName ( )
430
479
}
431
480
}
432
481
}
0 commit comments