@@ -563,7 +563,11 @@ private module Cached {
563563 THashSplatArgumentPosition ( ) or
564564 TSynthHashSplatArgumentPosition ( ) or
565565 TSplatArgumentPosition ( int pos ) { exists ( Call c | c .getArgument ( pos ) instanceof SplatExpr ) } or
566- TSynthSplatArgumentPosition ( ) or
566+ TSynthSplatArgumentPosition ( int actualSplatPos ) {
567+ actualSplatPos = - 1 // represents no actual splat
568+ or
569+ exists ( Call c | c .getArgument ( actualSplatPos ) instanceof SplatExpr )
570+ } or
567571 TAnyArgumentPosition ( ) or
568572 TAnyKeywordArgumentPosition ( )
569573
@@ -590,11 +594,15 @@ private module Cached {
590594 THashSplatParameterPosition ( ) or
591595 TSynthHashSplatParameterPosition ( ) or
592596 TSplatParameterPosition ( int pos ) {
593- pos = 0
597+ pos = 0 // needed for flow summaries
594598 or
595599 exists ( Parameter p | p .getPosition ( ) = pos and p instanceof SplatParameter )
596600 } or
597- TSynthSplatParameterPosition ( ) or
601+ TSynthSplatParameterPosition ( int actualSplatPos ) {
602+ actualSplatPos = - 1 // represents no actual splat
603+ or
604+ exists ( Callable c | c .getParameter ( actualSplatPos ) instanceof SplatParameter )
605+ } or
598606 TAnyParameterPosition ( ) or
599607 TAnyKeywordParameterPosition ( )
600608}
@@ -1383,8 +1391,14 @@ class ParameterPosition extends TParameterPosition {
13831391 /** Holds if this position represents a splat parameter at position `n`. */
13841392 predicate isSplat ( int n ) { this = TSplatParameterPosition ( n ) }
13851393
1386- /** Holds if this position represents a synthetic splat parameter. */
1387- predicate isSynthSplat ( ) { this = TSynthSplatParameterPosition ( ) }
1394+ /**
1395+ * Holds if this position represents a synthetic splat parameter.
1396+ *
1397+ * `actualSplatPos` indicates the position of the (unique) actual splat
1398+ * parameter belonging to the same method, with `-1` representing no actual
1399+ * splat parameter.
1400+ */
1401+ predicate isSynthSplat ( int actualSplatPos ) { this = TSynthSplatParameterPosition ( actualSplatPos ) }
13881402
13891403 /**
13901404 * Holds if this position represents any parameter, except `self` parameters. This
@@ -1419,7 +1433,11 @@ class ParameterPosition extends TParameterPosition {
14191433 or
14201434 exists ( int pos | this .isSplat ( pos ) and result = "* (position " + pos + ")" )
14211435 or
1422- this .isSynthSplat ( ) and result = "synthetic *"
1436+ exists ( int actualSplatPos , string suffix |
1437+ this .isSynthSplat ( actualSplatPos ) and
1438+ result = "synthetic *" + suffix and
1439+ if actualSplatPos = - 1 then suffix = "" else suffix = " (actual at " + actualSplatPos + ")"
1440+ )
14231441 }
14241442}
14251443
@@ -1458,8 +1476,14 @@ class ArgumentPosition extends TArgumentPosition {
14581476 /** Holds if this position represents a splat argument at position `n`. */
14591477 predicate isSplat ( int n ) { this = TSplatArgumentPosition ( n ) }
14601478
1461- /** Holds if this position represents a synthetic splat argument. */
1462- predicate isSynthSplat ( ) { this = TSynthSplatArgumentPosition ( ) }
1479+ /**
1480+ * Holds if this position represents a synthetic splat argument.
1481+ *
1482+ * `actualSplatPos` indicates the position of the (unique) actual splat
1483+ * argument belonging to the same call, with `-1` representing no actual
1484+ * splat argument.
1485+ */
1486+ predicate isSynthSplat ( int actualSplatPos ) { this = TSynthSplatArgumentPosition ( actualSplatPos ) }
14631487
14641488 /** Gets a textual representation of this position. */
14651489 string toString ( ) {
@@ -1483,7 +1507,11 @@ class ArgumentPosition extends TArgumentPosition {
14831507 or
14841508 exists ( int pos | this .isSplat ( pos ) and result = "* (position " + pos + ")" )
14851509 or
1486- this .isSynthSplat ( ) and result = "synthetic *"
1510+ exists ( int actualSplatPos , string suffix |
1511+ this .isSynthSplat ( actualSplatPos ) and
1512+ result = "synthetic *" + suffix and
1513+ if actualSplatPos = - 1 then suffix = "" else suffix = " (actual at " + actualSplatPos + ")"
1514+ )
14871515 }
14881516}
14891517
@@ -1517,19 +1545,29 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) {
15171545 exists ( string name | ppos .isKeyword ( name ) and apos .isKeyword ( name ) )
15181546 or
15191547 ( ppos .isHashSplat ( ) or ppos .isSynthHashSplat ( ) ) and
1520- ( apos .isHashSplat ( ) or apos .isSynthHashSplat ( ) )
1548+ ( apos .isHashSplat ( ) or apos .isSynthHashSplat ( ) ) and
1549+ // prevent synthetic hash-splat parameters from matching synthetic hash-splat
1550+ // arguments when direct keyword matching is possible
1551+ not ( ppos .isSynthHashSplat ( ) and apos .isSynthHashSplat ( ) )
15211552 or
15221553 exists ( int pos |
15231554 (
15241555 ppos .isSplat ( pos )
15251556 or
1526- ppos .isSynthSplat ( ) and pos = 0
1557+ ppos .isSynthSplat ( _) and
1558+ pos = 0
15271559 ) and
15281560 (
15291561 apos .isSplat ( pos )
15301562 or
1531- apos .isSynthSplat ( ) and pos = 0
1563+ apos .isSynthSplat ( _ ) and pos = 0
15321564 )
1565+ ) and
1566+ // prevent synthetic splat parameters from matching synthetic splat arguments
1567+ // when direct positional matching is possible
1568+ not exists ( int actualSplatPos |
1569+ ppos .isSynthSplat ( actualSplatPos ) and
1570+ apos .isSynthSplat ( actualSplatPos )
15331571 )
15341572 or
15351573 ppos .isAny ( ) and argumentPositionIsNotSelf ( apos )
0 commit comments