Repository: phpactor/phpactor (php)

Issue:
Complete not working due to error in cache file
Using the phpactor rpc and a little sourcefile gave this response was as follows
```
{"version":"1.0.0","action":"error","parameters":{"message":"Do not know how to create record of type \" *\/\" with identifier \"\"","details":"0: Do not know how to create record of type \" *\/\" with identifier \"\"\n#
... error stack follows
```
After searching for some time, I found out why completion no longer worked.
A vendor (cassandra) file contained a licence declaration in the form of a comment.
 ```php
<?php

/**
 * Copyright 2015-2017 DataStax, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
```
it is a file in the php cassandra driver: `vendor/datastax/php-driver/support/ccm.php`

after indexing the following apears in the cachefile:
```
constant        LICENSE_COMMENT
constant        /**
 * Copyright 2017 DataStax, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the \"License\");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an \"AS IS\" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
constant        DOC_COMMENT_HEADER
constant        DOC_COMMENT_LINE
constant         *
constant        DOC_COMMENT_LINE_EMPTY
```
I found this by catching the exception thrown in: `phpactor/lib/Indexer/Adapter/Php/FileSearchIndex.php`
```
    public function search(Criteria $criteria): Generator
    {
        $this->open();
        $types = [];

        foreach ($this->subjects as [ $recordType, $identifier, $type ]) {
            try {
                $types[] = sprintf('%s %s', $recordType, $identifier);
                $record = RecordFactory::create($recordType, $identifier);
                if ($record instanceof ClassRecord) {
                    $record = $record->withType($type);
                }

                if (false === $criteria->isSatisfiedBy($record)) {
                    continue;
                }

                yield $record;
            } catch(\Exception $e) {
                //catching here
                var_dump($this->path);
                print implode("\n", $types);
                die;
            }
        }
    }

```
I don't know if the error is made by the index-writer or the index-reader, maybe someone can tell me?
in the mean time I leave the catch there without the `var_dump()` so I can use phpactor again for completion.
This issue was hunting me for months.

Thx in advance

Pull request:
Fixing constant indexer
Closes #2168

## What was the problem?
The problem was that in the old code phpactor created a constant for every (string literal) argument in a define call. This isn't correct since the first argument in the call is the name and the second argument is the value of the constant. The multilineness of the value was what tricked the cache. But this isn't a problem since the second argument shouldn't be a constant in the first place.

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4c122e18..9199bbdb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ Features:
 
 Bug fixes:
 
+  - Fix constant declaration indexing with `define` #2249 @mamazu
   - Fix use of class-string<Foo> variable as static scope resolution qualifier #2238
   - URL decode root URI - fixes issues with special chars in path #2228
   - Do not deduplicate suggestions of different types (e.g. prop/method with same name) #2214
diff --git a/lib/Indexer/Adapter/Tolerant/Indexer/ConstantDeclarationIndexer.php b/lib/Indexer/Adapter/Tolerant/Indexer/ConstantDeclarationIndexer.php
index c46c297f..eedebb82 100644
--- a/lib/Indexer/Adapter/Tolerant/Indexer/ConstantDeclarationIndexer.php
+++ b/lib/Indexer/Adapter/Tolerant/Indexer/ConstantDeclarationIndexer.php
@@ -95,6 +95,9 @@ class ConstantDeclarationIndexer implements TolerantIndexer
             $record->setStart(ByteOffset::fromInt($node->getStartPosition()));
             $record->setFilePath($document->uri()->path());
             $index->write($record);
+
+            // Return after the first argument, because we only need the name of the constant.
+            return;
         }
     }
 }


Test patch:
diff --git a/lib/Indexer/Tests/Adapter/Tolerant/Indexer/ConstantDeclarationIndexerTest.php b/lib/Indexer/Tests/Adapter/Tolerant/Indexer/ConstantDeclarationIndexerTest.php
index 46f543a1..6e17c20d 100644
--- a/lib/Indexer/Tests/Adapter/Tolerant/Indexer/ConstantDeclarationIndexerTest.php
+++ b/lib/Indexer/Tests/Adapter/Tolerant/Indexer/ConstantDeclarationIndexerTest.php
@@ -17,6 +17,8 @@ class ConstantDeclarationIndexerTest extends TolerantIndexerTestCase
 
     /**
      * @dataProvider provideDeclaration
+     *
+     * @param Closure(IndexAgent):void $assertion
      */
     public function testDeclaration(string $manifest, Closure $assertion): void
     {
@@ -34,7 +36,7 @@ class ConstantDeclarationIndexerTest extends TolerantIndexerTestCase
     }
 
     /**
-     * @return Generator<mixed>
+     * @return Generator<array{string, Closure(IndexAgent):void}>
      */
     public function provideDeclaration(): Generator
     {
@@ -82,6 +84,26 @@ class ConstantDeclarationIndexerTest extends TolerantIndexerTestCase
                 ));
             }
         ];
+
+        yield 'a define creates only one constant'  => [
+            "// File: src/file1.php\n<?php define('FOOBAR', 'FOOBAR123');",
+            function (IndexAgent $agent): void {
+                self::assertInstanceOf(
+                    ConstantRecord::class,
+                    $agent->query()->constant()->get('FOOBAR')
+                );
+
+                self::assertCount(1, iterator_to_array(
+                    $agent->search()->search(
+                        Criteria::and(
+                            Criteria::isConstant(),
+                            Criteria::fqnBeginsWith('FOOBAR')
+                        )
+                    )
+                ));
+            }
+        ];
+
         yield 'namespaced define' => [
             "// File: src/file1.php\n<?php namespace Foo; define('Barfoo\FOOBAR', 1)",
             function (IndexAgent $agent): void {