@@ -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
/**
@@ -320,12 +318,54 @@ module Rbi {
320
318
ParamsCall ( ) { this .getMethodName ( ) = "params" }
321
319
322
320
/**
323
- * Gets the type of a parameter defined by this call.
321
+ * Gets the type of a positional parameter defined by this call.
324
322
*/
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
+ }
326
361
}
327
362
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
+ */
328
367
abstract class ReturnsTypeCall extends MethodCall {
368
+ /** Get the `ReturnType` corresponding to this call. */
329
369
abstract ReturnType getReturnType ( ) ;
330
370
}
331
371
@@ -391,6 +431,7 @@ module Rbi {
391
431
abstract class ProcReturnsTypeCall extends ReturnsTypeCall , ProcSignatureDefiningCall { }
392
432
393
433
/** 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
394
435
class ProcParamsCall extends ParamsCall , ProcSignatureDefiningCall { }
395
436
396
437
/** A call that defines the return type of a non-void proc or block. */
@@ -408,25 +449,30 @@ module Rbi {
408
449
409
450
/**
410
451
* A pair defining the type of a parameter to a method.
452
+ *
453
+ * This is an argument to some call to `params`.
411
454
*/
412
455
class ParameterType extends Pair {
413
- private RbiType t ;
456
+ private ParamsCall paramsCall ;
414
457
415
- ParameterType ( ) { t = this . getValue ( ) }
458
+ ParameterType ( ) { paramsCall . getAnArgument ( ) = this }
416
459
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 ( ) }
421
461
422
462
private MethodBase getAssociatedMethod ( ) {
423
- result = this .getOuterMethodSignatureCall ( ) .( MethodSignatureCall ) .getAssociatedMethod ( )
463
+ result = this .getMethodSignatureCall ( ) .( MethodSignatureCall ) .getAssociatedMethod ( )
424
464
}
425
465
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. */
427
473
NamedParameter getParameter ( ) {
428
474
result = this .getAssociatedMethod ( ) .getAParameter ( ) and
429
- result .getName ( ) = this .getKey ( ) . getConstantValue ( ) . getStringlikeValue ( )
475
+ result .getName ( ) = this .getName ( )
430
476
}
431
477
}
432
478
}
0 commit comments