Skip to content

Commit

Permalink
[DX] Add RectorAssert to warn about invalid class names (#1339)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Nov 29, 2021
1 parent 50bbdd1 commit 23679ac
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 0 deletions.
10 changes: 10 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -597,3 +597,13 @@ parameters:
-
message: '#Instanceof between PhpParser\\Node\\Expr\\BinaryOp\\BooleanAnd and PhpParser\\Node\\Expr\\BinaryOp will always evaluate to true#'
path: packages/NodeCollector/NodeAnalyzer/BooleanAndAnalyzer.php

# respect webmozzart naming convention to make eaiser to discovery
-
message: '#Method name should be different to its parameter name, in a verb form#'
path: src/Validation/RectorAssert.php

-
message: '#Class has a static method must so must contains "Static" in its name#'
path: src/Validation/RectorAssert.php

Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
namespace Rector\CodingStyle\ValueObject;

use PHPStan\Type\ObjectType;
use Rector\Core\Validation\RectorAssert;

final class ReturnArrayClassMethodToYield
{
public function __construct(
private string $type,
private string $method
) {
RectorAssert::className($type);
}

public function getObjectType(): ObjectType
Expand Down
2 changes: 2 additions & 0 deletions rules/DeadCode/ValueObject/VariableNodeUse.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PhpParser\Node;
use PhpParser\Node\Expr\Variable;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Validation\RectorAssert;
use Rector\NodeTypeResolver\Node\AttributeKey;

final class VariableNodeUse
Expand All @@ -28,6 +29,7 @@ public function __construct(
private Variable $variable,
private ?string $nestingHash = null
) {
RectorAssert::className($type);
}

public function isName(string $name): bool
Expand Down
2 changes: 2 additions & 0 deletions rules/Renaming/ValueObject/RenameAnnotation.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Rector\Renaming\ValueObject;

use PHPStan\Type\ObjectType;
use Rector\Core\Validation\RectorAssert;

final class RenameAnnotation
{
Expand All @@ -13,6 +14,7 @@ public function __construct(
private string $oldAnnotation,
private string $newAnnotation
) {
RectorAssert::className($type);
}

public function getObjectType(): ObjectType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Rector\Transform\ValueObject;

use PHPStan\Type\ObjectType;
use Rector\Core\Validation\RectorAssert;

final class MethodCallToAnotherMethodCallWithArguments
{
Expand All @@ -17,6 +18,7 @@ public function __construct(
private string $newMethod,
private array $newArguments
) {
RectorAssert::className($type);
}

public function getObjectType(): ObjectType
Expand Down
4 changes: 4 additions & 0 deletions rules/Transform/ValueObject/MethodCallToMethodCall.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Rector\Transform\ValueObject;

use Rector\Core\Validation\RectorAssert;

final class MethodCallToMethodCall
{
/**
Expand All @@ -16,6 +18,8 @@ public function __construct(
private string $newType,
private string $newMethod,
) {
RectorAssert::className($oldType);
RectorAssert::className($newType);
}

public function getOldType(): string
Expand Down
2 changes: 2 additions & 0 deletions rules/Transform/ValueObject/PropertyFetchToMethodCall.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Rector\Transform\ValueObject;

use PHPStan\Type\ObjectType;
use Rector\Core\Validation\RectorAssert;

final class PropertyFetchToMethodCall
{
Expand All @@ -18,6 +19,7 @@ public function __construct(
private ?string $newSetMethod = null,
private array $newGetArguments = []
) {
RectorAssert::className($oldType);
}

public function getOldObjectType(): ObjectType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Rector\Transform\ValueObject;

use PHPStan\Type\ObjectType;
use Rector\Core\Validation\RectorAssert;

final class ServiceGetterToConstructorInjection
{
Expand All @@ -13,6 +14,8 @@ public function __construct(
private string $oldMethod,
private string $serviceType
) {
RectorAssert::className($oldType);
RectorAssert::className($serviceType);
}

public function getOldObjectType(): ObjectType
Expand Down
2 changes: 2 additions & 0 deletions rules/TypeDeclaration/ValueObject/AddParamTypeDeclaration.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use Rector\Core\Validation\RectorAssert;

final class AddParamTypeDeclaration
{
Expand All @@ -15,6 +16,7 @@ public function __construct(
private int $position,
private Type $paramType
) {
RectorAssert::className($className);
}

public function getObjectType(): ObjectType
Expand Down
34 changes: 34 additions & 0 deletions src/Validation/RectorAssert.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Rector\Core\Validation;

use Rector\Core\Util\StringUtils;
use Webmozart\Assert\InvalidArgumentException;

/**
* @see \Rector\Core\Tests\Validation\RectorAssertTest
*/
final class RectorAssert
{
/**
* @see https://stackoverflow.com/a/12011255/1348344
* @see https://regex101.com/r/PYQaPF/1
* @var string
*/
public const CLASS_NAME_REGEX = '#^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*$#';
/**
* Assert value is valid class name
*/
public static function className(string $className): void
{
if (StringUtils::isMatch($className, self::CLASS_NAME_REGEX)) {
return;
}
$errorMessage = $className . ' is not a valid class name';
throw new InvalidArgumentException($errorMessage);
}
}
52 changes: 52 additions & 0 deletions tests/Validation/RectorAssertTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace Rector\Core\Tests\Validation;

use Iterator;
use PHPUnit\Framework\TestCase;
use Rector\Core\Validation\RectorAssert;
use Webmozart\Assert\InvalidArgumentException;

final class RectorAssertTest extends TestCase
{
/**
* @doesNotPerformAssertions
* @dataProvider provideDataValidClassNames()
*/
public function testValidClasNames(string $className): void
{
RectorAssert::className($className);
}

/**
* @dataProvider provideDataInvalidClassNames()
*/
public function testInvalidClasNames(string $className): void
{
$this->expectException(InvalidArgumentException::class);
RectorAssert::className($className);
}

/**
* @return Iterator<string[]>
*/
public function provideDataValidClassNames(): Iterator
{
yield ['App'];
yield ['App\\SomeClass'];
}

/**
* @return Iterator<string[]>
*/
public function provideDataInvalidClassNames(): Iterator
{
yield ['App Some'];
yield ['App$SomeClass'];
yield ['$SomeClass'];
yield ['App\\\\Some'];
yield ['3AppSome'];
}
}

0 comments on commit 23679ac

Please sign in to comment.