diff --git a/examples/TemplateChecker.php b/examples/TemplateChecker.php index 92bedc5cef0..9d2f50e3dbe 100644 --- a/examples/TemplateChecker.php +++ b/examples/TemplateChecker.php @@ -6,6 +6,7 @@ use Psalm\Codebase; use Psalm\Internal\Analyzer\ClassAnalyzer; use Psalm\Internal\Analyzer\ClassLikeAnalyzer; +use Psalm\Internal\Analyzer\ClassLikeNameOptions; use Psalm\Internal\Analyzer\MethodAnalyzer; use Psalm\Internal\Analyzer\StatementsAnalyzer; use Psalm\CodeLocation; @@ -86,7 +87,7 @@ private function checkMethod(\Psalm\Internal\MethodIdentifier $method_id, PhpPar null, null, [], - true + new ClassLikeNameOptions(true) ) === false ) { return false; diff --git a/src/Psalm/Internal/Analyzer/AttributeAnalyzer.php b/src/Psalm/Internal/Analyzer/AttributeAnalyzer.php index 072fad416d6..9c857fd82b5 100644 --- a/src/Psalm/Internal/Analyzer/AttributeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/AttributeAnalyzer.php @@ -34,11 +34,13 @@ public static function analyze( null, null, $suppressed_issues, - false, - false, - false, - false, - true + new ClassLikeNameOptions( + false, + false, + false, + false, + true + ) ) === false) { return; } diff --git a/src/Psalm/Internal/Analyzer/ClassAnalyzer.php b/src/Psalm/Internal/Analyzer/ClassAnalyzer.php index 073cfdafb4e..5d11a3e36f1 100644 --- a/src/Psalm/Internal/Analyzer/ClassAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/ClassAnalyzer.php @@ -2191,7 +2191,9 @@ private function checkImplementedInterfaces( null, null, $this->getSuppressedIssues(), - false + new ClassLikeNameOptions( + false + ) ) === false) { return false; } @@ -2449,7 +2451,9 @@ private function checkParentClass( null, null, $storage->suppressed_issues + $this->getSuppressedIssues(), - false + new ClassLikeNameOptions( + false + ) ) === false) { return; } diff --git a/src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php b/src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php index 86f929455a9..a662722cb33 100644 --- a/src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php @@ -196,7 +196,6 @@ public function getFunctionLikeAnalyzer(string $method_name) : ?MethodAnalyzer /** * @param array $suppressed_issues - * @param bool $inferred - whether or not the type was inferred */ public static function checkFullyQualifiedClassLikeName( StatementsSource $statements_source, @@ -205,12 +204,12 @@ public static function checkFullyQualifiedClassLikeName( ?string $calling_fq_class_name, ?string $calling_method_id, array $suppressed_issues, - bool $inferred = true, - bool $allow_trait = false, - bool $allow_interface = true, - bool $from_docblock = false, - bool $from_attribute = false + ?ClassLikeNameOptions $options = null ): ?bool { + if ($options === null) { + $options = new ClassLikeNameOptions(); + } + $codebase = $statements_source->getCodebase(); if ($fq_class_name === '') { if (IssueBuffer::accepts( @@ -257,20 +256,20 @@ public static function checkFullyQualifiedClassLikeName( $class_exists = $codebase->classlikes->classExists( $fq_class_name, - !$inferred ? $code_location : null, + !$options->inferred ? $code_location : null, $calling_fq_class_name, $calling_method_id ); $interface_exists = $codebase->classlikes->interfaceExists( $fq_class_name, - !$inferred ? $code_location : null, + !$options->inferred ? $code_location : null, $calling_fq_class_name, $calling_method_id ); - if (!$class_exists && !($interface_exists && $allow_interface)) { - if (!$allow_trait || !$codebase->classlikes->traitExists($fq_class_name, $code_location)) { - if ($from_docblock) { + if (!$class_exists && !($interface_exists && $options->allow_interface)) { + if (!$options->allow_trait || !$codebase->classlikes->traitExists($fq_class_name, $code_location)) { + if ($options->from_docblock) { if (IssueBuffer::accepts( new UndefinedDocblockClass( 'Docblock-defined class or interface ' . $fq_class_name . ' does not exist', @@ -281,7 +280,7 @@ public static function checkFullyQualifiedClassLikeName( )) { return false; } - } elseif ($from_attribute) { + } elseif ($options->from_attribute) { if (IssueBuffer::accepts( new UndefinedAttributeClass( 'Attribute class ' . $fq_class_name . ' does not exist', @@ -316,7 +315,7 @@ public static function checkFullyQualifiedClassLikeName( try { $class_storage = $codebase->classlike_storage_provider->get($aliased_name); } catch (\InvalidArgumentException $e) { - if (!$inferred) { + if (!$options->inferred) { throw $e; } @@ -343,7 +342,7 @@ public static function checkFullyQualifiedClassLikeName( } } - if (!$inferred) { + if (!$options->inferred) { if (($class_exists && !$codebase->classHasCorrectCasing($fq_class_name)) || ($interface_exists && !$codebase->interfaceHasCorrectCasing($fq_class_name)) ) { @@ -362,7 +361,7 @@ public static function checkFullyQualifiedClassLikeName( } } - if (!$inferred) { + if (!$options->inferred) { $event = new AfterClassLikeExistenceCheckEvent( $fq_class_name, $code_location, diff --git a/src/Psalm/Internal/Analyzer/ClassLikeNameOptions.php b/src/Psalm/Internal/Analyzer/ClassLikeNameOptions.php new file mode 100644 index 00000000000..fc4ba3e0ed8 --- /dev/null +++ b/src/Psalm/Internal/Analyzer/ClassLikeNameOptions.php @@ -0,0 +1,34 @@ +inferred = $inferred; + $this->allow_trait = $allow_trait; + $this->allow_interface = $allow_interface; + $this->from_docblock = $from_docblock; + $this->from_attribute = $from_attribute; + } +} diff --git a/src/Psalm/Internal/Analyzer/FileAnalyzer.php b/src/Psalm/Internal/Analyzer/FileAnalyzer.php index 9337796ffc9..2726edcf17a 100644 --- a/src/Psalm/Internal/Analyzer/FileAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/FileAnalyzer.php @@ -248,10 +248,12 @@ public function analyze( null, null, $this->suppressed_issues, - true, - false, - true, - true + new ClassLikeNameOptions( + true, + false, + true, + true + ) ) === false) { continue; } diff --git a/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php b/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php index 62d6c36ea73..4ea85b5f61b 100644 --- a/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php @@ -624,10 +624,12 @@ public function analyze( $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues(), - false, - false, - true, - true + new ClassLikeNameOptions( + false, + false, + true, + true + ) )) { $input_type = new Type\Union([new TNamedObject($expected_exception)]); $container_type = new Type\Union([new TNamedObject('Exception'), new TNamedObject('Throwable')]); diff --git a/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php index 14f3129ce39..bd4b0c1da95 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php @@ -4,6 +4,7 @@ use PhpParser; use Psalm\Codebase; use Psalm\Internal\Analyzer\ClassLikeAnalyzer; +use Psalm\Internal\Analyzer\ClassLikeNameOptions; use Psalm\Internal\Analyzer\CommentAnalyzer; use Psalm\Internal\Analyzer\Statements\Expression\AssignmentAnalyzer; use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer; @@ -609,7 +610,8 @@ public static function checkIteratorType( new CodeLocation($statements_analyzer->getSource(), $expr), $context->self, $context->calling_method_id, - $statements_analyzer->getSuppressedIssues() + $statements_analyzer->getSuppressedIssues(), + new ClassLikeNameOptions(true) ) === false) { return false; } diff --git a/src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php index ad594874415..0fc9c07d140 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php @@ -3,6 +3,7 @@ use PhpParser; use Psalm\Internal\Analyzer\ClassLikeAnalyzer; +use Psalm\Internal\Analyzer\ClassLikeNameOptions; use Psalm\Internal\Analyzer\ScopeAnalyzer; use Psalm\Internal\Analyzer\StatementsAnalyzer; use Psalm\Internal\DataFlow\DataFlowNode; @@ -223,7 +224,7 @@ public static function analyze( $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues(), - false + new ClassLikeNameOptions(true) ) === false) { // fall through } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php b/src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php index c7a089b1768..9f6ae9a4b79 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php @@ -4,6 +4,7 @@ use PhpParser; use Psalm\Codebase; use Psalm\Internal\Analyzer\ClassLikeAnalyzer; +use Psalm\Internal\Analyzer\ClassLikeNameOptions; use Psalm\Internal\Analyzer\StatementsAnalyzer; use Psalm\Internal\Type\Comparator\UnionTypeComparator; use Psalm\CodeLocation; @@ -2457,8 +2458,7 @@ private static function getGetclassInequalityAssertions( new CodeLocation($source, $whichclass_expr), null, null, - $source->getSuppressedIssues(), - false + $source->getSuppressedIssues() ) === false ) { // fall through @@ -3148,7 +3148,7 @@ private static function getGetclassEqualityAssertions( null, null, $source->getSuppressedIssues(), - true + new ClassLikeNameOptions(true) ) === false ) { return []; diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php index 52163f99f58..8496df7d379 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php @@ -4,6 +4,7 @@ use PhpParser; use Psalm\Codebase; use Psalm\Internal\Analyzer\ClassLikeAnalyzer; +use Psalm\Internal\Analyzer\ClassLikeNameOptions; use Psalm\Internal\Analyzer\MethodAnalyzer; use Psalm\Internal\Analyzer\Statements\Block\ForeachAnalyzer; use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer; @@ -1164,7 +1165,8 @@ private static function verifyExplicitParam( $arg_location, $context->self, $context->calling_method_id, - $statements_analyzer->getSuppressedIssues() + $statements_analyzer->getSuppressedIssues(), + new ClassLikeNameOptions(true) ) === false ) { return; @@ -1182,7 +1184,8 @@ private static function verifyExplicitParam( $arg_location, $context->self, $context->calling_method_id, - $statements_analyzer->getSuppressedIssues() + $statements_analyzer->getSuppressedIssues(), + new ClassLikeNameOptions(true) ) === false ) { return; @@ -1258,7 +1261,8 @@ private static function verifyExplicitParam( $arg_location, $context->self, $context->calling_method_id, - $statements_analyzer->getSuppressedIssues() + $statements_analyzer->getSuppressedIssues(), + new ClassLikeNameOptions(true) ) === false ) { return; diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php index e0bc8fecea7..5b40640f6b3 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php @@ -3,6 +3,7 @@ use PhpParser; use Psalm\Internal\Analyzer\ClassLikeAnalyzer; +use Psalm\Internal\Analyzer\ClassLikeNameOptions; use Psalm\Internal\Analyzer\FunctionLikeAnalyzer; use Psalm\Internal\Analyzer\MethodAnalyzer; use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer; @@ -144,10 +145,7 @@ public static function analyze( $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues(), - true, - false, - true, - $lhs_type_part->from_docblock + new ClassLikeNameOptions(true, false, true, $lhs_type_part->from_docblock) ); } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.php index 82d85bcd785..a878619979f 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.php @@ -163,8 +163,7 @@ public static function analyze( new CodeLocation($statements_analyzer->getSource(), $stmt->class), $context->self, $context->calling_method_id, - $statements_analyzer->getSuppressedIssues(), - false + $statements_analyzer->getSuppressedIssues() ) === false) { ArgumentsAnalyzer::analyze( $statements_analyzer, diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php index fcb3987848c..7b7cdb946e7 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php @@ -3,6 +3,7 @@ use PhpParser; use Psalm\Internal\Analyzer\ClassLikeAnalyzer; +use Psalm\Internal\Analyzer\ClassLikeNameOptions; use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer; use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer; use Psalm\Internal\Analyzer\StatementsAnalyzer; @@ -148,9 +149,7 @@ public static function analyze( ? $context->calling_method_id : null, $statements_analyzer->getSuppressedIssues(), - false, - false, - false + new ClassLikeNameOptions(false, false, false) ); } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php index cc175a1ea6f..307ca0c0c99 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php @@ -3,6 +3,7 @@ use PhpParser; use Psalm\Internal\Analyzer\ClassLikeAnalyzer; +use Psalm\Internal\Analyzer\ClassLikeNameOptions; use Psalm\Internal\Analyzer\MethodAnalyzer; use Psalm\Internal\Analyzer\NamespaceAnalyzer; use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer; @@ -65,9 +66,11 @@ public static function analyze( ? $context->calling_method_id : null, $statements_analyzer->getSuppressedIssues(), - $stmt->class instanceof PhpParser\Node\Name - && count($stmt->class->parts) === 1 - && in_array(strtolower($stmt->class->parts[0]), ['self', 'static'], true) + new ClassLikeNameOptions( + $stmt->class instanceof PhpParser\Node\Name + && count($stmt->class->parts) === 1 + && in_array(strtolower($stmt->class->parts[0]), ['self', 'static'], true) + ) )) { return; } @@ -84,8 +87,7 @@ public static function analyze( new CodeLocation($statements_analyzer, $stmt->class), $context->self, $context->calling_method_id, - $statements_analyzer->getSuppressedIssues(), - false + $statements_analyzer->getSuppressedIssues() )) { return; } @@ -118,8 +120,7 @@ public static function analyze( new CodeLocation($statements_analyzer, $stmt->class), $context->self, $context->calling_method_id, - $statements_analyzer->getSuppressedIssues(), - false + $statements_analyzer->getSuppressedIssues() )) { return; } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ClassConstFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ClassConstFetchAnalyzer.php index 755bedc7fe6..3a51d132848 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ClassConstFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ClassConstFetchAnalyzer.php @@ -3,6 +3,7 @@ use PhpParser; use Psalm\Internal\Analyzer\ClassLikeAnalyzer; +use Psalm\Internal\Analyzer\ClassLikeNameOptions; use Psalm\Internal\Analyzer\NamespaceAnalyzer; use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer; use Psalm\Internal\Analyzer\StatementsAnalyzer; @@ -89,8 +90,7 @@ public static function analyze( $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues(), - false, - true + new ClassLikeNameOptions(false, true) ) === false) { return true; } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php index a1b5b29f1f9..8f5238020a8 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php @@ -94,8 +94,7 @@ public static function analyze( new CodeLocation($statements_analyzer->getSource(), $stmt->class), $context->self, $context->calling_method_id, - $statements_analyzer->getSuppressedIssues(), - false + $statements_analyzer->getSuppressedIssues() ) !== true) { return false; } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/InstanceofAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/InstanceofAnalyzer.php index 7f38f96805b..0ee24442f24 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/InstanceofAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/InstanceofAnalyzer.php @@ -66,8 +66,7 @@ public static function analyze( new CodeLocation($statements_analyzer->getSource(), $stmt->class), $context->self, $context->calling_method_id, - $statements_analyzer->getSuppressedIssues(), - false + $statements_analyzer->getSuppressedIssues() ) === false) { return false; } diff --git a/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php index 30b2eda7dc5..5ccf808b994 100644 --- a/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php @@ -4,6 +4,7 @@ use PhpParser; use Psalm\Codebase; use Psalm\Internal\Analyzer\ClassLikeAnalyzer; +use Psalm\Internal\Analyzer\ClassLikeNameOptions; use Psalm\Internal\Analyzer\ClosureAnalyzer; use Psalm\Internal\Analyzer\CommentAnalyzer; use Psalm\Internal\Analyzer\FunctionLikeAnalyzer; @@ -440,7 +441,8 @@ public static function analyze( new CodeLocation($source, $stmt->expr), $context->self, $context->calling_method_id, - $statements_analyzer->getSuppressedIssues() + $statements_analyzer->getSuppressedIssues(), + new ClassLikeNameOptions(true) ) === false ) { return false; @@ -460,7 +462,8 @@ public static function analyze( new CodeLocation($source, $item->value), $context->self, $context->calling_method_id, - $statements_analyzer->getSuppressedIssues() + $statements_analyzer->getSuppressedIssues(), + new ClassLikeNameOptions(true) ) === false ) { return false; diff --git a/src/Psalm/Internal/TypeVisitor/TypeChecker.php b/src/Psalm/Internal/TypeVisitor/TypeChecker.php index 6890436510f..120ec498f0c 100644 --- a/src/Psalm/Internal/TypeVisitor/TypeChecker.php +++ b/src/Psalm/Internal/TypeVisitor/TypeChecker.php @@ -3,6 +3,7 @@ use Psalm\CodeLocation; use Psalm\Internal\Analyzer\ClassLikeAnalyzer; +use Psalm\Internal\Analyzer\ClassLikeNameOptions; use Psalm\Internal\Type\Comparator\UnionTypeComparator; use Psalm\Internal\Type\TypeExpander; use Psalm\Storage\MethodStorage; @@ -167,10 +168,7 @@ private function checkNamedObject(TNamedObject $atomic) : void $this->source->getFQCLN(), $this->calling_method_id, $this->suppressed_issues, - $this->inferred, - false, - true, - $atomic->from_docblock + new ClassLikeNameOptions($this->inferred, false, true, $atomic->from_docblock) ) === false ) { $this->has_errors = true; @@ -308,10 +306,7 @@ public function checkScalarClassConstant(TScalarClassConstant $atomic) : void null, null, $this->suppressed_issues, - $this->inferred, - false, - true, - $atomic->from_docblock + new ClassLikeNameOptions($this->inferred, false, true, $atomic->from_docblock) ) === false ) { $this->has_errors = true;