Repository: phpactor/phpactor (php)

Issue:
[CB] Properties should be inserted after constants.
Currently when completing constructor or adding missing assignments the properties are prepended before constants.

This happens in the code-builder library.

Pull request description:
Creating properties after constant declaration
Closes #226

Patch:
diff --git a/lib/CodeBuilder/Adapter/TolerantParser/Updater/ClassLikeUpdater.php b/lib/CodeBuilder/Adapter/TolerantParser/Updater/ClassLikeUpdater.php
index 15faba8a..6a1170de 100644
--- a/lib/CodeBuilder/Adapter/TolerantParser/Updater/ClassLikeUpdater.php
+++ b/lib/CodeBuilder/Adapter/TolerantParser/Updater/ClassLikeUpdater.php
@@ -3,10 +3,12 @@
 namespace Phpactor\CodeBuilder\Adapter\TolerantParser\Updater;
 
 use Microsoft\PhpParser\Node;
+use Microsoft\PhpParser\Node\ClassConstDeclaration;
 use Microsoft\PhpParser\Node\Expression\AssignmentExpression;
 use Microsoft\PhpParser\Node\Expression\Variable;
 use Microsoft\PhpParser\Node\MethodDeclaration;
 use Microsoft\PhpParser\Node\PropertyDeclaration;
+use Microsoft\PhpParser\Token;
 use Phpactor\CodeBuilder\Adapter\TolerantParser\Edits;
 use Phpactor\CodeBuilder\Domain\Prototype\ClassLikePrototype;
 use Phpactor\CodeBuilder\Domain\Prototype\Type;
@@ -49,8 +51,8 @@ abstract class ClassLikeUpdater
             return;
         }
 
-        $lastProperty = $classMembers->openBrace;
         $memberDeclarations = $this->memberDeclarations($classMembers);
+        $lastProperty = $this->getInsertPlace($classMembers, $memberDeclarations);
 
         $nextMember = null;
         $existingPropertyNames = [];
@@ -86,4 +88,21 @@ abstract class ClassLikeUpdater
             }
         }
     }
+
+    /**
+     * @param Node[] $memberDeclarations
+    */
+    protected function getInsertPlace(Node $classNode, array $memberDeclarations): Token
+    {
+        $insert = $classNode->openBrace;
+        foreach ($memberDeclarations as $member) {
+            if ($member instanceof ClassConstDeclaration) {
+                $insert = $member->semicolon;
+            } else {
+                break;
+            }
+        }
+
+        return $insert;
+    }
 }


Test patch:
diff --git a/lib/CodeTransform/Tests/Adapter/WorseReflection/Transformer/CompleteConstructorTest.php b/lib/CodeTransform/Tests/Adapter/WorseReflection/Transformer/CompleteConstructorTest.php
index 999f4fe0..57cb6b55 100644
--- a/lib/CodeTransform/Tests/Adapter/WorseReflection/Transformer/CompleteConstructorTest.php
+++ b/lib/CodeTransform/Tests/Adapter/WorseReflection/Transformer/CompleteConstructorTest.php
@@ -565,5 +565,37 @@ class CompleteConstructorTest extends WorseTestCase
                 EOT
 
         ];
+
+        yield 'Importing property before constants' => [
+            <<<'EOT'
+                <?php
+                class Foobar
+                {
+                    const FOO = 1;
+
+                    public function __construct(string $bar)
+                    {
+                    }
+                }
+                EOT
+        ,
+            <<<'EOT'
+                <?php
+                class Foobar
+                {
+                    const FOO = 1;
+                    /**
+                     * @var string
+                     */
+                    private $bar;
+
+                    public function __construct(string $bar)
+                    {
+                        $this->bar = $bar;
+                    }
+                }
+                EOT
+
+        ];
     }
 }