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
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,9 @@ It supports all versions of PHP from 5.2 and many open-source projects:

## How to Apply Coding Standards?

The AST libraries that Rector uses aren't well-suited for coding standards, so it's better to let coding standard tools do that.
Rector uses [nikic/php-parser](https://github.com/nikic/PHP-Parser/), that build on technology called *abstract syntax tree*) technology* (AST). AST doesn't care about spaces and produces mall-formatted code. That's why your project needs to have coding standard tool and set of rules, so it can make refactored nice and shiny again.

Don't have a coding standard tool for your project? Consider adding [EasyCodingStandard](https://github.com/Symplify/EasyCodingStandard), [PHP CS Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) or [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer).

*Tip: If you have EasyCodingStandard, you can start your set with [`ecs-after-rector.yaml`](/ecs-after-rector.yaml).*
Don't have any coding standard tool? Add [EasyCodingStandard](https://github.com/Symplify/EasyCodingStandard) and use prepared [`ecs-after-rector.yaml`](/ecs-after-rector.yaml) set.

## Install

Expand Down
5 changes: 5 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,8 @@ parameters:
- '#Class (.*?) should be written with \:\:class notation, string found#'
- '#Parameter \#2 \$key of method Rector\\BetterPhpDocParser\\PhpDocNode\\AbstractTagValueNode\:\:printArrayItem\(\) expects string\|null, int\|string given#'
- '#Method Rector\\Naming\\Naming\\PropertyNaming\:\:resolveShortClassName\(\) should return string but returns string\|null#'

-
message: "#^Class \"Rector\\\\PSR4\\\\Rector\\\\Namespace_\\\\NormalizeNamespaceByPSR4ComposerAutoloadRector\" is missing @see annotation with test case class reference$#"
count: 1
path: rules/psr4/src/Rector/Namespace_/NormalizeNamespaceByPSR4ComposerAutoloadRector.php
1 change: 1 addition & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<directory>rules/*/tests</directory>
<directory>packages/*/tests</directory>
<directory>tests</directory>
<directory>utils/*/tests</directory>
</testsuite>
</testsuites>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\NetteTesterToPHPUnit\AssertManipulator;

/**
* @see \Rector\NetteTesterToPHPUnit\Tests\Rector\Class_\NetteTesterClassToPHPUnitClassRector\NetteTesterPHPUnitRectorTest
*/
final class NetteAssertToPHPUnitAssertRector extends AbstractRector
{
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;

/**
* @see \Rector\Oxid\Tests\Rector\FuncCall\OxidReplaceBackwardsCompatabilityClassRector\OxidReplaceBackwardsCompatabilityClassRectorTest
*/
final class OxidReplaceBackwardsCompatabilityClassRector extends AbstractRector
{
/**
Expand Down
2 changes: 2 additions & 0 deletions rules/php72/src/Rector/Each/ListEachRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

/**
* @source https://wiki.php.net/rfc/deprecations_php_7_2#each
*
* @see \Rector\Php72\Tests\Rector\Each\EachRectorTest
*/
final class ListEachRector extends AbstractRector
{
Expand Down
2 changes: 2 additions & 0 deletions rules/php72/src/Rector/Each/WhileEachToForeachRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

/**
* @source https://wiki.php.net/rfc/deprecations_php_7_2#each
*
* @see \Rector\Php72\Tests\Rector\Each\EachRectorTest
*/
final class WhileEachToForeachRector extends AbstractRector
{
Expand Down
1 change: 1 addition & 0 deletions rules/psr4/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ services:
_defaults:
public: true
autowire: true
autoconfigure: true

Rector\PSR4\:
resource: '../src'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

/**
* @see \Rector\Sensio\Tests\Rector\FrameworkExtraBundle\TemplateAnnotationRector\TemplateAnnotationVersion3RectorTest
* @see \Rector\Sensio\Tests\Rector\FrameworkExtraBundle\TemplateAnnotationRector\TemplateAnnotationVersion5RectorTest
*/
final class TemplateAnnotationRector extends AbstractRector
{
/**
Expand Down Expand Up @@ -139,6 +143,7 @@ private function classHasTemplateAnnotations(Class_ $node): bool

private function getSensioTemplateTagValueNode(ClassMethod $classMethod): ?SensioTemplateTagValueNode
{
/** @var PhpDocInfo|null $phpDocInfo */
$phpDocInfo = $classMethod->getAttribute(AttributeKey::PHP_DOC_INFO);
if ($phpDocInfo === null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\NodeTypeResolver\Node\AttributeKey;

/**
* @see \Rector\Core\Tests\Rector\Architecture\DependencyInjection\ActionInjectionToConstructorInjectionRector\ActionInjectionToConstructorInjectionRectorTest
*/
final class ReplaceVariableByPropertyFetchRector extends AbstractRector
{
/**
Expand Down
13 changes: 11 additions & 2 deletions utils/phpstan-extensions/config/phpstan-extensions.neon
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
services:
- { class: Rector\PHPStanExtensions\Rule\ClassMethod\PreventParentMethodVisibilityOverrideRule, tags: [phpstan.rules.rule] }
- { class: Rector\PHPStanExtensions\Rule\ClassLike\KeepRectorNamespaceForRectorRule, tags: [phpstan.rules.rule] }
-
class: Rector\PHPStanExtensions\Rule\SeeAnnotationToTestRule
tags: [phpstan.rules.rule]

-
class: Rector\PHPStanExtensions\Rule\ClassMethod\PreventParentMethodVisibilityOverrideRule
tags: [phpstan.rules.rule]

-
class: Rector\PHPStanExtensions\Rule\ClassLike\KeepRectorNamespaceForRectorRule
tags: [phpstan.rules.rule]

- Rector\PHPStanExtensions\Utils\PHPStanValueResolver

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,25 @@
use PhpParser\Node\Stmt\ClassLike;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;

/**
* @see \Rector\PHPStanExtensions\Tests\Rule\ClassLike\KeepRectorNamespaceForRectorRuleTest
*/
final class KeepRectorNamespaceForRectorRule implements Rule
{
/**
* @var string
*/
public const ERROR_MESSAGE = 'Change namespace for "%s". It cannot be in "Rector" namespace, unless Rector rule.';

public function getNodeType(): string
{
return ClassLike::class;
}

/**
* @param ClassLike $node
* @return RuleError[]
* @return string[]
*/
public function processNode(Node $node, Scope $scope): array
{
Expand All @@ -32,28 +38,31 @@ public function processNode(Node $node, Scope $scope): array
/** @var string $classLikeName */
$classLikeName = $node->name->toString();

$ruleError = $this->createRuleError($node, $scope, $classLikeName);
$errorMessage = sprintf(self::ERROR_MESSAGE, $classLikeName);

return [$ruleError];
return [$errorMessage];
}

private function shouldSkip(Node $node, Scope $scope): bool
private function shouldSkip(ClassLike $classLike, Scope $scope): bool
{
$namespace = $scope->getNamespace();
if ($namespace === null) {
return true;
}

// skip interface and tests
if (Strings::match($namespace, '#\\\\(Contract|Exception|Tests)\\\\#')) {
// skip interface and tests, except tests here
if (Strings::match($namespace, '#\\\\(Contract|Exception|Tests)\\\\#') && ! Strings::contains(
$namespace,
'PHPStanExtensions'
)) {
return true;
}

if (! Strings::endsWith($namespace, '\\Rector') && ! Strings::match($namespace, '#\\\\Rector\\\\#')) {
return true;
}

$name = $node->name;
$name = $classLike->name;
if ($name === null) {
return true;
}
Expand All @@ -63,18 +72,4 @@ private function shouldSkip(Node $node, Scope $scope): bool

return (bool) Strings::match($classLikeName, '#(Rector|Test|Trait)$#');
}

private function createRuleError(Node $node, Scope $scope, string $classLikeName): RuleError
{
$message = sprintf(
'Change namespace for "%s". It cannot be in "Rector" namespace, unless Rector rule.',
$classLikeName
);

$ruleErrorBuilder = RuleErrorBuilder::message($message);
$ruleErrorBuilder->line($node->getLine());
$ruleErrorBuilder->file($scope->getFile());

return $ruleErrorBuilder->build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,27 @@
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
use Rector\Core\Exception\NotImplementedException;
use ReflectionMethod;

/**
* @see \Rector\PHPStanExtensions\Tests\Rule\ClassMethod\PreventParentMethodVisibilityOverrideRuleTest
*/
final class PreventParentMethodVisibilityOverrideRule implements Rule
{
/**
* @var string
*/
public const ERROR_MESSAGE = 'Change "%s()" method visibility to "%s" to respect parent method visibility.';

public function getNodeType(): string
{
return ClassMethod::class;
}

/**
* @param ClassMethod $node
* @return RuleError[]
* @return string[]
*/
public function processNode(Node $node, Scope $scope): array
{
Expand All @@ -49,8 +55,8 @@ public function processNode(Node $node, Scope $scope): array

$methodVisibility = $this->resolveReflectionMethodVisibilityAsStrings($parentReflectionMethod);

$ruleError = $this->createRuleError($node, $scope, $methodName, $methodVisibility);
return [$ruleError];
$errorMessage = sprintf(self::ERROR_MESSAGE, $methodName, $methodVisibility);
return [$errorMessage];
}

return [];
Expand Down Expand Up @@ -87,19 +93,4 @@ private function resolveReflectionMethodVisibilityAsStrings(ReflectionMethod $re

throw new NotImplementedException();
}

private function createRuleError(Node $node, Scope $scope, string $methodName, string $methodVisibility): RuleError
{
$message = sprintf(
'Change "%s()" method visibility to "%s" to respect parent method visibility.',
$methodName,
$methodVisibility
);

$ruleErrorBuilder = RuleErrorBuilder::message($message);
$ruleErrorBuilder->line($node->getLine());
$ruleErrorBuilder->file($scope->getFile());

return $ruleErrorBuilder->build();
}
}
Loading