66
77use PhpParser \Node ;
88use PhpParser \Node \Arg ;
9+ use PhpParser \Node \Expr ;
910use PhpParser \Node \Expr \ConstFetch ;
1011use PhpParser \Node \Expr \FuncCall ;
12+ use PhpParser \Node \Expr \Ternary ;
1113use PhpParser \Node \Scalar \String_ ;
14+ use PhpParser \NodeVisitor ;
1215use PHPStan \Type \IntegerRangeType ;
16+ use Rector \DeadCode \ConditionResolver ;
17+ use Rector \DeadCode \ValueObject \VersionCompareCondition ;
1318use Rector \NodeAnalyzer \ArgsAnalyzer ;
1419use Rector \PhpParser \Node \Value \ValueResolver ;
1520use Rector \PHPStan \ScopeFetcher ;
@@ -36,6 +41,7 @@ final class DowngradeHashAlgorithmXxHashRector extends AbstractRector
3641 public function __construct (
3742 private readonly ArgsAnalyzer $ argsAnalyzer ,
3843 private readonly ValueResolver $ valueResolver ,
44+ private readonly ConditionResolver $ conditionResolver
3945 ) {
4046 }
4147
@@ -74,14 +80,22 @@ public function run()
7480 */
7581 public function getNodeTypes (): array
7682 {
77- return [FuncCall::class];
83+ return [Ternary::class, FuncCall::class];
7884 }
7985
8086 /**
81- * @param FuncCall $node
87+ * @param Ternary| FuncCall $node
8288 */
83- public function refactor (Node $ node ): ? Node
89+ public function refactor (Node $ node ): null | int | Node
8490 {
91+ if ($ node instanceof Ternary) {
92+ if ($ this ->isVersionCompareTernary ($ node )) {
93+ return NodeVisitor::DONT_TRAVERSE_CHILDREN ;
94+ }
95+
96+ return null ;
97+ }
98+
8599 if ($ this ->shouldSkip ($ node )) {
86100 return null ;
87101 }
@@ -104,6 +118,24 @@ public function refactor(Node $node): ?Node
104118 return $ node ;
105119 }
106120
121+ private function isVersionCompareTernary (Ternary $ ternary ): bool
122+ {
123+ if ($ ternary ->if instanceof Expr && $ ternary ->cond instanceof FuncCall) {
124+ $ versionCompare = $ this ->conditionResolver ->resolveFromExpr ($ ternary ->cond );
125+ if ($ versionCompare instanceof VersionCompareCondition && $ versionCompare ->getSecondVersion () === 80100 ) {
126+ if ($ versionCompare ->getCompareSign () === '>= ' ) {
127+ return $ ternary ->if instanceof FuncCall && $ this ->isName ($ ternary ->if , 'hash ' );
128+ }
129+
130+ if ($ versionCompare ->getCompareSign () === '< ' ) {
131+ return $ ternary ->else instanceof FuncCall && $ this ->isName ($ ternary ->else , 'hash ' );
132+ }
133+ }
134+ }
135+
136+ return false ;
137+ }
138+
107139 private function shouldSkip (FuncCall $ funcCall ): bool
108140 {
109141 if ($ funcCall ->isFirstClassCallable ()) {
0 commit comments