Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/set/phpunit/phpunit-code-quality.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
services:
Rector\PHPUnit\Rector\MethodCall\RemoveExpectAnyFromMockRector: ~
Rector\PHPUnit\Rector\Class_\AddSeeTestAnnotationRector: ~
Rector\PHPUnit\Rector\Class_\ArrayArgumentInTestToDataProviderRector: ~
5 changes: 4 additions & 1 deletion ecs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ services:
- 'PhpParser\NodeVisitor\NameResolver'
- 'PhpParser\Node\*'
- '*Data'
- '*Recipe'
- '*ValueObject'
- 'PhpParser\Comment'
- 'PhpParser\Lexer'
- 'PhpParser\Comment\Doc'
Expand All @@ -38,7 +40,6 @@ services:
- 'Rector\DependencyInjection\Loader\*'
- 'Symplify\PackageBuilder\*'
- 'Symfony\Component\Console\Input\*Input'
- '*ValueObject'
- 'PHPStan\Analyser\NameScope'

Symplify\CodingStandard\Fixer\Naming\PropertyNameMatchingTypeFixer:
Expand Down Expand Up @@ -110,10 +111,12 @@ parameters:

Symplify\CodingStandard\Sniffs\CleanCode\CognitiveComplexitySniff:
# tough logic
- 'packages/PHPUnit/src/Rector/Class_/ArrayArgumentInTestToDataProviderRector.php'
- 'packages/DoctrinePhpDocParser/src/Ast/PhpDoc/*/*TagValueNode.php'
- 'packages/NodeTypeResolver/src/PhpDoc/NodeAnalyzer/FqnNamePhpDocNodeDecorator.php'
- 'packages/NodeTypeResolver/src/PHPStan/Type/StaticTypeAnalyzer.php'
- 'src/NodeContainer/ParsedNodesByType.php'
- 'packages/NodeTypeResolver/src/StaticTypeMapper.php'
- 'packages/PHPStan/src/Rector/Node/RemoveNonExistingVarAnnotationRector.php'
- 'packages/Architecture/src/Rector/Class_/ConstructorInjectionToActionInjectionRector.php'
- 'src/PhpParser/Node/Commander/NodeRemovingCommander.php'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PHPStan\PhpDocParser\Ast\PhpDoc\InvalidTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocChildNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
Expand Down Expand Up @@ -149,18 +148,6 @@ public function hasTag(Node $node, string $name): bool
return $phpDocInfo->hasTag($name);
}

public function removeParamTagByName(Node $node, string $name): void
{
if ($node->getDocComment() === null) {
return;
}

$phpDocInfo = $this->createPhpDocInfoFromNode($node);
$this->removeParamTagByParameter($phpDocInfo, $name);

$this->updateNodeWithPhpDocInfo($node, $phpDocInfo);
}

public function addTag(Node $node, PhpDocChildNode $phpDocChildNode): void
{
$phpDocChildNode = $this->attributeAwareNodeFactory->createFromNode($phpDocChildNode);
Expand Down Expand Up @@ -363,31 +350,6 @@ public function removeTagByName(PhpDocInfo $phpDocInfo, string $tagName): void
}
}

public function removeParamTagByParameter(PhpDocInfo $phpDocInfo, string $parameterName): void
{
$phpDocNode = $phpDocInfo->getPhpDocNode();

/** @var PhpDocTagNode[] $phpDocTagNodes */
$phpDocTagNodes = $phpDocNode->getTagsByName('@param');

foreach ($phpDocTagNodes as $phpDocTagNode) {
/** @var ParamTagValueNode|InvalidTagValueNode $paramTagValueNode */
$paramTagValueNode = $phpDocTagNode->value;

$parameterName = '$' . ltrim($parameterName, '$');

// process invalid tag values
if ($paramTagValueNode instanceof InvalidTagValueNode) {
if ($paramTagValueNode->value === $parameterName) {
$this->removeTagFromPhpDocNode($phpDocNode, $phpDocTagNode);
}
// process normal tag
} elseif ($paramTagValueNode->parameterName === $parameterName) {
$this->removeTagFromPhpDocNode($phpDocNode, $phpDocTagNode);
}
}
}

/**
* @param PhpDocTagNode|PhpDocTagValueNode $phpDocTagOrPhpDocTagValueNode
*/
Expand Down
137 changes: 137 additions & 0 deletions packages/NodeTypeResolver/src/StaticTypeMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?php declare(strict_types=1);

namespace Rector\NodeTypeResolver;

use PhpParser\Node;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\NullableType;
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\Type\ArrayType;
use PHPStan\Type\BooleanType;
use PHPStan\Type\FloatType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use Rector\BetterPhpDocParser\Attributes\Ast\PhpDoc\Type\AttributeAwareUnionTypeNode;
use Rector\Exception\NotImplementedException;
use Rector\Exception\ShouldNotHappenException;
use Rector\Php\PhpVersionProvider;

