bump to PHPStan 0.12

This commit is contained in:
TomasVotruba 2019-12-08 22:00:38 +01:00
parent bace233ed4
commit 9075363fef
37 changed files with 325 additions and 113 deletions

View File

@ -16,10 +16,5 @@
},
"require-dev": {
"phpunit/phpunit": "^8.4"
},
"extra": {
"cleaner-ignore": {
"phpstan/phpstan": ["conf"]
}
}
}

View File

@ -66,9 +66,6 @@ final class CompileCommand extends Command
{
$this->processFactory->setOutput($output);
// this breaks phpstan dependency by removing whole "/conf" directory - https://github.com/dg/composer-cleaner#configuration
$this->processFactory->create(['composer', 'require', '--no-update', 'dg/composer-cleaner:^2.0'], $this->buildDir);
$composerJsonFile = $this->buildDir . '/composer.json';
$this->fixComposerJson($composerJsonFile);

View File

@ -20,9 +20,9 @@
"nette/utils": "^3.0",
"nikic/php-parser": "^4.3",
"ondram/ci-detector": "^3.1",
"phpstan/phpdoc-parser": "^0.3.5",
"phpstan/phpstan": "0.11.19",
"phpstan/phpstan-phpunit": "^0.11.2",
"phpstan/phpdoc-parser": "0.4 as 0.3.5",
"phpstan/phpstan": "0.12 as 0.11.19",
"phpstan/phpstan-phpunit": "0.12 as 0.11.2",
"sebastian/diff": "^3.0",
"symfony/console": "^4.4|^5.0",
"symfony/dependency-injection": "^4.4|^5.0",
@ -40,7 +40,7 @@
"symplify/easy-coding-standard": "^7.0",
"symplify/monorepo-builder": "^7.0",
"symplify/phpstan-extensions": "^7.0",
"thecodingmachine/phpstan-strict-rules": "^0.11.2",
"thecodingmachine/phpstan-strict-rules": "^0.12",
"tracy/tracy": "^2.7"
},
"autoload": {
@ -199,7 +199,7 @@
"ecs check bin packages src tests utils compiler --fix --ansi",
"ci/clean_trailing_spaces.sh"
],
"phpstan": "phpstan analyse packages src tests compiler/src --error-format symplify --ansi",
"phpstan": "phpstan analyse packages src tests compiler/src --ansi",
"changelog": [
"changelog-linker dump-merges --in-categories",
"changelog-linker link",
@ -225,5 +225,7 @@
"branch-alias": {
"dev-master": "0.6-dev"
}
}
},
"minimum-stability": "dev",
"prefer-stable": true
}

View File

@ -42,7 +42,7 @@ services:
Symplify\PackageBuilder\Strings\StringFormatConverter: ~
# alises
Symfony\Component\EventDispatcher\EventDispatcherInterface: '@Rector\EventDispatcher\AutowiredEventDispatcher'
Symfony\Contracts\EventDispatcher\EventDispatcherInterface: '@Rector\EventDispatcher\AutowiredEventDispatcher'
Rector\Bridge\Contract\AnalyzedApplicationContainerInterface: '@Rector\Symfony\Bridge\DefaultAnalyzedSymfonyApplicationContainer'
OndraM\CiDetector\CiDetector: ~

View File

