mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-24 11:44:14 +01:00
Merge pull request #2850 from rectorphp/phpstan-rector-rule
[PHPStan] Add KeepRectorNamespaceForRectorRule
This commit is contained in:
commit
71a855f29d
1
.gitignore
vendored
1
.gitignore
vendored
@ -13,7 +13,6 @@ create-rector.yaml
|
||||
|
||||
# tests - travis
|
||||
/laravel-dir
|
||||
/utils
|
||||
|
||||
# compiler
|
||||
/compiler/composer.lock
|
||||
|
@ -143,7 +143,8 @@
|
||||
"Rector\\NetteToSymfony\\Tests\\": "rules/nette-to-symfony/tests",
|
||||
"Rector\\Nette\\Tests\\": "packages/nette/tests",
|
||||
"Rector\\NodeTypeResolver\\Tests\\": "packages/node-type-resolver/tests",
|
||||
"Rector\\PHPStanExtensions\\": "utils/PHPStanExtensions/src",
|
||||
"Rector\\PHPStanExtensions\\": "utils/phpstan-extensions/src",
|
||||
"Rector\\PHPStanExtensions\\Tests\\": "utils/phpstan-extensions/tests",
|
||||
"Rector\\PHPStan\\Tests\\": "rules/phpstan/tests",
|
||||
"Rector\\PHPUnitSymfony\\Tests\\": "rules/phpunit-symfony/tests",
|
||||
"Rector\\PHPUnit\\Tests\\": "rules/phpunit/tests",
|
||||
@ -178,9 +179,9 @@
|
||||
"Rector\\DynamicTypeAnalysis\\Tests\\": "packages/dynamic-type-analysis/tests",
|
||||
"Rector\\PhpDeglobalize\\Tests\\": "rules/php-deglobalize/tests",
|
||||
"Rector\\Phalcon\\Tests\\": "rules/phalcon/tests",
|
||||
"Rector\\Utils\\DocumentationGenerator\\": "utils/DocumentationGenerator/src",
|
||||
"Rector\\Utils\\PHPStanAttributeTypeSyncer\\": "utils/PHPStanAttributeTypeSyncer/src",
|
||||
"Rector\\Utils\\PHPStanStaticTypeMapperChecker\\": "utils/PHPStanStaticTypeMapperChecker/src",
|
||||
"Rector\\Utils\\DocumentationGenerator\\": "utils/documentation-generator/src",
|
||||
"Rector\\Utils\\PHPStanAttributeTypeSyncer\\": "utils/phpstan-attribute-type-syncer/src",
|
||||
"Rector\\Utils\\PHPStanStaticTypeMapperChecker\\": "utils/phpstan-static-type-mapper-checker/src",
|
||||
"Rector\\DoctrineGedmoToKnplabs\\Tests\\": "rules/doctrine-gedmo-to-knplabs/tests",
|
||||
"Rector\\MinimalScope\\Tests\\": "rules/minimal-scope/tests",
|
||||
"Rector\\Polyfill\\Tests\\": "packages/polyfill/tests",
|
||||
|
@ -17,9 +17,6 @@ services:
|
||||
- '../src/ValueObject/*'
|
||||
- '../src/functions/*'
|
||||
|
||||
# extra services
|
||||
Rector\Symfony\Rector\Form\Helper\FormTypeStringToTypeProvider: null
|
||||
|
||||
Symfony\Component\Console\Application:
|
||||
alias: 'Rector\Core\Console\Application'
|
||||
|
||||
|
2
ecs.yaml
2
ecs.yaml
@ -93,7 +93,7 @@ parameters:
|
||||
- "rules/coding-style/src/Rector/ClassMethod/NewlineBeforeNewAssignSetRector.php"
|
||||
|
||||
# per node logic
|
||||
- 'utils/DocumentationGenerator/src/Command/DumpNodesCommand.php'
|
||||
- 'utils/documentation-generator/src/Command/DumpNodesCommand.php'
|
||||
# copied 3rd party logic
|
||||
- 'rules/php-70/src/EregToPcreTransformer.php'
|
||||
# dev
|
||||
|
@ -1,5 +1,5 @@
|
||||
includes:
|
||||
- 'utils/PHPStanExtensions/config/phpstan-extensions.neon'
|
||||
- 'utils/phpstan-extensions/config/phpstan-extensions.neon'
|
||||
- 'vendor/symplify/phpstan-extensions/config/config.neon'
|
||||
- 'vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon'
|
||||
- 'vendor/phpstan/phpstan/conf/bleedingEdge.neon'
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Symfony\Rector\Form\Helper;
|
||||
namespace Rector\Symfony\FormHelper;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
|
@ -10,7 +10,7 @@ use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\Symfony\Rector\Form\Helper\FormTypeStringToTypeProvider;
|
||||
use Rector\Symfony\FormHelper\FormTypeStringToTypeProvider;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\AbstractTypeExtension;
|
||||
|
||||
|
@ -10,7 +10,7 @@ use PhpParser\Node\Scalar\String_;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\Symfony\Rector\Form\Helper\FormTypeStringToTypeProvider;
|
||||
use Rector\Symfony\FormHelper\FormTypeStringToTypeProvider;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
/**
|
||||
|
@ -6,7 +6,7 @@ sonar.projectKey=rectorphp_rector
|
||||
# wildcards don't work :(
|
||||
sonar.sources=compiler/src,src,rules/autodiscovery/src,rules/architecture/src,packages/attribute-aware-php-doc/src,packages/better-php-doc-parser/src,rules/cakephp/src,rules/celebrity/src,rules/code-quality/src,rules/coding-style/src,packages/console-differ/src,rules/dead-code/src,rules/doctrine/src,rules/doctrine-code-quality/src,rules/framework-migration/src,packages/file-system-rector/src,rules/elastic-search-dsl/src,rules/guzzle/src,rules/laravel/src,packages/legacy/src,rules/mysql-to-mysqli/src,rules/nette-tester-to-phpunit/src,rules/nette-to-symfony/src,packages/nette/src,packages/node-collector/src,packages/node-type-resolver/src,packages/node-name-resolver/src,rules/phpstan/src,packages/phpstan-static-type-mapper/src,rules/phpunit-symfony/src,rules/phpunit/src,rules/psr4/src,rules/php-spec-to-phpunit/src,rules/php-52/src,rules/php-53/src,rules/php-54/src,rules/php-55/src,rules/php-56/src,rules/php-70/src,rules/php-71/src,rules/php-72/src,rules/php-73/src,rules/php-74/src,rules/php-80/src,rules/removing-static/src,rules/renaming/src,rules/restoration/src,packages/refactoring/src,rules/solid/src,rules/sensio/src,rules/shopware/src,rules/silverstripe/src,packages/static-type-mapper/src,rules/sylius/src,rules/symfony-code-quality/src,rules/symfony-phpunit/src,rules/symfony/src,rules/twig/src,rules/type-declaration/src,packages/vendor-locker/src,rules/zend-to-symfony/src,packages/rector-generator/src,rules/strict-code-quality/src,packages/dynamic-type-analysis/src,rules/php-deglobalize/src,rules/phalcon/src,rules/doctrine-gedmo-to-knplabs/src,rules/minimal-scope/src,packages/polyfill/src,rules/cakephp-to-symfony/src
|
||||
|
||||
sonar.tests=tests,rules/autodiscovery/tests,rules/architecture/tests,packages/better-php-doc-parser/tests,rules/cakephp/tests,rules/celebrity/tests,rules/code-quality/tests,rules/coding-style/tests,rules/dead-code/tests,rules/doctrine/tests,rules/doctrine-code-quality/tests,rules/elastic-search-dsl/tests,rules/guzzle/tests,rules/laravel/tests,packages/legacy/tests,rules/mysql-to-mysqli/tests,rules/nette-tester-to-phpunit/tests,rules/nette-to-symfony/tests,packages/nette/tests,packages/node-type-resolver/tests,utils/PHPStanExtensions/src,rules/phpstan/tests,rules/phpunit-symfony/tests,rules/phpunit/tests,rules/psr4/tests,rules/php-spec-to-phpunit/tests,rules/php-52/tests,rules/php-53/tests,rules/php-54/tests,rules/php-55/tests,rules/php-56/tests,rules/php-70/tests,rules/php-71/tests,rules/php-72/tests,rules/php-73/tests,rules/php-74/tests,rules/php-80/tests,rules/removing-static/tests,rules/renaming/tests,rules/restoration/tests,rules/solid/tests,rules/sensio/tests,rules/shopware/tests,rules/silverstripe/tests,rules/sylius/tests,rules/symfony-code-quality/tests,rules/symfony-phpunit/tests,rules/symfony/tests,rules/twig/tests,rules/type-declaration/tests,rules/zend-to-symfony/tests,rules/strict-code-quality/tests,packages/dynamic-type-analysis/tests,rules/php-deglobalize/tests,rules/phalcon/tests,utils/DocumentationGenerator/src,utils/PHPStanAttributeTypeSyncer/src,utils/PHPStanStaticTypeMapperChecker/src,rules/doctrine-gedmo-to-knplabs/tests,rules/minimal-scope/tests,packages/polyfill/tests,rules/cakephp-to-symfony/tests
|
||||
sonar.tests=tests,rules/autodiscovery/tests,rules/architecture/tests,packages/better-php-doc-parser/tests,rules/cakephp/tests,rules/celebrity/tests,rules/code-quality/tests,rules/coding-style/tests,rules/dead-code/tests,rules/doctrine/tests,rules/doctrine-code-quality/tests,rules/elastic-search-dsl/tests,rules/guzzle/tests,rules/laravel/tests,packages/legacy/tests,rules/mysql-to-mysqli/tests,rules/nette-tester-to-phpunit/tests,rules/nette-to-symfony/tests,packages/nette/tests,packages/node-type-resolver/tests,utils/phpstan-extensions/src,rules/phpstan/tests,rules/phpunit-symfony/tests,rules/phpunit/tests,rules/psr4/tests,rules/php-spec-to-phpunit/tests,rules/php-52/tests,rules/php-53/tests,rules/php-54/tests,rules/php-55/tests,rules/php-56/tests,rules/php-70/tests,rules/php-71/tests,rules/php-72/tests,rules/php-73/tests,rules/php-74/tests,rules/php-80/tests,rules/removing-static/tests,rules/renaming/tests,rules/restoration/tests,rules/solid/tests,rules/sensio/tests,rules/shopware/tests,rules/silverstripe/tests,rules/sylius/tests,rules/symfony-code-quality/tests,rules/symfony-phpunit/tests,rules/symfony/tests,rules/twig/tests,rules/type-declaration/tests,rules/zend-to-symfony/tests,rules/strict-code-quality/tests,packages/dynamic-type-analysis/tests,rules/php-deglobalize/tests,rules/phalcon/tests,utils/documentation-generator/src,utils/phpstan-attribute-type-syncer/src,utils/phpstan-static-type-mapper-checker/src,rules/doctrine-gedmo-to-knplabs/tests,rules/minimal-scope/tests,packages/polyfill/tests,rules/cakephp-to-symfony/tests
|
||||
|
||||
# see https://docs.sonarqube.org/latest/project-administration/narrowing-the-focus/#NarrowingtheFocus-patterns
|
||||
sonar.exclusions=src/**/*.php.inc,rules/**/*.php.inc,packages/**/*.php.inc,packages/**/Fixture/**/*,rules/**/Fixture/**/*,tests/**/Source/**/*
|
||||
|
@ -10,7 +10,7 @@ use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\PhpParser\NodeTraverser\RectorNodeTraverser;
|
||||
use Rector\Core\PhpParser\Parser\Parser;
|
||||
use Rector\Core\PhpParser\Printer\FormatPerservingPrinter;
|
||||
use Rector\Core\Rector\AffectedFilesCollector;
|
||||
use Rector\Core\Report\AffectedFilesCollector;
|
||||
use Rector\Core\Stubs\StubLoader;
|
||||
use Rector\NodeTypeResolver\FileSystem\CurrentFileInfoProvider;
|
||||
use Rector\NodeTypeResolver\NodeScopeAndMetadataDecorator;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\Configuration\Rector\Architecture\DependencyInjection;
|
||||
namespace Rector\Core\Configuration\Collector;
|
||||
|
||||
use PHPStan\Type\Type;
|
||||
|
@ -12,7 +12,7 @@ use PhpParser\NodeTraverser;
|
||||
use Rector\Core\Contract\PhpParser\Node\CommanderInterface;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\PhpParser\Node\NodeVisitorFactory\NodeRemovingNodeVisitorFactory;
|
||||
use Rector\Core\Rector\AffectedFilesCollector;
|
||||
use Rector\Core\Report\AffectedFilesCollector;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
|
@ -10,7 +10,7 @@ use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Configuration\Rector\Architecture\DependencyInjection\VariablesToPropertyFetchCollection;
|
||||
use Rector\Core\Configuration\Collector\VariablesToPropertyFetchCollection;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
@ -9,7 +9,7 @@ use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Configuration\Rector\Architecture\DependencyInjection\VariablesToPropertyFetchCollection;
|
||||
use Rector\Core\Configuration\Collector\VariablesToPropertyFetchCollection;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\Rector;
|
||||
namespace Rector\Core\Report;
|
||||
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
@ -1,5 +1,6 @@
|
||||
services:
|
||||
- { class: Rector\PHPStanExtensions\Rule\ClassMethod\PreventParentMethodVisibilityOverrideRule, tags: [phpstan.rules.rule] }
|
||||
- { class: Rector\PHPStanExtensions\Rule\ClassLike\KeepRectorNamespaceForRectorRule, tags: [phpstan.rules.rule] }
|
||||
|
||||
- Rector\PHPStanExtensions\Utils\PHPStanValueResolver
|
||||
|
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PHPStanExtensions\Rule\ClassLike;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Rules\Rule;
|
||||
use PHPStan\Rules\RuleError;
|
||||
use PHPStan\Rules\RuleErrorBuilder;
|
||||
|
||||
final class KeepRectorNamespaceForRectorRule implements Rule
|
||||
{
|
||||
public function getNodeType(): string
|
||||
{
|
||||
return ClassLike::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassLike $node
|
||||
* @return RuleError[]
|
||||
*/
|
||||
public function processNode(Node $node, Scope $scope): array
|
||||
{
|
||||
if ($this->shouldSkip($node, $scope)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/** @var string $classLikeName */
|
||||
$classLikeName = $node->name->toString();
|
||||
|
||||
$ruleError = $this->createRuleError($node, $scope, $classLikeName);
|
||||
|
||||
return [$ruleError];
|
||||
}
|
||||
|
||||
private function shouldSkip(Node $node, Scope $scope): bool
|
||||
{
|
||||
$namespace = $scope->getNamespace();
|
||||
if ($namespace === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// skip interface and tests
|
||||
if (Strings::match($namespace, '#\\\\(Contract|Exception|Tests)\\\\#')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (! Strings::endsWith($namespace, '\\Rector') && ! Strings::match($namespace, '#\\\\Rector\\\\#')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$name = $node->name;
|
||||
if ($name === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// correct name
|
||||
$classLikeName = $name->toString();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
@ -9,8 +9,8 @@ use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Rules\Rule;
|
||||
use PHPStan\Rules\RuleError;
|
||||
use PHPStan\Rules\RuleErrors\RuleErrorWithMessageAndLineAndFile;
|
||||
use Rector\Exception\NotImplementedException;
|
||||
use PHPStan\Rules\RuleErrorBuilder;
|
||||
use Rector\Core\Exception\NotImplementedException;
|
||||
use ReflectionMethod;
|
||||
|
||||
final class PreventParentMethodVisibilityOverrideRule implements Rule
|
||||
@ -49,16 +49,7 @@ final class PreventParentMethodVisibilityOverrideRule implements Rule
|
||||
|
||||
$methodVisibility = $this->resolveReflectionMethodVisibilityAsStrings($parentReflectionMethod);
|
||||
|
||||
$ruleError = new RuleErrorWithMessageAndLineAndFile(
|
||||
sprintf(
|
||||
'Change "%s()" method visibility to "%s" to respect parent method visibility.',
|
||||
$methodName,
|
||||
$methodVisibility
|
||||
),
|
||||
$node->getLine(),
|
||||
$scope->getFile()
|
||||
);
|
||||
|
||||
$ruleError = $this->createRuleError($node, $scope, $methodName, $methodVisibility);
|
||||
return [$ruleError];
|
||||
}
|
||||
|
||||
@ -100,4 +91,19 @@ final class PreventParentMethodVisibilityOverrideRule implements Rule
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PHPStanExtensions\Tests\Rule\ClassLike;
|
||||
|
||||
use Iterator;
|
||||
use PHPStan\Rules\Rule;
|
||||
use PHPStan\Testing\RuleTestCase;
|
||||
use Rector\PHPStanExtensions\Rule\ClassLike\KeepRectorNamespaceForRectorRule;
|
||||
|
||||
final class KeepRectorNamespaceForRectorRuleTest extends RuleTestCase
|
||||
{
|
||||
/**
|
||||
* @param array<string|int> $expectedErrorsWithLines
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function testRule(string $filePath, array $expectedErrorsWithLines): void
|
||||
{
|
||||
$this->analyse([$filePath], [$expectedErrorsWithLines]);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
yield [__DIR__ . '/Source/Rector/ClassInCorrectNamespaceRector.php', []];
|
||||
yield [
|
||||
__DIR__ . '/Source/Rector/WrongClass.php',
|
||||
['Change namespace for "WrongClass". It cannot be in Rector namespace, unless Rector rule.', 8],
|
||||
];
|
||||
}
|
||||
|
||||
protected function getRule(): Rule
|
||||
{
|
||||
return new KeepRectorNamespaceForRectorRule();
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PHPStanExtensions\Tests\Rule\ClassLike\Source\Rector;
|
||||
|
||||
final class ClassInCorrectNamespaceRector
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Rector\PHPStanExtensions\Tests\Rule\ClassLike\Source\Rector;
|
||||
|
||||
final class WrongClass
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PHPStanExtensions\Tests\Rule\ClassMethod;
|
||||
|
||||
use PHPStan\Rules\Rule;
|
||||
use PHPStan\Testing\RuleTestCase;
|
||||
use Rector\PHPStanExtensions\Rule\ClassMethod\PreventParentMethodVisibilityOverrideRule;
|
||||
|
||||
final class PreventParentMethodVisibilityOverrideRuleTest extends RuleTestCase
|
||||
{
|
||||
public function testRule(): void
|
||||
{
|
||||
$this->analyse(
|
||||
[__DIR__ . '/Source/ClassWithOverridingVisibility.php'],
|
||||
[['Change "run()" method visibility to "protected" to respect parent method visibility.', 10]]
|
||||
);
|
||||
}
|
||||
|
||||
protected function getRule(): Rule
|
||||
{
|
||||
return new PreventParentMethodVisibilityOverrideRule();
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Rector\PHPStanExtensions\Tests\Rule\ClassMethod\Source;
|
||||
|
||||
final class ClassWithOverridingVisibility extends GoodVisibility
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
abstract class GoodVisibility
|
||||
{
|
||||
protected function run()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user