/**
* Inspired by @see StaticTypeToStringResolver
*/
final class StaticTypeMapper
{
/**
* @var string
*/
private const PHP_VERSION_SCALAR_TYPES = '7.0';

/**
* @var PhpVersionProvider
*/
private $phpVersionProvider;

public function __construct(PhpVersionProvider $phpVersionProvider)
{
$this->phpVersionProvider = $phpVersionProvider;
}

public function mapPHPStanTypeToPHPStanPhpDocTypeNode(Type $currentPHPStanType): ?TypeNode
{
if ($currentPHPStanType instanceof UnionType) {
$unionTypesNodes = [];
foreach ($currentPHPStanType->getTypes() as $unionedType) {
$unionTypesNodes[] = $this->mapPHPStanTypeToPHPStanPhpDocTypeNode($unionedType);
}

return new AttributeAwareUnionTypeNode($unionTypesNodes);
}

if ($currentPHPStanType instanceof ArrayType) {
$itemTypeNode = $this->mapPHPStanTypeToPHPStanPhpDocTypeNode($currentPHPStanType->getItemType());
if ($itemTypeNode === null) {
throw new ShouldNotHappenException();
}

return new ArrayTypeNode($itemTypeNode);
}

if ($currentPHPStanType instanceof IntegerType) {
return new IdentifierTypeNode('int');
}

if ($currentPHPStanType instanceof StringType) {
return new IdentifierTypeNode('string');
}

if ($currentPHPStanType instanceof FloatType) {
return new IdentifierTypeNode('float');
}

throw new NotImplementedException(__METHOD__ . ' for ' . get_class($currentPHPStanType));
}

/**
* @return Identifier|Name|NullableType|null
*/
public function mapPHPStanTypeToPhpParserNode(Type $currentPHPStanType): ?Node
{
if ($currentPHPStanType instanceof IntegerType) {
if ($this->phpVersionProvider->isAtLeast(self::PHP_VERSION_SCALAR_TYPES)) {
return new Identifier('int');
}

return null;
}

if ($currentPHPStanType instanceof StringType) {
if ($this->phpVersionProvider->isAtLeast(self::PHP_VERSION_SCALAR_TYPES)) {
return new Identifier('string');
}

return null;
}

if ($currentPHPStanType instanceof BooleanType) {
if ($this->phpVersionProvider->isAtLeast(self::PHP_VERSION_SCALAR_TYPES)) {
return new Identifier('bool');
}

return null;
}

if ($currentPHPStanType instanceof FloatType) {
if ($this->phpVersionProvider->isAtLeast(self::PHP_VERSION_SCALAR_TYPES)) {
return new Identifier('float');
}

return null;
}

if ($currentPHPStanType instanceof ArrayType) {
return new Identifier('array');
}

if ($currentPHPStanType instanceof ObjectType) {
return new FullyQualified($currentPHPStanType->getClassName());
}

if ($currentPHPStanType instanceof UnionType) {
return null;
}

if ($currentPHPStanType instanceof MixedType) {
return null;
}

throw new NotImplementedException(__METHOD__ . ' for ' . get_class($currentPHPStanType));
}
}
15 changes: 15 additions & 0 deletions packages/NodeTypeResolver/src/StaticTypeToStringResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ function (ObjectType $objectType): array {
$this->resolversByArgumentType = $callableCollectorPopulator->populate($resolvers);
}

/**
* @param Type[] $staticTypes
* @return string[]
*/
public function resolveTypes(array $staticTypes): array
{
$typesAsStrings = [];
foreach ($staticTypes as $staticType) {
$currentTypesAsStrings = $this->resolveObjectType($staticType);
$typesAsStrings = array_merge($typesAsStrings, $currentTypesAsStrings);
}

return array_unique($typesAsStrings);
}

/**
* @return string[]
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,30 +56,6 @@ public function provideDataForRemoveTagByName(): Iterator
yield [__DIR__ . '/RemoveSource/before.txt', '', '@var'];
}

/**
* @dataProvider provideDataForRemoveParamTagByParameter()
*/
public function testRemoveParamTagByParameter(
string $phpDocBeforeFilePath,
string $phpDocAfterFilePath,
string $parameterName
): void {
$phpDocInfo = $this->createPhpDocInfoFromFile($phpDocBeforeFilePath);

$this->docBlockManipulator->removeParamTagByParameter($phpDocInfo, $parameterName);

$this->assertStringEqualsFile(
$phpDocAfterFilePath,
$this->phpDocInfoPrinter->printFormatPreserving($phpDocInfo)
);
}

public function provideDataForRemoveParamTagByParameter(): Iterator
{
yield [__DIR__ . '/RemoveSource/before3.txt', __DIR__ . '/RemoveSource/after3.txt', 'paramName'];
yield [__DIR__ . '/RemoveSource/before3.txt', __DIR__ . '/RemoveSource/after3.txt', '$paramName'];
}

private function createPhpDocInfoFromFile(string $phpDocBeforeFilePath): PhpDocInfo
{
$phpDocBefore = FileSystem::read($phpDocBeforeFilePath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,6 @@ public function testHasAnnotation(): void
$this->assertFalse($this->docBlockManipulator->hasTag($node, 'var'));
}

public function testRemoveAnnotationFromNode(): void
{
$node = $this->createNodeWithDoc('@param ParamType $paramName');

$this->assertNotSame('', $node->getDocComment()->getText());

$this->docBlockManipulator->removeTagFromNode($node, 'param');
$this->assertNull($node->getDocComment());

$initDoc = <<<'CODE_SAMPLE'
* @param ParamType $paramName
* @param AnotherValue $anotherValue
CODE_SAMPLE;
$node = $this->createNodeWithDoc($initDoc);

$this->docBlockManipulator->removeParamTagByName($node, 'paramName');

$expectedDoc = <<<'CODE_SAMPLE'
/**
* @param AnotherValue $anotherValue
*/
CODE_SAMPLE;
$this->assertSame($expectedDoc, $node->getDocComment()->getText());
}

private function createNodeWithDoc(string $doc): String_
{
$node = new String_('string');
Expand Down
2 changes: 1 addition & 1 deletion packages/PHPUnit/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ services:

Rector\PHPUnit\:
resource: '../src'
exclude: '../src/{Rector/**/*Rector.php}'
exclude: '../src/{Rector/**/*Rector.php,ValueObject/*}'
Loading