slevomat / coding-standard

Slevomat Coding Standard for PHP_CodeSniffer provides many useful sniffs
MIT License
1.39k stars 171 forks source link

Undefined index: scope_closer UseStatementHelper.php #644

Closed soullivaneuh closed 5 years ago

soullivaneuh commented 5 years ago
Changing into directory /code/src/Migrations/2016/11
Processing Version20161103111038.php [PHP => 221 tokens in 46 lines]... DONE in 3ms (2 fixable violations)
        => Fixing file: 2/2 violations remaining [made 1 pass]... [PHP => 138 tokens in 46 lines]... 
Fatal error: Uncaught PHP_CodeSniffer\Exceptions\RuntimeException: Undefined index: scope_closer in /home/developer/.composer/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/UseStatementHelper.php on line 207 in /home/developer/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php:600
Stack trace:
#0 /home/developer/.composer/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/UseStatementHelper.php(207): PHP_CodeSniffer\Runner->handleErrors(8, 'Undefined index...', '/home/developer...', 207, Array)
#1 /home/developer/.composer/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/UseStatementHelper.php(149): SlevomatCodingStandard\Helpers\UseStatementHelper::getUseStatementPointers(Object(PHP_CodeSniffer\Files\LocalFile), 0)
#2 /home/developer/.composer/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Namespaces/UselessAliasSniff.php(40): SlevomatCodingStandard\Helpers\UseStatementHelper::getFileUseStatements(Object(PHP_CodeSniffer\Files\LocalFile))
#3 /home/developer/. in /home/developer/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php on line 600

The file crashing the fixer:

<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;

/**
 * FPM server properties
 */
class Version20161103111038 extends AbstractMigration
{
    public function up(Schema $schema): void
    {
        $this->abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.');

        $this->addSql(<<<'SQL'
ALTER TABLE server
ADD fpm_mode VARCHAR(16) NOT NULL AFTER web_server_ssl_port,
ADD fpm_listen VARCHAR(64) NOT NULL AFTER fpm_mode,
ADD fpm_port SMALLINT UNSIGNED NOT NULL AFTER fpm_listen

SQL
        );

        $this->addSql("UPDATE server SET fpm_mode = 'socket', fpm_listen = '127.0.0.1', fpm_port = 9001");
        $this->addSql(<<<'SQL'
ALTER TABLE server_audit
ADD fpm_mode VARCHAR(16) DEFAULT NULL AFTER web_server_ssl_port,
ADD fpm_listen VARCHAR(64) DEFAULT NULL AFTER fpm_mode,
ADD fpm_port SMALLINT UNSIGNED DEFAULT NULL AFTER fpm_listen

SQL
        );
    }

    public function down(Schema $schema): void
    {
        $this->abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.');

        $this->addSql('ALTER TABLE server DROP fpm_mode, DROP fpm_listen, DROP fpm_port');
        $this->addSql('ALTER TABLE server_audit DROP fpm_mode, DROP fpm_listen, DROP fpm_port');
    }
}
soullivaneuh commented 5 years ago

So i removed this three fixer causing the issue:

<exclude name="SlevomatCodingStandard.Namespaces.UselessAlias"/>
<exclude name="SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses"/>
<exclude name="SlevomatCodingStandard.Namespaces.UseSpacing"/>

Now I have:

Processing UsernameChangeListener.php [PHP => 255 tokens in 38 lines]... DONE in 4ms (1 fixable violations)
        => Fixing file: 84/1 violations remaining [made 1 pass]... [PHP => 235 tokens in 40 lines]... 
Fatal error: Uncaught PHP_CodeSniffer\Exceptions\RuntimeException: Undefined index: scope_closer in /home/developer/.composer/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/UseStatementHelper.php on line 207 in /home/developer/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php:600
Stack trace:
#0 /home/developer/.composer/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/UseStatementHelper.php(207): PHP_CodeSniffer\Runner->handleErrors(8, 'Undefined index...', '/home/developer...', 207, Array)
#1 /home/developer/.composer/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/UseStatementHelper.php(149): SlevomatCodingStandard\Helpers\UseStatementHelper::getUseStatementPointers(Object(PHP_CodeSniffer\Files\LocalFile), 0)
#2 /home/developer/.composer/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/UseStatementHelper.php(111): SlevomatCodingStandard\Helpers\UseStatementHelper::getFileUseStatements(Object(PHP_CodeSniffer\Files\LocalFile))
#3 /home/developer/.composer in /home/developer/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php on line 600

Related file:

<?php

declare(strict_types=1);

namespace AppBundle\Listener;

use AppBundle\Entity\User;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\OnFlushEventArgs;

final class UsernameChangeListener implements EventSubscriber
{
    /**
     * {@inheritdoc}
     */
    public function getSubscribedEvents()
    {
        return [
            'onFlush',
        ];
    }

    public function onFlush(OnFlushEventArgs $eventArgs): void
    {
        $em = $eventArgs->getEntityManager();
        $uow = $em->getUnitOfWork();

        foreach ($uow->getScheduledEntityUpdates() as $entity) {
            if ($entity instanceof User && \array_key_exists('username', $uow->getEntityChangeSet($entity))) {
                [$oldUsername, $newUsername] = $uow->getEntityChangeSet($entity)['username'];
                $queryFormat = <<<'SQL'
UPDATE revisions SET username = '%s' WHERE username = '%s'
SQL;
                $em->getConnection()->exec(\sprintf($queryFormat, $newUsername, $oldUsername));
            }
        }
    }
}
kukulich commented 5 years ago

I'm sorry I'm not able to reproduce the error. Please provide failing test and then reopen the issue.

soullivaneuh commented 5 years ago

@theofidry I see you had a similar problem in #526.

Did you find any clue?

theofidry commented 5 years ago

Nope, couldn't find the time to dig into it at all :/

kukulich commented 5 years ago

@soullivaneuh @theofidry It's probably bug in PHPCS itself.

soullivaneuh commented 5 years ago

Here is a dump of $token when the exception occur:

array(8) {
  ["code"]=>
  int(361)
  ["type"]=>
  string(7) "T_CLASS"
  ["content"]=>
  string(5) "class"
  ["line"]=>
  int(11)
  ["column"]=>
  int(7)
  ["length"]=>
  int(5)
  ["level"]=>
  int(0)
  ["conditions"]=>
  array(0) {
  }
}
kukulich commented 5 years ago

Yes, it's really bug in PHPCS itself. T_CLASS token should have scope attributes.

soullivaneuh commented 5 years ago

It's probably bug in PHPCS itself.

@kukulich Maybe. The scope_closer existence is not checked on the failing source file. Do you expect to always have it?

kukulich commented 5 years ago

Yes, because you cannot write class definition without { and }

soullivaneuh commented 5 years ago

Right, I think I found the related issue: https://github.com/squizlabs/PHP_CodeSniffer/issues/2142#issuecomment-476140225

Thanks for your time @kukulich!

github-actions[bot] commented 4 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.