diff --git a/lib/CodeBuilder/Adapter/TolerantParser/TolerantUpdater.php b/lib/CodeBuilder/Adapter/TolerantParser/TolerantUpdater.php index 14263fe36..9d9439e44 100644 --- a/lib/CodeBuilder/Adapter/TolerantParser/TolerantUpdater.php +++ b/lib/CodeBuilder/Adapter/TolerantParser/TolerantUpdater.php @@ -1,6 +1,7 @@ getDescendantNodes() as $classNode) { + if ($classNode instanceof ObjectCreationExpression && $classNode->classTypeDesignator instanceof Token) { + $name = NodeUtil::nameFromTokenOrNode($classNode, $classNode); + $classNodes[$name] = $classNode; + } + } + foreach ($prototype->classes()->in(array_keys($classNodes)) as $classPrototype) { $this->classUpdater->updateClass($edits, $classPrototype, $classNodes[$classPrototype->name()]); } diff --git a/lib/CodeBuilder/Adapter/TolerantParser/Updater/AbstractMethodUpdater.php b/lib/CodeBuilder/Adapter/TolerantParser/Updater/AbstractMethodUpdater.php index a8ee2c47d..24fdb05c9 100644 --- a/lib/CodeBuilder/Adapter/TolerantParser/Updater/AbstractMethodUpdater.php +++ b/lib/CodeBuilder/Adapter/TolerantParser/Updater/AbstractMethodUpdater.php @@ -6,6 +6,7 @@ use Microsoft\PhpParser\Node; use Microsoft\PhpParser\Node\DelimitedList\ParameterDeclarationList; use Microsoft\PhpParser\Node\EnumCaseDeclaration; +use Microsoft\PhpParser\Node\Expression\ObjectCreationExpression; use Microsoft\PhpParser\Node\MethodDeclaration; use Microsoft\PhpParser\Node\Parameter; use Microsoft\PhpParser\Node\PropertyDeclaration; @@ -30,8 +31,11 @@ public function __construct(private Renderer $renderer) { } - public function updateMethods(Edits $edits, ClassLikePrototype $classPrototype, ClassLike $classNode): void - { + public function updateMethods( + Edits $edits, + ClassLikePrototype $classPrototype, + ClassLike|ObjectCreationExpression $classNode, + ): void { if (count($classPrototype->methods()) === 0) { return; } @@ -137,7 +141,7 @@ public function updateMethods(Edits $edits, ClassLikePrototype $classPrototype, /** * @return array */ - abstract protected function memberDeclarations(ClassLike $classNode): array; + abstract protected function memberDeclarations(ClassLike|ObjectCreationExpression $classNode): array; /** @return TMembersNodeType */ abstract protected function memberDeclarationsNode(ClassLike $classNode); diff --git a/lib/CodeBuilder/Adapter/TolerantParser/Updater/ClassMethodUpdater.php b/lib/CodeBuilder/Adapter/TolerantParser/Updater/ClassMethodUpdater.php index 25b6235c3..93e79c565 100644 --- a/lib/CodeBuilder/Adapter/TolerantParser/Updater/ClassMethodUpdater.php +++ b/lib/CodeBuilder/Adapter/TolerantParser/Updater/ClassMethodUpdater.php @@ -5,6 +5,7 @@ use Microsoft\PhpParser\Node\ClassMembersNode; use Microsoft\PhpParser\ClassLike; use Microsoft\PhpParser\Node\EnumMembers; +use Microsoft\PhpParser\Node\Expression\ObjectCreationExpression; use Microsoft\PhpParser\Node\Statement\ClassDeclaration; use Microsoft\PhpParser\Node\Statement\EnumDeclaration; use Microsoft\PhpParser\Node\Statement\TraitDeclaration; @@ -22,9 +23,9 @@ class ClassMethodUpdater extends AbstractMethodUpdater /** * @return ClassMembersNode|TraitMembers|EnumMembers */ - public function memberDeclarationsNode(ClassLike $classNode) + public function memberDeclarationsNode(ClassLike|ObjectCreationExpression $classNode): ClassMembersNode|TraitMembers|EnumMembers { - if ($classNode instanceof ClassDeclaration) { + if ($classNode instanceof ClassDeclaration || $classNode instanceof ObjectCreationExpression) { return $classNode->classMembers; } if ($classNode instanceof TraitDeclaration) { @@ -48,9 +49,9 @@ public function renderMethod(Renderer $renderer, Method $method): string } /** @return array */ - protected function memberDeclarations(ClassLike $classNode): array + protected function memberDeclarations(ClassLike|ObjectCreationExpression $classNode): array { - if ($classNode instanceof ClassDeclaration) { + if ($classNode instanceof ClassDeclaration || $classNode instanceof ObjectCreationExpression) { return $classNode->classMembers->classMemberDeclarations; } if ($classNode instanceof TraitDeclaration) { diff --git a/lib/CodeBuilder/Adapter/TolerantParser/Updater/ClassUpdater.php b/lib/CodeBuilder/Adapter/TolerantParser/Updater/ClassUpdater.php index a24784eec..0f8d40e6d 100644 --- a/lib/CodeBuilder/Adapter/TolerantParser/Updater/ClassUpdater.php +++ b/lib/CodeBuilder/Adapter/TolerantParser/Updater/ClassUpdater.php @@ -4,6 +4,7 @@ use Microsoft\PhpParser\Node; use Microsoft\PhpParser\Node\ClassConstDeclaration; +use Microsoft\PhpParser\Node\Expression\ObjectCreationExpression; use Microsoft\PhpParser\Node\MethodDeclaration; use Microsoft\PhpParser\Node\PropertyDeclaration; use Microsoft\PhpParser\Node\Statement\ClassDeclaration; @@ -15,8 +16,11 @@ class ClassUpdater extends ClassLikeUpdater { - public function updateClass(Edits $edits, ClassPrototype $classPrototype, ClassDeclaration $classNode): void - { + public function updateClass( + Edits $edits, + ClassPrototype $classPrototype, + ClassDeclaration|ObjectCreationExpression $classNode, + ): void { if (false === $classPrototype->applyUpdate()) { return; } @@ -24,8 +28,10 @@ public function updateClass(Edits $edits, ClassPrototype $classPrototype, ClassD $this->updateDocblock($edits, $classPrototype, $classNode); $this->updateExtends($edits, $classPrototype, $classNode); $this->updateImplements($edits, $classPrototype, $classNode); - $this->updateConstants($edits, $classPrototype, $classNode->classMembers); - $this->updateProperties($edits, $classPrototype, $classNode->classMembers); + if ($classNode->classMembers instanceof ClassMembersNode) { + $this->updateConstants($edits, $classPrototype, $classNode->classMembers); + $this->updateProperties($edits, $classPrototype, $classNode->classMembers); + } $this->methodUpdater->updateMethods($edits, $classPrototype, $classNode); } @@ -79,7 +85,11 @@ protected function memberDeclarations(Node $node): array return $node->classMemberDeclarations; } - private function updateExtends(Edits $edits, ClassPrototype $classPrototype, ClassDeclaration $classNode): void + private function updateExtends( + Edits $edits, + ClassPrototype $classPrototype, + ClassDeclaration|ObjectCreationExpression $classNode, + ): void { if (ExtendsClass::none() == $classPrototype->extendsClass()) { return; @@ -94,7 +104,11 @@ private function updateExtends(Edits $edits, ClassPrototype $classPrototype, Cla $edits->replace($classNode->classBaseClause, ' extends ' . (string) $classPrototype->extendsClass()); } - private function updateImplements(Edits $edits, ClassPrototype $classPrototype, ClassDeclaration $classNode): void + private function updateImplements( + Edits $edits, + ClassPrototype $classPrototype, + ClassDeclaration|ObjectCreationExpression $classNode, + ): void { if (ImplementsInterfaces::empty() == $classPrototype->implementsInterfaces()) { return; diff --git a/lib/CodeBuilder/Adapter/TolerantParser/Updater/InterfaceMethodUpdater.php b/lib/CodeBuilder/Adapter/TolerantParser/Updater/InterfaceMethodUpdater.php index c13e4988a..e4a5e44e5 100644 --- a/lib/CodeBuilder/Adapter/TolerantParser/Updater/InterfaceMethodUpdater.php +++ b/lib/CodeBuilder/Adapter/TolerantParser/Updater/InterfaceMethodUpdater.php @@ -3,6 +3,7 @@ namespace Phpactor\CodeBuilder\Adapter\TolerantParser\Updater; use Microsoft\PhpParser\ClassLike; +use Microsoft\PhpParser\Node\Expression\ObjectCreationExpression; use Microsoft\PhpParser\Node\InterfaceMembers; use Phpactor\CodeBuilder\Domain\Renderer; use Phpactor\CodeBuilder\Domain\Prototype\Method; @@ -27,7 +28,7 @@ public function renderMethod(Renderer $renderer, Method $method): string } /** @return array */ - protected function memberDeclarations(ClassLike $classNode): array + protected function memberDeclarations(ClassLike|ObjectCreationExpression $classNode): array { return $classNode->interfaceMembers->interfaceMemberDeclarations; } diff --git a/lib/CodeTransform/Tests/Adapter/WorseReflection/Transformer/ImplementContractsTest.php b/lib/CodeTransform/Tests/Adapter/WorseReflection/Transformer/ImplementContractsTest.php index 8b8c4fb3b..1365c1bbe 100644 --- a/lib/CodeTransform/Tests/Adapter/WorseReflection/Transformer/ImplementContractsTest.php +++ b/lib/CodeTransform/Tests/Adapter/WorseReflection/Transformer/ImplementContractsTest.php @@ -28,323 +28,492 @@ public function testImplementContracts(string $example, string $expected): void public function provideCompleteConstructor(): array { return [ - 'It does nothing on source with no classes' => [ - <<<'EOT' - [ - <<<'EOT' - [ - <<<'EOT' - [ - <<<'EOT' - [ - <<<'EOT' - [ - <<<'EOT' - [ + //<<<'EOT' + // [ + //<<<'EOT' + // [ + //<<<'EOT' + // [ + //<<<'EOT' + // [ + //<<<'EOT' + // [ + //<<<'EOT' + // [ - <<<'EOT' - [ - <<<'EOT' - [ - <<<'EOT' - [ - <<<'EOT' - [ + //public function chirp(); + //} + + //class Foobar implements Bird + //{ + //public function chirp() + //{ + //} + //} + //EOT + + //], + //'It is idempotent' => [ + //<<<'EOT' + // [ + //<<<'EOT' + // [ + //<<<'EOT' + // [ + //<<<'EOT' + // [ + //<<<'EOT' + // [ + //<<<'EOT' + // [ + //<<<'EOT' + // [ + //<<<'EOT' + // [ + //<<<'EOT' + // [ <<<'EOT' [ - <<<'EOT' - [ - <<<'EOT' - [ - <<<'EOT' - [ - <<<'EOT' -