@@ -4,6 +4,7 @@ private import DataFlowPrivate
4
4
private import codeql.ruby.typetracking.TypeTracker
5
5
private import codeql.ruby.ast.internal.Module
6
6
private import FlowSummaryImpl as FlowSummaryImpl
7
+ private import FlowSummaryImplSpecific as FlowSummaryImplSpecific
7
8
private import codeql.ruby.dataflow.FlowSummary
8
9
9
10
newtype TReturnKind =
@@ -230,6 +231,30 @@ private module Cached {
230
231
result = yieldCall ( call )
231
232
)
232
233
}
234
+
235
+ cached
236
+ newtype TArgumentPosition =
237
+ TSelfArgumentPosition ( ) or
238
+ TBlockArgumentPosition ( ) or
239
+ TPositionalArgumentPosition ( int pos ) {
240
+ exists ( Call c | exists ( c .getArgument ( pos ) ) )
241
+ or
242
+ FlowSummaryImplSpecific:: ParsePositions:: isParsedParameterPosition ( _, pos )
243
+ } or
244
+ TKeywordArgumentPosition ( string name ) { name = any ( KeywordParameter kp ) .getName ( ) }
245
+
246
+ cached
247
+ newtype TParameterPosition =
248
+ TSelfParameterPosition ( ) or
249
+ TBlockParameterPosition ( ) or
250
+ TPositionalParameterPosition ( int pos ) {
251
+ pos = any ( Parameter p ) .getPosition ( )
252
+ or
253
+ pos in [ 0 .. 10 ] // TODO: remove once `Argument[_]` summaries are replaced with `Argument[i..]`
254
+ or
255
+ FlowSummaryImplSpecific:: ParsePositions:: isParsedArgumentPosition ( _, pos )
256
+ } or
257
+ TKeywordParameterPosition ( string name ) { name = any ( KeywordParameter kp ) .getName ( ) }
233
258
}
234
259
235
260
import Cached
@@ -458,18 +483,66 @@ predicate exprNodeReturnedFrom(DataFlow::ExprNode e, Callable c) {
458
483
)
459
484
}
460
485
461
- private int parameterPosition ( ) { result in [ - 2 .. max ( [ any ( Parameter p ) .getPosition ( ) , 10 ] ) ] }
486
+ /** A parameter position. */
487
+ class ParameterPosition extends TParameterPosition {
488
+ /** Holds if this position represents a `self` parameter. */
489
+ predicate isSelf ( ) { this = TSelfParameterPosition ( ) }
462
490
463
- /** A parameter position represented by an integer. */
464
- class ParameterPosition extends int {
465
- ParameterPosition ( ) { this = parameterPosition ( ) }
491
+ /** Holds if this position represents a block parameter. */
492
+ predicate isBlock ( ) { this = TBlockParameterPosition ( ) }
493
+
494
+ /** Holds if this position represents a positional parameter at position `pos`. */
495
+ predicate isPositional ( int pos ) { this = TPositionalParameterPosition ( pos ) }
496
+
497
+ /** Holds if this position represents a keyword parameter named `name`. */
498
+ predicate isKeyword ( string name ) { this = TKeywordParameterPosition ( name ) }
499
+
500
+ /** Gets a textual representation of this position. */
501
+ string toString ( ) {
502
+ this .isSelf ( ) and result = "self"
503
+ or
504
+ this .isBlock ( ) and result = "block"
505
+ or
506
+ exists ( int pos | this .isPositional ( pos ) and result = "position " + pos )
507
+ or
508
+ exists ( string name | this .isKeyword ( name ) and result = "keyword " + name )
509
+ }
466
510
}
467
511
468
- /** An argument position represented by an integer. */
469
- class ArgumentPosition extends int {
470
- ArgumentPosition ( ) { this = parameterPosition ( ) }
512
+ /** An argument position. */
513
+ class ArgumentPosition extends TArgumentPosition {
514
+ /** Holds if this position represents a `self` argument. */
515
+ predicate isSelf ( ) { this = TSelfArgumentPosition ( ) }
516
+
517
+ /** Holds if this position represents a block argument. */
518
+ predicate isBlock ( ) { this = TBlockArgumentPosition ( ) }
519
+
520
+ /** Holds if this position represents a positional argument at position `pos`. */
521
+ predicate isPositional ( int pos ) { this = TPositionalArgumentPosition ( pos ) }
522
+
523
+ /** Holds if this position represents a keyword argument named `name`. */
524
+ predicate isKeyword ( string name ) { this = TKeywordArgumentPosition ( name ) }
525
+
526
+ /** Gets a textual representation of this position. */
527
+ string toString ( ) {
528
+ this .isSelf ( ) and result = "self"
529
+ or
530
+ this .isBlock ( ) and result = "block"
531
+ or
532
+ exists ( int pos | this .isPositional ( pos ) and result = "position " + pos )
533
+ or
534
+ exists ( string name | this .isKeyword ( name ) and result = "keyword " + name )
535
+ }
471
536
}
472
537
473
538
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
474
539
pragma [ inline]
475
- predicate parameterMatch ( ParameterPosition ppos , ArgumentPosition apos ) { ppos = apos }
540
+ predicate parameterMatch ( ParameterPosition ppos , ArgumentPosition apos ) {
541
+ ppos .isSelf ( ) and apos .isSelf ( )
542
+ or
543
+ ppos .isBlock ( ) and apos .isBlock ( )
544
+ or
545
+ exists ( int pos | ppos .isPositional ( pos ) and apos .isPositional ( pos ) )
546
+ or
547
+ exists ( string name | ppos .isKeyword ( name ) and apos .isKeyword ( name ) )
548
+ }
0 commit comments