add builder types

This commit is contained in:
TomasVotruba 2020-05-07 01:22:02 +02:00
parent 1795cd538c
commit c8111834b3
15 changed files with 201 additions and 27 deletions

View File

@ -208,9 +208,7 @@ parameters:
- '#Parameter \#1 \$typeNode of method Rector\\StaticTypeMapper\\StaticTypeMapper\:\:mapPHPStanPhpDocTypeNodeToPHPStanType\(\) expects PHPStan\\PhpDocParser\\Ast\\Type\\TypeNode, PHPStan\\PhpDocParser\\Ast\\Node given#'
- '#Parameter \#1 \$str of function preg_quote expects string, int\|string given#'
- '#Parameter \#2 \$propertyName of method Rector\\TypeDeclaration\\TypeInferer\\PropertyTypeInferer\\SingleMethodAssignedNodePropertyTypeInferer\:\:resolveAssignedNodeToProperty\(\) expects string, string\|null given#'
- '#Parameter \#1 \$sprintfFuncCall of method Rector\\Core\\PhpParser\\NodeTransformer\:\:transformSprintfToArray\(\) expects PhpParser\\Node\\Expr\\FuncCall, PhpParser\\Node given#'
- '#Parameter \#1 \$nodes of method Rector\\CodeQuality\\Rector\\Array_\\CallableThisArrayToAnonymousFunctionRector\:\:hasClassMethodReturn\(\) expects array<PhpParser\\Node\\Stmt\\Return_\>, array<PhpParser\\Node\> given#'
- '#Parameter \#1 \$nodes of method Rector\\Core\\PhpParser\\Node\\BetterNodeFinder\:\:find\(\) expects array<PhpParser\\Node\>\|PhpParser\\Node, array<PhpParser\\Node\\Stmt\>\|null given#'
- '#PHPDoc tag @return with type iterable<object\> is not subtype of native type array#'
- '#Method Rector\\SOLID\\Reflection\\ParentConstantReflectionResolver\:\:(.*?)\(\) should return ReflectionClassConstant\|null but returns ReflectionClassConstant\|false#'
@ -231,10 +229,6 @@ parameters:
- '#Parameter \#1 \$node of method Rector\\PostRector\\Collector\\NodesToAddCollector\:\:wrapToExpression\(\) expects PhpParser\\Node\\Expr\|PhpParser\\Node\\Stmt, PhpParser\\Node given#'
# generics
- '#Method Rector\\BetterPhpDocParser\\AnnotationReader\\NodeAnnotationReader\:\:createClassReflectionFromNode\(\) return type with generic class ReflectionClass does not specify its types\: T#'
- '#Method Rector\\NodeCollector\\StaticAnalyzer\:\:hasStaticAnnotation\(\) has parameter \$reflectionClass with generic class ReflectionClass but does not specify its types\: T#'
# mixed
- '#Property Rector\\Polyfill\\ValueObject\\BinaryToVersionCompareCondition\:\:\$expectedValue has no typehint specified#'
# node finder
@ -291,13 +285,20 @@ parameters:
count: 1
path: rules/php70/src/EregToPcreTransformer.php
-
message: "#^Cognitive complexity for \"Rector\\\\Php70\\\\EregToPcreTransformer\\:\\:(.*?)\" is (.*?), keep it under 9$#"
path: rules/php70/src/EregToPcreTransformer.php
- "#^Cognitive complexity for \"Rector\\\\Php70\\\\EregToPcreTransformer\\:\\:(.*?)\" is (.*?), keep it under 9$#"
- '#Use explicit return value over magic &reference#'
- '#Method Rector\\Order\\StmtOrder\:\:createOldToNewKeys\(\) should return array<int\> but returns array\|false#'
- '#In method "Rector\\Utils\\ProjectValidator\\Process\\ParallelTaskRunner\:\:evaluateRunningProcesses", caught "Throwable" must be rethrown\. Either catch a more specific exception or add a "throw" clause in the "catch" block to propagate the exception\. More info\: http\://bit\.ly/failloud#'
- '#In method "Rector\\Utils\\ProjectValidator\\Process\\ParallelTaskRunner\:\:(.*?)", caught "Throwable" must be rethrown\. Either catch a more specific exception or add a "throw" clause in the "catch" block to propagate the exception#'
# weird
- '#Method (.*?) specified in iterable type Symfony\\Component\\Process\\Process#'
- '#Cannot cast PhpParser\\Node\\Expr\\Error\|PhpParser\\Node\\Identifier to string#'
- '#Class cognitive complexity for "DumpNodesCommand" is 103, keep it under 50#'
- '#Cognitive complexity for "Rector\\Utils\\DocumentationGenerator\\Command\\DumpNodesCommand\:\:execute\(\)" is \d+, keep it under 9#'
# just for utils
- '#Class "Rector\\Utils\\DoctrineAnnotationParserSyncer\\Rector\\(.*?)" is missing @see annotation with test case class reference#'
- '#Method Rector\\Utils\\DocumentationGenerator\\Node\\NodeClassProvider\:\:getNodeClasses\(\) should return array<class\-string\> but returns array<int, \(int\|string\)\>#'

