Skip to content

unreached code error after optimation with PHPCS #4370

@mimmi20

Description

@mimmi20

Bug report

We used friendsofphp/php-cs-fixer in our project and switching now to doctrine/coding-standard. After the optimation of the code, I get an error.

Code snippet that reproduces the problem

https://phpstan.org/r/4b5e90b0-8028-4772-a09e-98ab9de07d1a

code before the optimation which passes PHPStan

<?php

declare(strict_types=1);

namespace Browscap\Coverage;

use Seld\JsonLint\Lexer;

/**
 * This class creates coverage data for the json files in the resources directory
 */
final class P
{
    /**
     * The codes representing different JSON elements
     *
     * These come from the Seld\JsonLint\JsonParser class. The values are returned by the lexer when
     * the lex() method is called.
     */
    private const JSON_OBJECT_START = 17;
    private const JSON_OBJECT_END   = 18;

    /**
     * Processes JSON object block that isn't needed for coverage data
     */
    public function ignoreObjectBlock(Lexer $lexer): int
    {
        do {
            $code = $lexer->lex();

            // recursively ignore nested objects
            if (self::JSON_OBJECT_START === $code) {
                $this->ignoreObjectBlock($lexer);
            }
        } while (self::JSON_OBJECT_END !== $code);

        return $lexer->lex();
    }
}

code after the optimation which failes PHPStan

<?php

declare(strict_types=1);

namespace Browscap\Coverage;

use Seld\JsonLint\Lexer;

/**
 * This class creates coverage data for the json files in the resources directory
 */
final class P
{
    /**
     * The codes representing different JSON elements
     *
     * These come from the Seld\JsonLint\JsonParser class. The values are returned by the lexer when
     * the lex() method is called.
     */
    private const JSON_OBJECT_START = 17;
    private const JSON_OBJECT_END   = 18;

    /**
     * Processes JSON object block that isn't needed for coverage data
     */
    public function ignoreObjectBlock(Lexer $lexer): int
    {
        do {
            $code = $lexer->lex();

            // recursively ignore nested objects
            if ($code !== self::JSON_OBJECT_START) {
                continue;
            }

            $this->ignoreObjectBlock($lexer);
        } while ($code !== self::JSON_OBJECT_END);

        return $lexer->lex();
    }
}

I get the error in the optimized file:

------ -------------------------------------------------------
  Line   src\Browscap\Coverage\P.php
 ------ -------------------------------------------------------
  39     Unreachable statement - code above always terminates.
 ------ -------------------------------------------------------

the file phpstan.neon has the content:

parameters:
  level: max
  parallel:
    maximumNumberOfProcesses: 1
    processTimeout: 200.0
  paths:
    - src
    - tests/UserAgentsTest
    - tests/BrowscapTest
    - tests/fixtures
  scanFiles:
    - %currentWorkingDirectory%/vendor/autoload.php
  excludes_analyse:
    - */tests/*/data/*
    - */V3/*Test.php
  ignoreErrors:
    - '~expects string, Exception given~'
    - '~expects string, Twig\\Error\\LoaderError\|Twig\\Error\\RuntimeError\|Twig\\Error\\SyntaxError given~'
    - '~expects string, BrowserDetector\\Loader\\NotFoundException given~'
  checkMissingIterableValueType: false

the composer.json has the following content:

{
  "name": "browscap/browscap",
  "type": "application",
  "description": "Browser Capabilities Tools",
  "keywords": [
    "browscap"
  ],
  "homepage": "https://github.com/browscap/browscap",
  "license": "MIT",
  "authors": [
    {
      "name": "Joshua Estes",
      "email": "f1gm3nt@gmail.com",
      "homepage": "http://joshuaestes.me"
    },
    {
      "name": "James Titcumb",
      "email": "james@asgrim.com",
      "homepage": "http://www.jamestitcumb.com"
    },
    {
      "name": "Thomas Müller",
      "homepage": "https://github.com/mimmi20",
      "role": "Developer"
    },
    {
      "name": "Contributors",
      "homepage": "https://github.com/browscap/browscap/graphs/contributors"
    }
  ],
  "require": {
    "php": "^7.1.3",
    "ext-json": "*",
    "beberlei/assert": "^3.3.0",
    "ergebnis/json-normalizer": "^0.13.0 || ^1.0.2",
    "mimmi20/json-class": "~2.0.16",
    "mimmi20/ua-browser-type": "^7.0.15",
    "mimmi20/ua-device-type": "^7.1.14",
    "monolog/monolog": "^1.26.0 || ^2.2.0",
    "seld/jsonlint": "^1.8.3",
    "symfony/console": "^4.4.18 || ^5.2.1",
    "symfony/finder": "^4.4.18 || ^5.2.1",
    "twig/twig": "^2.13.1 || ^3.2.1"
  },
  "require-dev": {
    "ext-zip": "*",
    "browscap/browscap-php": "^4.3.0 || ^5.0.0",
    "doctrine/coding-standard": "^8.2.0",
    "mikey179/vfsstream": "^1.6.8",
    "phpstan/extension-installer": "~1.1.0",
    "phpstan/phpstan": "^0.12.65",
    "phpstan/phpstan-beberlei-assert": "^0.12.4",
    "phpstan/phpstan-deprecation-rules": "^0.12.6",
    "phpstan/phpstan-phpunit": "^0.12.17",
    "phpunit/phpunit": "^7.5.20 || ^8.5.13 || ^9.5.0"
  },
  "suggest": {
    "ext-zip": "to create a zip file containing all other generated files"
  },
  "config": {
    "platform": {
      "php": "7.1.3"
    },
    "preferred-install": "dist",
    "sort-packages": true
  },
  "autoload": {
    "psr-4": {
      "Browscap\\": "src/Browscap/"
    }
  },
  "autoload-dev": {
    "psr-4": {
      "BrowscapTest\\": "tests/BrowscapTest/",
      "UserAgentsTest\\": "tests/UserAgentsTest/"
    }
  },
  "minimum-stability": "stable",
  "prefer-stable": true,
  "bin": [
    "bin/browscap"
  ],
  "support": {
    "issues": "https://github.com/browscap/browscap/issues",
    "source": "https://github.com/browscap/browscap"
  }
}

Expected output

no error

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions