From cfec9f87475b0b7e8c1c2e9d07ced4a606c963ec Mon Sep 17 00:00:00 2001 From: Caleb White Date: Tue, 25 Aug 2026 21:30:43 -0500 Subject: [PATCH] Register conditionally enabled rules with attributes Adds the optional enabledBy parameter to RegisteredRule and RegisteredCollector. It accepts a boolean parameter reference and only adds the rule or collector tag when that parameter is enabled. This moves PHPStan's 22 conditionally registered rules out of conditionalTags and service definitions and onto the rule classes. The five conditional restricted-usage extension tags remain in NEON because they are not rules or collectors. Amp-Thread-ID: https://ampcode.com/threads/T-01a19219-8e6c-730d-9b2f-3ac8a4a98fcc --- conf/config.level0.neon | 5 -- conf/config.level1.neon | 8 --- conf/config.level2.neon | 10 ---- conf/config.level4.neon | 57 ------------------ conf/config.level5.neon | 25 -------- conf/config.neon | 29 --------- .../AutowiredAttributeServicesExtension.php | 59 +++++++++++++++++-- .../RegisteredCollector.php | 6 +- src/DependencyInjection/RegisteredRule.php | 6 +- ...wStaticInAbstractClassStaticMethodRule.php | 2 + ...possibleInArrayHaystackFiniteTypesRule.php | 4 ++ src/Rules/Comparison/SwitchConditionRule.php | 4 ++ .../Constants/ValueAssignedToDefineRule.php | 2 + .../ValueAssignedToGlobalConstantRule.php | 2 + src/Rules/DateIntervalInstantiationRule.php | 2 + src/Rules/DeadCode/UnusedVariableRule.php | 2 + .../MethodThrowTypeCovarianceRule.php | 4 ++ ...ngCheckedExceptionInFunctionThrowsRule.php | 2 + ...singCheckedExceptionInMethodThrowsRule.php | 2 + ...eckedExceptionInPropertyHookThrowsRule.php | 2 + .../TooWideFunctionThrowTypeRule.php | 2 + .../Exceptions/TooWideMethodThrowTypeRule.php | 5 ++ .../TooWidePropertyHookThrowTypeRule.php | 4 ++ .../ParameterCastableToNumberRule.php | 2 + .../Functions/PrintfParameterTypeRule.php | 4 ++ src/Rules/Functions/SortWithoutEffectRule.php | 5 ++ .../UnusedFunctionParametersRule.php | 2 + src/Rules/Keywords/UnusedLabelRule.php | 2 + .../Methods/UnusedMethodParametersRule.php | 2 + .../Properties/UninitializedPropertyRule.php | 2 + .../AssignToByRefExprFromForeachRule.php | 2 + 31 files changed, 125 insertions(+), 140 deletions(-) diff --git a/conf/config.level0.neon b/conf/config.level0.neon index 805ea348a91..c6020232152 100644 --- a/conf/config.level0.neon +++ b/conf/config.level0.neon @@ -12,13 +12,8 @@ conditionalTags: phpstan.restrictedClassNameUsageExtension: %featureToggles.internalTag% PHPStan\Rules\InternalTag\RestrictedInternalFunctionUsageExtension: phpstan.restrictedFunctionUsageExtension: %featureToggles.internalTag% - PHPStan\Rules\Classes\NewStaticInAbstractClassStaticMethodRule: - phpstan.rules.rule: %featureToggles.newStaticInAbstractClassStaticMethod% services: - - - class: PHPStan\Rules\Classes\NewStaticInAbstractClassStaticMethodRule - - class: PHPStan\Rules\InternalTag\RestrictedInternalClassConstantUsageExtension diff --git a/conf/config.level1.neon b/conf/config.level1.neon index 70f5a903f8d..9dc4f8bc670 100644 --- a/conf/config.level1.neon +++ b/conf/config.level1.neon @@ -10,11 +10,3 @@ parameters: autowiredAttributeServices: # registers rules with #[RegisteredRule] attribute level: 1 - -conditionalTags: - PHPStan\Rules\Variables\AssignToByRefExprFromForeachRule: - phpstan.rules.rule: %featureToggles.assignToByRefForeachExpr% - -services: - - - class: PHPStan\Rules\Variables\AssignToByRefExprFromForeachRule diff --git a/conf/config.level2.neon b/conf/config.level2.neon index bb615c07c34..dd50138b541 100644 --- a/conf/config.level2.neon +++ b/conf/config.level2.neon @@ -15,10 +15,6 @@ conditionalTags: phpstan.restrictedPropertyUsageExtension: %featureToggles.internalTag% PHPStan\Rules\InternalTag\RestrictedInternalMethodUsageExtension: phpstan.restrictedMethodUsageExtension: %featureToggles.internalTag% - PHPStan\Rules\Constants\ValueAssignedToDefineRule: - phpstan.rules.rule: %featureToggles.checkDynamicConstantNameValues% - PHPStan\Rules\Constants\ValueAssignedToGlobalConstantRule: - phpstan.rules.rule: %featureToggles.checkDynamicConstantNameValues% services: - @@ -26,9 +22,3 @@ services: - class: PHPStan\Rules\InternalTag\RestrictedInternalMethodUsageExtension - - - - class: PHPStan\Rules\Constants\ValueAssignedToDefineRule - - - - class: PHPStan\Rules\Constants\ValueAssignedToGlobalConstantRule diff --git a/conf/config.level4.neon b/conf/config.level4.neon index f437c1e58ff..06cd652606b 100644 --- a/conf/config.level4.neon +++ b/conf/config.level4.neon @@ -5,62 +5,5 @@ autowiredAttributeServices: # registers rules with #[RegisteredRule] and #[RegisteredCollector] attributes level: 4 -conditionalTags: - PHPStan\Rules\Exceptions\TooWideFunctionThrowTypeRule: - phpstan.rules.rule: %exceptions.check.tooWideThrowType% - PHPStan\Rules\Exceptions\TooWideMethodThrowTypeRule: - phpstan.rules.rule: %exceptions.check.tooWideThrowType% - PHPStan\Rules\Exceptions\TooWidePropertyHookThrowTypeRule: - phpstan.rules.rule: %exceptions.check.tooWideThrowType% - PHPStan\Rules\Keywords\UnusedLabelRule: - phpstan.rules.rule: %featureToggles.unusedLabel% - PHPStan\Rules\Comparison\ImpossibleInArrayHaystackFiniteTypesRule: - phpstan.rules.rule: %featureToggles.finiteTypesInHaystack% - PHPStan\Rules\Comparison\SwitchConditionRule: - phpstan.rules.rule: %featureToggles.switchConditionAlwaysFalse% - PHPStan\Rules\DeadCode\UnusedVariableRule: - phpstan.rules.rule: %featureToggles.unusedVariable% - PHPStan\Rules\Functions\UnusedFunctionParametersRule: - phpstan.rules.rule: %featureToggles.unusedParameters% - PHPStan\Rules\Methods\UnusedMethodParametersRule: - phpstan.rules.rule: %featureToggles.unusedParameters% - parameters: checkAdvancedIsset: true - -services: - - - class: PHPStan\Rules\Exceptions\TooWideFunctionThrowTypeRule - - - - class: PHPStan\Rules\Exceptions\TooWideMethodThrowTypeRule - arguments: - checkProtectedAndPublicMethods: %checkTooWideThrowTypesInProtectedAndPublicMethods% - tooWideImplicitThrows: %exceptions.check.tooWideImplicitThrowType% - - - - class: PHPStan\Rules\Exceptions\TooWidePropertyHookThrowTypeRule - arguments: - checkProtectedAndPublicMethods: %checkTooWideThrowTypesInProtectedAndPublicMethods% - - - - class: PHPStan\Rules\Keywords\UnusedLabelRule - - - - class: PHPStan\Rules\Comparison\ImpossibleInArrayHaystackFiniteTypesRule - arguments: - treatPhpDocTypesAsCertain: %treatPhpDocTypesAsCertain% - - - - class: PHPStan\Rules\Comparison\SwitchConditionRule - arguments: - treatPhpDocTypesAsCertain: %treatPhpDocTypesAsCertain% - - - - class: PHPStan\Rules\DeadCode\UnusedVariableRule - - - - class: PHPStan\Rules\Functions\UnusedFunctionParametersRule - - - - class: PHPStan\Rules\Methods\UnusedMethodParametersRule diff --git a/conf/config.level5.neon b/conf/config.level5.neon index aef90f4d9e5..a5719c183ec 100644 --- a/conf/config.level5.neon +++ b/conf/config.level5.neon @@ -5,31 +5,6 @@ parameters: checkFunctionArgumentTypes: true checkArgumentsPassedByReference: true -conditionalTags: - PHPStan\Rules\Functions\ParameterCastableToNumberRule: - phpstan.rules.rule: %featureToggles.checkParameterCastableToNumberFunctions% - PHPStan\Rules\Functions\PrintfParameterTypeRule: - phpstan.rules.rule: %featureToggles.checkPrintfParameterTypes% - PHPStan\Rules\DateIntervalInstantiationRule: - phpstan.rules.rule: %featureToggles.checkDateIntervalConstructor% - PHPStan\Rules\Functions\SortWithoutEffectRule: - phpstan.rules.rule: %featureToggles.sortWithoutEffect% - autowiredAttributeServices: # registers rules with #[RegisteredRule] attribute level: 5 - -services: - - - class: PHPStan\Rules\Functions\ParameterCastableToNumberRule - - - class: PHPStan\Rules\Functions\PrintfParameterTypeRule - arguments: - checkStrictPrintfPlaceholderTypes: %checkStrictPrintfPlaceholderTypes% - - - class: PHPStan\Rules\DateIntervalInstantiationRule - - - class: PHPStan\Rules\Functions\SortWithoutEffectRule - arguments: - treatPhpDocTypesAsCertain: %treatPhpDocTypesAsCertain% - treatPhpDocTypesAsCertainTip: %tips.treatPhpDocTypesAsCertain% diff --git a/conf/config.neon b/conf/config.neon index 0eb6c0c764b..77f2024eed8 100644 --- a/conf/config.neon +++ b/conf/config.neon @@ -271,36 +271,7 @@ parameters: autowiredAttributeServices: level: null -conditionalTags: - PHPStan\Rules\Exceptions\MissingCheckedExceptionInFunctionThrowsRule: - phpstan.rules.rule: %exceptions.check.missingCheckedExceptionInThrows% - PHPStan\Rules\Exceptions\MissingCheckedExceptionInMethodThrowsRule: - phpstan.rules.rule: %exceptions.check.missingCheckedExceptionInThrows% - PHPStan\Rules\Exceptions\MissingCheckedExceptionInPropertyHookThrowsRule: - phpstan.rules.rule: %exceptions.check.missingCheckedExceptionInThrows% - PHPStan\Rules\Properties\UninitializedPropertyRule: - phpstan.rules.rule: %checkUninitializedProperties% - PHPStan\Rules\Exceptions\MethodThrowTypeCovarianceRule: - phpstan.rules.rule: %exceptions.check.throwTypeCovariance% - services: - - - class: PHPStan\Rules\Exceptions\MissingCheckedExceptionInFunctionThrowsRule - - - - class: PHPStan\Rules\Exceptions\MissingCheckedExceptionInMethodThrowsRule - - - - class: PHPStan\Rules\Exceptions\MissingCheckedExceptionInPropertyHookThrowsRule - - - - class: PHPStan\Rules\Properties\UninitializedPropertyRule - - - - class: PHPStan\Rules\Exceptions\MethodThrowTypeCovarianceRule - arguments: - implicitThrows: %exceptions.implicitThrows% - # autowired services are now registered with the help of attributes # like #[PHPStan\DependencyInjection\AutowiredService] or #[PHPStan\DependencyInjection\GenerateFactory] diff --git a/src/DependencyInjection/AutowiredAttributeServicesExtension.php b/src/DependencyInjection/AutowiredAttributeServicesExtension.php index 6f71bd6b86a..40240d85cf7 100644 --- a/src/DependencyInjection/AutowiredAttributeServicesExtension.php +++ b/src/DependencyInjection/AutowiredAttributeServicesExtension.php @@ -27,6 +27,8 @@ use function explode; use function implode; use function is_array; +use function is_bool; +use function preg_match; use function preg_split; use function sprintf; use function strcasecmp; @@ -38,6 +40,9 @@ final class AutowiredAttributeServicesExtension extends CompilerExtension { + /** @var list */ + private array $conditionalTags = []; + #[Override] public function getConfigSchema(): Schema { @@ -133,9 +138,9 @@ public function loadConfiguration(): void $definition = $builder->addDefinition(null) ->setFactory($class->name) - ->setAutowired($class->name) - ->addTag(LazyRegistry::RULE_TAG); + ->setAutowired($class->name); + $this->tag($definition, LazyRegistry::RULE_TAG, $attribute->enabledBy); self::processConstructorParameters($builder, $class->name, $definition, $constructorParameters); } @@ -147,13 +152,59 @@ public function loadConfiguration(): void $definition = $builder->addDefinition(null) ->setFactory($class->name) - ->setAutowired($class->name) - ->addTag(RegistryFactory::COLLECTOR_TAG); + ->setAutowired($class->name); + $this->tag($definition, RegistryFactory::COLLECTOR_TAG, $attribute->enabledBy); self::processConstructorParameters($builder, $class->name, $definition, $constructorParameters); } } + private function tag(ServiceDefinition $definition, string $tag, ?string $enabledBy): void + { + if ($enabledBy === null) { + $definition->addTag($tag); + + return; + } + + $this->conditionalTags[] = [$definition, $tag, $enabledBy]; + } + + #[Override] + public function beforeCompile(): void + { + $builder = $this->getContainerBuilder(); + foreach ($this->conditionalTags as [$definition, $tag, $enabledBy]) { + if (!self::resolveCondition($builder, $enabledBy)) { + continue; + } + + $definition->addTag($tag); + } + } + + private static function resolveCondition(ContainerBuilder $builder, string $enabledBy): bool + { + if (preg_match('#^%([\w.-]+)%$#D', $enabledBy, $matches) !== 1) { + throw new ShouldNotHappenException(sprintf('enabledBy must be a parameter reference, %s given.', $enabledBy)); + } + + $parameter = $builder->parameters; + foreach (explode('.', $matches[1]) as $key) { + if (!is_array($parameter) || !array_key_exists($key, $parameter)) { + throw new ShouldNotHappenException(sprintf("Missing parameter '%s'.", $matches[1])); + } + + $parameter = $parameter[$key]; + } + + if (!is_bool($parameter)) { + throw new ShouldNotHappenException(sprintf('Parameter %s referenced by enabledBy must be bool.', $enabledBy)); + } + + return $parameter; + } + /** * @param class-string $className * @param array>> $constructorParameters diff --git a/src/DependencyInjection/RegisteredCollector.php b/src/DependencyInjection/RegisteredCollector.php index 42af140bfcf..7916575b1a3 100644 --- a/src/DependencyInjection/RegisteredCollector.php +++ b/src/DependencyInjection/RegisteredCollector.php @@ -7,6 +7,10 @@ /** * Registers a collector in the DI container on the set rule level. * + * Pass enabledBy a `%parameter%` reference to make the registration depend on + * configuration, the way a `conditionalTags` entry would. The collector is only + * tagged when the parameter is truthy. + * * Works thanks to https://github.com/ondrejmirtes/composer-attribute-collector * and AutowiredAttributeServicesExtension. */ @@ -14,7 +18,7 @@ final class RegisteredCollector { - public function __construct(public int $level) + public function __construct(public int $level, public ?string $enabledBy = null) { } diff --git a/src/DependencyInjection/RegisteredRule.php b/src/DependencyInjection/RegisteredRule.php index 3bb80348d50..8590cb93b94 100644 --- a/src/DependencyInjection/RegisteredRule.php +++ b/src/DependencyInjection/RegisteredRule.php @@ -7,6 +7,10 @@ /** * Registers a rule in the DI container on the set rule level. * + * Pass enabledBy a `%parameter%` reference to make the registration depend on + * configuration, the way a `conditionalTags` entry would. The rule is only + * tagged when the parameter is truthy. + * * Works thanks to https://github.com/ondrejmirtes/composer-attribute-collector * and AutowiredAttributeServicesExtension. */ @@ -14,7 +18,7 @@ final class RegisteredRule { - public function __construct(public int $level) + public function __construct(public int $level, public ?string $enabledBy = null) { } diff --git a/src/Rules/Classes/NewStaticInAbstractClassStaticMethodRule.php b/src/Rules/Classes/NewStaticInAbstractClassStaticMethodRule.php index 0b2842648b2..38cc6fb9bc4 100644 --- a/src/Rules/Classes/NewStaticInAbstractClassStaticMethodRule.php +++ b/src/Rules/Classes/NewStaticInAbstractClassStaticMethodRule.php @@ -4,6 +4,7 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Reflection\Php\PhpMethodFromParserNodeReflection; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; @@ -13,6 +14,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 0, enabledBy: '%featureToggles.newStaticInAbstractClassStaticMethod%')] final class NewStaticInAbstractClassStaticMethodRule implements Rule { diff --git a/src/Rules/Comparison/ImpossibleInArrayHaystackFiniteTypesRule.php b/src/Rules/Comparison/ImpossibleInArrayHaystackFiniteTypesRule.php index 621b94a7c50..c286bd6c665 100644 --- a/src/Rules/Comparison/ImpossibleInArrayHaystackFiniteTypesRule.php +++ b/src/Rules/Comparison/ImpossibleInArrayHaystackFiniteTypesRule.php @@ -5,6 +5,8 @@ use PhpParser\Node; use PhpParser\Node\Expr\FuncCall; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\AutowiredParameter; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Reflection\InitializerExprTypeResolver; use PHPStan\Rules\IdentifierRuleError; use PHPStan\Rules\Rule; @@ -30,6 +32,7 @@ * * @implements Rule */ +#[RegisteredRule(level: 4, enabledBy: '%featureToggles.finiteTypesInHaystack%')] final class ImpossibleInArrayHaystackFiniteTypesRule implements Rule { @@ -42,6 +45,7 @@ final class ImpossibleInArrayHaystackFiniteTypesRule implements Rule public function __construct( private InitializerExprTypeResolver $initializerExprTypeResolver, + #[AutowiredParameter(ref: '%treatPhpDocTypesAsCertain%')] private bool $treatPhpDocTypesAsCertain, ) { diff --git a/src/Rules/Comparison/SwitchConditionRule.php b/src/Rules/Comparison/SwitchConditionRule.php index 923550c3d3e..ef597fe88d4 100644 --- a/src/Rules/Comparison/SwitchConditionRule.php +++ b/src/Rules/Comparison/SwitchConditionRule.php @@ -7,6 +7,8 @@ use PHPStan\Analyser\CollectedDataEmitter; use PHPStan\Analyser\NodeCallbackInvoker; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\AutowiredParameter; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Node\Printer\ExprPrinter; use PHPStan\Node\SwitchConditionNode; use PHPStan\Php\PhpVersion; @@ -20,6 +22,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 4, enabledBy: '%featureToggles.switchConditionAlwaysFalse%')] final class SwitchConditionRule implements Rule { @@ -28,6 +31,7 @@ public function __construct( private ConstantConditionInTraitHelper $constantConditionInTraitHelper, private ExprPrinter $exprPrinter, private PhpVersion $phpVersion, + #[AutowiredParameter(ref: '%treatPhpDocTypesAsCertain%')] private bool $treatPhpDocTypesAsCertain, ) { diff --git a/src/Rules/Constants/ValueAssignedToDefineRule.php b/src/Rules/Constants/ValueAssignedToDefineRule.php index 75af39cca47..2e3711b98d5 100644 --- a/src/Rules/Constants/ValueAssignedToDefineRule.php +++ b/src/Rules/Constants/ValueAssignedToDefineRule.php @@ -6,6 +6,7 @@ use PhpParser\Node\Expr\FuncCall; use PHPStan\Analyser\ConstantResolver; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; @@ -16,6 +17,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 2, enabledBy: '%featureToggles.checkDynamicConstantNameValues%')] final class ValueAssignedToDefineRule implements Rule { diff --git a/src/Rules/Constants/ValueAssignedToGlobalConstantRule.php b/src/Rules/Constants/ValueAssignedToGlobalConstantRule.php index dd75bddd0c0..a079008fe17 100644 --- a/src/Rules/Constants/ValueAssignedToGlobalConstantRule.php +++ b/src/Rules/Constants/ValueAssignedToGlobalConstantRule.php @@ -5,6 +5,7 @@ use PhpParser\Node; use PHPStan\Analyser\ConstantResolver; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\VerbosityLevel; @@ -13,6 +14,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 2, enabledBy: '%featureToggles.checkDynamicConstantNameValues%')] final class ValueAssignedToGlobalConstantRule implements Rule { diff --git a/src/Rules/DateIntervalInstantiationRule.php b/src/Rules/DateIntervalInstantiationRule.php index 97e5753aa1d..2601f16f370 100644 --- a/src/Rules/DateIntervalInstantiationRule.php +++ b/src/Rules/DateIntervalInstantiationRule.php @@ -6,6 +6,7 @@ use PhpParser\Node; use PhpParser\Node\Expr\New_; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use Throwable; use function count; use function sprintf; @@ -14,6 +15,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 5, enabledBy: '%featureToggles.checkDateIntervalConstructor%')] final class DateIntervalInstantiationRule implements Rule { diff --git a/src/Rules/DeadCode/UnusedVariableRule.php b/src/Rules/DeadCode/UnusedVariableRule.php index f639a549e54..01a3dabf716 100644 --- a/src/Rules/DeadCode/UnusedVariableRule.php +++ b/src/Rules/DeadCode/UnusedVariableRule.php @@ -4,6 +4,7 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Node\Printer\ExprPrinter; use PHPStan\Node\Variable\VariableWrite; use PHPStan\Node\VariableWritesNode; @@ -22,6 +23,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 4, enabledBy: '%featureToggles.unusedVariable%')] final class UnusedVariableRule implements Rule { diff --git a/src/Rules/Exceptions/MethodThrowTypeCovarianceRule.php b/src/Rules/Exceptions/MethodThrowTypeCovarianceRule.php index e723ef21fe6..1624c3d7db6 100644 --- a/src/Rules/Exceptions/MethodThrowTypeCovarianceRule.php +++ b/src/Rules/Exceptions/MethodThrowTypeCovarianceRule.php @@ -4,6 +4,8 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\AutowiredParameter; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Node\InClassMethodNode; use PHPStan\Rules\Methods\ParentMethodHelper; use PHPStan\Rules\Rule; @@ -17,11 +19,13 @@ /** * @implements Rule */ +#[RegisteredRule(level: 0, enabledBy: '%exceptions.check.throwTypeCovariance%')] final class MethodThrowTypeCovarianceRule implements Rule { public function __construct( private ParentMethodHelper $parentMethodHelper, + #[AutowiredParameter(ref: '%exceptions.implicitThrows%')] private bool $implicitThrows, ) { diff --git a/src/Rules/Exceptions/MissingCheckedExceptionInFunctionThrowsRule.php b/src/Rules/Exceptions/MissingCheckedExceptionInFunctionThrowsRule.php index f3ed6e08f89..8e320f2ed1d 100644 --- a/src/Rules/Exceptions/MissingCheckedExceptionInFunctionThrowsRule.php +++ b/src/Rules/Exceptions/MissingCheckedExceptionInFunctionThrowsRule.php @@ -4,6 +4,7 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Node\FunctionReturnStatementsNode; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; @@ -12,6 +13,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 0, enabledBy: '%exceptions.check.missingCheckedExceptionInThrows%')] final class MissingCheckedExceptionInFunctionThrowsRule implements Rule { diff --git a/src/Rules/Exceptions/MissingCheckedExceptionInMethodThrowsRule.php b/src/Rules/Exceptions/MissingCheckedExceptionInMethodThrowsRule.php index c564711b2f7..4d356679770 100644 --- a/src/Rules/Exceptions/MissingCheckedExceptionInMethodThrowsRule.php +++ b/src/Rules/Exceptions/MissingCheckedExceptionInMethodThrowsRule.php @@ -4,6 +4,7 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Node\MethodReturnStatementsNode; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; @@ -12,6 +13,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 0, enabledBy: '%exceptions.check.missingCheckedExceptionInThrows%')] final class MissingCheckedExceptionInMethodThrowsRule implements Rule { diff --git a/src/Rules/Exceptions/MissingCheckedExceptionInPropertyHookThrowsRule.php b/src/Rules/Exceptions/MissingCheckedExceptionInPropertyHookThrowsRule.php index d9b7a6b864e..328ce6c70cd 100644 --- a/src/Rules/Exceptions/MissingCheckedExceptionInPropertyHookThrowsRule.php +++ b/src/Rules/Exceptions/MissingCheckedExceptionInPropertyHookThrowsRule.php @@ -4,6 +4,7 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Node\PropertyHookReturnStatementsNode; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; @@ -14,6 +15,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 0, enabledBy: '%exceptions.check.missingCheckedExceptionInThrows%')] final class MissingCheckedExceptionInPropertyHookThrowsRule implements Rule { diff --git a/src/Rules/Exceptions/TooWideFunctionThrowTypeRule.php b/src/Rules/Exceptions/TooWideFunctionThrowTypeRule.php index 6688dec466f..bf50be44ce7 100644 --- a/src/Rules/Exceptions/TooWideFunctionThrowTypeRule.php +++ b/src/Rules/Exceptions/TooWideFunctionThrowTypeRule.php @@ -4,6 +4,7 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Node\FunctionReturnStatementsNode; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; @@ -12,6 +13,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 4, enabledBy: '%exceptions.check.tooWideThrowType%')] final class TooWideFunctionThrowTypeRule implements Rule { diff --git a/src/Rules/Exceptions/TooWideMethodThrowTypeRule.php b/src/Rules/Exceptions/TooWideMethodThrowTypeRule.php index 92eb7c025f7..169359d3d84 100644 --- a/src/Rules/Exceptions/TooWideMethodThrowTypeRule.php +++ b/src/Rules/Exceptions/TooWideMethodThrowTypeRule.php @@ -5,6 +5,8 @@ use PhpParser\Comment\Doc; use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\AutowiredParameter; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Node\MethodReturnStatementsNode; use PHPStan\Reflection\ClassReflection; use PHPStan\Rules\Rule; @@ -21,13 +23,16 @@ /** * @implements Rule */ +#[RegisteredRule(level: 4, enabledBy: '%exceptions.check.tooWideThrowType%')] final class TooWideMethodThrowTypeRule implements Rule { public function __construct( private FileTypeMapper $fileTypeMapper, private TooWideThrowTypeCheck $check, + #[AutowiredParameter(ref: '%checkTooWideThrowTypesInProtectedAndPublicMethods%')] private bool $checkProtectedAndPublicMethods, + #[AutowiredParameter(ref: '%exceptions.check.tooWideImplicitThrowType%')] private bool $tooWideImplicitThrows, ) { diff --git a/src/Rules/Exceptions/TooWidePropertyHookThrowTypeRule.php b/src/Rules/Exceptions/TooWidePropertyHookThrowTypeRule.php index ce9be38a969..75e03e478a9 100644 --- a/src/Rules/Exceptions/TooWidePropertyHookThrowTypeRule.php +++ b/src/Rules/Exceptions/TooWidePropertyHookThrowTypeRule.php @@ -4,6 +4,8 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\AutowiredParameter; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Node\PropertyHookReturnStatementsNode; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; @@ -14,11 +16,13 @@ /** * @implements Rule */ +#[RegisteredRule(level: 4, enabledBy: '%exceptions.check.tooWideThrowType%')] final class TooWidePropertyHookThrowTypeRule implements Rule { public function __construct( private TooWideThrowTypeCheck $check, + #[AutowiredParameter(ref: '%checkTooWideThrowTypesInProtectedAndPublicMethods%')] private bool $checkProtectedAndPublicMethods, ) { diff --git a/src/Rules/Functions/ParameterCastableToNumberRule.php b/src/Rules/Functions/ParameterCastableToNumberRule.php index 92d33b98e4d..66797125f9d 100644 --- a/src/Rules/Functions/ParameterCastableToNumberRule.php +++ b/src/Rules/Functions/ParameterCastableToNumberRule.php @@ -5,6 +5,7 @@ use PhpParser\Node; use PhpParser\Node\Expr\FuncCall; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Php\PhpVersion; use PHPStan\Reflection\ParametersAcceptorSelector; use PHPStan\Reflection\ReflectionProvider; @@ -19,6 +20,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 5, enabledBy: '%featureToggles.checkParameterCastableToNumberFunctions%')] final class ParameterCastableToNumberRule implements Rule { diff --git a/src/Rules/Functions/PrintfParameterTypeRule.php b/src/Rules/Functions/PrintfParameterTypeRule.php index 3ebbfc91d6e..2d808a0e481 100644 --- a/src/Rules/Functions/PrintfParameterTypeRule.php +++ b/src/Rules/Functions/PrintfParameterTypeRule.php @@ -4,6 +4,8 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\AutowiredParameter; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Php\PhpVersions; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Rules\Rule; @@ -28,6 +30,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 5, enabledBy: '%featureToggles.checkPrintfParameterTypes%')] final class PrintfParameterTypeRule implements Rule { @@ -46,6 +49,7 @@ public function __construct( private PrintfFormatParser $printfFormatParser, private ReflectionProvider $reflectionProvider, private RuleLevelHelper $ruleLevelHelper, + #[AutowiredParameter(ref: '%checkStrictPrintfPlaceholderTypes%')] private bool $checkStrictPrintfPlaceholderTypes, ) { diff --git a/src/Rules/Functions/SortWithoutEffectRule.php b/src/Rules/Functions/SortWithoutEffectRule.php index 3fbda5be7b3..dfe41c0a07d 100644 --- a/src/Rules/Functions/SortWithoutEffectRule.php +++ b/src/Rules/Functions/SortWithoutEffectRule.php @@ -6,6 +6,8 @@ use PhpParser\Node\Expr\FuncCall; use PHPStan\Analyser\ArgumentsNormalizer; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\AutowiredParameter; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Reflection\ParametersAcceptor; use PHPStan\Reflection\ParametersAcceptorSelector; use PHPStan\Reflection\ReflectionProvider; @@ -27,6 +29,7 @@ * * @implements Rule */ +#[RegisteredRule(level: 5, enabledBy: '%featureToggles.sortWithoutEffect%')] final class SortWithoutEffectRule implements Rule { @@ -55,7 +58,9 @@ final class SortWithoutEffectRule implements Rule public function __construct( private ReflectionProvider $reflectionProvider, + #[AutowiredParameter(ref: '%treatPhpDocTypesAsCertain%')] private bool $treatPhpDocTypesAsCertain, + #[AutowiredParameter(ref: '%tips.treatPhpDocTypesAsCertain%')] private bool $treatPhpDocTypesAsCertainTip, ) { diff --git a/src/Rules/Functions/UnusedFunctionParametersRule.php b/src/Rules/Functions/UnusedFunctionParametersRule.php index 4311eee0b97..2295b701fbf 100644 --- a/src/Rules/Functions/UnusedFunctionParametersRule.php +++ b/src/Rules/Functions/UnusedFunctionParametersRule.php @@ -4,6 +4,7 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Internal\SprintfHelper; use PHPStan\Node\VariableWritesNode; use PHPStan\Rules\Rule; @@ -14,6 +15,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 4, enabledBy: '%featureToggles.unusedParameters%')] final class UnusedFunctionParametersRule implements Rule { diff --git a/src/Rules/Keywords/UnusedLabelRule.php b/src/Rules/Keywords/UnusedLabelRule.php index 5a8d9551fa6..5fb26e8ee19 100644 --- a/src/Rules/Keywords/UnusedLabelRule.php +++ b/src/Rules/Keywords/UnusedLabelRule.php @@ -4,6 +4,7 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Parser\GotoLabelVisitor; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; @@ -12,6 +13,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 4, enabledBy: '%featureToggles.unusedLabel%')] final class UnusedLabelRule implements Rule { diff --git a/src/Rules/Methods/UnusedMethodParametersRule.php b/src/Rules/Methods/UnusedMethodParametersRule.php index 4e7bad0ccec..27a984b9e2e 100644 --- a/src/Rules/Methods/UnusedMethodParametersRule.php +++ b/src/Rules/Methods/UnusedMethodParametersRule.php @@ -4,6 +4,7 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Internal\SprintfHelper; use PHPStan\Node\VariableWritesNode; use PHPStan\Rules\Rule; @@ -20,6 +21,7 @@ * * @implements Rule */ +#[RegisteredRule(level: 4, enabledBy: '%featureToggles.unusedParameters%')] final class UnusedMethodParametersRule implements Rule { diff --git a/src/Rules/Properties/UninitializedPropertyRule.php b/src/Rules/Properties/UninitializedPropertyRule.php index 525a9ecbb69..70dbc7edcd4 100644 --- a/src/Rules/Properties/UninitializedPropertyRule.php +++ b/src/Rules/Properties/UninitializedPropertyRule.php @@ -4,6 +4,7 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Node\ClassPropertiesNode; use PHPStan\Reflection\ConstructorsHelper; use PHPStan\Rules\Rule; @@ -13,6 +14,7 @@ /** * @implements Rule */ +#[RegisteredRule(level: 0, enabledBy: '%checkUninitializedProperties%')] final class UninitializedPropertyRule implements Rule { diff --git a/src/Rules/Variables/AssignToByRefExprFromForeachRule.php b/src/Rules/Variables/AssignToByRefExprFromForeachRule.php index 21d31e5a64e..6fe372fd112 100644 --- a/src/Rules/Variables/AssignToByRefExprFromForeachRule.php +++ b/src/Rules/Variables/AssignToByRefExprFromForeachRule.php @@ -5,6 +5,7 @@ use PhpParser\Node; use PhpParser\NodeAbstract; use PHPStan\Analyser\Scope; +use PHPStan\DependencyInjection\RegisteredRule; use PHPStan\Node\Expr\ForeachValueByRefExpr; use PHPStan\Node\Printer\ExprPrinter; use PHPStan\Node\PropertyAssignNode; @@ -16,6 +17,7 @@ /** * @implements MultipleNodeTypesRule */ +#[RegisteredRule(level: 1, enabledBy: '%featureToggles.assignToByRefForeachExpr%')] final class AssignToByRefExprFromForeachRule implements MultipleNodeTypesRule {