|
4 | 4 | namespace Rector\Php70\Rector\StaticCall; |
5 | 5 |
|
6 | 6 | use PhpParser\Node; |
7 | | -use PhpParser\Node\Expr; |
8 | | -use PhpParser\Node\Expr\MethodCall; |
9 | | -use PhpParser\Node\Expr\New_; |
10 | | -use PhpParser\Node\Expr\PropertyFetch; |
11 | 7 | use PhpParser\Node\Expr\StaticCall; |
12 | | -use PhpParser\Node\Expr\Variable; |
13 | | -use PHPStan\Analyser\Scope; |
14 | | -use PHPStan\Reflection\ClassReflection; |
15 | | -use PHPStan\Reflection\MethodReflection; |
16 | | -use PHPStan\Reflection\ReflectionProvider; |
17 | | -use PHPStan\Type\ObjectType; |
18 | | -use Rector\CodingStyle\ValueObject\ObjectMagicMethods; |
19 | | -use Rector\Enum\ObjectReference; |
20 | | -use Rector\NodeCollector\ScopeResolver\ParentClassScopeResolver; |
21 | | -use Rector\NodeCollector\StaticAnalyzer; |
22 | | -use Rector\PHPStan\ScopeFetcher; |
| 8 | +use Rector\Configuration\Deprecation\Contract\DeprecatedInterface; |
| 9 | +use Rector\Exception\ShouldNotHappenException; |
23 | 10 | use Rector\Rector\AbstractRector; |
24 | | -use Rector\Reflection\ReflectionResolver; |
25 | 11 | use Rector\ValueObject\PhpVersionFeature; |
26 | 12 | use Rector\VersionBonding\Contract\MinPhpVersionInterface; |
27 | | -use ReflectionMethod; |
28 | 13 | use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; |
29 | 14 | use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; |
30 | 15 | /** |
31 | | - * @see \Rector\Tests\Php70\Rector\StaticCall\StaticCallOnNonStaticToInstanceCallRector\StaticCallOnNonStaticToInstanceCallRectorTest |
| 16 | + * @deprecated as risky change with little value. Use manually or custom rule where needed instead. |
32 | 17 | */ |
33 | | -final class StaticCallOnNonStaticToInstanceCallRector extends AbstractRector implements MinPhpVersionInterface |
| 18 | +final class StaticCallOnNonStaticToInstanceCallRector extends AbstractRector implements MinPhpVersionInterface, DeprecatedInterface |
34 | 19 | { |
35 | | - /** |
36 | | - * @readonly |
37 | | - */ |
38 | | - private StaticAnalyzer $staticAnalyzer; |
39 | | - /** |
40 | | - * @readonly |
41 | | - */ |
42 | | - private ReflectionProvider $reflectionProvider; |
43 | | - /** |
44 | | - * @readonly |
45 | | - */ |
46 | | - private ReflectionResolver $reflectionResolver; |
47 | | - /** |
48 | | - * @readonly |
49 | | - */ |
50 | | - private ParentClassScopeResolver $parentClassScopeResolver; |
51 | | - public function __construct(StaticAnalyzer $staticAnalyzer, ReflectionProvider $reflectionProvider, ReflectionResolver $reflectionResolver, ParentClassScopeResolver $parentClassScopeResolver) |
52 | | - { |
53 | | - $this->staticAnalyzer = $staticAnalyzer; |
54 | | - $this->reflectionProvider = $reflectionProvider; |
55 | | - $this->reflectionResolver = $reflectionResolver; |
56 | | - $this->parentClassScopeResolver = $parentClassScopeResolver; |
57 | | - } |
58 | 20 | public function provideMinPhpVersion(): int |
59 | 21 | { |
60 | 22 | return PhpVersionFeature::INSTANCE_CALL; |
@@ -107,98 +69,6 @@ public function getNodeTypes(): array |
107 | 69 | */ |
108 | 70 | public function refactor(Node $node): ?Node |
109 | 71 | { |
110 | | - if ($node->name instanceof Expr) { |
111 | | - return null; |
112 | | - } |
113 | | - $methodName = $this->getName($node->name); |
114 | | - $className = $this->resolveStaticCallClassName($node); |
115 | | - if ($methodName === null) { |
116 | | - return null; |
117 | | - } |
118 | | - if ($className === null) { |
119 | | - return null; |
120 | | - } |
121 | | - $scope = ScopeFetcher::fetch($node); |
122 | | - if ($this->shouldSkip($methodName, $className, $node, $scope)) { |
123 | | - return null; |
124 | | - } |
125 | | - $classReflection = $scope->getClassReflection(); |
126 | | - if ($classReflection instanceof ClassReflection && $classReflection->getName() === $className) { |
127 | | - // detect any scope where $this is unavailable or possibly unavailable |
128 | | - if (!$scope->hasVariableType('this')->yes()) { |
129 | | - return null; |
130 | | - } |
131 | | - return new MethodCall(new Variable('this'), $node->name, $node->args); |
132 | | - } |
133 | | - if ($this->isInstantiable($className, $scope)) { |
134 | | - $new = new New_($node->class); |
135 | | - return new MethodCall($new, $node->name, $node->args); |
136 | | - } |
137 | | - return null; |
138 | | - } |
139 | | - private function resolveStaticCallClassName(StaticCall $staticCall): ?string |
140 | | - { |
141 | | - if ($staticCall->class instanceof PropertyFetch) { |
142 | | - $objectType = $this->getType($staticCall->class); |
143 | | - if ($objectType instanceof ObjectType) { |
144 | | - return $objectType->getClassName(); |
145 | | - } |
146 | | - } |
147 | | - return $this->getName($staticCall->class); |
148 | | - } |
149 | | - private function shouldSkip(string $methodName, string $className, StaticCall $staticCall, Scope $scope): bool |
150 | | - { |
151 | | - if (in_array($methodName, ObjectMagicMethods::METHOD_NAMES, \true)) { |
152 | | - return \true; |
153 | | - } |
154 | | - if (!$this->reflectionProvider->hasClass($className)) { |
155 | | - return \true; |
156 | | - } |
157 | | - $classReflection = $this->reflectionProvider->getClass($className); |
158 | | - if ($classReflection->isAbstract()) { |
159 | | - return \true; |
160 | | - } |
161 | | - // does the method even exist? |
162 | | - if (!$classReflection->hasMethod($methodName)) { |
163 | | - return \true; |
164 | | - } |
165 | | - $isStaticMethod = $this->staticAnalyzer->isStaticMethod($classReflection, $methodName); |
166 | | - if ($isStaticMethod) { |
167 | | - return \true; |
168 | | - } |
169 | | - $currentClassReflection = $scope->getClassReflection(); |
170 | | - if ($currentClassReflection instanceof ClassReflection && $this->reflectionProvider->hasClass($className) && $currentClassReflection->isSubclassOfClass($this->reflectionProvider->getClass($className))) { |
171 | | - return \true; |
172 | | - } |
173 | | - $className = $this->getName($staticCall->class); |
174 | | - if (in_array($className, [ObjectReference::PARENT, ObjectReference::SELF, ObjectReference::STATIC], \true)) { |
175 | | - return \true; |
176 | | - } |
177 | | - if ($className === 'class') { |
178 | | - return \true; |
179 | | - } |
180 | | - $parentClassName = $this->parentClassScopeResolver->resolveParentClassName($scope); |
181 | | - return $className === $parentClassName; |
182 | | - } |
183 | | - private function isInstantiable(string $className, Scope $scope): bool |
184 | | - { |
185 | | - if (!$this->reflectionProvider->hasClass($className)) { |
186 | | - return \false; |
187 | | - } |
188 | | - $methodReflection = $this->reflectionResolver->resolveMethodReflection($className, '__callStatic', $scope); |
189 | | - if ($methodReflection instanceof MethodReflection) { |
190 | | - return \false; |
191 | | - } |
192 | | - $classReflection = $this->reflectionProvider->getClass($className); |
193 | | - $nativeReflection = $classReflection->getNativeReflection(); |
194 | | - $reflectionMethod = $nativeReflection->getConstructor(); |
195 | | - if (!$reflectionMethod instanceof ReflectionMethod) { |
196 | | - return \true; |
197 | | - } |
198 | | - if (!$reflectionMethod->isPublic()) { |
199 | | - return \false; |
200 | | - } |
201 | | - // required parameters in constructor, nothing we can do |
202 | | - return !(bool) $reflectionMethod->getNumberOfRequiredParameters(); |
| 72 | + throw new ShouldNotHappenException(sprintf('"%s" is deprecated as risky change with little value. Use manually or custom rule where needed instead', self::class)); |
203 | 73 | } |
204 | 74 | } |
0 commit comments