1111use PhpParser \Node \Expr \Closure ;
1212use PhpParser \Node \Expr \FuncCall ;
1313use PhpParser \Node \Expr \Include_ ;
14- use PhpParser \Node \Expr \MethodCall ;
15- use PhpParser \Node \Expr \NullsafeMethodCall ;
16- use PhpParser \Node \Expr \StaticCall ;
1714use PhpParser \Node \Expr \Variable ;
18- use PhpParser \Node \Name ;
1915use PhpParser \Node \Stmt ;
2016use PhpParser \Node \Stmt \Class_ ;
2117use PhpParser \Node \Stmt \ClassMethod ;
2218use PhpParser \Node \Stmt \Expression ;
2319use PhpParser \Node \Stmt \Function_ ;
2420use PhpParser \NodeVisitor ;
25- use PHPStan \Reflection \AttributeReflection ;
2621use PHPStan \Reflection \ClassReflection ;
27- use PHPStan \Reflection \ReflectionProvider ;
2822use PHPStan \Type \ObjectType ;
23+ use Rector \DeadCode \NodeAnalyzer \NoDiscardCallAnalyzer ;
2924use Rector \DeadCode \SideEffect \SideEffectNodeDetector ;
3025use Rector \NodeAnalyzer \VariableAnalyzer ;
3126use Rector \NodeManipulator \StmtsManipulator ;
3227use Rector \Php \ReservedKeywordAnalyzer ;
3328use Rector \PhpParser \Enum \NodeGroup ;
3429use Rector \PhpParser \Node \BetterNodeFinder ;
35- use Rector \PHPStan \ScopeFetcher ;
3630use Rector \Rector \AbstractRector ;
3731use Rector \ValueObject \MethodName ;
3832use Symplify \RuleDocGenerator \ValueObject \CodeSample \CodeSample ;
@@ -65,15 +59,15 @@ final class RemoveUnusedVariableAssignRector extends AbstractRector
6559 /**
6660 * @readonly
6761 */
68- private ReflectionProvider $ reflectionProvider ;
69- public function __construct (ReservedKeywordAnalyzer $ reservedKeywordAnalyzer , SideEffectNodeDetector $ sideEffectNodeDetector , VariableAnalyzer $ variableAnalyzer , BetterNodeFinder $ betterNodeFinder , StmtsManipulator $ stmtsManipulator , ReflectionProvider $ reflectionProvider )
62+ private NoDiscardCallAnalyzer $ noDiscardCallAnalyzer ;
63+ public function __construct (ReservedKeywordAnalyzer $ reservedKeywordAnalyzer , SideEffectNodeDetector $ sideEffectNodeDetector , VariableAnalyzer $ variableAnalyzer , BetterNodeFinder $ betterNodeFinder , StmtsManipulator $ stmtsManipulator , NoDiscardCallAnalyzer $ noDiscardCallAnalyzer )
7064 {
7165 $ this ->reservedKeywordAnalyzer = $ reservedKeywordAnalyzer ;
7266 $ this ->sideEffectNodeDetector = $ sideEffectNodeDetector ;
7367 $ this ->variableAnalyzer = $ variableAnalyzer ;
7468 $ this ->betterNodeFinder = $ betterNodeFinder ;
7569 $ this ->stmtsManipulator = $ stmtsManipulator ;
76- $ this ->reflectionProvider = $ reflectionProvider ;
70+ $ this ->noDiscardCallAnalyzer = $ noDiscardCallAnalyzer ;
7771 }
7872 public function getRuleDefinition (): RuleDefinition
7973 {
@@ -249,7 +243,7 @@ private function resolvedAssignedVariablesByStmtPosition(array $stmts): array
249243 if ($ this ->shouldSkipVariable ($ assign ->var , $ variableName , $ refVariableNames )) {
250244 continue ;
251245 }
252- if ($ this ->isNoDiscardCall ($ assign ->expr )) {
246+ if ($ this ->noDiscardCallAnalyzer -> isNoDiscardCall ($ assign ->expr )) {
253247 continue ;
254248 }
255249 $ assignedVariableNamesByStmtPosition [$ key ] = $ variableName ;
@@ -269,55 +263,4 @@ private function shouldSkipVariable(Variable $variable, string $variableName, ar
269263 }
270264 return in_array ($ variableName , $ refVariableNames , \true);
271265 }
272- private function isNoDiscardCall (Expr $ expr ): bool
273- {
274- if ($ expr instanceof FuncCall) {
275- $ name = $ this ->getName ($ expr );
276- if ($ name === null ) {
277- return \false;
278- }
279- $ scope = ScopeFetcher::fetch ($ expr );
280- if (!$ this ->reflectionProvider ->hasFunction (new Name ($ name ), $ scope )) {
281- return \false;
282- }
283- return $ this ->hasNoDiscardAttribute ($ this ->reflectionProvider ->getFunction (new Name ($ name ), $ scope )->getAttributes ());
284- }
285- if ($ expr instanceof StaticCall) {
286- $ classNames = $ this ->getType ($ expr ->class )->getObjectClassNames ();
287- $ methodName = $ this ->getName ($ expr ->name );
288- } elseif ($ expr instanceof MethodCall || $ expr instanceof NullsafeMethodCall) {
289- $ classNames = $ this ->getType ($ expr ->var )->getObjectClassNames ();
290- $ methodName = $ this ->getName ($ expr ->name );
291- } else {
292- return \false;
293- }
294- if ($ classNames === [] || $ methodName === null ) {
295- return \false;
296- }
297- foreach ($ classNames as $ className ) {
298- if (!$ this ->reflectionProvider ->hasClass ($ className )) {
299- continue ;
300- }
301- $ classReflection = $ this ->reflectionProvider ->getClass ($ className );
302- if (!$ classReflection ->hasNativeMethod ($ methodName )) {
303- continue ;
304- }
305- if ($ this ->hasNoDiscardAttribute ($ classReflection ->getNativeMethod ($ methodName )->getAttributes ())) {
306- return \true;
307- }
308- }
309- return \false;
310- }
311- /**
312- * @param AttributeReflection[] $attributes
313- */
314- private function hasNoDiscardAttribute (array $ attributes ): bool
315- {
316- foreach ($ attributes as $ attribute ) {
317- if ($ attribute ->getName () === 'NoDiscard ' ) {
318- return \true;
319- }
320- }
321- return \false;
322- }
323266}
0 commit comments