@ -6768,7 +6768,7 @@ Make Symfony commands lazy
Make event object a first argument of dispatch() method, event name as second
```diff
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class SomeClass
{

View File

@ -1,35 +1,53 @@
<?php
namespace Rector\CodeQuality\Tests\Rector\If_\SimplifyIfReturnBoolRector\Fixture;
use PhpCsFixer\Tokenizer\Token;
function simplifyIfReturnBool()
class SomeClass
{
$docToken = new Token([]);
if (strpos($docToken->getContent(), "\n") === false) {
return true;
public function first()
{
$docToken = new Token([]);
if (strpos($docToken->getContent(), "\n") === false) {
return true;
}
return false;
}
return false;
public function second()
{
$docToken = new Token([]);
if (strpos($docToken->getContent(), "\n") !== false) {
return true;
}
if (strpos($docToken->getContent(), "\n") !== false) {
return true;
return false;
}
return false;
}
?>
-----
<?php
namespace Rector\CodeQuality\Tests\Rector\If_\SimplifyIfReturnBoolRector\Fixture;
use PhpCsFixer\Tokenizer\Token;
function simplifyIfReturnBool()
class SomeClass
{
$docToken = new Token([]);
return strpos($docToken->getContent(), "\n") === false;
return strpos($docToken->getContent(), "\n") !== false;
public function first()
{
$docToken = new Token([]);
return strpos($docToken->getContent(), "\n") === false;
}
public function second()
{
$docToken = new Token([]);
return strpos($docToken->getContent(), "\n") !== false;
}
}
?>

View File

@ -8,7 +8,11 @@ class EdgeCases
{
$order = $someQueryBuilder->getQuery()->getOneOrNullResult();
return $order ? true : false;
}
public function go(): bool
{
$order = $someQueryBuilder->getQuery()->getOneOrNullResult();
return $order ? false : true;
}
@ -16,7 +20,11 @@ class EdgeCases
{
$order = false;
return $order ? true : false;
}
public function switchBack(): bool
{
$order = false;
return $order ? false : true;
}
}
@ -33,7 +41,11 @@ class EdgeCases
{
$order = $someQueryBuilder->getQuery()->getOneOrNullResult();
return (bool) $order;
}
public function go(): bool
{
$order = $someQueryBuilder->getQuery()->getOneOrNullResult();
return !(bool) $order;
}
@ -41,7 +53,11 @@ class EdgeCases
{
$order = false;
return $order;
}
public function switchBack(): bool
{
$order = false;
return !$order;
}
}

View File

@ -2,7 +2,7 @@
namespace Rector\DeadCode\Tests\Rector\ClassMethod\RemoveDelegatingParentCallRector\Fixture;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class SkipRequired extends ParentClassWithoutRequired
{

View File

@ -219,11 +219,11 @@ final class AssertManipulator
if (isset($typeToMethod[$value])) {
$staticCall->name = new Identifier($typeToMethod[$value]);
unset($staticCall->args[0]);
array_values($staticCall->args);
$staticCall->args = array_values($staticCall->args);
} elseif ($value === 'null') {
$staticCall->name = new Identifier('assertNull');
unset($staticCall->args[0]);
array_values($staticCall->args);
$staticCall->args = array_values($staticCall->args);
} else {
$staticCall->name = new Identifier('assertInstanceOf');
}

View File

@ -347,7 +347,7 @@ PHP
$presenterPart = Strings::substring($presenterPart, 0, -Strings::length('Presenter'));
$presenterPart = RectorStrings::camelCaseToDashes($presenterPart);
$match = Strings::match($this->getName($classMethod), '#^(action|render)(?<short_action_name>.*?$)#sm');
$match = (array) Strings::match($this->getName($classMethod), '#^(action|render)(?<short_action_name>.*?$)#sm');
$actionPart = lcfirst($match['short_action_name']);
return $presenterPart . '/' . $actionPart;

View File

@ -4,11 +4,11 @@ declare(strict_types=1);
namespace Rector\NodeTypeResolver\DependencyInjection;
use Nette\DI\Container;
use PHPStan\Analyser\NodeScopeResolver;
use PHPStan\Analyser\ScopeFactory;
use PHPStan\Analyser\TypeSpecifier;
use PHPStan\Broker\Broker;
use PHPStan\DependencyInjection\Container;
use PHPStan\DependencyInjection\ContainerFactory;
final class PHPStanServicesFactory

View File

@ -21,6 +21,7 @@ use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Param;
use PhpParser\Node\Scalar;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassConst;
@ -36,6 +37,8 @@ use PHPStan\Type\Accessory\HasOffsetType;
use PHPStan\Type\Accessory\NonEmptyArrayType;
use PHPStan\Type\ArrayType;
use PHPStan\Type\Constant\ConstantBooleanType;
use PHPStan\Type\Constant\ConstantFloatType;
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\FloatType;
use PHPStan\Type\IntegerType;
@ -326,6 +329,23 @@ final class NodeTypeResolver
/** @var Scope|null $nodeScope */
$nodeScope = $node->getAttribute(AttributeKey::SCOPE);
if ($node instanceof Scalar) {
if ($nodeScope === null) {
if ($node instanceof Node\Scalar\DNumber) {
return new ConstantFloatType($node->value);
}
if ($node instanceof Node\Scalar\String_) {
return new ConstantStringType($node->value);
}
if ($node instanceof Node\Scalar\LNumber) {
return new ConstantIntegerType($node->value);
}
}
}
if (! $node instanceof Expr || $nodeScope === null) {
return new MixedType();
}
@ -336,9 +356,6 @@ final class NodeTypeResolver
}
}
// make object type specific to alias or FQN
$staticType = $nodeScope->getType($node);
// false type correction of inherited method
if ($node instanceof MethodCall) {
if ($this->isObjectType($node->var, SplFileInfo::class)) {
@ -349,6 +366,7 @@ final class NodeTypeResolver
}
}
$staticType = $nodeScope->getType($node);
if (! $staticType instanceof ObjectType) {
return $staticType;
}

View File

@ -10,6 +10,7 @@ use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Interface_;
use PhpParser\Node\Stmt\Trait_;
use PhpParser\NodeTraverser;
use PHPStan\Analyser\MutatingScope;
use PHPStan\Analyser\NodeScopeResolver as PHPStanNodeScopeResolver;
use PHPStan\Analyser\Scope;
use PHPStan\Broker\Broker;
@ -75,7 +76,7 @@ final class NodeScopeResolver
$scope = $this->scopeFactory->createFromFile($filePath);
// skip chain method calls, performance issue: https://github.com/phpstan/phpstan/issues/254
$nodeCallback = function (Node $node, Scope $scope): void {
$nodeCallback = function (Node $node, MutatingScope $scope): void {
// the class reflection is resolved AFTER entering to class node
// so we need to get it from the first after this one
if ($node instanceof Class_ || $node instanceof Interface_) {
@ -100,6 +101,7 @@ final class NodeScopeResolver
}
};
/** @var MutatingScope $scope */
$this->phpStanNodeScopeResolver->processNodes($nodes, $scope, $nodeCallback);
return $nodes;
@ -118,7 +120,7 @@ final class NodeScopeResolver
/**
* @param Class_|Interface_ $classOrInterfaceNode
*/
private function resolveClassOrInterfaceScope(Node $classOrInterfaceNode, Scope $scope): Scope
private function resolveClassOrInterfaceScope(Node $classOrInterfaceNode, MutatingScope $scope): MutatingScope
{
$className = $this->resolveClassName($classOrInterfaceNode);
$classReflection = $this->broker->getClass($className);

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Rector\NodeTypeResolver\PHPStan\Scope;
use PHPStan\Analyser\MutatingScope;
use PHPStan\Analyser\Scope;
use PHPStan\Analyser\ScopeContext;
use PHPStan\Analyser\ScopeFactory as PHPStanScopeFactory;
@ -48,7 +49,7 @@ final class ScopeFactory
public function createFromFile(string $filePath): Scope
{
return new Scope(
return new MutatingScope(
$this->phpStanScopeFactory,
$this->broker,
$this->betterStandardPrinter,

View File

@ -6,7 +6,10 @@ function runContinueZeroes($random)
{
continue 0;
break 0;
}
function breakIt()
{
$five = 5;
continue $five;
@ -23,7 +26,10 @@ function runContinueZeroes($random)
{
continue;
break;
}
function breakIt()
{
$five = 5;
continue 5;

View File

@ -69,7 +69,7 @@ PHP
$defaultCases[] = $case;
}
if ($defaultCases < 2) {
if (count($defaultCases) < 2) {
return null;
}

View File

@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Rector\Php71\Tests\Rector\FuncCall\RemoveExtraParametersRector\Source;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
final class MagicEventDispatcher
{

View File

@ -13,7 +13,7 @@ use PHPStan\Type\ObjectType;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* @see https://symfony.com/blog/new-in-symfony-4-3-simpler-event-dispatching
@ -26,7 +26,7 @@ final class MakeDispatchFirstArgumentEventRector extends AbstractRector
return new RectorDefinition('Make event object a first argument of dispatch() method, event name as second', [
new CodeSample(
<<<'PHP'
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class SomeClass
{
@ -38,7 +38,7 @@ class SomeClass
PHP
,
<<<'PHP'
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class SomeClass
{

View File

@ -2,7 +2,7 @@
namespace Rector\Symfony\Tests\Rector\MethodCall\MakeDispatchFirstArgumentEventRector\Fixture;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class SomeClass
{
@ -20,7 +20,7 @@ class SomeClass
namespace Rector\Symfony\Tests\Rector\MethodCall\MakeDispatchFirstArgumentEventRector\Fixture;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class SomeClass
{

View File

@ -112,6 +112,7 @@ PHP
$node,
[ReturnTypeDeclarationReturnTypeInferer::class]
);
if ($inferedType instanceof MixedType) {
return null;
}
@ -138,22 +139,15 @@ PHP
$currentType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($node->returnType);
// is current class implementation/subtype
if ($currentType instanceof ObjectType && $inferedType instanceof ObjectType) {
if (is_a($currentType->getClassName(), $inferedType->getClassName(), true)) {
return null;
}
if ($this->isCurrentObjectTypeSubType($currentType, $inferedType)) {
return null;
}
// nullable aase
if ($currentType instanceof UnionType && $inferedType instanceof UnionType) {
if ($inferedType->isSubTypeOf($currentType)->yes()) {
return null;
}
if ($this->isNullableTypeSubType($currentType, $inferedType)) {
return null;
}
// @see https://wiki.php.net/rfc/covariant-returns-and-contravariant-parameters
if ($this->isAtLeastPhpVersion('7.4') && $isSubtype) {
if ($this->isAtLeastPhpVersion(PhpVersionFeature::COVARIANT_RETURN) && $isSubtype) {
$node->returnType = $inferredReturnNode;
} elseif (! $isSubtype) { // type override
$node->returnType = $inferredReturnNode;
@ -311,4 +305,33 @@ PHP
return false;
}
/**
* E.g. current E, new type A, E extends A true
*/
private function isCurrentObjectTypeSubType(Type $currentType, Type $inferedType): bool
{
if (! $currentType instanceof ObjectType) {
return false;
}
if (! $inferedType instanceof ObjectType) {
return false;
}
return is_a($currentType->getClassName(), $inferedType->getClassName(), true);
}
private function isNullableTypeSubType(Type $currentType, Type $inferedType): bool
{
if (! $currentType instanceof UnionType) {
return false;
}
if (! $inferedType instanceof UnionType) {
return false;
}
return $inferedType->isSubTypeOf($currentType)->yes();
}
}

View File

@ -52,8 +52,7 @@ final class ReturnedNodesReturnTypeInferer extends AbstractTypeInferer implement
continue;
}
$staticType = $this->nodeTypeResolver->resolveNodeToPHPStanType($localReturnNode->expr);
$types[] = $staticType;
$types[] = $this->nodeTypeResolver->resolveNodeToPHPStanType($localReturnNode->expr);
}
return $this->typeFactory->createMixedPassedOrUnionType($types);

View File

@ -10,22 +10,7 @@ class KnownFloat
return 5.2;
}
$value = 5.3;
return $value;
}
public function getFloatingParam(float $float)
{
return $float;
}
public function getFloatingTanks(float $float)
{
if (true) {
return $float;
}
return 5.0;
return 5.3;
}
}
@ -43,22 +28,7 @@ class KnownFloat
return 5.2;
}
$value = 5.3;
return $value;
}
public function getFloatingParam(float $float): float
{
return $float;
}
public function getFloatingTanks(float $float): float
{
if (true) {
return $float;
}
return 5.0;
return 5.3;
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\ReturnTypeDeclarationRector\Fixture;
class KnownFloatInVariable
{
public function getFloating()
{
$value = 5.3;
return $value;
}
}
?>
-----
<?php
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\ReturnTypeDeclarationRector\Fixture;
class KnownFloatInVariable
{
public function getFloating(): float
{
$value = 5.3;
return $value;
}
}
?>

View File

@ -0,0 +1,27 @@
<?php
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\ReturnTypeDeclarationRector\Fixture;
class KnownFloatParamType
{
public function getFloatingParam(float $float)
{
return $float;
}
}
?>
-----
<?php
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\ReturnTypeDeclarationRector\Fixture;
class KnownFloatParamType
{
public function getFloatingParam(float $float): float
{
return $float;
}
}
?>

View File

@ -0,0 +1,35 @@
<?php
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\ReturnTypeDeclarationRector\Fixture;
class KnownFloatParamTypeWithCondition
{
public function getFloatingTanks(float $float)
{
if (true) {
return $float;
}
return 5.0;
}
}
?>
-----
<?php
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\ReturnTypeDeclarationRector\Fixture;
class KnownFloatParamTypeWithCondition
{
public function getFloatingTanks(float $float): float
{
if (true) {
return $float;
}
return 5.0;
}
}
?>

View File

@ -21,7 +21,7 @@ class KnownStatic
public function getMoreItems()
{
if (true) {
if (rand(0, 10)) {
return [];
}
@ -60,7 +60,7 @@ class KnownStatic
public function getMoreItems(): array
{
if (true) {
if (rand(0, 10)) {
return [];
}

View File

@ -6,7 +6,7 @@ class KnownStaticNullable
{
public function getMoreItems()
{
if (true) {
if ((bool) rand(0, 100)) {
return null;
}
@ -32,7 +32,7 @@ class KnownStaticNullable
{
public function getMoreItems(): ?array
{
if (true) {
if ((bool) rand(0, 100)) {
return null;
}

View File

@ -6,7 +6,7 @@ class KnownStaticNullableFloat
{
public function getFloating()
{
if (true) {
if ((bool) rand(0, 10)) {
return 5.2;
}
@ -25,7 +25,7 @@ class KnownStaticNullableFloat
{
public function getFloating(): float
{
if (true) {
if ((bool) rand(0, 10)) {
return 5.2;
}

View File

@ -1,11 +1,13 @@
includes:
- 'utils/PHPStanExtensions/config/phpstan-extensions.neon'
- 'vendor/symplify/phpstan-extensions/config/config.neon'
- 'vendor/symplify/phpstan-extensions/config/php.level.neon'
- 'vendor/symplify/phpstan-extensions/config/symfony.level.neon'
- 'vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon'
# bleeing edge
- 'vendor/phpstan/phpstan/conf/bleedingEdge.neon'
parameters:
checkGenericClassInNonGenericObjectType: false
# to allow installing with various phsptan versions without reporting old errors here
reportUnmatchedIgnoredErrors: false
level: max
@ -246,3 +248,30 @@ parameters:
-
message: "#Internal error: Cannot find function 'inlineSections#"
path: utils/Composer/bin/SortNamespaces.php
# mixed
- '#in iterable type Iterator#'
- '#with no typehint specified#'
- '#return type has no value type specified in iterable type array#'
- '#has no return typehint#'
- '#Offset int\|string\|null does not exist on array<PhpParser\\Node\\Stmt>\|null#'
- '#class-string<T of object>\|T of object#'
- '#with no value type specified in iterable type array#'
- '#type specified in iterable type (array|iterable)#'
# known values
- '#Offset 0 does not exist on array<PhpParser\\Node\\Stmt>\|null#'
- '#Parameter \#1 \$left of class PhpParser\\Node\\Expr\\BinaryOp\\Spaceship constructor expects PhpParser\\Node\\Expr, PhpParser\\Node\\Expr\|null given#'
- '#Parameter \#2 \$right of class PhpParser\\Node\\Expr\\BinaryOp\\Spaceship constructor expects PhpParser\\Node\\Expr, PhpParser\\Node\\Expr\|null given#'
- '#Parameter \#3 \$nodeCallback of method PHPStan\\Analyser\\NodeScopeResolver::processNodes\(\) expects Closure\(PhpParser\\Node, PHPStan\\Analyser\\Scope\): void, Closure\(PhpParser\\Node, PHPStan\\Analyser\\MutatingScope\): void given#'
# false positive
- '#Array \(array\) does not accept key#'
- '#Array \(array<int, PhpParser\\Node\\Arg>\) does not accept key#'
- '#Comparison operation "<" between 0 and 2 is always true#'
- '#Property Rector\\Compiler\\Process\\SymfonyProcess::\$process type has no value type specified in iterable type Symfony\\Component\\Process\\Process#'
- '#Method Rector\\Compiler\\Process\\SymfonyProcess::getProcess\(\) return type has no value type specified in iterable type Symfony\\Component\\Process\\Process#'
- '#Method Rector\\Compiler\\Contract\\Process\\ProcessInterface::getProcess\(\) return type has no value type specified in iterable type Symfony\\Component\\Process\\Process#'
# phpstan compiler bug
- '#Parameter \#1 \$docComment of method PhpParser\\Builder\\Property::setDocComment\(\) expects _HumbugBox3be60b26ad9d\\PhpParser\\Comment\\Doc\|string, PhpParser\\Comment\\Doc given#'

View File

@ -17,7 +17,7 @@ use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symplify\PackageBuilder\Console\Command\CommandNaming;
use Symplify\SmartFileSystem\SmartFileInfo;

View File

@ -15,16 +15,34 @@ use PhpParser\NodeDumper;
final class BetterNodeDumper extends NodeDumper
{
private $dumpComments;
/**
* @var bool
*/
private $dumpComments = false;
private $dumpPositions;
/**
* @var bool
*/
private $dumpPositions = false;
/**
* @var int[]
*/
private $printedNodes = [];
/**
* @var int
*/
private $nodeIds = 0;
/**
* @var bool
*/
private $skipEmpty = true;
/**
* @var string[]
*/
private $filterAttributes = [];
/**

View File

@ -133,7 +133,8 @@ PHP
private function getFactoryPropertyName(string $factoryFullQualifiedName): string
{
$className = (new ReflectionClass($factoryFullQualifiedName))->getShortName();
$reflectionClass = new ReflectionClass($factoryFullQualifiedName);
$className = $reflectionClass->getShortName();
return Strings::firstLower($className);
}

View File

@ -66,6 +66,12 @@ final class PhpVersionFeature
*/
public const BEFORE_UNION_TYPES = '7.4';
/**
* @see https://wiki.php.net/rfc/covariant-returns-and-contravariant-parameters
* @var string
*/
public const COVARIANT_RETURN = '7.4';
/**
* @var string
*/

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Symfony\Component\EventDispatcher;
if (interface_exists('Symfony\Component\EventDispatcher\EventDispatcherInterface')) {
if (interface_exists('Symfony\Contracts\EventDispatcher\EventDispatcherInterface')) {
return;
}

View File

@ -1,12 +1,14 @@
<?php
use Nette\Configurator;
namespace Rector\Tests\Rector\Constant\RenameClassConstantsUseToStringsRector\Fixture;
use Rector\Tests\Rector\Constant\RenameClassConstantsUseToStringsRector\Source\OldClassWithConstants;
class ClassWithExternalConstant
{
public function getValue()
{
return Configurator::DEVELOPMENT;
return OldClassWithConstants::DEVELOPMENT;
}
}
@ -14,7 +16,9 @@ class ClassWithExternalConstant
-----
<?php
use Nette\Configurator;
namespace Rector\Tests\Rector\Constant\RenameClassConstantsUseToStringsRector\Fixture;
use Rector\Tests\Rector\Constant\RenameClassConstantsUseToStringsRector\Source\OldClassWithConstants;
class ClassWithExternalConstant
{

View File

@ -5,9 +5,9 @@ declare(strict_types=1);
namespace Rector\Tests\Rector\Constant\RenameClassConstantsUseToStringsRector;
use Iterator;
use Nette\Configurator;
use Rector\Rector\Constant\RenameClassConstantsUseToStringsRector;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Rector\Tests\Rector\Constant\RenameClassConstantsUseToStringsRector\Source\OldClassWithConstants;
final class RenameClassConstantsUseToStringsRectorTest extends AbstractRectorTestCase
{
@ -32,7 +32,7 @@ final class RenameClassConstantsUseToStringsRectorTest extends AbstractRectorTes
return [
RenameClassConstantsUseToStringsRector::class => [
'$oldConstantsToNewValuesByType' => [
Configurator::class => [
OldClassWithConstants::class => [
'DEVELOPMENT' => 'development',
'PRODUCTION' => 'production',
],

View File

@ -0,0 +1,16 @@
<?php declare(strict_types=1);
namespace Rector\Tests\Rector\Constant\RenameClassConstantsUseToStringsRector\Source;
final class OldClassWithConstants
{
/**
* @var string
*/
public const DEVELOPMENT = 'development';
/**
* @var string
*/
public const PRODUCTION = 'production';
}