|
5 | 5 | namespace Rector\PHPUnit\CodeQuality\Rector\MethodCall; |
6 | 6 |
|
7 | 7 | use PhpParser\Node; |
8 | | -use PhpParser\Node\Arg; |
9 | | -use PhpParser\Node\ClosureUse; |
10 | | -use PhpParser\Node\Expr\Closure; |
11 | 8 | use PhpParser\Node\Expr\MethodCall; |
12 | | -use PhpParser\Node\Expr\New_; |
13 | | -use PhpParser\Node\Expr\Throw_; |
14 | | -use PhpParser\Node\Expr\Variable; |
15 | | -use PhpParser\Node\Name\FullyQualified; |
16 | | -use PhpParser\Node\Scalar\String_; |
17 | | -use PhpParser\Node\Stmt\Expression; |
18 | | -use PhpParser\Node\Stmt\If_; |
19 | | -use Rector\PHPUnit\Enum\ConsecutiveVariable; |
20 | | -use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer; |
21 | | -use Rector\PHPUnit\NodeFactory\MatcherInvocationCountMethodCallNodeFactory; |
| 9 | +use Rector\Configuration\Deprecation\Contract\DeprecatedInterface; |
| 10 | +use Rector\Exception\ShouldNotHappenException; |
22 | 11 | use Rector\Rector\AbstractRector; |
23 | 12 | use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; |
24 | 13 | use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; |
25 | 14 |
|
26 | 15 | /** |
27 | | - * @see \Rector\PHPUnit\Tests\CodeQuality\Rector\MethodCall\WillReturnCallbackFallbackToThrowRector\WillReturnCallbackFallbackToThrowRectorTest |
| 16 | + * @deprecated This rule is deprecated as the case is very rare, hardly automatable and it is not part of any set. Handle it in a custom way or keep the code untouched. |
28 | 17 | */ |
29 | | -final class WillReturnCallbackFallbackToThrowRector extends AbstractRector |
| 18 | +final class WillReturnCallbackFallbackToThrowRector extends AbstractRector implements DeprecatedInterface |
30 | 19 | { |
31 | | - public function __construct( |
32 | | - private readonly TestsNodeAnalyzer $testsNodeAnalyzer, |
33 | | - private readonly MatcherInvocationCountMethodCallNodeFactory $matcherInvocationCountMethodCallNodeFactory, |
34 | | - ) { |
35 | | - } |
36 | | - |
37 | 20 | public function getRuleDefinition(): RuleDefinition |
38 | 21 | { |
39 | 22 | return new RuleDefinition( |
@@ -99,93 +82,9 @@ public function getNodeTypes(): array |
99 | 82 | */ |
100 | 83 | public function refactor(Node $node): ?MethodCall |
101 | 84 | { |
102 | | - if (! $this->testsNodeAnalyzer->isInTestClass($node)) { |
103 | | - return null; |
104 | | - } |
105 | | - |
106 | | - if (! $this->isName($node->name, 'willReturnCallback')) { |
107 | | - return null; |
108 | | - } |
109 | | - |
110 | | - if ($node->isFirstClassCallable()) { |
111 | | - return null; |
112 | | - } |
113 | | - |
114 | | - if (count($node->getArgs()) !== 1) { |
115 | | - return null; |
116 | | - } |
117 | | - |
118 | | - $closure = $node->getArgs()[0] |
119 | | - ->value; |
120 | | - if (! $closure instanceof Closure) { |
121 | | - return null; |
122 | | - } |
123 | | - |
124 | | - if (! $this->usesMatcher($closure)) { |
125 | | - return null; |
126 | | - } |
127 | | - |
128 | | - // the closure must branch on the matcher invocation count first |
129 | | - if (! $this->hasConsecutiveIf($closure)) { |
130 | | - return null; |
131 | | - } |
132 | | - |
133 | | - $lastStmt = $closure->stmts[array_key_last($closure->stmts)] ?? null; |
134 | | - |
135 | | - // the last statement must be an if branch; an explicit fallback "return <expr>;" is left untouched |
136 | | - if (! $lastStmt instanceof If_) { |
137 | | - return null; |
138 | | - } |
139 | | - |
140 | | - $closure->stmts[] = $this->createThrow(); |
141 | | - |
142 | | - return $node; |
143 | | - } |
144 | | - |
145 | | - private function usesMatcher(Closure $closure): bool |
146 | | - { |
147 | | - return array_any( |
148 | | - $closure->uses, |
149 | | - fn (ClosureUse $use): bool => $this->isName($use->var, ConsecutiveVariable::MATCHER) |
150 | | - ); |
151 | | - } |
152 | | - |
153 | | - private function hasConsecutiveIf(Closure $closure): bool |
154 | | - { |
155 | | - foreach ($closure->stmts as $stmt) { |
156 | | - if (! $stmt instanceof If_) { |
157 | | - continue; |
158 | | - } |
159 | | - |
160 | | - $hasMatcherCall = false; |
161 | | - $this->traverseNodesWithCallable($stmt->cond, function (Node $node) use (&$hasMatcherCall): null { |
162 | | - if ($node instanceof MethodCall |
163 | | - && $node->var instanceof Variable |
164 | | - && $this->isName($node->var, ConsecutiveVariable::MATCHER) |
165 | | - ) { |
166 | | - $hasMatcherCall = true; |
167 | | - } |
168 | | - |
169 | | - return null; |
170 | | - }); |
171 | | - |
172 | | - if ($hasMatcherCall) { |
173 | | - return true; |
174 | | - } |
175 | | - } |
176 | | - |
177 | | - return false; |
178 | | - } |
179 | | - |
180 | | - private function createThrow(): Expression |
181 | | - { |
182 | | - $sprintfFuncCall = $this->nodeFactory->createFuncCall('sprintf', [ |
183 | | - new String_('Method should not be called for the %dth time'), |
184 | | - $this->matcherInvocationCountMethodCallNodeFactory->create(), |
185 | | - ]); |
186 | | - |
187 | | - $new = new New_(new FullyQualified('PHPUnit\Framework\Exception'), [new Arg($sprintfFuncCall)]); |
188 | | - |
189 | | - return new Expression(new Throw_($new)); |
| 85 | + throw new ShouldNotHappenException(sprintf( |
| 86 | + '"%s" is deprecated and should not be used anymore. Remove it from your config files.', |
| 87 | + self::class, |
| 88 | + )); |
190 | 89 | } |
191 | 90 | } |
0 commit comments