Skip to content

Commit

Permalink
[TypePerfect] Skip self on NarrowPublicClassMethodParamTypeRule (#5)
Browse files Browse the repository at this point in the history
* Added failling test

* [TypePerfect] Skip self on NarrowPublicClassMethodParamTypeRule

---------

Co-authored-by: Markus Staab <[email protected]>
  • Loading branch information
samsonasik and clxmstaab authored Jun 14, 2024
1 parent d6301ad commit 801399b
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public function processNode(Node $node, Scope $scope): ?array
return null;
}

$printedParamTypesString = $this->collectorMetadataPrinter->printParamTypesToString($node);
$printedParamTypesString = $this->collectorMetadataPrinter->printParamTypesToString($node, $classReflection->getName());
return [$classReflection->getName(), $methodName, $printedParamTypesString, $node->getLine()];
}
}
28 changes: 24 additions & 4 deletions src/Printer/CollectorMetadataPrinter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

namespace Rector\TypePerfect\Printer;

use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Identifier;
use PhpParser\Node\IntersectionType as NodeIntersectionType;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\UnionType;
Expand Down Expand Up @@ -65,7 +68,7 @@ public function printArgTypesAsString(MethodCall $methodCall, Scope $scope): str
return implode('|', $stringArgTypes);
}

public function printParamTypesToString(ClassMethod $classMethod): string
public function printParamTypesToString(ClassMethod $classMethod, ?string $className): string
{
$printedParamTypes = [];
foreach ($classMethod->params as $param) {
Expand All @@ -74,14 +77,14 @@ public function printParamTypesToString(ClassMethod $classMethod): string
continue;
}

$paramType = $param->type;
$paramType = $this->transformSelfToClassName($param->type, $className);
if ($paramType instanceof NullableType) {
// unite to phpstan type
$paramType = new UnionType([$paramType->type, new Identifier('null')]);
}

if ($paramType instanceof UnionType) {
$paramType = $this->resolveSortedUnionType($paramType);
$paramType = $this->resolveSortedUnionType($paramType, $className);
}

$printedParamType = $this->printerStandard->prettyPrint([$paramType]);
Expand All @@ -94,19 +97,36 @@ public function printParamTypesToString(ClassMethod $classMethod): string
return implode('|', $printedParamTypes);
}

private function resolveSortedUnionType(UnionType $unionType): UnionType
private function transformSelfToClassName(Node $node, ?string $className): Node
{
if (! $node instanceof Name || $className === null) {
return $node;
}

if ($node->toString() !== 'self') {
return $node;
}

return new FullyQualified($className);
}

private function resolveSortedUnionType(UnionType $unionType, ?string $className): UnionType
{
$typeNames = [];

foreach ($unionType->types as $type) {
if ($type instanceof NodeIntersectionType) {
foreach ($type->types as $intersectionType) {
/** @var FullyQualified $intersectionType */
$intersectionType = $this->transformSelfToClassName($intersectionType, $className);
$typeNames[] = (string) $intersectionType;
}

continue;
}

/** @var FullyQualified $type */
$type = $this->transformSelfToClassName($type, $className);
$typeNames[] = (string) $type;
}

Expand Down
6 changes: 3 additions & 3 deletions src/Rules/NarrowPublicClassMethodParamTypeRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ private function resolveUniqueArgTypesString(
private function flattenCollectedData(array $methodCallablesByFilePath): array
{
$methodFirstClassCallables = [];
foreach ($methodCallablesByFilePath as $collectedData) {
foreach ($collectedData as $collectedItem) {
$methodFirstClassCallables[] = $collectedItem[0];
foreach ($methodCallablesByFilePath as $methodCallables) {
foreach ($methodCallables as $methodCallable) {
$methodFirstClassCallables[] = $methodCallable[0];
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Rector\TypePerfect\Tests\Rules\NarrowPublicClassMethodParamTypeRule\Fixture;

class SkipSelf {
public function takesSelf(self $code): bool
{
return true;
}

static public function run(SkipSelf $self): void
{
$self->takesSelf(new SkipSelf());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ public static function provideData(): Iterator
__DIR__ . '/Fixture/ThisPassedFromInterface.php',
__DIR__ . '/Source/ExpectedThisType/CallByThisFromInterface.php',
], [[$argErrorMessage, 11]]];

yield [[
__DIR__ . '/Fixture/SkipSelf.php',
], []];
}

/**
Expand Down

0 comments on commit 801399b

Please sign in to comment.