View File

@ -6,6 +6,7 @@ namespace Rector\Utils\DoctrineAnnotationParserSyncer;
use PhpParser\Node;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitor;
use Rector\PostRector\Application\PostFileProcessor;
use Rector\Utils\DoctrineAnnotationParserSyncer\Contract\Rector\ClassSyncerRectorInterface;
@ -22,6 +23,7 @@ final class ClassSyncerNodeTraverser extends NodeTraverser
public function __construct(array $classSyncerRectors, PostFileProcessor $postFileProcessor)
{
foreach ($classSyncerRectors as $classSyncerRector) {
/** @var ClassSyncerRectorInterface&NodeVisitor $classSyncerRector */
$this->addVisitor($classSyncerRector);
}

View File

@ -48,7 +48,7 @@ final class LogIdentifierAndResolverValueInConstantClassMethodRector extends Abs
$firstStmt = $node->stmts[0];
unset($node->stmts[0]);
$assignExpression = $this->createAssignOriginalIdentifierExpression();
$node->stmts = array_merge([$firstStmt], [$assignExpression], $node->stmts);
$node->stmts = array_merge([$firstStmt], [$assignExpression], (array) $node->stmts);
// 2. record value in each return
$this->traverseNodesWithCallable((array) $node->stmts, function (Node $node) {
@ -56,10 +56,15 @@ final class LogIdentifierAndResolverValueInConstantClassMethodRector extends Abs
return null;
}
if ($node->expr === null) {
return null;
}
// assign resolved value to temporary variable
$resolvedValueVariable = new Variable('resolvedValue');
$assign = new Assign($resolvedValueVariable, $node->expr);
$assignExpression = new Expression($assign);
$this->addNodeBeforeNode($assignExpression, $node);
// log the value in static call

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Rector\Utils\DocumentationGenerator\Command;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Const_;
use PhpParser\Node\Expr\ArrayDimFetch;
@ -194,6 +195,7 @@ final class DumpNodesCommand extends AbstractCommand
$constructorReflection = $nodeClassReflection->getConstructor();
if ($constructorReflection->getNumberOfRequiredParameters() === 0) {
/** @var Node $node */
$node = $nodeClassReflection->newInstance();
// special case
if ($node instanceof ArrowFunction) {

View File

@ -149,11 +149,12 @@ final class AttributeAwareClassFactoryFactory
private function createIsAFuncCall(string $nodeClass): FuncCall
{
return new FuncCall(new Name('is_a'), [
new Variable(self::NODE),
$this->createClassReference($nodeClass),
new ConstFetch(new Name('true')),
]);
$variable = new Variable(self::NODE);
$true = new ConstFetch(new Name('true'));
$args = [new Arg($variable), new Arg($this->createClassReference($nodeClass)), new Arg($true)];
return new FuncCall(new Name('is_a'), $args);
}
private function completeNewArgs(New_ $new, string $phpDocParserNodeClass): void

View File

@ -42,3 +42,14 @@ services:
# $phpDocInfo->getByType($1) => Type|null by $1
- { class: Rector\PHPStanExtensions\ReturnTypeExtension\PhpDocInfoGetByTypeReturnTypeExtension, tags: [phpstan.broker.dynamicMethodReturnTypeExtension] }
# $<type>builder->getNode() => Type
-
class: Rector\PHPStanExtensions\ReturnTypeExtension\Builder\NamespaceBuilderReturnTypeExtension
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
-
class: Rector\PHPStanExtensions\ReturnTypeExtension\Builder\ClassMethodBuilderReturnTypeExtension
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
-
class: Rector\PHPStanExtensions\ReturnTypeExtension\Builder\ClassBuilderReturnTypeExtension
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]

View File

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace Rector\PHPStanExtensions\ReturnTypeExtension\Builder;
use PhpParser\Builder\Class_ as ClassBuilder;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Stmt\Class_;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\Type;
use Rector\PHPStan\Type\FullyQualifiedObjectType;
final class ClassBuilderReturnTypeExtension implements DynamicMethodReturnTypeExtension
{
public function getClass(): string
{
return ClassBuilder::class;
}
public function isMethodSupported(MethodReflection $methodReflection): bool
{
return $methodReflection->getName() === 'getNode';
}
public function getTypeFromMethodCall(
MethodReflection $methodReflection,
MethodCall $methodCall,
Scope $scope
): Type {
return new FullyQualifiedObjectType(Class_::class);
}
}

View File

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace Rector\PHPStanExtensions\ReturnTypeExtension\Builder;
use PhpParser\Builder\Method;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\Type;
use Rector\PHPStan\Type\FullyQualifiedObjectType;
final class ClassMethodBuilderReturnTypeExtension implements DynamicMethodReturnTypeExtension
{
public function getClass(): string
{
return Method::class;
}
public function isMethodSupported(MethodReflection $methodReflection): bool
{
return $methodReflection->getName() === 'getNode';
}
public function getTypeFromMethodCall(
MethodReflection $methodReflection,
MethodCall $methodCall,
Scope $scope
): Type {
return new FullyQualifiedObjectType(ClassMethod::class);
}
}

View File

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace Rector\PHPStanExtensions\ReturnTypeExtension\Builder;
use PhpParser\Builder\Namespace_ as NamespaceBuilder;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Stmt\Namespace_;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\Type;
use Rector\PHPStan\Type\FullyQualifiedObjectType;
final class NamespaceBuilderReturnTypeExtension implements DynamicMethodReturnTypeExtension
{
public function getClass(): string
{
return NamespaceBuilder::class;
}
public function isMethodSupported(MethodReflection $methodReflection): bool
{
return $methodReflection->getName() === 'getNode';
}
public function getTypeFromMethodCall(
MethodReflection $methodReflection,
MethodCall $methodCall,
Scope $scope
): Type {
return new FullyQualifiedObjectType(Namespace_::class);
}
}

View File

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace Rector\PHPStanExtensions\ReturnTypeExtension\Builder;
use PhpParser\Builder\Property as PropertyBuilder;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Stmt\Property;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\Type;
use Rector\PHPStan\Type\FullyQualifiedObjectType;
final class PropertyBuilderReturnTypeExtension implements DynamicMethodReturnTypeExtension
{
public function getClass(): string
{
return PropertyBuilder::class;
}
public function isMethodSupported(MethodReflection $methodReflection): bool
{
return $methodReflection->getName() === 'getNode';
}
public function getTypeFromMethodCall(
MethodReflection $methodReflection,
MethodCall $methodCall,
Scope $scope
): Type {
return new FullyQualifiedObjectType(Property::class);
}
}

View File

@ -4,14 +4,14 @@ declare(strict_types=1);
namespace Rector\PHPStanExtensions\ReturnTypeExtension;
use PhpParser\NodeVisitor\NameResolver;
use PHPStan\Reflection\MethodReflection;
use Rector\NodeNameResolver\NodeNameResolver;
final class NameResolverReturnTypeExtension extends AbstractResolvedNameReturnTypeExtension
{
public function getClass(): string
{
return NameResolver::class;
return NodeNameResolver::class;
}
public function isMethodSupported(MethodReflection $methodReflection): bool

View File

@ -93,7 +93,6 @@ final class SeeAnnotationToTestRule implements Rule
}
foreach ($this->requiredSeeTypes as $requiredSeeType) {
dump($requiredSeeType);
if ($classReflection->isSubclassOf($requiredSeeType)) {
return false;
}

View File

@ -23,6 +23,8 @@ final class PHPStanTypeClassFinder
$robotLoader->rebuild();
$classLikesToFilePaths = $robotLoader->getIndexedClasses();
/** @var class-string[] $classLikes */
$classLikes = array_keys($classLikesToFilePaths);
return $this->filterClassesOnly($classLikes);

View File

@ -19,14 +19,7 @@ final class CpuCoreCountResolver
public function resolve(): int
{
if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
$str = trim(shell_exec('wmic cpu get NumberOfCores 2>&1'));
$matches = Strings::match($str, '#(\d+)#');
if (! $matches) {
throw new CouldNotDeterminedCpuCoresException('wmic failed to get number of cpu cores on windows!');
}
return (int) $matches[1];
return $this->resolveForWindows();
}
$ret = @shell_exec('nproc');
@ -47,4 +40,21 @@ final class CpuCoreCountResolver
throw new CouldNotDeterminedCpuCoresException('Failed to detect number of CPUs');
}
private function resolveForWindows(): int
{
$numberOfCores = shell_exec('wmic cpu get NumberOfCores 2>&1');
if ($numberOfCores === null) {
throw new CouldNotDeterminedCpuCoresException('wmic failed to get number of cpu cores on windows!');
}
$str = trim($numberOfCores);
$matches = Strings::match($str, '#(\d+)#');
if (! $matches) {
throw new CouldNotDeterminedCpuCoresException('wmic failed to get number of cpu cores on windows!');
}
return (int) $matches[1];
}
}

View File

@ -124,6 +124,7 @@ final class ParallelTaskRunner
if ($this->canStartAnotherProcess($maxProcesses)) {
/** @var string $setName */
$setName = array_key_first($this->remainingTasks);
/** @var SetTask $task */
$task = array_shift($this->remainingTasks);
try {