19 declare(strict_types=1);
35 public const DIC =
'DIC';
45 private \Rector\Core\Contract\Console\OutputStyleInterface
$outputStyle;
48 \Rector\Core\PhpParser\Node\NodeFactory $nodeFactory,
49 \Rector\Core\NodeManipulator\StmtsManipulator $stmtsManipulator,
50 \Rector\NodeNameResolver\NodeNameResolver $nodeNameResolver,
51 \Rector\Core\PhpParser\Comparing\NodeComparator $nodeComparator,
52 NodesToAddCollector $nodesToAddCollector,
53 \Rector\Core\PhpParser\Node\BetterNodeFinder $betterNodeFinder,
54 \Rector\Core\Contract\Console\OutputStyleInterface $outputStyle
70 return new Variable(self::DIC);
82 ClassMethod $classMethod,
86 $class_method_string = $class->name->name .
'::' . $classMethod->name->name;
87 $stmt_string = $this->nodeComparator->printWithoutComments($stmt);
88 if (isset($this->duplicate_checker[$class_method_string][$stmt_string])
89 && $this->duplicate_checker[$class_method_string][$stmt_string] ===
true) {
92 $stmts = $this->stmtsManipulator->filterOutExistingStmts(
101 foreach ($classMethod->getStmts() as $inner_statement) {
102 if ($inner_statement->getAttributes() === []) {
105 $first = $inner_statement;
108 if ($first !== null) {
109 $this->nodesToAddCollector->addNodeBeforeNode($stmt, $first);
111 $classMethod->stmts[] = $stmt;
113 $this->duplicate_checker[$class_method_string][$stmt_string] =
true;
117 \PhpParser\Node\Stmt\Class_ $class
119 if (isset($this->added_constructors[$class->name->name])) {
120 return $this->added_constructors[$class->name->name];
122 $classMethod = $this->nodeFactory->createPublicMethod(
123 \Rector\Core\ValueObject\MethodName::CONSTRUCT
128 \Rector\Core\ValueObject\MethodName::CONSTRUCT
131 \Rector\Core\ValueObject\MethodName::CONSTRUCT
134 $first_class_method = array_filter($class->stmts,
function (\PhpParser\Node $n):
bool {
135 return $n instanceof ClassMethod;
137 $first_class_method = array_shift($first_class_method);
138 if ($first_class_method !== null) {
139 $this->nodesToAddCollector->addNodeBeforeNode($classMethod, $first_class_method);
141 array_unshift($class->stmts, $classMethod);
143 $this->outputStyle->newline();
144 $this->outputStyle->warning(
145 'created constructor for ' . $class->name->name .
'. Please check the parent-call for missing parameters!' 147 $this->outputStyle->newline();
150 $this->added_constructors[$class->name->name] = $classMethod;
156 \PhpParser\Node\Stmt\Class_ $class,
159 $classMethod = $class->getMethod(
160 \Rector\Core\ValueObject\MethodName::CONSTRUCT
162 if (!$classMethod instanceof \PhpParser\Node\Stmt\ClassMethod) {
179 $this->duplicate_checker[$class->name->name][$this->nodeComparator->printWithoutComments($stmt)] =
true;
193 ClassMethod $classMethod,
197 $class_method_string = $class->name->name .
'::' . $classMethod->name->name;
198 $statement_string = $this->nodeComparator->printWithoutComments($stmt);
199 if (isset($this->duplicate_checker[$class_method_string][$statement_string])
200 && $this->duplicate_checker[$class_method_string][$statement_string] ===
true) {
203 $stmts = $this->stmtsManipulator->filterOutExistingStmts(
212 $existing_dic = $this->betterNodeFinder->findFirst($classMethod->stmts,
function (\PhpParser\Node $n):
bool {
213 if (!$n instanceof Stmt\Global_) {
216 foreach ($n->vars as $var) {
217 if (isset($var->name) && $var->name === self::DIC) {
223 $dic_statement_string = $this->nodeComparator->printWithoutComments($this->
getGlobalDIC());
224 if ($existing_dic === null
225 && !isset($this->duplicate_checker[$class_method_string][$dic_statement_string])
226 && !$this->duplicate_checker[$class_method_string][$dic_statement_string] ===
true 228 throw new ShouldNotHappenException(
229 'no dic found: ' . $class_method_string .
' (' . $statement_string .
') ' 234 $first_existing = array_filter($classMethod->stmts,
function (\PhpParser\Node $n):
bool {
235 if ($n->getAttributes() === []) {
238 return !$n instanceof Stmt\Global_;
240 $first_existing = array_shift($first_existing);
241 if ($first_existing !== null) {
242 $this->nodesToAddCollector->addNodeBeforeNode($stmt, $first_existing);
247 $classMethod->stmts[] = $stmt;
249 $this->duplicate_checker[$class_method_string][$statement_string] =
true;
253 \PhpParser\Node\Stmt\Class_ $class,
256 $classMethod = $class->getMethod(
257 \Rector\Core\ValueObject\MethodName::CONSTRUCT
259 if (!$classMethod instanceof \PhpParser\Node\Stmt\ClassMethod) {
270 \PhpParser\Node\Stmt\Class_ $class,
273 $scope = $class->getAttribute(
274 \Rector\NodeTypeResolver\Node\AttributeKey::SCOPE
276 if (!
$scope instanceof \PHPStan\Analyser\Scope) {
279 $classReflection =
$scope->getClassReflection();
280 if (!$classReflection instanceof \PHPStan\Reflection\ClassReflection) {
283 foreach ($classReflection->getParents() as $parentClassReflection) {
284 if ($parentClassReflection->hasMethod($methodName)) {
293 ): \PhpParser\Node\Stmt\Expression {
294 $staticCall = new \PhpParser\Node\Expr\StaticCall(
295 new \PhpParser\Node\Name(
296 \Rector\Core\Enum\ObjectReference::PARENT()->
getValue()
304 return new \PhpParser\Node\Stmt\Expression($staticCall);
308 \PhpParser\Node\Stmt\Class_ $class,
311 $constructClassMethod = $class->getMethod(
312 \Rector\Core\ValueObject\MethodName::CONSTRUCT
314 if (!$constructClassMethod instanceof \PhpParser\Node\Stmt\ClassMethod) {
317 foreach ($constructClassMethod->params as
$param) {
318 if ($this->nodeNameResolver->isName($param, $propertyName)) {
326 \PhpParser\Node\Stmt\ClassMethod $classMethod,
329 foreach ($classMethod->params as
$param) {
330 if ($this->nodeNameResolver->isName($param->var, $name)) {
isParamInConstructor(\PhpParser\Node\Stmt\Class_ $class, string $propertyName)
Rector Core PhpParser Node BetterNodeFinder $betterNodeFinder
NodesToAddCollector $nodesToAddCollector
createParentClassMethodCall(string $methodName)
__construct(\Rector\Core\PhpParser\Node\NodeFactory $nodeFactory, \Rector\Core\NodeManipulator\StmtsManipulator $stmtsManipulator, \Rector\NodeNameResolver\NodeNameResolver $nodeNameResolver, \Rector\Core\PhpParser\Comparing\NodeComparator $nodeComparator, NodesToAddCollector $nodesToAddCollector, \Rector\Core\PhpParser\Node\BetterNodeFinder $betterNodeFinder, \Rector\Core\Contract\Console\OutputStyleInterface $outputStyle)
hasClassParentClassMethod(\PhpParser\Node\Stmt\Class_ $class, string $methodName)
Rector Core NodeManipulator StmtsManipulator $stmtsManipulator
array $added_constructors
ensureGlobalDICinConstructor(Stmt\Class_ $class)
Rector NodeNameResolver NodeNameResolver $nodeNameResolver
hasMethodParameter(\PhpParser\Node\Stmt\ClassMethod $classMethod, string $name)
addStmtToMethodIfNotThereAfterGlobalDIC(ClassMethod $classMethod, Stmt\Class_ $class, Stmt $stmt)
addStmtToConstructorIfNotThereAfterGlobalDIC(\PhpParser\Node\Stmt\Class_ $class, Stmt $stmt)
createConstructor(\PhpParser\Node\Stmt\Class_ $class)
Rector Core NodeDecorator CreatedByRuleDecorator $createdByRuleDecorator
Rector Core PhpParser Comparing NodeComparator $nodeComparator
Rector Core Contract Console OutputStyleInterface $outputStyle
addStmtToConstructorIfNotThereYetAtFirstPosition(\PhpParser\Node\Stmt\Class_ $class, Stmt $stmt)
ensureGlobalDICinMethod(ClassMethod $classMethod, Stmt\Class_ $class)
addStmtToMethodIfNotThereYetAtFirstPosition(ClassMethod $classMethod, Stmt\Class_ $class, Stmt $stmt)
Rector Core PhpParser Node NodeFactory $nodeFactory