diff --git a/src/Psalm/Internal/Analyzer/AlgebraAnalyzer.php b/src/Psalm/Internal/Analyzer/AlgebraAnalyzer.php index ad466338ea6..98a68319c8c 100644 --- a/src/Psalm/Internal/Analyzer/AlgebraAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/AlgebraAnalyzer.php @@ -61,16 +61,14 @@ public static function checkForParadox( && (isset($formula_1_hashes[$hash]) || isset($formula_2_hashes[$hash])) && !array_intersect_key($new_assigned_var_ids, $formula_2_clause->possibilities) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantCondition( $formula_2_clause . ' has already been asserted', new CodeLocation($statements_analyzer, $stmt), null ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } foreach ($formula_2_clause->possibilities as $key => $values) { @@ -79,15 +77,13 @@ public static function checkForParadox( && !isset($new_assigned_var_ids[$key]) && count(array_unique($values)) < count($values) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ParadoxicalCondition( 'Found a redundant condition when evaluating assertion (' . $formula_2_clause . ')', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -102,16 +98,14 @@ public static function checkForParadox( && !isset($new_assigned_var_ids[$key]) && count(array_unique($values)) < count($values) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantCondition( 'Found a redundant condition when evaluating ' . $key, new CodeLocation($statements_analyzer, $stmt), null ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -161,15 +155,13 @@ public static function checkForParadox( . ' contradicts a previously-established condition (' . $clause_1 . ')'; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ParadoxicalCondition( $paradox_message, new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return; } diff --git a/src/Psalm/Internal/Analyzer/AttributeAnalyzer.php b/src/Psalm/Internal/Analyzer/AttributeAnalyzer.php index e0df55dcdfd..512e63ba385 100644 --- a/src/Psalm/Internal/Analyzer/AttributeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/AttributeAnalyzer.php @@ -54,57 +54,47 @@ public static function analyze( if ($attribute->fq_class_name === 'Attribute' && $classlike_storage) { if ($classlike_storage->is_trait) { - if (\Psalm\IssueBuffer::accepts( + \Psalm\IssueBuffer::maybeAdd( new InvalidAttribute( 'Traits cannot act as attribute classes', $attribute->name_location ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($classlike_storage->is_interface) { - if (\Psalm\IssueBuffer::accepts( + \Psalm\IssueBuffer::maybeAdd( new InvalidAttribute( 'Interfaces cannot act as attribute classes', $attribute->name_location ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($classlike_storage->abstract) { - if (\Psalm\IssueBuffer::accepts( + \Psalm\IssueBuffer::maybeAdd( new InvalidAttribute( 'Abstract classes cannot act as attribute classes', $attribute->name_location ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } elseif (isset($classlike_storage->methods['__construct']) && $classlike_storage->methods['__construct']->visibility !== ClassLikeAnalyzer::VISIBILITY_PUBLIC ) { - if (\Psalm\IssueBuffer::accepts( + \Psalm\IssueBuffer::maybeAdd( new InvalidAttribute( 'Classes with protected/private constructors cannot act as attribute classes', $attribute->name_location ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($classlike_storage->is_enum) { - if (\Psalm\IssueBuffer::accepts( + \Psalm\IssueBuffer::maybeAdd( new InvalidAttribute( 'Enums cannot act as attribute classes', $attribute->name_location ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -235,29 +225,25 @@ private static function checkAttributeTargets( 32 => 'function/method parameter' ]; - if (\Psalm\IssueBuffer::accepts( + \Psalm\IssueBuffer::maybeAdd( new InvalidAttribute( 'This attribute can not be used on a ' . $target_map[$target], $attribute->name_location ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } } if (!$has_attribute_attribute) { - if (\Psalm\IssueBuffer::accepts( + \Psalm\IssueBuffer::maybeAdd( new InvalidAttribute( 'The class ' . $attribute->fq_class_name . ' doesn’t have the Attribute attribute', $attribute->name_location ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/ClassAnalyzer.php b/src/Psalm/Internal/Analyzer/ClassAnalyzer.php index d77fa1a7d56..675303f6ae7 100644 --- a/src/Psalm/Internal/Analyzer/ClassAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/ClassAnalyzer.php @@ -146,7 +146,7 @@ public function analyze( $class_name_parts = explode('\\', $fq_class_name); $class_name = array_pop($class_name_parts); - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ReservedWord( $class_name . ' is a reserved word', new CodeLocation( @@ -158,9 +158,7 @@ public function analyze( $class_name ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); return; } @@ -259,16 +257,14 @@ public function analyze( ); if ($codebase->classOrInterfaceExists($fq_classlike_name)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ReservedWord( 'Cannot use ' . $param_name . ' as template name since the class already exists', new CodeLocation($this, $this->class), 'resource' ), $this->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -681,16 +677,14 @@ public static function addContextProperties( if ($property_storage->visibility > $guide_property_storage->visibility && $property_storage->location ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new OverriddenPropertyAccess( 'Property ' . $fq_class_name . '::$' . $property_name . ' has different access level than ' . $storage->name . '::$' . $property_name, $property_storage->location ) - )) { - // fall through - } + ); } if ((($property_storage->signature_type && !$guide_property_storage->signature_type) @@ -701,7 +695,7 @@ public static function addContextProperties( ))) && $property_storage->location ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new NonInvariantPropertyType( 'Property ' . $fq_class_name . '::$' . $property_name . ' has type ' @@ -718,9 +712,7 @@ public static function addContextProperties( $property_storage->location ), $property_storage->suppressed_issues - )) { - // fall through - } + ); } if ($property_storage->type === null) { @@ -795,7 +787,7 @@ public static function addContextProperties( && !$property_type->equals($guide_property_type, false) && $guide_class_storage->user_defined ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new NonInvariantDocblockPropertyType( 'Property ' . $fq_class_name . '::$' . $property_name . ' has type ' . $property_type->getId() @@ -805,9 +797,7 @@ public static function addContextProperties( $property_storage->location ), $property_storage->suppressed_issues - )) { - // fall through - } + ); } } } @@ -928,7 +918,7 @@ function ($stmt) use ($property_name): bool { $union_comparison_result ) && !$union_comparison_result->type_coerced_from_mixed ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MismatchingDocblockPropertyType( 'Parameter ' . $property_class_name . '::$' . $property_name @@ -936,9 +926,7 @@ function ($stmt) use ($property_name): bool { '\', should be \'' . $property_storage->signature_type . '\'', $property_type_location ) - )) { - // do nothing - } + ); } } } @@ -1276,7 +1264,7 @@ function (FunctionLikeParameter $param) : PhpParser\Node\Arg { ? 'private or final ' : ''; - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PropertyNotSetInConstructor( 'Property ' . $class_storage->name . '::$' . $property_name . ' is not defined in constructor of ' @@ -1286,9 +1274,7 @@ function (FunctionLikeParameter $param) : PhpParser\Node\Arg { $property_id ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // do nothing - } + ); } elseif (!$property_storage->has_default) { if (isset($this->inferred_property_types[$property_name])) { $this->inferred_property_types[$property_name]->addType(new Type\Atomic\TNull()); @@ -1310,7 +1296,7 @@ function (FunctionLikeParameter $param) : PhpParser\Node\Arg { if (!$storage->abstract && $uninitialized_typed_properties) { foreach ($uninitialized_typed_properties as $id => $uninitialized_property) { if ($uninitialized_property->location) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingConstructor( $class_storage->name . ' has an uninitialized property ' . $id . ', but no constructor', @@ -1318,9 +1304,7 @@ function (FunctionLikeParameter $param) : PhpParser\Node\Arg { $class_storage->name . '::' . $uninitialized_variables[0] ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -1353,15 +1337,13 @@ private function analyzeTraitUse( ); if (!$codebase->classlikes->hasFullyQualifiedTraitName($fq_trait_name, $trait_location)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedTrait( 'Trait ' . $fq_trait_name . ' does not exist', new CodeLocation($previous_trait_analyzer ?? $this, $trait_name) ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); return false; } @@ -1384,15 +1366,13 @@ private function analyzeTraitUse( $trait_storage = $codebase->classlike_storage_provider->get($fq_trait_name_resolved); if ($trait_storage->deprecated) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedTrait( 'Trait ' . $fq_trait_name . ' is deprecated', new CodeLocation($previous_trait_analyzer ?? $this, $trait_name) ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } if ($trait_storage->extension_requirement !== null) { @@ -1402,16 +1382,14 @@ private function analyzeTraitUse( $extensionRequirementMet = in_array($extension_requirement, $storage->parent_classes); if (!$extensionRequirementMet) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ExtensionRequirementViolation( $fq_trait_name . ' requires using class to extend ' . $extension_requirement . ', but ' . $storage->name . ' does not', new CodeLocation($previous_trait_analyzer ?? $this, $trait_name) ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -1420,29 +1398,25 @@ private function analyzeTraitUse( $implementationRequirementMet = in_array($implementation_requirement, $storage->class_implements); if (!$implementationRequirementMet) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImplementationRequirementViolation( $fq_trait_name . ' requires using class to implement ' . $implementation_requirement . ', but ' . $storage->name . ' does not', new CodeLocation($previous_trait_analyzer ?? $this, $trait_name) ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } } if ($storage->mutation_free && !$trait_storage->mutation_free) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MutableDependency( $storage->name . ' is marked @psalm-immutable but ' . $fq_trait_name . ' is not', new CodeLocation($previous_trait_analyzer ?? $this, $trait_name) ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } $trait_file_analyzer = $project_analyzer->getFileAnalyzerForClassLike($fq_trait_name_resolved); @@ -1586,16 +1560,14 @@ private function checkForMissingPropertyType( return; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingPropertyType( $message, new CodeLocation($source, $stmt->props[0]->name), $property_id ), $this->source->getSuppressedIssues() - )) { - // fall through - } + ); } private static function addOrUpdatePropertyType( @@ -1993,27 +1965,23 @@ private function checkTemplateParams( : count($parent_storage->template_types); if ($expected_param_count > $given_param_count) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingTemplateParam( $storage->name . ' has missing template params when extending ' . $parent_storage->name . ' , expecting ' . $expected_param_count, $code_location ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($expected_param_count < $given_param_count) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TooManyTemplateParams( $storage->name . ' has too many template params when extending ' . $parent_storage->name . ' , expecting ' . $expected_param_count, $code_location ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } $storage_param_count = ($storage->template_types ? count($storage->template_types) : 0); @@ -2022,27 +1990,23 @@ private function checkTemplateParams( && $expected_param_count !== $storage_param_count ) { if ($expected_param_count > $storage_param_count) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingTemplateParam( $storage->name . ' requires the same number of template params as ' . $parent_storage->name . ' but saw ' . $storage_param_count, $code_location ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TooManyTemplateParams( $storage->name . ' requires the same number of template params as ' . $parent_storage->name . ' but saw ' . $storage_param_count, $code_location ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -2071,16 +2035,14 @@ private function checkTemplateParams( !== false && !empty($storage->template_covariants[$local_offset]) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidTemplateParam( 'Cannot extend an invariant template param ' . $template_name . ' into a covariant context', $code_location ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -2090,7 +2052,7 @@ private function checkTemplateParams( if (!$t instanceof Type\Atomic\TTemplateParam || !isset($storage->template_types[$t->param_name]) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidTemplateParam( 'Cannot extend a strictly-enforced parent template param ' . $template_name @@ -2098,13 +2060,11 @@ private function checkTemplateParams( $code_location ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($storage->template_types[$t->param_name][$storage->name]->getId() !== $template_type->getId() ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidTemplateParam( 'Cannot extend a strictly-enforced parent template param ' . $template_name @@ -2115,9 +2075,7 @@ private function checkTemplateParams( $code_location ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -2141,7 +2099,7 @@ private function checkTemplateParams( ); if (!UnionTypeComparator::isContainedBy($codebase, $extended_type, $template_type_copy)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidTemplateParam( 'Extended template param ' . $template_name . ' expects type ' . $template_type_copy->getId() @@ -2149,9 +2107,7 @@ private function checkTemplateParams( $code_location ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } else { $previous_extended[$template_name] = [ $declaring_class => $extended_type @@ -2247,16 +2203,14 @@ private function checkImplementedInterfaces( ); if (!$interface_storage->is_interface) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedInterface( $fq_interface_name . ' is not an interface', $code_location, $fq_interface_name ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } if (isset($storage->template_type_implements_count[$fq_interface_name_lc])) { @@ -2293,43 +2247,37 @@ private function checkImplementedInterfaces( && !isset($storage->parent_classes['domnodelist']) && !isset($storage->parent_classes['dateperiod']) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidTraversableImplementation( 'Traversable should be implemented by implementing IteratorAggregate or Iterator', $code_location, $fq_class_name ) - )) { - // fall through - } + ); } if ($interface_storage->deprecated) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedInterface( $fq_interface_name . ' is marked deprecated', $code_location, $fq_interface_name ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } if ($interface_storage->external_mutation_free && !$storage->external_mutation_free ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingImmutableAnnotation( $fq_interface_name . ' is marked @psalm-immutable, but ' . $fq_class_name . ' is not marked @psalm-immutable', $code_location ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } foreach ($interface_storage->methods as $interface_method_name_lc => $interface_method_storage) { @@ -2366,7 +2314,7 @@ private function checkImplementedInterfaces( } if (!$implementer_method_storage) { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UnimplementedInterfaceMethod( 'Method ' . $interface_method_name_lc . ' is not defined on class ' . $storage->name, @@ -2404,7 +2352,7 @@ private function checkImplementedInterfaces( } if ($implementer_visibility !== self::VISIBILITY_PUBLIC) { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InaccessibleMethod( 'Interface-defined method ' . $implementer_method_storage->cased_name . ' must be public in ' . $storage->name, @@ -2417,7 +2365,7 @@ private function checkImplementedInterfaces( } if ($interface_method_storage->is_static && !$implementer_method_storage->is_static) { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MethodSignatureMismatch( 'Method ' . $implementer_method_storage->cased_name . ' should be static like ' @@ -2503,46 +2451,40 @@ private function checkParentClass( ); if ($parent_class_storage->is_trait || $parent_class_storage->is_interface) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedClass( $parent_fq_class_name . ' is not a class', $code_location, $parent_fq_class_name . ' as class' ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } if ($parent_class_storage->final) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidExtendClass( 'Class ' . $fq_class_name . ' may not inherit from final class ' . $parent_fq_class_name, $code_location, $fq_class_name ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } if ($parent_class_storage->deprecated) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedClass( $parent_fq_class_name . ' is marked deprecated', $code_location, $parent_fq_class_name ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } if (!NamespaceAnalyzer::isWithin($fq_class_name, $parent_class_storage->internal)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InternalClass( $parent_fq_class_name . ' is internal to ' . $parent_class_storage->internal . ' but called from ' . $fq_class_name, @@ -2550,38 +2492,32 @@ private function checkParentClass( $parent_fq_class_name ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } if ($parent_class_storage->external_mutation_free && !$storage->external_mutation_free ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingImmutableAnnotation( $parent_fq_class_name . ' is marked @psalm-immutable, but ' . $fq_class_name . ' is not marked @psalm-immutable', $code_location ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } if ($storage->mutation_free && !$parent_class_storage->mutation_free ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MutableDependency( $fq_class_name . ' is marked @psalm-immutable but ' . $parent_fq_class_name . ' is not', $code_location ), $storage->suppressed_issues + $this->getSuppressedIssues() - )) { - // fall through - } + ); } if ($codebase->store_node_types) { diff --git a/src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php b/src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php index 622cf8b158e..494f1448204 100644 --- a/src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php @@ -240,16 +240,14 @@ public static function checkFullyQualifiedClassLikeName( $class_name_parts = explode('\\', $fq_class_name); $class_name = array_pop($class_name_parts); - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ReservedWord( $class_name . ' is a reserved word', $code_location, $class_name ), $suppressed_issues - )) { - // fall through - } + ); return null; } @@ -359,16 +357,14 @@ public static function checkFullyQualifiedClassLikeName( || ($enum_exists && !$codebase->classlikes->enumHasCorrectCasing($fq_class_name)) ) { if ($codebase->classlikes->isUserDefined(strtolower($aliased_name))) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidClass( 'Class, interface or enum ' . $fq_class_name . ' has wrong casing', $code_location, $fq_class_name ), $suppressed_issues - )) { - // fall through here - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/FileAnalyzer.php b/src/Psalm/Internal/Analyzer/FileAnalyzer.php index a10ed537852..b65f823de24 100644 --- a/src/Psalm/Internal/Analyzer/FileAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/FileAnalyzer.php @@ -219,14 +219,12 @@ public function analyze( foreach ($uncaught_throws as $possibly_thrown_exception => $codelocations) { foreach ($codelocations as $codelocation) { // issues are suppressed in ThrowAnalyzer, CallAnalyzer, etc. - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UncaughtThrowInGlobalScope( $possibly_thrown_exception . ' is thrown but not caught in global scope', $codelocation ) - )) { - // fall through - } + ); } } } @@ -262,7 +260,7 @@ public function analyze( $referenced_class_storage = $codebase->classlike_storage_provider->get($fq_source_classlike); if (!isset($referenced_class_storage->type_aliases[$alias->alias_name])) { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidTypeImport( 'Type alias ' . $alias->alias_name . ' imported from ' . $fq_source_classlike diff --git a/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php b/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php index a8d45b1dea2..22a14c6dfad 100644 --- a/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php @@ -98,15 +98,13 @@ public static function verifyReturnType( ) ) { if (!$return_type) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingReturnType( 'Method ' . $cased_method_id . ' does not have a return type', new CodeLocation($function_like_analyzer, $function->name, null, true) ), $suppressed_issues - )) { - // fall through - } + ); } return null; @@ -313,16 +311,14 @@ static function (Union $union_type) : bool { } if ($union_comparison_results->to_string_cast) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImplicitToStringCast( 'The declared return type for ' . $cased_method_id . ' expects string, ' . '\'' . $inferred_return_type . '\' provided with a __toString method', $return_type_location ), $suppressed_issues - )) { - // fall through - } + ); } return null; @@ -353,16 +349,14 @@ static function (Union $union_type) : bool { return null; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingClosureReturnType( 'Closure does not have a return type, expecting ' . $inferred_return_type->getId(), new CodeLocation($function_like_analyzer, $function, null, true) ), $suppressed_issues, !$inferred_return_type->hasMixed() && !$inferred_return_type->isNull() - )) { - // fall through - } + ); } return null; @@ -392,7 +386,7 @@ static function (Union $union_type) : bool { return null; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingReturnType( 'Method ' . $cased_method_id . ' does not have a return type' . (!$inferred_return_type->hasMixed() ? ', expecting ' . $inferred_return_type->getId() : ''), @@ -400,9 +394,7 @@ static function (Union $union_type) : bool { ), $suppressed_issues, !$inferred_return_type->hasMixed() && !$inferred_return_type->isNull() - )) { - // fall through - } + ); return null; } @@ -643,7 +635,7 @@ static function (Union $union_type) : bool { } if ($union_comparison_results->to_string_cast) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImplicitToStringCast( 'The declared return type for ' . $cased_method_id . ' expects \'' . $declared_return_type . '\', ' . '\'' . $inferred_return_type . @@ -651,9 +643,7 @@ static function (Union $union_type) : bool { $return_type_location ), $suppressed_issues - )) { - // fall through - } + ); } if (!$inferred_return_type->ignore_nullable_issues diff --git a/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php b/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php index 9e7bea61d38..156814a46e1 100644 --- a/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php @@ -260,16 +260,14 @@ public function analyze( ); if ($codebase->classOrInterfaceExists($fq_classlike_name)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ReservedWord( 'Cannot use ' . $param_name . ' as template name since the class already exists', new CodeLocation($this, $this->function), 'resource' ), $this->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -370,7 +368,7 @@ public function analyze( foreach ($overridden_method_ids as $overridden_method_id) { $overridden_storage = $codebase->methods->getStorage($overridden_method_id); if ($overridden_storage->allow_named_arg_calls) { - IssueBuffer::accepts(new MethodSignatureMismatch( + IssueBuffer::maybeAdd(new MethodSignatureMismatch( 'Method ' . (string) $method_id . ' should accept named arguments ' . ' as ' . (string) $overridden_method_id . ' does', $storage->location @@ -518,7 +516,7 @@ public function analyze( if ($this->function instanceof Closure || $this->function instanceof ArrowFunction ) { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingClosureParamType( 'Parameter $' . $function_param->name . ' has no provided type', $function_param->location @@ -526,7 +524,7 @@ public function analyze( $storage->suppressed_issues + $this->getSuppressedIssues() ); } else { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingParamType( 'Parameter $' . $function_param->name . ' has no provided type', $function_param->location @@ -642,7 +640,7 @@ public function analyze( $container_type = new Type\Union([new TNamedObject('Exception'), new TNamedObject('Throwable')]); if (!UnionTypeComparator::isContainedBy($codebase, $input_type, $container_type)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\InvalidThrow( 'Class supplied for @throws ' . $expected_exception . ' does not implement Throwable', @@ -650,9 +648,7 @@ public function analyze( $expected_exception ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($codebase->alter_code) { @@ -683,15 +679,13 @@ public function analyze( if (!$is_expected) { foreach ($codelocations as $codelocation) { // issues are suppressed in ThrowAnalyzer, CallAnalyzer, etc. - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingThrowsDocblock( $possibly_thrown_exception . ' is thrown but not caught - please either catch' . ' or add a @throws annotation', $codelocation ) - )) { - // fall through - } + ); } } } @@ -854,25 +848,21 @@ private function checkParamReferences( || $storage->visibility === ClassLikeAnalyzer::VISIBILITY_PRIVATE ) { if ($this instanceof ClosureAnalyzer) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UnusedClosureParam( 'Param ' . $var_name . ' is never referenced in this method', $original_location ), $this->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UnusedParam( 'Param ' . $var_name . ' is never referenced in this method', $original_location ), $this->getSuppressedIssues() - )) { - // fall through - } + ); } } else { $fq_class_name = (string)$context->self; @@ -1123,7 +1113,7 @@ private function processParams( continue; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MismatchingDocblockParamType( 'Parameter $' . $function_param->name . ' has wrong type \'' . $param_type . '\', should be \'' . $signature_type . '\'', @@ -1131,9 +1121,7 @@ private function processParams( ), $storage->suppressed_issues, true - )) { - // do nothing - } + ); if ($signature_type->check( $this, @@ -1166,16 +1154,14 @@ private function processParams( true ) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidParamDefault( 'Default value type ' . $default_type->getId() . ' for argument ' . ($offset + 1) . ' of method ' . $cased_method_id . ' does not match the given type ' . $param_type->getId(), $function_param->type_location ) - )) { - // fall through - } + ); } } @@ -1192,16 +1178,14 @@ private function processParams( } } else { if ($param_type->isVoid()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ReservedWord( 'Parameter cannot be void', $function_param->type_location, 'void' ), $this->suppressed_issues - )) { - // fall through - } + ); } if ($param_type->check( @@ -1504,7 +1488,7 @@ public function examineParamTypes( $actual_type->ignore_falsable_issues ) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ReferenceConstraintViolation( 'Variable ' . '$' . $param->name . ' is limited to values of type ' . $param_out_type->getId() @@ -1516,9 +1500,7 @@ public function examineParamTypes( : $param->location ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/InterfaceAnalyzer.php b/src/Psalm/Internal/Analyzer/InterfaceAnalyzer.php index 21fa70b2cee..f0dabdc8b0f 100644 --- a/src/Psalm/Internal/Analyzer/InterfaceAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/InterfaceAnalyzer.php @@ -57,16 +57,14 @@ public function analyze(): void $extended_interface ); - if (\Psalm\IssueBuffer::accepts( + \Psalm\IssueBuffer::maybeAdd( new UndefinedInterface( $extended_interface_name . ' is not an interface', $code_location, $extended_interface_name ), $this->getSuppressedIssues() - )) { - // fall through - } + ); } if ($codebase->store_node_types && $extended_interface_name) { diff --git a/src/Psalm/Internal/Analyzer/MethodAnalyzer.php b/src/Psalm/Internal/Analyzer/MethodAnalyzer.php index a145385fc83..e0aa169e5d7 100644 --- a/src/Psalm/Internal/Analyzer/MethodAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/MethodAnalyzer.php @@ -264,14 +264,12 @@ public static function checkMethodSignatureMustOmitReturnType( $methodsOfInterest = ['__clone', '__construct', '__destruct']; if (in_array($cased_method_name, $methodsOfInterest)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MethodSignatureMustOmitReturnType( 'Method ' . $cased_method_name . ' must not declare a return type', $code_location ) - )) { - // fall through - } + ); } } diff --git a/src/Psalm/Internal/Analyzer/MethodComparator.php b/src/Psalm/Internal/Analyzer/MethodComparator.php index ff740bef303..3cb6f91a5e7 100644 --- a/src/Psalm/Internal/Analyzer/MethodComparator.php +++ b/src/Psalm/Internal/Analyzer/MethodComparator.php @@ -228,16 +228,14 @@ private static function checkForObviousMethodMismatches( || (!$implementer_method_storage->abstract && !$guide_method_storage->abstract) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new OverriddenMethodAccess( 'Method ' . $cased_implementer_method_id . ' has different access level than ' . $cased_guide_method_id, $code_location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } elseif (IssueBuffer::accepts( new TraitMethodSignatureMismatch( 'Method ' . $cased_implementer_method_id . ' has different access level than ' @@ -254,7 +252,7 @@ private static function checkForObviousMethodMismatches( && $prevent_method_signature_mismatch && $prevent_abstract_override ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MethodSignatureMismatch( 'Method ' . $cased_guide_method_id . ' is declared final and cannot be overridden', $code_location @@ -262,9 +260,7 @@ private static function checkForObviousMethodMismatches( $guide_method_storage->final_from_docblock ? $suppressed_issues + $implementer_classlike_storage->suppressed_issues : [] - )) { - // fall through - } + ); } if ($prevent_abstract_override @@ -273,16 +269,14 @@ private static function checkForObviousMethodMismatches( && !$guide_classlike_storage->abstract && !$guide_classlike_storage->is_interface ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MethodSignatureMismatch( 'Method ' . $cased_implementer_method_id . ' cannot be abstract when inherited method ' . $cased_guide_method_id . ' is non-abstract', $code_location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } if ($guide_method_storage->external_mutation_free @@ -290,7 +284,7 @@ private static function checkForObviousMethodMismatches( && !$guide_method_storage->mutation_free_inferred && $prevent_method_signature_mismatch ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingImmutableAnnotation( $cased_guide_method_id . ' is marked @psalm-immutable, but ' . $implementer_classlike_storage->name . '::' @@ -299,9 +293,7 @@ private static function checkForObviousMethodMismatches( $code_location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } } @@ -361,7 +353,7 @@ private static function compareMethodParams( !== strtolower($or_null_guide_param_signature_type->getId())) ) { if ($implementer_method_storage->cased_name === '__construct') { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ConstructorSignatureMismatch( 'Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' has wrong type \'' @@ -376,11 +368,9 @@ private static function compareMethodParams( : $code_location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MethodSignatureMismatch( 'Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' has wrong type \'' @@ -395,9 +385,7 @@ private static function compareMethodParams( : $code_location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } @@ -445,7 +433,7 @@ private static function compareMethodParams( } } } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ParamNameMismatch( 'Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' has wrong name $' . $implementer_param->name . ', expecting $' @@ -454,9 +442,7 @@ private static function compareMethodParams( $implementer_param->location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } } } @@ -505,7 +491,7 @@ private static function compareMethodParams( if ($guide_classlike_storage->user_defined && $implementer_param->by_ref !== $guide_param->by_ref) { $config = \Psalm\Config::getInstance(); - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MethodSignatureMismatch( 'Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' is' . ($implementer_param->by_ref ? '' : ' not') . ' passed by reference, but argument ' . @@ -518,9 +504,7 @@ private static function compareMethodParams( : $code_location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } } @@ -589,7 +573,7 @@ private static function compareMethodSignatureParams( && !$guide_method_storage->abstract) ) { if ($implementer_method_storage->cased_name === '__construct') { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ConstructorSignatureMismatch( 'Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id @@ -605,11 +589,9 @@ private static function compareMethodSignatureParams( : $code_location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MethodSignatureMismatch( 'Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id @@ -625,12 +607,10 @@ private static function compareMethodSignatureParams( : $code_location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TraitMethodSignatureMismatch( 'Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' has wrong type \'' . $implementer_param_signature_type . '\', expecting \'' . @@ -644,9 +624,7 @@ private static function compareMethodSignatureParams( : $code_location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } } } @@ -763,7 +741,7 @@ private static function compareMethodDocblockParams( // is the declared return type more specific than the inferred one? if ($union_comparison_results->type_coerced) { if ($guide_classlike_storage->user_defined) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MoreSpecificImplementedParamType( 'Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' has the more specific type \'' . @@ -774,9 +752,7 @@ private static function compareMethodDocblockParams( ?: $code_location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } } else { if (UnionTypeComparator::isContainedBy( @@ -886,7 +862,7 @@ private static function compareMethodSignatureReturnTypes( || (!$implementer_method_storage->abstract && !$guide_method_storage->abstract) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MethodSignatureMismatch( 'Method ' . $cased_implementer_method_id . ' with return type \'' . $implementer_signature_return_type . '\' is different to return type \'' @@ -894,11 +870,9 @@ private static function compareMethodSignatureReturnTypes( $code_location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TraitMethodSignatureMismatch( 'Method ' . $cased_implementer_method_id . ' with return type \'' . $implementer_signature_return_type . '\' is different to return type \'' @@ -906,9 +880,7 @@ private static function compareMethodSignatureReturnTypes( $code_location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } } } @@ -1018,7 +990,7 @@ private static function compareMethodDocblockReturnTypes( )) { // is the declared return type more specific than the inferred one? if ($union_comparison_results->type_coerced) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new LessSpecificImplementedReturnType( 'The inherited return type \'' . $guide_method_storage_return_type->getId() . '\' for ' . $cased_guide_method_id . ' is more specific than the implemented ' @@ -1028,11 +1000,9 @@ private static function compareMethodDocblockReturnTypes( ?: $code_location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImplementedReturnTypeMismatch( 'The inherited return type \'' . $guide_method_storage_return_type->getId() . '\' for ' . $cased_guide_method_id . ' is different to the implemented ' @@ -1042,9 +1012,7 @@ private static function compareMethodDocblockReturnTypes( ?: $code_location ), $suppressed_issues + $implementer_classlike_storage->suppressed_issues - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php index fab39cbd191..a67b0759126 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php @@ -74,14 +74,12 @@ public static function analyze( $type_aliases ); } catch (DocblockParseException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( $e->getMessage(), new CodeLocation($statements_analyzer, $stmt) ) - )) { - // fall through - } + ); } } @@ -374,29 +372,25 @@ public static function checkIteratorType( } if ($iterator_type->isNullable() && !$iterator_type->ignore_nullable_issues) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyNullIterator( 'Cannot iterate over nullable var ' . $iterator_type, new CodeLocation($statements_analyzer->getSource(), $expr) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return null; } if ($iterator_type->isFalsable() && !$iterator_type->ignore_falsable_issues) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyFalseIterator( 'Cannot iterate over falsable var ' . $iterator_type, new CodeLocation($statements_analyzer->getSource(), $expr) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return null; } @@ -509,15 +503,13 @@ public static function checkIteratorType( $statements_analyzer->getSource()->inferred_impure = true; } } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureMethodCall( 'Cannot call a possibly-mutating iterator from a pure context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } elseif ($iterator_atomic_type instanceof Type\Atomic\TIterable) { if ($iterator_atomic_type->extra_types) { @@ -589,15 +581,13 @@ public static function checkIteratorType( $statements_analyzer->getSource()->inferred_impure = true; } } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureMethodCall( 'Cannot call a possibly-mutating Traversable::getIterator from a pure context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } elseif ($iterator_atomic_type instanceof Type\Atomic\TNamedObject) { if ($iterator_atomic_type->value !== 'Traversable' && @@ -644,64 +634,54 @@ public static function checkIteratorType( $statements_analyzer->getSource()->inferred_impure = true; } } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureMethodCall( 'Cannot call a possibly-mutating iterator from a pure context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } if ($raw_object_types) { if ($has_valid_iterator) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossibleRawObjectIteration( 'Possibly undesired iteration over regular object ' . \reset($raw_object_types), new CodeLocation($statements_analyzer->getSource(), $expr) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RawObjectIteration( 'Possibly undesired iteration over regular object ' . \reset($raw_object_types), new CodeLocation($statements_analyzer->getSource(), $expr) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } if ($invalid_iterator_types) { if ($has_valid_iterator) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyInvalidIterator( 'Cannot iterate over ' . $invalid_iterator_types[0], new CodeLocation($statements_analyzer->getSource(), $expr) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidIterator( 'Cannot iterate over ' . $invalid_iterator_types[0], new CodeLocation($statements_analyzer->getSource(), $expr) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Block/IfConditionalAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Block/IfConditionalAnalyzer.php index 8448bfffa35..d687b480a62 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Block/IfConditionalAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Block/IfConditionalAnalyzer.php @@ -329,53 +329,45 @@ public static function handleParadoxicalCondition( if ($type !== null) { if ($type->isAlwaysFalsy()) { if ($type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DocblockTypeContradiction( 'Operand of type ' . $type->getId() . ' is always false', new CodeLocation($statements_analyzer, $stmt), 'false falsy' ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TypeDoesNotContainType( 'Operand of type ' . $type->getId() . ' is always false', new CodeLocation($statements_analyzer, $stmt), 'false falsy' ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } elseif ($type->isAlwaysTruthy() && (!$stmt instanceof PhpParser\Node\Expr\Assign || $emit_redundant_with_assignation) ) { if ($type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantConditionGivenDocblockType( 'Operand of type ' . $type->getId() . ' is always true', new CodeLocation($statements_analyzer, $stmt), 'true falsy' ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantCondition( 'Operand of type ' . $type->getId() . ' is always true', new CodeLocation($statements_analyzer, $stmt), 'true falsy' ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/ElseAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/ElseAnalyzer.php index 7e901947d76..4632a99fda1 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/ElseAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/ElseAnalyzer.php @@ -133,15 +133,13 @@ public static function analyze( $outer_constraint_type ) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ConflictingReferenceConstraint( 'There is more than one pass-by-reference constraint on ' . $var_id, new CodeLocation($statements_analyzer, $else, $outer_context->include_location, true) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { $outer_context->byref_constraints[$var_id] = $byref_constraint; } diff --git a/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/ElseIfAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/ElseIfAnalyzer.php index 9ff0bda05ae..d87d6dd5a9c 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/ElseIfAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/ElseIfAnalyzer.php @@ -291,15 +291,13 @@ function (array $carry, Clause $clause): array { $outer_constraint_type ) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ConflictingReferenceConstraint( 'There is more than one pass-by-reference constraint on ' . $var_id, new CodeLocation($statements_analyzer, $elseif, $outer_context->include_location, true) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { $outer_context->byref_constraints[$var_id] = $byref_constraint; } diff --git a/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/IfAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/IfAnalyzer.php index ac8e7e55d25..eae850b5d83 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/IfAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/IfAnalyzer.php @@ -104,7 +104,7 @@ public static function analyze( $outer_constraint_type ) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ConflictingReferenceConstraint( 'There is more than one pass-by-reference constraint on ' . $var_id . ' between ' . $byref_constraint->type->getId() @@ -112,9 +112,7 @@ public static function analyze( new CodeLocation($statements_analyzer, $stmt, $outer_context->include_location, true) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { $outer_context->byref_constraints[$var_id] = $byref_constraint; } diff --git a/src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php index 29b1978bec0..9b89d9a788d 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php @@ -235,16 +235,14 @@ public static function analyze( && strtolower($fq_catch_class) !== 'throwable' && !$codebase->interfaceExtends($fq_catch_class, 'Throwable')) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidCatch( 'Class/interface ' . $fq_catch_class . ' cannot be caught', new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_catch_class ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $fq_catch_classes[] = $fq_catch_class; diff --git a/src/Psalm/Internal/Analyzer/Statements/EchoAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/EchoAnalyzer.php index efe788674b8..837d8a499ef 100644 --- a/src/Psalm/Internal/Analyzer/Statements/EchoAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/EchoAnalyzer.php @@ -101,28 +101,24 @@ public static function analyze( return false; } } elseif (isset($codebase->config->forbidden_functions['echo'])) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ForbiddenCode( 'Use of echo', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSource()->getSuppressedIssues() - )) { - // continue - } + ); } if (!$context->collect_initializations && !$context->collect_mutations) { if ($context->mutation_free || $context->external_mutation_free) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureFunctionCall( 'Cannot call echo from a mutation-free context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations ) { diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php index 24e31b3dfd1..4b6f35e1132 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php @@ -140,15 +140,13 @@ public static function analyze( foreach ($item_key_type->getAtomicTypes() as $atomic_key_type) { if ($atomic_key_type instanceof Type\Atomic\TMixed) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedArrayOffset( 'Cannot create mixed offset – expecting array-key', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // do nothing - } + ); $bad_types[] = $atomic_key_type; @@ -168,15 +166,13 @@ public static function analyze( && isset($atomic_key_type->methods['__toString']) ) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidArrayOffset( 'Cannot create offset of type ' . $item_key_type->getKey() . ', expecting array-key', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // do nothing - } + ); $bad_types[] = $atomic_key_type; @@ -344,15 +340,13 @@ private static function analyzeArrayItem( if ($item_key_value !== null) { if (isset($array_creation_info->array_keys[$item_key_value])) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DuplicateArrayKey( 'Key \'' . $item_key_value . '\' already exists on array', new CodeLocation($statements_analyzer->getSource(), $item) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $array_creation_info->array_keys[$item_key_value] = true; @@ -493,15 +487,13 @@ private static function handleUnpackedArray( if ($codebase->php_major_version < 8 || ($codebase->php_major_version === 8 && $codebase->php_minor_version < 1) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DuplicateArrayKey( 'String keys are not supported in unpacked arrays', new CodeLocation($statements_analyzer->getSource(), $item->value) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return; } @@ -540,15 +532,13 @@ private static function handleUnpackedArray( if ($codebase->php_major_version < 8 || ($codebase->php_major_version === 8 && $codebase->php_minor_version < 1) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DuplicateArrayKey( 'String keys are not supported in unpacked arrays', new CodeLocation($statements_analyzer->getSource(), $item->value) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return; } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php b/src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php index 8d1db7db577..d4cf4319366 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php @@ -489,16 +489,14 @@ private static function scrapeEqualityAssertions( && $conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical ) { if (!UnionTypeComparator::canExpressionTypesBeIdentical($codebase, $var_type, $other_type)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TypeDoesNotContainType( $var_type->getId() . ' cannot be identical to ' . $other_type->getId(), new CodeLocation($source, $conditional), $var_type->getId() . ' ' . $other_type->getId() ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { // both side of the Identical can be asserted to the intersection of both $intersection_type = Type::intersectUnionTypes($var_type, $other_type, $codebase); @@ -833,51 +831,43 @@ private static function processIrreconcilableFunctionCall( if (!$negate) { if ($first_var_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantConditionGivenDocblockType( 'Docblock type ' . $first_var_type . ' always contains ' . $expected_type, new CodeLocation($source, $expr), $first_var_type . ' ' . $expected_type ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantCondition( $first_var_type . ' always contains ' . $expected_type, new CodeLocation($source, $expr), $first_var_type . ' ' . $expected_type ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } else { if ($first_var_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DocblockTypeContradiction( 'Docblock type !' . $first_var_type . ' does not contain ' . $expected_type, new CodeLocation($source, $expr), $first_var_type . ' ' . $expected_type ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TypeDoesNotContainType( '!' . $first_var_type . ' does not contain ' . $expected_type, new CodeLocation($source, $expr), $first_var_type . ' ' . $expected_type ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -982,7 +972,7 @@ protected static function processCustomAssertion( $args = $expr->getArgs(); if (!array_key_exists($var_id, $args)) { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( 'Variable '.$var_id.' is not an argument so cannot be asserted', new CodeLocation($source, $expr) @@ -997,7 +987,7 @@ protected static function processCustomAssertion( $arg_var_id = ExpressionIdentifier::getArrayVarId($arg_value, null, $source); if (null === $arg_var_id) { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( 'Variable being asserted as argument ' . ($var_id+1) . ' cannot be found in local scope', @@ -1016,7 +1006,7 @@ protected static function processCustomAssertion( ); if (null !== $failedMessage) { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock($failedMessage, new CodeLocation($source, $expr)) ); continue; @@ -1031,7 +1021,7 @@ protected static function processCustomAssertion( $assertion_var_id = $this_class_name.'::'.substr($assertion_var_id, 6); } } else { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( sprintf('Assertion of variable "%s" cannot be recognized', $assertion->var_id), new CodeLocation($source, $expr) @@ -1116,7 +1106,7 @@ protected static function processCustomAssertion( $args = $expr->getArgs(); if (!array_key_exists($var_id, $args)) { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( 'Variable '.$var_id.' is not an argument so cannot be asserted', new CodeLocation($source, $expr) @@ -1130,7 +1120,7 @@ protected static function processCustomAssertion( $arg_var_id = ExpressionIdentifier::getArrayVarId($arg_value, null, $source); if (null === $arg_var_id) { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( 'Variable being asserted as argument ' . ($var_id+1) . ' cannot be found in local scope', @@ -1149,7 +1139,7 @@ protected static function processCustomAssertion( ); if (null !== $failedMessage) { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock($failedMessage, new CodeLocation($source, $expr)) ); continue; @@ -1171,7 +1161,7 @@ protected static function processCustomAssertion( } $if_types[$var_id] = [['!'.$assertion->rule[0][0]]]; } else { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( sprintf('Assertion of variable "%s" cannot be recognized', $assertion->var_id), new CodeLocation($source, $expr) @@ -2048,27 +2038,23 @@ private static function getNullInequalityAssertions( $var_type )) { if ($var_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantConditionGivenDocblockType( 'Docblock-defined type ' . $var_type . ' can never contain null', new CodeLocation($source, $conditional), $var_type->getId() . ' null' ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantCondition( $var_type . ' can never contain null', new CodeLocation($source, $conditional), $var_type->getId() . ' null' ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -2151,15 +2137,13 @@ private static function getFalseInequalityAssertions( && $var_type->hasBool() && !$var_type->from_docblock ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantIdentityWithTrue( 'The "!== false" part of this comparison is redundant', new CodeLocation($source, $conditional) ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } $false_type = Type::getFalse(); @@ -2174,27 +2158,23 @@ private static function getFalseInequalityAssertions( $var_type )) { if ($var_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantConditionGivenDocblockType( 'Docblock-defined type ' . $var_type . ' can never contain false', new CodeLocation($source, $conditional), $var_type->getId() . ' false' ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantCondition( $var_type . ' can never contain false', new CodeLocation($source, $conditional), $var_type->getId() . ' false' ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -2301,27 +2281,23 @@ private static function getTrueInequalityAssertions( $var_type )) { if ($var_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantConditionGivenDocblockType( 'Docblock-defined type ' . $var_type . ' can never contain true', new CodeLocation($source, $conditional), $var_type->getId() . ' true' ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantCondition( $var_type . ' can never contain ' . $true_type, new CodeLocation($source, $conditional), $var_type->getId() . ' true' ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -2382,27 +2358,23 @@ private static function getEmptyInequalityAssertions( $var_type )) { if ($var_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantConditionGivenDocblockType( 'Docblock-defined type ' . $var_type->getId() . ' can never contain null', new CodeLocation($source, $conditional), $var_type->getId() . ' null' ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantCondition( $var_type->getId() . ' can never contain null', new CodeLocation($source, $conditional), $var_type->getId() . ' null' ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -2454,14 +2426,12 @@ private static function getGettypeInequalityAssertions( } if (!isset(ClassLikeAnalyzer::GETTYPE_TYPES[$var_type])) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UnevaluatedCode( 'gettype cannot return this value', new CodeLocation($source, $whichclass_expr) ) - )) { - // fall through - } + ); } else { if ($var_name && $var_type) { if ($var_type === 'class@anonymous') { @@ -2767,27 +2737,23 @@ private static function getNullEqualityAssertions( $var_type )) { if ($var_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DocblockTypeContradiction( $var_type . ' does not contain null', new CodeLocation($source, $conditional), $var_type . ' null' ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TypeDoesNotContainNull( $var_type . ' does not contain null', new CodeLocation($source, $conditional), $var_type->getId() ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -2879,15 +2845,13 @@ private static function getTrueEqualityAssertions( && $var_type->hasBool() && !$var_type->from_docblock ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantIdentityWithTrue( 'The "=== true" part of this comparison is redundant', new CodeLocation($source, $conditional) ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } $true_type = Type::getTrue(); @@ -2898,27 +2862,23 @@ private static function getTrueEqualityAssertions( $var_type )) { if ($var_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DocblockTypeContradiction( $var_type . ' does not contain true', new CodeLocation($source, $conditional), $var_type . ' true' ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TypeDoesNotContainType( $var_type . ' does not contain true', new CodeLocation($source, $conditional), $var_type . ' true' ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -3021,27 +2981,23 @@ private static function getFalseEqualityAssertions( $var_type )) { if ($var_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DocblockTypeContradiction( $var_type . ' does not contain false', new CodeLocation($source, $conditional), $var_type . ' false' ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TypeDoesNotContainType( $var_type . ' does not contain false', new CodeLocation($source, $conditional), $var_type . ' false' ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -3098,27 +3054,23 @@ private static function getEmptyArrayEqualityAssertions( $var_type )) { if ($var_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DocblockTypeContradiction( $var_type . ' does not contain an empty array', new CodeLocation($source, $conditional), null ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TypeDoesNotContainType( $var_type . ' does not contain empty array', new CodeLocation($source, $conditional), null ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -3159,14 +3111,12 @@ private static function getGettypeEqualityAssertions( $var_type = $string_expr->value; if (!isset(ClassLikeAnalyzer::GETTYPE_TYPES[$var_type])) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UnevaluatedCode( 'gettype cannot return this value', new CodeLocation($source, $string_expr) ) - )) { - // fall through - } + ); } else { if ($var_name && $var_type) { if ($var_type === 'class@anonymous') { @@ -4049,7 +3999,7 @@ private static function getInstanceofAssertions( $var_type )) { if ($var_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantConditionGivenDocblockType( $var_type->getId() . ' does not contain ' . $instanceof_type->getId(), @@ -4057,11 +4007,9 @@ private static function getInstanceofAssertions( $var_type->getId() . ' ' . $instanceof_type->getId() ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantCondition( $var_type->getId() . ' cannot be identical to ' . $instanceof_type->getId(), @@ -4069,9 +4017,7 @@ private static function getInstanceofAssertions( $var_type->getId() . ' ' . $instanceof_type->getId() ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -4108,39 +4054,33 @@ private static function handleParadoxicalAssertions( $var_type )) { if ($var_type->from_docblock || $other_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DocblockTypeContradiction( $var_type->getId() . ' does not contain ' . $other_type->getId(), new CodeLocation($source, $conditional), $var_type->getId() . ' ' . $other_type->getId() ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { if ($conditional instanceof NotEqual || $conditional instanceof NotIdentical) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantCondition( $var_type->getId() . ' can never contain ' . $other_type->getId(), new CodeLocation($source, $conditional), $var_type->getId() . ' ' . $other_type->getId() ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TypeDoesNotContainType( $var_type->getId() . ' cannot be identical to ' . $other_type->getId(), new CodeLocation($source, $conditional), $var_type->getId() . ' ' . $other_type->getId() ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/InstancePropertyAssignmentAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/InstancePropertyAssignmentAnalyzer.php index 4155613226c..048017198b3 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/InstancePropertyAssignmentAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/InstancePropertyAssignmentAnalyzer.php @@ -188,7 +188,7 @@ public static function analyze( if ($union_comparison_results->type_coerced) { if ($union_comparison_results->type_coerced_from_mixed) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedPropertyTypeCoercion( $var_id . ' expects \'' . $class_property_type->getId() . '\', ' . ' parent type `' . $assignment_type->getId() . '` provided', @@ -200,11 +200,9 @@ public static function analyze( $assigned_property->id ), $statements_analyzer->getSuppressedIssues() - )) { - // keep soldiering on - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PropertyTypeCoercion( $var_id . ' expects \'' . $class_property_type->getId() . '\', ' . ' parent type \'' . $assignment_type->getId() . '\' provided', @@ -216,14 +214,12 @@ public static function analyze( $assigned_property->id ), $statements_analyzer->getSuppressedIssues() - )) { - // keep soldiering on - } + ); } } if ($union_comparison_results->to_string_cast) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImplicitToStringCast( $var_id . ' expects \'' . $class_property_type . '\', ' . '\'' . $assignment_type . '\' provided with a __toString method', @@ -234,9 +230,7 @@ public static function analyze( ) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if (!$type_match_found && !$union_comparison_results->type_coerced) { @@ -378,15 +372,13 @@ public static function trackPropertyImpurity( if (!$can_set_readonly_property) { if ($property_storage->readonly) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InaccessibleProperty( $property_id . ' is marked readonly', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif (!$declaring_class_storage->mutation_free && isset($project_analyzer->getIssuesToFix()['MissingImmutableAnnotation']) && $statements_analyzer->getSource() @@ -953,16 +945,14 @@ private static function analyzeAtomicAssignment( } if (!$class_exists && !$interface_exists) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedClass( 'Cannot set properties of undefined class ' . $lhs_type_part->value, new CodeLocation($statements_analyzer->getSource(), $stmt), $lhs_type_part->value ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return null; } @@ -1066,16 +1056,14 @@ private static function analyzeAtomicAssignment( } if (!$class_exists) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedMagicPropertyAssignment( 'Magic instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -1137,39 +1125,33 @@ private static function analyzeAtomicAssignment( return null; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedThisPropertyAssignment( 'Instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { if ($has_magic_setter) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedMagicPropertyAssignment( 'Magic instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedPropertyAssignment( 'Instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -1244,20 +1226,18 @@ private static function analyzeAtomicAssignment( $property_storage = $declaring_class_storage->properties[$prop_name]; if ($property_storage->deprecated) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedProperty( $property_id . ' is marked deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($context->self && !NamespaceAnalyzer::isWithin($context->self, $property_storage->internal)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InternalProperty( $property_id . ' is internal to ' . $property_storage->internal . ' but called from ' . $context->self, @@ -1265,9 +1245,7 @@ private static function analyzeAtomicAssignment( $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } self::trackPropertyImpurity( @@ -1286,15 +1264,13 @@ private static function analyzeAtomicAssignment( && !$context->vars_in_scope[$lhs_var_id]->allow_mutations ) { if ($context->mutation_free) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpurePropertyAssignment( 'Cannot assign to a property from a mutation-free context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations @@ -1397,16 +1373,14 @@ private static function analyzeAtomicAssignment( $origin_location = null; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedAssignment( $message, new CodeLocation($statements_analyzer->getSource(), $stmt), $origin_location ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/StaticPropertyAssignmentAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/StaticPropertyAssignmentAnalyzer.php index dcce6046833..a77cc5164d4 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/StaticPropertyAssignmentAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/StaticPropertyAssignmentAnalyzer.php @@ -110,16 +110,14 @@ public static function analyze( } if (!$codebase->properties->propertyExists($property_id, false, $statements_analyzer, $context)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedPropertyAssignment( 'Static property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return null; } @@ -244,7 +242,7 @@ public static function analyze( if ($union_comparison_results->type_coerced) { if ($union_comparison_results->type_coerced_from_mixed) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedPropertyTypeCoercion( $var_id . ' expects \'' . $class_property_type->getId() . '\', ' . ' parent type `' . $assignment_value_type->getId() . '` provided', @@ -256,11 +254,9 @@ public static function analyze( $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // keep soldiering on - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PropertyTypeCoercion( $var_id . ' expects \'' . $class_property_type->getId() . '\', ' . ' parent type \'' . $assignment_value_type->getId() . '\' provided', @@ -272,14 +268,12 @@ public static function analyze( $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // keep soldiering on - } + ); } } if ($union_comparison_results->to_string_cast) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImplicitToStringCast( $var_id . ' expects \'' . $class_property_type . '\', ' . '\'' . $assignment_value_type . '\' provided with a __toString method', @@ -290,9 +284,7 @@ public static function analyze( ) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if (!$type_match_found && !$union_comparison_results->type_coerced) { diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php index e41a1424b54..661097f1b93 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php @@ -137,23 +137,19 @@ public static function analyze( $file_storage->type_aliases ); } catch (IncorrectDocblockException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingDocblockType( $e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $assign_var) ) - )) { - // fall through - } + ); } catch (DocblockParseException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( $e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $assign_var) ) - )) { - // fall through - } + ); } foreach ($var_comments as $var_comment) { @@ -296,14 +292,12 @@ public static function analyze( if ($array_var_id && isset($context->vars_in_scope[$array_var_id])) { if ($context->vars_in_scope[$array_var_id]->by_ref) { if ($context->mutation_free) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureByReferenceAssignment( 'Variable ' . $array_var_id . ' cannot be assigned to as it is passed by reference', new CodeLocation($statements_analyzer->getSource(), $assign_var) ) - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations ) { @@ -384,16 +378,14 @@ public static function analyze( $origin_location = null; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedAssignment( $message, $issue_location, $origin_location ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } else { if (!$context->collect_initializations @@ -418,7 +410,7 @@ public static function analyze( $assign_value_type->ignore_falsable_issues ) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ReferenceConstraintViolation( 'Variable ' . $var_id . ' is limited to values of type ' . $context->byref_constraints[$var_id]->type @@ -427,9 +419,7 @@ public static function analyze( new CodeLocation($statements_analyzer->getSource(), $assign_var) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -447,15 +437,13 @@ public static function analyze( if (isset($context->protected_var_ids[$var_id]) && $assign_value_type->hasLiteralInt() ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new LoopInvalidation( 'Variable ' . $var_id . ' has already been assigned in a for/foreach loop', new CodeLocation($statements_analyzer->getSource(), $assign_var) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($assign_var instanceof PhpParser\Node\Expr\Variable) { @@ -527,15 +515,13 @@ public static function analyze( if ($var_id && isset($context->vars_in_scope[$var_id])) { if ($context->vars_in_scope[$var_id]->isVoid()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new AssignmentToVoid( 'Cannot assign ' . $var_id . ' to type void', new CodeLocation($statements_analyzer->getSource(), $assign_var) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); $context->vars_in_scope[$var_id] = Type::getNull(); @@ -706,14 +692,12 @@ public static function assignTypeFromVarDocblock( $context->vars_in_scope[$var_comment->var_id] = $var_comment_type; } catch (\UnexpectedValueException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( $e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $stmt) ) - )) { - // fall through - } + ); } } @@ -967,15 +951,13 @@ public static function assignByRefParam( && !strpos($var_id, '->') && !strpos($var_id, '::') ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\NullReference( 'Not expecting null argument passed by reference', $location ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($stmt instanceof PhpParser\Node\Expr\Variable) { @@ -1070,15 +1052,13 @@ private static function analyzeDestructuringAssignment( && !$assign_value_type->isMixed() && !$assign_value_type->hasArrayAccessInterface($codebase) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidArrayOffset( 'Cannot destructure non-array of type ' . $assign_value_type->getId(), new CodeLocation($statements_analyzer->getSource(), $assign_var) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $can_be_empty = true; @@ -1135,15 +1115,13 @@ private static function analyzeDestructuringAssignment( $value_type = $assign_value_atomic_type->properties[$offset_value]; if ($value_type->possibly_undefined) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyUndefinedArrayOffset( 'Possibly undefined array key', new CodeLocation($statements_analyzer->getSource(), $var) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); $value_type = clone $value_type; $value_type->possibly_undefined = false; @@ -1188,28 +1166,24 @@ private static function analyzeDestructuringAssignment( } if ($assign_value_atomic_type->sealed) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidArrayOffset( 'Cannot access value with offset ' . $offset, new CodeLocation($statements_analyzer->getSource(), $var) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } if ($assign_value_atomic_type instanceof Type\Atomic\TMixed) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedArrayAccess( 'Cannot access array value on mixed variable ' . $array_var_id, new CodeLocation($statements_analyzer->getSource(), $var) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($assign_value_atomic_type instanceof Type\Atomic\TNull) { $has_null = true; @@ -1358,15 +1332,13 @@ private static function analyzeDestructuringAssignment( clone $assign_value_atomic_type->properties[$assign_var_item->key->value]; if ($new_assign_type->possibly_undefined) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyUndefinedArrayOffset( 'Possibly undefined array key', new CodeLocation($statements_analyzer->getSource(), $var) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); $new_assign_type->possibly_undefined = false; } @@ -1428,14 +1400,12 @@ private static function analyzeDestructuringAssignment( break; } } catch (\UnexpectedValueException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( $e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $assign_var) ) - )) { - // fall through - } + ); } } @@ -1572,15 +1542,13 @@ private static function analyzePropertyAssignment( && !$context->collect_initializations ) { if ($context->mutation_free || $context->external_mutation_free) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpurePropertyAssignment( 'Cannot assign to a property from a mutation-free context', new CodeLocation($statements_analyzer, $assign_var) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations ) { diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php index 28253bcc22c..024ec7ace51 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php @@ -214,25 +214,21 @@ public static function analyze( $first_left_message = $invalid_left_messages[0]; if ($has_valid_left_operand) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyInvalidOperand( $first_left_message, new CodeLocation($statements_source, $left) ), $statements_source->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidOperand( $first_left_message, new CodeLocation($statements_source, $left) ), $statements_source->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -240,38 +236,32 @@ public static function analyze( $first_right_message = $invalid_right_messages[0]; if ($has_valid_right_operand) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyInvalidOperand( $first_right_message, new CodeLocation($statements_source, $right) ), $statements_source->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidOperand( $first_right_message, new CodeLocation($statements_source, $right) ), $statements_source->getSuppressedIssues() - )) { - // fall through - } + ); } } if ($has_string_increment && $statements_source) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new StringIncrement( 'Possibly unintended string increment', new CodeLocation($statements_source, $left) ), $statements_source->getSuppressedIssues() - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ConcatAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ConcatAnalyzer.php index 79b298c514e..b4b8d618f7e 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ConcatAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ConcatAnalyzer.php @@ -85,16 +85,14 @@ public static function analyze( $origin_location = null; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedOperand( 'Left operand cannot be mixed', $arg_location, $origin_location ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { $arg_location = new CodeLocation($statements_analyzer->getSource(), $right); $origin_locations = []; @@ -114,16 +112,14 @@ public static function analyze( $origin_location = null; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedOperand( 'Right operand cannot be mixed', $arg_location, $origin_location ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } return; @@ -263,55 +259,47 @@ private static function analyzeOperand( $config = Config::getInstance(); if ($operand_type->isNull()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new NullOperand( 'Cannot concatenate with a ' . $operand_type, new CodeLocation($statements_analyzer->getSource(), $operand) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return; } if ($operand_type->isFalse()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new FalseOperand( 'Cannot concatenate with a ' . $operand_type, new CodeLocation($statements_analyzer->getSource(), $operand) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return; } if ($operand_type->isNullable() && !$operand_type->ignore_nullable_issues) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyNullOperand( 'Cannot concatenate with a possibly null ' . $operand_type, new CodeLocation($statements_analyzer->getSource(), $operand) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($operand_type->isFalsable() && !$operand_type->ignore_falsable_issues) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyFalseOperand( 'Cannot concatenate with a possibly false ' . $operand_type, new CodeLocation($statements_analyzer->getSource(), $operand) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $operand_type_match = true; @@ -320,15 +308,13 @@ private static function analyzeOperand( foreach ($operand_type->getAtomicTypes() as $operand_type_part) { if ($operand_type_part instanceof Type\Atomic\TTemplateParam && !$operand_type_part->as->isString()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedOperand( "$side operand cannot be a non-string template param", new CodeLocation($statements_analyzer->getSource(), $operand) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return; } @@ -351,15 +337,13 @@ private static function analyzeOperand( $has_valid_operand = $has_valid_operand || $operand_type_part_match; if ($comparison_result->to_string_cast && $config->strict_binary_operands) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImplicitToStringCast( "$side side of concat op expects string, '$operand_type' provided with a __toString method", new CodeLocation($statements_analyzer->getSource(), $operand) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } foreach ($operand_type->getAtomicTypes() as $atomic_type) { @@ -388,16 +372,14 @@ private static function analyzeOperand( } if ($context->mutation_free && !$storage->mutation_free) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureMethodCall( 'Cannot call a possibly-mutating method ' . $atomic_type->value . '::__toString from a pure context', new CodeLocation($statements_analyzer, $operand) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations @@ -414,25 +396,21 @@ private static function analyzeOperand( && (!$comparison_result->scalar_type_match_found || $config->strict_binary_operands) ) { if ($has_valid_operand) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyInvalidOperand( 'Cannot concatenate with a ' . $operand_type, new CodeLocation($statements_analyzer->getSource(), $operand) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidOperand( 'Cannot concatenate with a ' . $operand_type, new CodeLocation($statements_analyzer->getSource(), $operand) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOpAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOpAnalyzer.php index f599b317093..745555521ff 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOpAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOpAnalyzer.php @@ -227,15 +227,13 @@ public static function analyze( && (($stmt_left_type->isSingle() && $stmt_left_type->hasBool()) || ($stmt_right_type->isSingle() && $stmt_right_type->hasBool())) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidOperand( 'Cannot compare ' . $stmt_left_type->getId() . ' to ' . $stmt_right_type->getId(), new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if (($stmt instanceof PhpParser\Node\Expr\BinaryOp\Equal @@ -271,51 +269,43 @@ public static function analyze( || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Identical ) { if ($atomic_right_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\DocblockTypeContradiction( $atomic_right_type . ' string length is not ' . $string_length, new CodeLocation($statements_analyzer, $stmt), null ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\TypeDoesNotContainType( $atomic_right_type . ' string length is not ' . $string_length, new CodeLocation($statements_analyzer, $stmt), null ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } else { if ($atomic_right_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\RedundantConditionGivenDocblockType( $atomic_right_type . ' string length is never ' . $string_length, new CodeLocation($statements_analyzer, $stmt), null ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\RedundantCondition( $atomic_right_type . ' string length is never ' . $string_length, new CodeLocation($statements_analyzer, $stmt), null ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -471,16 +461,14 @@ private static function checkForImpureEqualityComparison( $statements_analyzer->getSource()->inferred_has_mutation = true; $statements_analyzer->getSource()->inferred_impure = true; } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureMethodCall( 'Cannot call a possibly-mutating method ' . $atomic_type->value . '::__toString from a pure context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -506,16 +494,14 @@ private static function checkForImpureEqualityComparison( $statements_analyzer->getSource()->inferred_has_mutation = true; $statements_analyzer->getSource()->inferred_impure = true; } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureMethodCall( 'Cannot call a possibly-mutating method ' . $atomic_type->value . '::__toString from a pure context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/BitwiseNotAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/BitwiseNotAnalyzer.php index 25e183d9977..59324f54ddb 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/BitwiseNotAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/BitwiseNotAnalyzer.php @@ -65,25 +65,21 @@ public static function analyze( if ($unacceptable_type || !$acceptable_types) { $message = 'Cannot negate a non-numeric non-string type ' . $unacceptable_type; if ($has_valid_operand) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyInvalidOperand( $message, new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidOperand( $message, new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $statements_analyzer->node_data->setType($stmt, Type::getMixed()); diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php index 078371ecc1a..c4052ea9764 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php @@ -110,7 +110,7 @@ public static function checkArgumentMatches( } if ($param_type && !$param_type->hasMixed()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedArgument( 'Argument ' . ($argument_offset + 1) . ' of ' . $cased_method_id . ' cannot be mixed, expecting ' . $param_type, @@ -118,9 +118,7 @@ public static function checkArgumentMatches( $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -155,7 +153,7 @@ public static function checkArgumentMatches( } if (count($values) < 12 || ($gt_count / count($values)) < 0.8) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidLiteralArgument( 'Argument ' . ($argument_offset + 1) . ' of ' . $cased_method_id . ' expects a non-literal value, ' . $arg_value_type->getId() . ' provided', @@ -163,9 +161,7 @@ public static function checkArgumentMatches( $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -419,7 +415,7 @@ private static function checkFunctionLikeTypeMatches( $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath()); } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedArgument( 'Argument ' . ($argument_offset + 1) . ' of ' . $cased_method_id . ' cannot unpack ' . $arg_type->getId() . ', expecting iterable', @@ -427,9 +423,7 @@ private static function checkFunctionLikeTypeMatches( $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); if ($cased_method_id) { $arg_location = new CodeLocation($statements_analyzer->getSource(), $arg->value); @@ -503,7 +497,7 @@ private static function checkFunctionLikeTypeMatches( } if (!$arg_key_allowed) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new NamedArgumentNotAllowed( 'Method ' . $cased_method_id . ' called with named unpacked array ' . $unpacked_atomic_array->getId() @@ -512,9 +506,7 @@ private static function checkFunctionLikeTypeMatches( $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } else { $non_iterable = false; @@ -546,19 +538,17 @@ private static function checkFunctionLikeTypeMatches( $issue_type = $possibly_matches ? PossiblyInvalidArgument::class : InvalidArgument::class; if ($non_iterable) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new $issue_type( 'Tried to unpack non-iterable ' . $arg_type->getId(), new CodeLocation($statements_analyzer->getSource(), $arg->value), $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($invalid_key) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new $issue_type( 'Method ' . $cased_method_id . ' called with unpacked iterable ' . $arg_type->getId() @@ -568,24 +558,20 @@ private static function checkFunctionLikeTypeMatches( $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($invalid_string_key) { if ($codebase->php_major_version < 8) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new $issue_type( 'String keys not supported in unpacked arguments', new CodeLocation($statements_analyzer->getSource(), $arg->value), $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new NamedArgumentNotAllowed( 'Method ' . $cased_method_id . ' called with named unpacked iterable ' . $arg_type->getId() @@ -594,9 +580,7 @@ private static function checkFunctionLikeTypeMatches( $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -604,16 +588,14 @@ private static function checkFunctionLikeTypeMatches( } } else { if (!$allow_named_args && $arg->name !== null) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new NamedArgumentNotAllowed( 'Method ' . $cased_method_id. ' called with named argument ' . $arg->name->name, new CodeLocation($statements_analyzer->getSource(), $arg->value), $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -745,7 +727,7 @@ public static function verifyType( $origin_location = null; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedArgument( 'Argument ' . ($argument_offset + 1) . $method_identifier . ' cannot be ' . $input_type->getId() . ', expecting ' . @@ -755,9 +737,7 @@ public static function verifyType( $origin_location ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); if ($input_type->isMixed()) { if (!$function_param->by_ref @@ -802,15 +782,13 @@ public static function verifyType( } if ($input_type->isNever()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new NoValue( 'This function or method call never returns output', $arg_location ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return null; } @@ -970,7 +948,7 @@ public static function verifyType( $origin_location = null; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedArgumentTypeCoercion( 'Argument ' . ($argument_offset + 1) . $method_identifier . ' expects ' . $param_type->getId() . ', parent type ' . $input_type->getId() . ' provided', @@ -979,11 +957,9 @@ public static function verifyType( $origin_location ), $statements_analyzer->getSuppressedIssues() - )) { - // keep soldiering on - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ArgumentTypeCoercion( 'Argument ' . ($argument_offset + 1) . $method_identifier . ' expects ' . $param_type->getId() . ', parent type ' . $input_type->getId() . ' provided', @@ -991,23 +967,19 @@ public static function verifyType( $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // keep soldiering on - } + ); } } if ($union_comparison_results->to_string_cast && $cased_method_id !== 'echo' && $cased_method_id !== 'print') { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImplicitToStringCast( 'Argument ' . ($argument_offset + 1) . $method_identifier . ' expects ' . $param_type->getId() . ', ' . $input_type->getId() . ' provided with a __toString method', $arg_location ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if (!$type_match_found && !$union_comparison_results->type_coerced) { @@ -1022,7 +994,7 @@ public static function verifyType( $type = ($input_type->possibly_undefined ? 'possibly undefined ' : '') . $input_type->getId(); if ($union_comparison_results->scalar_type_match_found) { if ($cased_method_id !== 'echo' && $cased_method_id !== 'print') { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidScalarArgument( 'Argument ' . ($argument_offset + 1) . $method_identifier . ' expects ' . $param_type->getId() . ', ' . $type . ' provided', @@ -1030,12 +1002,10 @@ public static function verifyType( $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } elseif ($types_can_be_identical) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyInvalidArgument( 'Argument ' . ($argument_offset + 1) . $method_identifier . ' expects ' . $param_type->getId() . ', possibly different type ' . $type . ' provided', @@ -1043,11 +1013,9 @@ public static function verifyType( $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidArgument( 'Argument ' . ($argument_offset + 1) . $method_identifier . ' expects ' . $param_type->getId() . ', ' . $type . ' provided', @@ -1055,9 +1023,7 @@ public static function verifyType( $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } return null; @@ -1080,7 +1046,7 @@ public static function verifyType( if (!$param_type->isNullable() && $cased_method_id !== 'echo' && $cased_method_id !== 'print') { if ($input_type->isNull()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new NullArgument( 'Argument ' . ($argument_offset + 1) . $method_identifier . ' cannot be null, ' . 'null value provided to parameter with type ' . $param_type->getId(), @@ -1088,15 +1054,13 @@ public static function verifyType( $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return null; } if ($input_type->isNullable() && !$input_type->ignore_nullable_issues) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyNullArgument( 'Argument ' . ($argument_offset + 1) . $method_identifier . ' cannot be null, possibly ' . 'null value provided', @@ -1104,9 +1068,7 @@ public static function verifyType( $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -1117,7 +1079,7 @@ public static function verifyType( $cased_method_id !== 'print' ) { if ($input_type->isFalse()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidArgument( 'Argument ' . ($argument_offset + 1) . $method_identifier . ' cannot be false, ' . $param_type->getId() . ' value expected', @@ -1125,15 +1087,13 @@ public static function verifyType( $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return null; } if ($input_type->isFalsable() && !$input_type->ignore_falsable_issues) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyFalseArgument( 'Argument ' . ($argument_offset + 1) . $method_identifier . ' cannot be false, possibly ' . $param_type->getId() . ' value expected', @@ -1141,9 +1101,7 @@ public static function verifyType( $cased_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php index 4792a545805..d1692deb30c 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php @@ -673,7 +673,7 @@ public static function checkArgumentsMatch( if ($candidate_param->name === $key_type->value || $candidate_param->is_variadic) { if ($candidate_param->name === $key_type->value) { if (isset($matched_args[$candidate_param->name])) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidNamedArgument( 'Parameter $' . $key_type->value . ' has already been used in ' . ($cased_method_id ?: $method_id), @@ -681,9 +681,7 @@ public static function checkArgumentsMatch( (string)$method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $matched_args[$candidate_param->name] = true; @@ -695,7 +693,7 @@ public static function checkArgumentsMatch( } if (!$param_found) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidNamedArgument( 'Parameter $' . $key_type->value . ' does not exist on function ' . ($cased_method_id ?: $method_id), @@ -703,9 +701,7 @@ public static function checkArgumentsMatch( (string)$method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -715,7 +711,7 @@ public static function checkArgumentsMatch( if ($candidate_param->name === $arg->name->name || $candidate_param->is_variadic) { if ($candidate_param->name === $arg->name->name) { if (isset($matched_args[$candidate_param->name])) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidNamedArgument( 'Parameter $' . $arg->name->name . ' has already been used in ' . ($cased_method_id ?: $method_id), @@ -723,9 +719,7 @@ public static function checkArgumentsMatch( (string) $method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $matched_args[$candidate_param->name] = true; @@ -737,7 +731,7 @@ public static function checkArgumentsMatch( } if (!isset($arg_function_params[$argument_offset])) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidNamedArgument( 'Parameter $' . $arg->name->name . ' does not exist on function ' . ($cased_method_id ?: $method_id), @@ -745,9 +739,7 @@ public static function checkArgumentsMatch( (string) $method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } elseif ($function_param_count > $argument_offset) { $arg_function_params[$argument_offset] = [$function_params[$argument_offset]]; @@ -846,27 +838,23 @@ public static function checkArgumentsMatch( if ($method_id === 'array_map' || $method_id === 'array_filter') { if ($method_id === 'array_map' && count($args) < 2) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TooFewArguments( 'Too few arguments for ' . $method_id, $code_location, $method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($method_id === 'array_filter' && count($args) < 1) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TooFewArguments( 'Too few arguments for ' . $method_id, $code_location, $method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } ArrayFunctionArgumentsAnalyzer::checkArgumentsMatch( @@ -934,15 +922,13 @@ private static function handlePossiblyMatchingByRefParam( ) ) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidPassByReference( 'Parameter ' . ($argument_offset + 1) . ' of ' . $cased_method_id . ' expects a variable', new CodeLocation($statements_analyzer->getSource(), $arg->value) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return false; } @@ -1120,16 +1106,14 @@ private static function evaluateArbitraryParam( if (!isset($context->vars_in_scope[$var_id]) && $arg->value instanceof PhpParser\Node\Expr\Variable ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyUndefinedVariable( 'Variable ' . $var_id . ' must be defined prior to use within an unknown function or method', new CodeLocation($statements_analyzer->getSource(), $arg->value) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } // we don't know if it exists, assume it's passed by reference @@ -1421,7 +1405,7 @@ private static function checkArgCount( || ($method_id instanceof MethodIdentifier && $method_id->method_name === '__construct')) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TooManyArguments( 'Too many arguments for ' . ($cased_method_id ?: $method_id) . ' - expecting ' . count($function_params) . ' but saw ' . count($args), @@ -1429,9 +1413,7 @@ private static function checkArgCount( (string)$method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return; } @@ -1462,7 +1444,7 @@ private static function checkArgCount( || ($method_id instanceof MethodIdentifier && $method_id->method_name === '__construct')) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TooFewArguments( 'Too few arguments for ' . $cased_method_id . ' - expecting ' . $expected_param_count @@ -1471,9 +1453,7 @@ private static function checkArgCount( (string)$method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); break; } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArrayFunctionArgumentsAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArrayFunctionArgumentsAnalyzer.php index b4c2bdefed4..6f4017e92db 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArrayFunctionArgumentsAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArrayFunctionArgumentsAnalyzer.php @@ -766,7 +766,7 @@ private static function checkClosureTypeArgs( if (count($closure_params) < $min_closure_param_count) { $argument_text = $min_closure_param_count === 1 ? 'one argument' : $min_closure_param_count . ' arguments'; - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TooManyArguments( 'The callable passed to ' . $method_id . ' will be called with ' . $argument_text . ', expecting ' . $required_param_count, @@ -774,9 +774,7 @@ private static function checkClosureTypeArgs( $method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return; } @@ -784,7 +782,7 @@ private static function checkClosureTypeArgs( if ($required_param_count > $max_closure_param_count) { $argument_text = $max_closure_param_count === 1 ? 'one argument' : $max_closure_param_count . ' arguments'; - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TooFewArguments( 'The callable passed to ' . $method_id . ' will be called with ' . $argument_text . ', expecting ' . $required_param_count, @@ -792,9 +790,7 @@ private static function checkClosureTypeArgs( $method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return; } @@ -880,7 +876,7 @@ private static function checkClosureTypeArgs( if ($union_comparison_results->type_coerced) { if ($union_comparison_results->type_coerced_from_mixed) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedArgumentTypeCoercion( 'Parameter ' . ($i + 1) . ' of closure passed to function ' . $method_id . ' expects ' . $closure_param_type->getId() . ', parent type ' . $input_type->getId() . ' provided', @@ -888,11 +884,9 @@ private static function checkClosureTypeArgs( $method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // keep soldiering on - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ArgumentTypeCoercion( 'Parameter ' . ($i + 1) . ' of closure passed to function ' . $method_id . ' expects ' . $closure_param_type->getId() . ', parent type ' . $input_type->getId() . ' provided', @@ -900,9 +894,7 @@ private static function checkClosureTypeArgs( $method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // keep soldiering on - } + ); } } @@ -914,7 +906,7 @@ private static function checkClosureTypeArgs( ); if ($union_comparison_results->scalar_type_match_found) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidScalarArgument( 'Parameter ' . ($i + 1) . ' of closure passed to function ' . $method_id . ' expects ' . $closure_param_type->getId() . ', ' . $input_type->getId() . ' provided', @@ -922,11 +914,9 @@ private static function checkClosureTypeArgs( $method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($types_can_be_identical) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyInvalidArgument( 'Parameter ' . ($i + 1) . ' of closure passed to function ' . $method_id . ' expects ' . $closure_param_type->getId() . ', possibly different type ' @@ -935,9 +925,7 @@ private static function checkClosureTypeArgs( $method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif (IssueBuffer::accepts( new InvalidArgument( 'Parameter ' . ($i + 1) . ' of closure passed to function ' . $method_id . ' expects ' . diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.php index 7c4ace3d8c3..9e97cd6696e 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.php @@ -308,16 +308,14 @@ function (Assertion $assertion) use ($inferred_lower_bounds, $codebase) : Assert } if ($function_call_info->function_storage->deprecated && $function_call_info->function_id) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedFunction( 'The function ' . $function_call_info->function_id . ' has been marked as deprecated', $code_location, $function_call_info->function_id ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); } } @@ -537,29 +535,25 @@ private static function getAnalyzeNamedExpression( if ($stmt_name_type = $statements_analyzer->node_data->getType($function_name)) { if ($stmt_name_type->isNull()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new NullFunctionCall( 'Cannot call function on null value', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return $function_call_info; } if ($stmt_name_type->isNullable()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyNullFunctionCall( 'Cannot call function on possibly null value', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $invalid_function_call_types = []; @@ -577,15 +571,13 @@ private static function getAnalyzeNamedExpression( if ($var_type_part instanceof Type\Atomic\TClosure || $var_type_part instanceof TCallable) { if (!$var_type_part->is_pure && $context->pure) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureFunctionCall( 'Cannot call an impure function from a mutation-free context', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $function_call_info->function_params = $var_type_part->params; @@ -616,15 +608,13 @@ private static function getAnalyzeNamedExpression( } elseif ($var_type_part instanceof TMixed || $var_type_part instanceof TTemplateParam) { $has_valid_function_call_type = true; - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedFunctionCall( 'Cannot call function on ' . $var_type_part->getId(), new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($var_type_part instanceof TCallableObject || $var_type_part instanceof TCallableString ) { @@ -711,25 +701,21 @@ private static function getAnalyzeNamedExpression( $var_type_part = reset($invalid_function_call_types); if ($has_valid_function_call_type) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyInvalidFunctionCall( 'Cannot treat type ' . $var_type_part . ' as callable', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidFunctionCall( 'Cannot treat type ' . $var_type_part . ' as callable', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } return $function_call_info; @@ -963,15 +949,13 @@ private static function checkFunctionCallPurity( || ($callmap_function_pure === false) ) { if ($context->mutation_free || $context->external_mutation_free) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureFunctionCall( 'Cannot call an impure function from a mutation-free context', new CodeLocation($statements_analyzer, $function_name) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations ) { @@ -1004,16 +988,14 @@ private static function checkFunctionCallPurity( $function_call_info->function_storage->return_type->isNever() ) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UnusedFunctionCall( 'The call to ' . $function_call_info->function_id . ' is not used', new CodeLocation($statements_analyzer, $function_name), $function_call_info->function_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { $stmt->setAttribute('pure', true); } 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 38febd4e269..a8f24804a2b 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php @@ -612,16 +612,14 @@ private static function handleInvalidClass( $origin_location = null; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedMethodCall( $message, $name_code_location, $origin_location ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/ExistingAtomicMethodCallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/ExistingAtomicMethodCallAnalyzer.php index 0c0e1980e7a..13202539872 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/ExistingAtomicMethodCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/ExistingAtomicMethodCallAnalyzer.php @@ -535,7 +535,7 @@ private static function getMagicGetterOrSetterProperty( if ($union_comparison_results->type_coerced) { if ($union_comparison_results->type_coerced_from_mixed) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedPropertyTypeCoercion( $prop_name . ' expects \'' . $pseudo_set_type->getId() . '\', ' . ' parent type `' . $second_arg_type . '` provided', @@ -543,11 +543,9 @@ private static function getMagicGetterOrSetterProperty( $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // keep soldiering on - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PropertyTypeCoercion( $prop_name . ' expects \'' . $pseudo_set_type->getId() . '\', ' . ' parent type `' . $second_arg_type . '` provided', @@ -555,9 +553,7 @@ private static function getMagicGetterOrSetterProperty( $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // keep soldiering on - } + ); } } @@ -567,7 +563,7 @@ private static function getMagicGetterOrSetterProperty( $second_arg_type, $pseudo_set_type )) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyInvalidPropertyAssignmentValue( $prop_name . ' with declared type \'' . $pseudo_set_type @@ -576,11 +572,9 @@ private static function getMagicGetterOrSetterProperty( $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidPropertyAssignmentValue( $prop_name . ' with declared type \'' . $pseudo_set_type @@ -589,9 +583,7 @@ private static function getMagicGetterOrSetterProperty( $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallProhibitionAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallProhibitionAnalyzer.php index a5724d1a7a5..175272bf3e8 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallProhibitionAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallProhibitionAnalyzer.php @@ -35,7 +35,7 @@ public static function analyze( $storage = $codebase_methods->getStorage($method_id); if ($storage->deprecated) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedMethod( 'The method ' . $codebase_methods->getCasedMethodId($method_id) . ' has been marked as deprecated', @@ -43,16 +43,14 @@ public static function analyze( (string) $method_id ), $suppressed_issues - )) { - // continue - } + ); } if (!$context->collect_initializations && !$context->collect_mutations ) { if (!NamespaceAnalyzer::isWithin($namespace ?: '', $storage->internal)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InternalMethod( 'The method ' . $codebase_methods->getCasedMethodId($method_id) . ' is internal to ' . $storage->internal @@ -61,9 +59,7 @@ public static function analyze( (string) $method_id ), $suppressed_issues - )) { - // fall through - } + ); } } return null; diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallPurityAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallPurityAnalyzer.php index 54e63533988..dd1a130d384 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallPurityAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallPurityAnalyzer.php @@ -35,45 +35,39 @@ public static function analyze( && !$method_storage->mutation_free && !$method_pure_compatible ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureMethodCall( 'Cannot call a non-mutation-free method ' . $cased_method_id . ' from a pure context', new CodeLocation($statements_analyzer, $stmt->name) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($context->mutation_free && !$method_storage->mutation_free && !$method_pure_compatible ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureMethodCall( 'Cannot call a possibly-mutating method ' . $cased_method_id . ' from a mutation-free context', new CodeLocation($statements_analyzer, $stmt->name) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($context->external_mutation_free && !$method_storage->mutation_free && $method_id->fq_class_name !== $context->self && !$method_pure_compatible ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureMethodCall( 'Cannot call a possibly-mutating method ' . $cased_method_id . ' from a mutation-free context', new CodeLocation($statements_analyzer, $stmt->name) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif (($method_storage->mutation_free || ($method_storage->external_mutation_free && ($stmt->var->getAttribute('external_mutation_free', false) @@ -114,16 +108,14 @@ public static function analyze( && !$method_storage->if_false_assertions && !$method_storage->throws ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\UnusedMethodCall( 'The call to ' . $cased_method_id . ' is not used', new CodeLocation($statements_analyzer, $stmt->name), (string) $method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif (!$method_storage->mutation_free_inferred) { $stmt->setAttribute('pure', true); } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php index 8d85d521fbf..85aff3c251b 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php @@ -139,15 +139,13 @@ public static function analyze( && !($stmt->name->name === 'offsetGet' && $context->inside_isset) && !self::hasNullsafe($stmt->var) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyNullReference( 'Cannot call method ' . $stmt->name->name . ' on possibly null value', new CodeLocation($statements_analyzer->getSource(), $stmt->name) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($class_type @@ -155,15 +153,13 @@ public static function analyze( && $class_type->isFalsable() && !$class_type->ignore_falsable_issues ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyFalseReference( 'Cannot call method ' . $stmt->name->name . ' on possibly false value', new CodeLocation($statements_analyzer->getSource(), $stmt->name) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $codebase = $statements_analyzer->getCodebase(); @@ -231,67 +227,57 @@ function (?Type\Union $type_1, Type\Union $type_2) use ($codebase): Type\Union { $invalid_class_type = $result->invalid_method_call_types[0]; if ($result->has_valid_method_call_type || $result->has_mixed_method_call) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyInvalidMethodCall( 'Cannot call method on possible ' . $invalid_class_type . ' variable ' . $lhs_var_id, new CodeLocation($source, $stmt->name) ), $statements_analyzer->getSuppressedIssues() - )) { - // keep going - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidMethodCall( 'Cannot call method on ' . $invalid_class_type . ' variable ' . $lhs_var_id, new CodeLocation($source, $stmt->name) ), $statements_analyzer->getSuppressedIssues() - )) { - // keep going - } + ); } } if ($result->non_existent_magic_method_ids) { if ($context->check_methods) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedMagicMethod( 'Magic method ' . $result->non_existent_magic_method_ids[0] . ' does not exist', new CodeLocation($source, $stmt->name), $result->non_existent_magic_method_ids[0] ), $statements_analyzer->getSuppressedIssues() - )) { - // keep going - } + ); } } if ($result->non_existent_class_method_ids) { if ($context->check_methods) { if ($result->existent_method_ids || $result->has_mixed_method_call) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyUndefinedMethod( 'Method ' . $result->non_existent_class_method_ids[0] . ' does not exist', new CodeLocation($source, $stmt->name), $result->non_existent_class_method_ids[0] ), $statements_analyzer->getSuppressedIssues() - )) { - // keep going - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedMethod( 'Method ' . $result->non_existent_class_method_ids[0] . ' does not exist', new CodeLocation($source, $stmt->name), $result->non_existent_class_method_ids[0] ), $statements_analyzer->getSuppressedIssues() - )) { - // keep going - } + ); } } @@ -301,27 +287,23 @@ function (?Type\Union $type_1, Type\Union $type_2) use ($codebase): Type\Union { if ($result->non_existent_interface_method_ids) { if ($context->check_methods) { if ($result->existent_method_ids || $result->has_mixed_method_call) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyUndefinedMethod( 'Method ' . $result->non_existent_interface_method_ids[0] . ' does not exist', new CodeLocation($source, $stmt->name), $result->non_existent_interface_method_ids[0] ), $statements_analyzer->getSuppressedIssues() - )) { - // keep going - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedInterfaceMethod( 'Method ' . $result->non_existent_interface_method_ids[0] . ' does not exist', new CodeLocation($source, $stmt->name), $result->non_existent_interface_method_ids[0] ), $statements_analyzer->getSuppressedIssues() - )) { - // keep going - } + ); } } @@ -331,31 +313,27 @@ function (?Type\Union $type_1, Type\Union $type_2) use ($codebase): Type\Union { if ($result->too_many_arguments && $result->too_many_arguments_method_ids) { $error_method_id = $result->too_many_arguments_method_ids[0]; - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TooManyArguments( 'Too many arguments for method ' . $error_method_id . ' - saw ' . count($stmt->getArgs()), new CodeLocation($source, $stmt->name), (string) $error_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($result->too_few_arguments && $result->too_few_arguments_method_ids) { $error_method_id = $result->too_few_arguments_method_ids[0]; - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TooFewArguments( 'Too few arguments for method ' . $error_method_id . ' saw ' . count($stmt->getArgs()), new CodeLocation($source, $stmt->name), (string) $error_method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $stmt_type = $result->return_type; @@ -446,16 +424,14 @@ function (?Type\Union $type_1, Type\Union $type_2) use ($codebase): Type\Union { $storage->if_this_is_type ) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new IfThisIsMismatch( 'Class is not ' . (string) $storage->if_this_is_type . ' as required by psalm-if-this-is', new CodeLocation($source, $stmt->name) ), $statements_analyzer->getSuppressedIssues() - )) { - // keep going - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NamedFunctionCallHandler.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NamedFunctionCallHandler.php index c2e663a4a52..4a822a3ebe4 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NamedFunctionCallHandler.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NamedFunctionCallHandler.php @@ -241,27 +241,23 @@ public static function handle( if ($function_id === 'var_dump' || $function_id === 'shell_exec' ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ForbiddenCode( 'Unsafe ' . implode('', $function_name->parts), new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); } if (isset($codebase->config->forbidden_functions[strtolower((string) $function_name)])) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ForbiddenCode( 'You have forbidden the use of ' . $function_name, new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); return; } @@ -375,25 +371,21 @@ function (array $_) : bool { ) ) { if ($first_arg_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\RedundantCastGivenDocblockType( 'The call to array_values is unnecessary given the list docblock type '.$first_arg_type, new CodeLocation($statements_analyzer, $function_name) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\RedundantCast( 'The call to array_values is unnecessary, '.$first_arg_type.' is already a list', new CodeLocation($statements_analyzer, $function_name) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -408,25 +400,21 @@ function (array $_) : bool { ) ) { if ($first_arg_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\RedundantCastGivenDocblockType( 'The call to strtolower is unnecessary given the docblock type', new CodeLocation($statements_analyzer, $function_name) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\RedundantCast( 'The call to strtolower is unnecessary', new CodeLocation($statements_analyzer, $function_name) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -440,23 +428,19 @@ function (array $_) : bool { if ($first_arg_type && $first_arg_type->hasObjectType()) { if ($first_arg_type->isSingle()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\RawObjectIteration( 'Possibly undesired iteration over object properties', new CodeLocation($statements_analyzer, $function_name) ) - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\PossibleRawObjectIteration( 'Possibly undesired iteration over object properties', new CodeLocation($statements_analyzer, $function_name) ) - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.php index 8156b5de738..e306397c2b6 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.php @@ -263,16 +263,14 @@ private static function analyzeNamedConstructor( if ($from_static) { if (!$storage->preserve_constructor_signature) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UnsafeInstantiation( 'Cannot safely instantiate class ' . $fq_class_name . ' with "new static" as' . ' its constructor might change in child classes', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($storage->template_types && !$storage->enforce_template_inheritance ) { @@ -284,7 +282,7 @@ private static function analyzeNamedConstructor( if ($function_storage->return_type && preg_match('/\bstatic\b/', $function_storage->return_type->getId()) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UnsafeGenericInstantiation( 'Cannot safely instantiate generic class ' . $fq_class_name . ' with "new static" as' @@ -292,9 +290,7 @@ private static function analyzeNamedConstructor( new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -314,16 +310,14 @@ private static function analyzeNamedConstructor( } if ($storage->deprecated && strtolower($fq_class_name) !== strtolower((string)$context->self)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedClass( $fq_class_name . ' is marked deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } @@ -332,7 +326,7 @@ private static function analyzeNamedConstructor( && !$context->collect_mutations && !NamespaceAnalyzer::isWithin($context->self, $storage->internal) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InternalClass( $fq_class_name . ' is internal to ' . $storage->internal . ' but called from ' . $context->self, @@ -340,9 +334,7 @@ private static function analyzeNamedConstructor( $fq_class_name ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $method_id = new \Psalm\Internal\MethodIdentifier($fq_class_name, '__construct'); @@ -399,7 +391,7 @@ private static function analyzeNamedConstructor( $namespace, $method_storage->internal )) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InternalMethod( 'Constructor ' . $codebase->methods->getCasedMethodId($declaring_method_id) . ' is internal to ' . $method_storage->internal @@ -408,22 +400,18 @@ private static function analyzeNamedConstructor( (string) $method_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if (!$method_storage->external_mutation_free && !$context->inside_throw) { if ($context->pure) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureMethodCall( 'Cannot call an impure constructor from a pure context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations @@ -529,16 +517,14 @@ function ($bounds) use ($codebase) { ); } } elseif ($stmt->getArgs()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TooManyArguments( 'Class ' . $fq_class_name . ' has no __construct, but arguments were passed', new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name . '::__construct' ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($storage->template_types) { $result_atomic_type = new Type\Atomic\TGenericObject( $fq_class_name, @@ -676,15 +662,13 @@ private static function analyzeConstructorExpression( ); if (!$lhs_type_part->as_type) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedMethodCall( 'Cannot call constructor on an unknown class', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $new_type = Type::combineUnionTypes($new_type, new Type\Union([$new_type_part])); @@ -697,7 +681,7 @@ private static function analyzeConstructorExpression( ); if (!$as_storage->preserve_constructor_signature) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UnsafeInstantiation( 'Cannot safely instantiate class ' . $lhs_type_part->as_type->value . ' with "new $class_name" as' @@ -705,9 +689,7 @@ private static function analyzeConstructorExpression( new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -747,7 +729,7 @@ private static function analyzeConstructorExpression( ); if (!$as_storage->preserve_constructor_signature) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UnsafeInstantiation( 'Cannot safely instantiate class ' . $lhs_type_part->as_type->value . ' with "new $class_name" as' @@ -755,9 +737,7 @@ private static function analyzeConstructorExpression( new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } elseif ($lhs_type_part instanceof Type\Atomic\TDependentGetClass) { @@ -785,15 +765,13 @@ private static function analyzeConstructorExpression( } if ($generated_type instanceof Type\Atomic\TObject) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedMethodCall( 'Cannot call constructor on an unknown class', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $new_type = Type::combineUnionTypes($new_type, new Type\Union([$generated_type])); @@ -817,15 +795,13 @@ private static function analyzeConstructorExpression( // fall through } } elseif ($lhs_type_part instanceof Type\Atomic\TMixed) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedMethodCall( 'Cannot call constructor on an unknown class', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($lhs_type_part instanceof Type\Atomic\TFalse && $stmt_class_type->ignore_falsable_issues ) { 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 df3bcde536b..0bd645d2bfe 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php @@ -143,16 +143,14 @@ public static function analyze( } if (!$fq_class_name) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedClass( 'Type ' . $lhs_type_part->as . ' cannot be called as a class', new CodeLocation($statements_analyzer->getSource(), $stmt), (string) $lhs_type_part ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return; } @@ -521,25 +519,21 @@ private static function handleNamedCall( if (!$context->inside_throw) { if ($context->pure && !$callstatic_storage->pure) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureMethodCall( 'Cannot call an impure method from a pure context', new CodeLocation($statements_analyzer, $stmt_name) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($context->mutation_free&& !$callstatic_storage->mutation_free) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureMethodCall( 'Cannot call a possibly-mutating method from a mutation-free context', new CodeLocation($statements_analyzer, $stmt_name) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations @@ -676,20 +670,18 @@ function (PhpParser\Node\Arg $arg): PhpParser\Node\Expr\ArrayItem { $class_storage = $codebase->classlike_storage_provider->get($fq_class_name); if ($class_storage->deprecated && $fq_class_name !== $context->self) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedClass( $fq_class_name . ' is marked deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($context->self && ! NamespaceAnalyzer::isWithin($context->self, $class_storage->internal)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InternalClass( $fq_class_name . ' is internal to ' . $class_storage->internal . ' but called from ' . $context->self, @@ -697,9 +689,7 @@ function (PhpParser\Node\Arg $arg): PhpParser\Node\Expr\ArrayItem { $fq_class_name ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if (MethodVisibilityAnalyzer::analyze( @@ -920,15 +910,13 @@ public static function handleNonObjectCall( ); } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedMethodCall( 'Cannot call method on an unknown class', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return; } @@ -940,15 +928,13 @@ public static function handleNonObjectCall( return; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidStringClass( 'String cannot be used as a class', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return; } @@ -959,15 +945,13 @@ public static function handleNonObjectCall( return; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedClass( 'Type ' . $lhs_type_part . ' cannot be called as a class', new CodeLocation($statements_analyzer->getSource(), $stmt), (string) $lhs_type_part ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php index da6cea51fbc..fd106f5c715 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php @@ -255,38 +255,32 @@ public static function analyze( ]) )) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new AbstractMethodCall( 'Cannot call an abstract static method ' . $method_id . ' directly', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if (!$context->inside_throw) { if ($context->pure && !$method_storage->pure) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureMethodCall( 'Cannot call an impure method from a pure context', new CodeLocation($statements_analyzer, $stmt_name) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($context->mutation_free && !$method_storage->mutation_free) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureMethodCall( 'Cannot call a possibly-mutating method from a mutation-free context', new CodeLocation($statements_analyzer, $stmt_name) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php index a77e0094a45..3172a081333 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php @@ -599,16 +599,14 @@ public static function checkFunctionExists( ) { $function_id = $root_function_id; } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedFunction( 'Function ' . $cased_function_id . ' does not exist', $code_location, $function_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return false; } @@ -1022,7 +1020,7 @@ public static function checkTemplateResult( )) { if ($union_comparison_result->type_coerced) { if ($union_comparison_result->type_coerced_from_mixed) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedArgumentTypeCoercion( 'Type ' . $lower_bound_type->getId() . ' should be a subtype of ' . $upper_bound_type->getId(), @@ -1030,11 +1028,9 @@ public static function checkTemplateResult( $function_id ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ArgumentTypeCoercion( 'Type ' . $lower_bound_type->getId() . ' should be a subtype of ' . $upper_bound_type->getId(), @@ -1042,12 +1038,10 @@ public static function checkTemplateResult( $function_id ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); } } elseif ($union_comparison_result->scalar_type_match_found) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidScalarArgument( 'Type ' . $lower_bound_type->getId() . ' should be a subtype of ' . $upper_bound_type->getId(), @@ -1055,11 +1049,9 @@ public static function checkTemplateResult( $function_id ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidArgument( 'Type ' . $lower_bound_type->getId() . ' should be a subtype of ' . $upper_bound_type->getId(), @@ -1067,9 +1059,7 @@ public static function checkTemplateResult( $function_id ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); } } } else { @@ -1108,7 +1098,7 @@ function ($bound_with_equality) { ); if (count($equality_types) > 1) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidArgument( 'Incompatible types found for ' . $template_name . ' (must have only one of ' . implode(', ', $equality_types) . ')', @@ -1116,14 +1106,12 @@ function ($bound_with_equality) { $function_id ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); } else { foreach ($lower_bounds as $lower_bound) { if ($lower_bound->equality_bound_classlike === null) { if (!in_array($lower_bound->type->getId(), $equality_types, true)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidArgument( 'Incompatible types found for ' . $template_name . ' (' . $lower_bound->type->getId() . ' is not in ' . @@ -1132,9 +1120,7 @@ function ($bound_with_equality) { $function_id ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/CastAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/CastAnalyzer.php index e6dc20960fb..ce5b01d31df 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/CastAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/CastAnalyzer.php @@ -253,15 +253,13 @@ public static function analyze( return true; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UnrecognizedExpression( 'Psalm does not understand the cast ' . get_class($stmt), new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return false; } @@ -401,25 +399,21 @@ public static function castStringAttempt( if ($invalid_casts) { if ($valid_strings || $castable_types) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyInvalidCast( $invalid_casts[0] . ' cannot be cast to string', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidCast( $invalid_casts[0] . ' cannot be cast to string', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } elseif ($explicit_cast && !$castable_types) { // todo: emit error here diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/CloneAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/CloneAnalyzer.php index 04115752008..538d234a5ee 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/CloneAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/CloneAnalyzer.php @@ -96,38 +96,32 @@ public static function analyze( } if ($mixed_clone) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedClone( 'Cannot clone mixed', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($invalid_clones) { if ($possibly_valid) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyInvalidClone( 'Cannot clone ' . $invalid_clones[0], new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidClone( 'Cannot clone ' . $invalid_clones[0], new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } return true; diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/EmptyAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/EmptyAnalyzer.php index 331ff93f506..a4431b16542 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/EmptyAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/EmptyAnalyzer.php @@ -21,15 +21,13 @@ public static function analyze( $codebase = $statements_analyzer->getCodebase(); if (isset($codebase->config->forbidden_functions['empty'])) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ForbiddenCode( 'You have forbidden the use of empty', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); } if (($stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr)) @@ -37,16 +35,14 @@ public static function analyze( && $stmt_expr_type->isSingle() && !$stmt_expr_type->from_docblock ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\InvalidArgument( 'Calling empty on a boolean value is almost certainly unintended', new CodeLocation($statements_analyzer->getSource(), $stmt->expr), 'empty' ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $statements_analyzer->node_data->setType($stmt, Type::getBool()); diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/EvalAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/EvalAnalyzer.php index db6de89421e..05049f1ced2 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/EvalAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/EvalAnalyzer.php @@ -66,15 +66,13 @@ public static function analyze( } if (isset($codebase->config->forbidden_functions['eval'])) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ForbiddenCode( 'You have forbidden the use of eval', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); } $context->check_classes = false; diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/ExitAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/ExitAnalyzer.php index f9f80a8b66f..5dd1eb4632a 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/ExitAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/ExitAnalyzer.php @@ -42,15 +42,13 @@ public static function analyze( } if ($forbidden) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ForbiddenCode( 'You have forbidden the use of ' . $forbidden, new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($stmt->expr) { @@ -120,15 +118,13 @@ public static function analyze( if ($context->mutation_free || $context->external_mutation_free) { $function_name = $stmt->getAttribute('kind') === Exit_::KIND_DIE ? 'die' : 'exit'; - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureFunctionCall( 'Cannot call ' . $function_name . ' with a non-integer argument from a mutation-free context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations ) { diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php index eda12481585..b9a1561266b 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php @@ -168,15 +168,13 @@ public static function analyze( if ($stmt_var_type) { if ($stmt_var_type->isNull()) { if (!$context->inside_isset) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new NullArrayAccess( 'Cannot access array value on null variable ' . $array_var_id, new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $stmt_type = $statements_analyzer->node_data->getType($stmt); @@ -292,16 +290,14 @@ public static function analyze( && !$context->inside_unset && ($stmt_var_type && !$stmt_var_type->hasMixed()) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyUndefinedArrayOffset( 'Possibly undefined array key ' . $keyed_array_var_id . ' on ' . $stmt_var_type->getId(), new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $stmt_type->possibly_undefined = false; @@ -478,15 +474,13 @@ public static function getArrayAccessTypeGivenOffset( $array_access_type = null; if ($offset_type->isNull()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new NullArrayOffset( 'Cannot access value on variable ' . $array_var_id . ' using null offset', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); if ($in_assignment) { $offset_type->removeType('null'); @@ -496,16 +490,14 @@ public static function getArrayAccessTypeGivenOffset( if ($offset_type->isNullable() && !$context->inside_isset) { if (!$offset_type->ignore_nullable_issues) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyNullArrayOffset( 'Cannot access value on variable ' . $array_var_id . ' using possibly null offset ' . $offset_type, new CodeLocation($statements_analyzer->getSource(), $stmt->var) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($in_assignment) { @@ -566,31 +558,27 @@ public static function getArrayAccessTypeGivenOffset( if ($replacement_type) { $array_access_type = Type::combineUnionTypes($array_access_type, clone $replacement_type); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyNullArrayAssignment( 'Cannot access array value on possibly null variable ' . $array_var_id . ' of type ' . $array_type, new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); $array_access_type = new Type\Union([new TEmpty]); } } else { if (!$context->inside_isset && !MethodCallAnalyzer::hasNullsafe($stmt->var)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyNullArrayAccess( 'Cannot access array value on possibly null variable ' . $array_var_id . ' of type ' . $array_type, new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $array_access_type = Type::combineUnionTypes($array_access_type, Type::getNull()); @@ -704,27 +692,23 @@ public static function getArrayAccessTypeGivenOffset( } } else { if ($in_assignment) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidArrayAssignment( 'Cannot access array value on non-array variable ' . $array_var_id . ' of type ' . $non_array_types[0], new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidArrayAccess( 'Cannot access array value on non-array variable ' . $array_var_id . ' of type ' . $non_array_types[0], new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $array_access_type = Type::getMixed(); @@ -742,15 +726,13 @@ public static function getArrayAccessTypeGivenOffset( $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath()); } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedArrayOffset( 'Cannot access value on variable ' . $array_var_id . ' using mixed offset', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { if (!$context->collect_initializations && !$context->collect_mutations @@ -775,16 +757,14 @@ public static function getArrayAccessTypeGivenOffset( // do nothing } elseif ($has_valid_expected_offset && $has_valid_absolute_offset) { if (!$context->inside_unset) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyInvalidArrayOffset( 'Cannot access value on variable ' . $array_var_id . ' ' . $used_offset . ', expecting ' . $invalid_offset_type, new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } else { $good_types = []; @@ -826,16 +806,14 @@ public static function getArrayAccessTypeGivenOffset( ); } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidArrayOffset( 'Cannot access value on variable ' . $array_var_id . ' ' . $used_offset . ', expecting ' . $invalid_offset_type, new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -894,7 +872,7 @@ private static function checkLiteralIntArrayOffset( } if (!$found_match) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyUndefinedIntArrayOffset( 'Possibly undefined array offset \'' . $offset_type->getId() . '\' ' @@ -904,9 +882,7 @@ private static function checkLiteralIntArrayOffset( new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -944,7 +920,7 @@ private static function checkLiteralStringArrayOffset( } if (!$found_match) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyUndefinedStringArrayOffset( 'Possibly undefined array offset \'' . $offset_type->getId() . '\' ' @@ -954,9 +930,7 @@ private static function checkLiteralStringArrayOffset( new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -1027,25 +1001,21 @@ public static function handleMixedArrayAccess( if (!$context->inside_isset) { if ($in_assignment) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedArrayAssignment( 'Cannot access array value on mixed variable ' . $array_var_id, new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedArrayAccess( 'Cannot access array value on mixed variable ' . $array_var_id, new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -1329,16 +1299,14 @@ private static function handleArrayAccessOnTArray( if ($union_comparison_results->type_coerced_from_mixed && !$offset_type->isMixed() ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedArrayTypeCoercion( 'Coercion from array offset type \'' . $offset_type->getId() . '\' ' . 'to the expected type \'' . $expected_offset_type->getId() . '\'', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { $expected_offset_types[] = $expected_offset_type->getId(); } @@ -1378,15 +1346,13 @@ private static function handleArrayAccessOnTArray( && !$in_assignment && !$context->inside_isset ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new EmptyArrayAccess( 'Cannot access value on empty array variable ' . $array_var_id, new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - //return Type::getMixed(true); - } + ); if (!IssueBuffer::isRecording()) { $array_access_type = Type::getMixed(true); @@ -1933,15 +1899,13 @@ private static function handleArrayAccessOnString( $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath()); } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedStringOffsetAssignment( 'Right-hand-side of string offset assignment cannot be mixed', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { if (!$context->collect_initializations && !$context->collect_mutations diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/AtomicPropertyFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/AtomicPropertyFetchAnalyzer.php index 5166cc16cb4..8f8d6d42563 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/AtomicPropertyFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/AtomicPropertyFetchAnalyzer.php @@ -401,7 +401,7 @@ public static function analyze( $property_storage = $declaring_class_storage->properties[$prop_name]; if ($context->self && !NamespaceAnalyzer::isWithin($context->self, $property_storage->internal)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InternalProperty( $property_id . ' is internal to ' . $property_storage->internal . ' but called from ' . $context->self, @@ -409,9 +409,7 @@ public static function analyze( $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($context->inside_unset) { @@ -446,15 +444,13 @@ public static function analyze( && $class_property_type->allow_mutations) ) { if ($context->pure) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpurePropertyFetch( 'Cannot access a property on a mutable object from a pure context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations ) { @@ -499,16 +495,14 @@ public static function checkPropertyDeprecation( $property_storage = $declaring_class_storage->properties[$prop_name]; if ($property_storage->deprecated) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedProperty( $property_id . ' is marked deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -669,16 +663,14 @@ private static function propertyFetchCanBeAnalyzed( if (!$class_exists) { $property_id = $lhs_type_part->value . '::$' . $prop_name; - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedMagicPropertyFetch( 'Magic instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return false; } @@ -905,15 +897,13 @@ private static function handleUndefinedProperty( ): void { if ($context->inside_isset || $context->collect_initializations) { if ($context->pure) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpurePropertyFetch( 'Cannot access a property on a mutable object from a pure context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($context->inside_isset && $statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer @@ -926,39 +916,33 @@ private static function handleUndefinedProperty( } if ($stmt_var_id === '$this') { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedThisPropertyFetch( 'Instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { if ($has_magic_getter) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedMagicPropertyFetch( 'Magic instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedPropertyFetch( 'Instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -1021,27 +1005,23 @@ private static function handleNonExistentClass( if (!$class_exists && !$interface_exists) { if ($lhs_type_part->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedDocblockClass( 'Cannot get properties of undefined docblock class ' . $lhs_type_part->value, new CodeLocation($statements_analyzer->getSource(), $stmt), $lhs_type_part->value ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedClass( 'Cannot get properties of undefined class ' . $lhs_type_part->value, new CodeLocation($statements_analyzer->getSource(), $stmt), $lhs_type_part->value ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -1146,7 +1126,7 @@ private static function getClassPropertyType( $declaring_class_storage->location->file_path ) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingPropertyType( 'Property ' . $fq_class_name . '::$' . $prop_name . ' does not have a declared type', @@ -1154,9 +1134,7 @@ private static function getClassPropertyType( $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } $class_property_type = Type::getMixed(); diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ClassConstFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ClassConstFetchAnalyzer.php index 6fc70b7e3b0..640983c53e7 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ClassConstFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ClassConstFetchAnalyzer.php @@ -134,16 +134,14 @@ public static function analyze( $fq_class_name = $const_class_storage->name; if ($const_class_storage->deprecated && $fq_class_name !== $context->self) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedClass( 'Class ' . $fq_class_name . ' is deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -236,15 +234,13 @@ public static function analyze( } catch (\InvalidArgumentException $_) { return true; } catch (\Psalm\Exception\CircularReferenceException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new CircularReference( 'Constant ' . $const_id . ' contains a circular reference', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return true; } @@ -260,25 +256,21 @@ public static function analyze( } if ($class_constant_type) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InaccessibleClassConstant( 'Constant ' . $const_id . ' is not visible in this context', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($context->check_consts) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedConstant( 'Constant ' . $const_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } return true; @@ -331,7 +323,7 @@ public static function analyze( && $const_class_storage->internal && !NamespaceAnalyzer::isWithin($context->self, $const_class_storage->internal) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InternalClass( $fq_class_name . ' is internal to ' . $const_class_storage->internal . ' but called from ' . $context->self, @@ -339,34 +331,28 @@ public static function analyze( $fq_class_name ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($const_class_storage->deprecated && $fq_class_name !== $context->self) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedClass( 'Class ' . $fq_class_name . ' is deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif (isset($const_class_storage->constants[$stmt->name->name]) && $const_class_storage->constants[$stmt->name->name]->deprecated ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedConstant( 'Constant ' . $const_id . ' is deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($first_part_lc !== 'static' || $const_class_storage->final) { @@ -535,15 +521,13 @@ public static function analyze( } catch (\InvalidArgumentException $_) { return true; } catch (\Psalm\Exception\CircularReferenceException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new CircularReference( 'Constant ' . $const_id . ' contains a circular reference', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return true; } @@ -559,25 +543,21 @@ public static function analyze( } if ($class_constant_type) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InaccessibleClassConstant( 'Constant ' . $const_id . ' is not visible in this context', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($context->check_consts) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedConstant( 'Constant ' . $const_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } return true; @@ -617,7 +597,7 @@ public static function analyze( && $const_class_storage->internal && !NamespaceAnalyzer::isWithin($context->self, $const_class_storage->internal) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InternalClass( $fq_class_name . ' is internal to ' . $const_class_storage->internal . ' but called from ' . $context->self, @@ -625,34 +605,28 @@ public static function analyze( $fq_class_name ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($const_class_storage->deprecated && $fq_class_name !== $context->self) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedClass( 'Class ' . $fq_class_name . ' is deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif (isset($const_class_storage->constants[$stmt->name->name]) && $const_class_storage->constants[$stmt->name->name]->deprecated ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedConstant( 'Constant ' . $const_id . ' is deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($const_class_storage->final || $lhs_type_definite_class === true) { diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ConstFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ConstFetchAnalyzer.php index e8ffd487c75..251ebb2e52d 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ConstFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ConstFetchAnalyzer.php @@ -85,15 +85,13 @@ public static function analyze( if ($const_type) { $statements_analyzer->node_data->setType($stmt, clone $const_type); } elseif ($context->check_consts) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedConstant( 'Const ' . $const_name . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/InstancePropertyFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/InstancePropertyFetchAnalyzer.php index fa46fbcfc18..c14ef2b858a 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/InstancePropertyFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/InstancePropertyFetchAnalyzer.php @@ -144,15 +144,13 @@ public static function analyze( ); } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedPropertyFetch( 'Cannot fetch property on mixed var ' . $stmt_var_id, new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); $statements_analyzer->node_data->setType($stmt, Type::getMixed()); @@ -184,15 +182,13 @@ public static function analyze( && $stmt->name instanceof PhpParser\Node\Identifier && !MethodCallAnalyzer::hasNullsafe($stmt->var) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyNullPropertyFetch( 'Cannot get property on possibly null variable ' . $stmt_var_id . ' of type ' . $stmt_var_type, new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { $statements_analyzer->node_data->setType($stmt, Type::getNull()); } @@ -279,25 +275,21 @@ public static function analyze( $lhs_type_part = $invalid_fetch_types[0]; if ($has_valid_fetch_type) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyInvalidPropertyFetch( 'Cannot fetch property on possible non-object ' . $stmt_var_id . ' of type ' . $lhs_type_part, new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidPropertyFetch( 'Cannot fetch property on non-object ' . $stmt_var_id . ' of type ' . $lhs_type_part, new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -377,16 +369,14 @@ private static function handleScopedProperty( ) { $stmt_type->initialized = true; } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UninitializedProperty( 'Cannot use uninitialized property ' . $var_id, new CodeLocation($statements_analyzer->getSource(), $stmt), $var_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); $stmt_type->addType(new Type\Atomic\TNull); } @@ -461,15 +451,13 @@ private static function handleScopedProperty( && $stmt_type->allow_mutations) ) { if ($context->pure) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpurePropertyFetch( 'Cannot access a property on a mutable object from a pure context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php index b1226382e95..38d335bd386 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php @@ -176,15 +176,13 @@ public static function analyze( } if ($context->mutation_free) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\ImpureStaticProperty( 'Cannot use a static property in a mutation-free context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations @@ -241,16 +239,14 @@ public static function analyze( return true; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedPropertyFetch( 'Static property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return true; } @@ -274,27 +270,23 @@ public static function analyze( } if ($context->inside_assignment) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedPropertyAssignment( 'Static property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedPropertyFetch( 'Static property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } return true; diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.php index 924e3612b80..ec716a646ae 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.php @@ -104,15 +104,13 @@ public static function analyze( if (!$context->collect_mutations && !$context->collect_initializations) { if ($context->pure) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureVariable( 'Cannot reference $this in a pure context', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations ) { @@ -177,15 +175,13 @@ public static function analyze( if (!is_string($stmt->name)) { if ($context->pure) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureVariable( 'Cannot reference an unknown variable in a pure context', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations ) { @@ -237,31 +233,27 @@ public static function analyze( || $statements_analyzer->getSource() instanceof FunctionLikeAnalyzer ) { if ($context->is_global || $from_global) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedGlobalVariable( 'Cannot find referenced variable ' . $var_name . ' in global scope', new CodeLocation($statements_analyzer->getSource(), $stmt), $var_name ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); $statements_analyzer->node_data->setType($stmt, Type::getMixed()); return true; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedVariable( 'Cannot find referenced variable ' . $var_name, new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); $statements_analyzer->node_data->setType($stmt, Type::getMixed()); @@ -287,7 +279,7 @@ public static function analyze( return true; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyUndefinedGlobalVariable( 'Possibly undefined global variable ' . $var_name . ', first seen on line ' . $first_appearance->getLineNumber(), @@ -296,9 +288,7 @@ public static function analyze( ), $statements_analyzer->getSuppressedIssues(), (bool) $statements_analyzer->getBranchPoint($var_name) - )) { - // fall through - } + ); } else { if ($codebase->alter_code) { if (!isset($project_analyzer->getIssuesToFix()['PossiblyUndefinedVariable'])) { @@ -314,7 +304,7 @@ public static function analyze( return true; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyUndefinedVariable( 'Possibly undefined variable ' . $var_name . ', first seen on line ' . $first_appearance->getLineNumber(), @@ -322,9 +312,7 @@ public static function analyze( ), $statements_analyzer->getSuppressedIssues(), (bool) $statements_analyzer->getBranchPoint($var_name) - )) { - // fall through - } + ); } if ($codebase->store_node_types @@ -357,26 +345,22 @@ public static function analyze( if ($stmt_type->possibly_undefined_from_try && !$context->inside_isset) { if ($context->is_global) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyUndefinedGlobalVariable( 'Possibly undefined global variable ' . $var_name . ' defined in try block', new CodeLocation($statements_analyzer->getSource(), $stmt), $var_name ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyUndefinedVariable( 'Possibly undefined variable ' . $var_name . ' defined in try block', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/IncludeAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/IncludeAnalyzer.php index c6ccdb0bc37..bc3a5142176 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/IncludeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/IncludeAnalyzer.php @@ -226,30 +226,26 @@ public static function analyze( $source = $statements_analyzer->getSource(); - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingFile( 'Cannot find file ' . $path_to_file . ' to include', new CodeLocation($source, $stmt) ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } else { $var_id = ExpressionIdentifier::getArrayVarId($stmt->expr, null); if (!$var_id || !isset($context->phantom_files[$var_id])) { $source = $statements_analyzer->getSource(); - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UnresolvableInclude( 'Cannot resolve the given expression to a file path', new CodeLocation($source, $stmt) ), $source->getSuppressedIssues() - )) { - // fall through - } + ); } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/MagicConstAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/MagicConstAnalyzer.php index 18f64a34f7e..bd6142f6895 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/MagicConstAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/MagicConstAnalyzer.php @@ -24,15 +24,13 @@ public static function analyze( $codebase = $statements_analyzer->getCodebase(); if (!$context->self) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedConstant( 'Cannot get __class__ outside a class', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); $statements_analyzer->node_data->setType($stmt, Type::getClassString()); } else { diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/MatchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/MatchAnalyzer.php index 74fccfe9c0b..1748960bbbb 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/MatchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/MatchAnalyzer.php @@ -123,15 +123,13 @@ public static function analyze( $last_arm = array_shift($arms); if (!$last_arm) { - if (\Psalm\IssueBuffer::accepts( + \Psalm\IssueBuffer::maybeAdd( new UnhandledMatchCondition( 'This match expression does not match anything', new \Psalm\CodeLocation($statements_analyzer->getSource(), $match_condition) ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); return false; } @@ -259,16 +257,14 @@ function ($type) { ); if ($array_literal_types) { - if (\Psalm\IssueBuffer::accepts( + \Psalm\IssueBuffer::maybeAdd( new UnhandledMatchCondition( 'This match expression is not exhaustive - consider values ' . $vars_in_scope_reconciled[$switch_var_id]->getId(), new \Psalm\CodeLocation($statements_analyzer->getSource(), $match_condition) ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/PrintAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/PrintAnalyzer.php index 34ca7330ac7..baeb254d58b 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/PrintAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/PrintAnalyzer.php @@ -73,28 +73,24 @@ public static function analyze( } if (isset($codebase->config->forbidden_functions['print'])) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ForbiddenCode( 'You have forbidden the use of print', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); } if (!$context->collect_initializations && !$context->collect_mutations) { if ($context->mutation_free || $context->external_mutation_free) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ImpureFunctionCall( 'Cannot call print from a mutation-free context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations ) { diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/YieldAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/YieldAnalyzer.php index 88a7c61798e..13c35d03ecb 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/YieldAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/YieldAnalyzer.php @@ -39,14 +39,12 @@ public static function analyze( $statements_analyzer->getAliases() ); } catch (DocblockParseException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( $e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $stmt) ) - )) { - // fall through - } + ); } foreach ($var_comments as $var_comment) { diff --git a/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php index b720c61b0c3..fe7a3194eaa 100644 --- a/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php @@ -406,15 +406,13 @@ private static function handleExpression( } } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ForbiddenCode( 'Use of shell_exec', new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // continue - } + ); return true; } diff --git a/src/Psalm/Internal/Analyzer/Statements/GlobalAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/GlobalAnalyzer.php index 6ebb3d34beb..9925e781964 100644 --- a/src/Psalm/Internal/Analyzer/Statements/GlobalAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/GlobalAnalyzer.php @@ -22,15 +22,13 @@ public static function analyze( ?Context $global_context ) : void { if (!$context->collect_initializations && !$global_context) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidGlobal( 'Cannot use global scope here', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSource()->getSuppressedIssues() - )) { - // fall through - } + ); } $source = $statements_analyzer->getSource(); diff --git a/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php index 31c39ba5d49..2959c352018 100644 --- a/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php @@ -71,14 +71,12 @@ public static function analyze( $file_storage->type_aliases ); } catch (DocblockParseException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( $e->getMessage(), new CodeLocation($source, $stmt) ) - )) { - // fall through - } + ); } foreach ($var_comments as $var_comment) { @@ -160,15 +158,13 @@ public static function analyze( $stmt_type = $stmt_expr_type; if ($stmt_type->isNever()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new NoValue( 'This function or method call never returns output', new CodeLocation($source, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); $stmt_type = Type::getEmpty(); } @@ -326,29 +322,25 @@ public static function analyze( $origin_location = null; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedReturnStatement( 'Could not infer a return type', $return_location, $origin_location ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); return; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedReturnStatement( 'Possibly-mixed return value', new CodeLocation($source, $stmt->expr) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } if ($local_return_type->isMixed()) { @@ -393,17 +385,15 @@ public static function analyze( if ($union_comparison_results->type_coerced_from_mixed) { if (!$union_comparison_results->type_coerced_from_as_mixed) { if ($inferred_type->hasMixed()) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedReturnStatement( 'Could not infer a return type', new CodeLocation($source, $stmt->expr) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MixedReturnTypeCoercion( 'The type \'' . $stmt_type->getId() . '\' is more general than the' . ' declared return type \'' . $local_return_type->getId() . '\'' @@ -411,13 +401,11 @@ public static function analyze( new CodeLocation($source, $stmt->expr) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new LessSpecificReturnStatement( 'The type \'' . $stmt_type->getId() . '\' is more general than the' . ' declared return type \'' . $local_return_type->getId() . '\'' @@ -425,9 +413,7 @@ public static function analyze( new CodeLocation($source, $stmt->expr) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } foreach ($local_return_type->getAtomicTypes() as $local_type_part) { @@ -474,7 +460,7 @@ public static function analyze( } } } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidReturnStatement( 'The inferred type \'' . $inferred_type->getId() . '\' does not match the declared return ' @@ -482,9 +468,7 @@ public static function analyze( new CodeLocation($source, $stmt->expr) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -493,7 +477,7 @@ public static function analyze( && !$local_return_type->isNullable() && !$local_return_type->hasTemplate() ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new NullableReturnStatement( 'The declared return type \'' . $local_return_type->getId() . '\' for ' . $cased_method_id . ' is not nullable, but the function returns \'' @@ -501,9 +485,7 @@ public static function analyze( new CodeLocation($source, $stmt->expr) ), $statements_analyzer->getSuppressedIssues() - )) { - //fall through - } + ); } if (!$stmt_type->ignore_falsable_issues @@ -512,7 +494,7 @@ public static function analyze( && (!$local_return_type->hasBool() || $local_return_type->isTrue()) && !$local_return_type->hasScalar() ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new FalsableReturnStatement( 'The declared return type \'' . $local_return_type . '\' for ' . $cased_method_id . ' does not allow false, but the function returns \'' @@ -520,9 +502,7 @@ public static function analyze( new CodeLocation($source, $stmt->expr) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } else { @@ -530,15 +510,13 @@ public static function analyze( && !$storage->signature_return_type->isVoid() && !$storage->has_yield ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidReturnStatement( 'Empty return statement is not expected in ' . $cased_method_id, new CodeLocation($source, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/Internal/Analyzer/Statements/StaticAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/StaticAnalyzer.php index 9fb604866ec..d0519882703 100644 --- a/src/Psalm/Internal/Analyzer/Statements/StaticAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/StaticAnalyzer.php @@ -24,15 +24,13 @@ public static function analyze( $codebase = $statements_analyzer->getCodebase(); if ($context->mutation_free) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\ImpureStaticVariable( 'Cannot use a static variable in a mutation-free context', new CodeLocation($statements_analyzer, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } foreach ($stmt->vars as $var) { @@ -58,23 +56,19 @@ public static function analyze( $statements_analyzer->getSource()->getTemplateTypeMap() ); } catch (\Psalm\Exception\IncorrectDocblockException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\MissingDocblockType( $e->getMessage(), new CodeLocation($statements_analyzer, $var) ) - )) { - // fall through - } + ); } catch (DocblockParseException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( $e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $var) ) - )) { - // fall through - } + ); } foreach ($var_comments as $var_comment) { @@ -127,14 +121,12 @@ public static function analyze( $context->vars_in_scope[$var_comment->var_id] = $var_comment_type; } catch (\UnexpectedValueException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( $e->getMessage(), new CodeLocation($statements_analyzer, $var) ) - )) { - // fall through - } + ); } } @@ -156,15 +148,13 @@ public static function analyze( $comment_type ) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\ReferenceConstraintViolation( $var_id . ' of type ' . $comment_type->getId() . ' cannot be assigned type ' . $var_default_type->getId(), new CodeLocation($statements_analyzer, $var) ) - )) { - // fall through - } + ); } } diff --git a/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php b/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php index 4e86869f38a..93b11f00745 100644 --- a/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php @@ -455,23 +455,19 @@ private static function analyzeStatement( $file_storage->type_aliases ); } catch (\Psalm\Exception\IncorrectDocblockException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingDocblockType( $e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $stmt) ) - )) { - // fall through - } + ); } catch (\Psalm\Exception\DocblockParseException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( $e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $stmt) ) - )) { - // fall through - } + ); } foreach ($var_comments as $var_comment) { @@ -636,25 +632,21 @@ private static function analyzeStatement( foreach ($traced_variables as $traced_variable) { if (isset($context->vars_in_scope[$traced_variable])) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new Trace( $traced_variable . ': ' . $context->vars_in_scope[$traced_variable]->getId(), new CodeLocation($statements_analyzer->source, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UndefinedTrace( 'Attempt to trace undefined variable ' . $traced_variable, new CodeLocation($statements_analyzer->source, $stmt) ), $statements_analyzer->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -671,14 +663,12 @@ private function parseStatementDocblock( try { $this->parsed_docblock = DocComment::parsePreservingLength($docblock); } catch (DocblockParseException $e) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( $e->getMessage(), new CodeLocation($this->getSource(), $stmt, null, true) ) - )) { - // fall through - } + ); $this->parsed_docblock = null; } @@ -689,15 +679,13 @@ private function parseStatementDocblock( $trimmed = trim(\reset($comments->tags['psalm-scope-this'])); if (!$codebase->classExists($trimmed)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\UndefinedDocblockClass( 'Scope class ' . $trimmed . ' does not exist', new CodeLocation($this->getSource(), $stmt, null, true), $trimmed ) - )) { - // fall through - } + ); } else { $this_type = Type::parseString($trimmed); $context->self = $trimmed; @@ -738,27 +726,23 @@ public function checkUnreferencedVars(array $stmts, Context $context): void && $average_destination_branches_converging > 1.1 ) { if ($source instanceof FunctionAnalyzer) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ComplexFunction( 'This function’s complexity is greater than the project limit' . ' (method graph size = ' . $count .', average path length = ' . round($mean). ')', $function_storage->location ), $this->getSuppressedIssues() - )) { - // fall through - } + ); } elseif ($source instanceof MethodAnalyzer) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new ComplexMethod( 'This method’s complexity is greater than the project limit' . ' (method graph size = ' . $count .', average path length = ' . round($mean) . ')', $function_storage->location ), $this->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -828,13 +812,11 @@ public function checkUnreferencedVars(array $stmts, Context $context): void ); } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( $issue, $this->getSuppressedIssues(), $issue instanceof UnusedVariable - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/Internal/Codebase/ClassLikes.php b/src/Psalm/Internal/Codebase/ClassLikes.php index 9f60c244aec..8ca8492e61a 100644 --- a/src/Psalm/Internal/Codebase/ClassLikes.php +++ b/src/Psalm/Internal/Codebase/ClassLikes.php @@ -853,16 +853,14 @@ public function consolidateAnalyzedData(Methods $methods, ?Progress $progress, b ) { if ($find_unused_code) { if (!$this->file_reference_provider->isClassReferenced($fq_class_name_lc)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new UnusedClass( 'Class ' . $classlike_storage->name . ' is never used', $classlike_storage->location, $classlike_storage->name ), $classlike_storage->suppressed_issues - )) { - // fall through - } + ); } else { $this->checkMethodReferences($classlike_storage, $methods); $this->checkPropertyReferences($classlike_storage); @@ -1885,25 +1883,21 @@ private function checkMethodReferences(ClassLikeStorage $classlike_storage, Meth if (!$method_return_referenced) { if ($method_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PRIVATE) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\UnusedReturnValue( 'The return value for this private method is never used', $method_storage->return_type_location ), $method_storage->suppressed_issues - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\PossiblyUnusedReturnValue( 'The return value for this method is never used', $method_storage->return_type_location ), $method_storage->suppressed_issues - )) { - // fall through - } + ); } } } @@ -1921,25 +1915,21 @@ private function checkMethodReferences(ClassLikeStorage $classlike_storage, Meth ) ) { if ($method_storage->final) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new \Psalm\Issue\UnusedParam( 'Param #' . ($offset + 1) . ' is never referenced in this method', $param_storage->location ), $method_storage->suppressed_issues - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new PossiblyUnusedParam( 'Param #' . ($offset + 1) . ' is never referenced in this method', $param_storage->location ), $method_storage->suppressed_issues - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/Internal/Codebase/TaintFlowGraph.php b/src/Psalm/Internal/Codebase/TaintFlowGraph.php index 3fcf5846c9f..2124be439fb 100644 --- a/src/Psalm/Internal/Codebase/TaintFlowGraph.php +++ b/src/Psalm/Internal/Codebase/TaintFlowGraph.php @@ -444,7 +444,7 @@ private function getChildNodes( ); } - IssueBuffer::accepts($issue); + IssueBuffer::maybeAdd($issue); } } } diff --git a/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php b/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php index 047c3365462..3e4242663f8 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php @@ -288,15 +288,13 @@ public function start(PhpParser\Node\Stmt\ClassLike $node): ?bool if ($node->scalarType->name === 'string' || $node->scalarType->name === 'int') { $storage->enum_type = $node->scalarType->name; } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidEnumBackingType( 'Enums cannot be backed by ' . $node->scalarType->name . ', string or int expected', new CodeLocation($this->file_scanner, $node->scalarType), $fq_classlike_name ) - )) { - // fall through - } + ); $this->file_storage->has_visitor_issues = true; $storage->has_visitor_issues = true; } diff --git a/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php b/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php index ec081db6f22..32ce22e8f19 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php @@ -944,7 +944,7 @@ private function createStorageForFunctionLike( return [$function_id, $storage, null, null, null, null, false, null, true]; } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DuplicateFunction( 'Method ' . $function_id . ' has already been defined' . ($duplicate_function_storage->location @@ -952,9 +952,7 @@ private function createStorageForFunctionLike( : ''), new CodeLocation($this->file_scanner, $stmt, null, true) ) - )) { - // fall through - } + ); $this->file_storage->has_visitor_issues = true; @@ -970,14 +968,12 @@ private function createStorageForFunctionLike( $reflection_function = new \ReflectionFunction($function_id); if ($reflection_function->getFileName() !== $this->file_path) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DuplicateFunction( 'Method ' . $function_id . ' has already been defined as a core function', new CodeLocation($this->file_scanner, $stmt, null, true) ) - )) { - // fall through - } + ); } } } @@ -1001,7 +997,7 @@ private function createStorageForFunctionLike( if (!$this->codebase->register_stub_files) { $duplicate_method_storage = $classlike_storage->methods[$method_name_lc]; - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DuplicateMethod( 'Method ' . $function_id . ' has already been defined' . ($duplicate_method_storage->location @@ -1009,9 +1005,7 @@ private function createStorageForFunctionLike( : ''), new CodeLocation($this->file_scanner, $stmt, null, true) ) - )) { - // fall through - } + ); $this->file_storage->has_visitor_issues = true; diff --git a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFilterReturnTypeProvider.php b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFilterReturnTypeProvider.php index 34834617b81..004a38ea584 100644 --- a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFilterReturnTypeProvider.php +++ b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFilterReturnTypeProvider.php @@ -215,7 +215,7 @@ static function ($keyed_type) { $closure_return_type = $closure_atomic_type->return_type ?: Type::getMixed(); if ($closure_return_type->isVoid()) { - IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidReturnType( 'No return type could be found in the closure passed to array_filter', $code_location diff --git a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayReduceReturnTypeProvider.php b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayReduceReturnTypeProvider.php index 0434873bd9a..00e0f91eb11 100644 --- a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayReduceReturnTypeProvider.php +++ b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayReduceReturnTypeProvider.php @@ -103,15 +103,13 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev if ($closure_atomic_type->params !== null) { if (count($closure_atomic_type->params) < 1) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidArgument( 'The closure passed to array_reduce at least one parameter', new CodeLocation($statements_source, $function_call_arg) ), $statements_source->getSuppressedIssues() - )) { - // fall through - } + ); return Type::getMixed(); } @@ -136,7 +134,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev ) ) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidArgument( 'The first param of the closure passed to array_reduce must take ' . $reduce_return_type . ' but only accepts ' . $carry_param->type, @@ -144,9 +142,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev ?: new CodeLocation($statements_source, $function_call_arg) ), $statements_source->getSuppressedIssues() - )) { - // fall through - } + ); return Type::getMixed(); } @@ -161,7 +157,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev $item_param->type ) ) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidArgument( 'The second param of the closure passed to array_reduce must take ' . $array_arg_atomic_type->type_params[1] . ' but only accepts ' . $item_param->type, @@ -169,9 +165,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev ?: new CodeLocation($statements_source, $function_call_arg) ), $statements_source->getSuppressedIssues() - )) { - // fall through - } + ); return Type::getMixed(); } diff --git a/src/Psalm/Internal/Type/AssertionReconciler.php b/src/Psalm/Internal/Type/AssertionReconciler.php index 235a599953b..f0796e89ad4 100644 --- a/src/Psalm/Internal/Type/AssertionReconciler.php +++ b/src/Psalm/Internal/Type/AssertionReconciler.php @@ -344,15 +344,13 @@ private static function refine( $new_type_part = new TMixed(); if ($code_location) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidDocblock( $assertion . ' cannot be used in an assertion', $code_location ), $suppressed_issues - )) { - // fall through - } + ); } } @@ -527,7 +525,7 @@ private static function refine( ) { if ($assertion === 'null') { if ($existing_var_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DocblockTypeContradiction( 'Cannot resolve types for ' . $key . ' - docblock-defined type ' . $existing_var_type . ' does not contain null', @@ -535,11 +533,9 @@ private static function refine( $existing_var_type->getId() . ' null' ), $suppressed_issues - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TypeDoesNotContainNull( 'Cannot resolve types for ' . $key . ' - ' . $existing_var_type . ' does not contain null', @@ -547,16 +543,14 @@ private static function refine( $existing_var_type->getId() ), $suppressed_issues - )) { - // fall through - } + ); } } elseif (!($statements_analyzer->getSource()->getSource() instanceof TraitAnalyzer) || ($key !== '$this' && !($existing_var_type->hasLiteralClassString() && $new_type->hasLiteralClassString())) ) { if ($existing_var_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DocblockTypeContradiction( 'Cannot resolve types for ' . $key . ' - docblock-defined type ' . $existing_var_type->getId() . ' does not contain ' . $new_type->getId(), @@ -564,11 +558,9 @@ private static function refine( $existing_var_type->getId() . ' ' . $new_type->getId() ), $suppressed_issues - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TypeDoesNotContainType( 'Cannot resolve types for ' . $key . ' - ' . $existing_var_type->getId() . ' does not contain ' . $new_type->getId(), @@ -576,9 +568,7 @@ private static function refine( $existing_var_type->getId() . ' ' . $new_type->getId() ), $suppressed_issues - )) { - // fall through - } + ); } } @@ -1402,16 +1392,14 @@ private static function handleIsA( if ($existing_has_string && !$existing_has_object) { if (!$allow_string_comparison && $code_location) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TypeDoesNotContainType( 'Cannot allow string comparison to object for ' . $key, $code_location, null ), $suppressed_issues - )) { - // fall through - } + ); return Type::getMixed(); } else { diff --git a/src/Psalm/Internal/Type/NegatedAssertionReconciler.php b/src/Psalm/Internal/Type/NegatedAssertionReconciler.php index 8a796147e2f..622460268ae 100644 --- a/src/Psalm/Internal/Type/NegatedAssertionReconciler.php +++ b/src/Psalm/Internal/Type/NegatedAssertionReconciler.php @@ -94,7 +94,7 @@ public static function reconcile( if ($code_location) { if ($existing_var_type->from_static_property) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantPropertyInitializationCheck( 'Static property ' . $key . ' with type ' . $existing_var_type @@ -102,22 +102,18 @@ public static function reconcile( $code_location ), $suppressed_issues - )) { - // fall through - } + ); } elseif ($existing_var_type->from_property) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantPropertyInitializationCheck( 'Property ' . $key . ' with type ' . $existing_var_type . ' should already be set in the constructor', $code_location ), $suppressed_issues - )) { - // fall through - } + ); } elseif ($existing_var_type->from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DocblockTypeContradiction( 'Cannot resolve types for ' . $key . ' with docblock-defined type ' . $existing_var_type . ' and !isset assertion', @@ -125,11 +121,9 @@ public static function reconcile( null ), $suppressed_issues - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TypeDoesNotContainType( 'Cannot resolve types for ' . $key . ' with type ' . $existing_var_type . ' and !isset assertion', @@ -137,9 +131,7 @@ public static function reconcile( null ), $suppressed_issues - )) { - // fall through - } + ); } } diff --git a/src/Psalm/Internal/TypeVisitor/TypeChecker.php b/src/Psalm/Internal/TypeVisitor/TypeChecker.php index d402cbd01e7..2f64b6c30b2 100644 --- a/src/Psalm/Internal/TypeVisitor/TypeChecker.php +++ b/src/Psalm/Internal/TypeVisitor/TypeChecker.php @@ -113,15 +113,13 @@ protected function enterNode(TypeNode $type) : ?int $this->checkResource($type); } elseif ($type instanceof TArray) { if (\count($type->type_params) > 2) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TooManyTemplateParams( $type->getId(). ' has too many template params, expecting 2', $this->code_location ), $this->suppressed_issues - )) { - // fall through - } + ); } } @@ -186,16 +184,14 @@ private function checkNamedObject(TNamedObject $atomic) : void $class_storage = $codebase->classlike_storage_provider->get($fq_class_name_lc); if ($class_storage->deprecated) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DeprecatedClass( 'Class ' . $atomic->value . ' is marked as deprecated', $this->code_location, $atomic->value ), $this->source->getSuppressedIssues() + $this->suppressed_issues - )) { - // fall through - } + ); } } @@ -221,27 +217,23 @@ private function checkGenericParams(TGenericObject $atomic) : void $template_param_count = \count($atomic->type_params); if ($template_type_count > $template_param_count) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new MissingTemplateParam( $atomic->value . ' has missing template params, expecting ' . $template_type_count, $this->code_location ), $this->suppressed_issues - )) { - // fall through - } + ); } elseif ($template_type_count < $template_param_count) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new TooManyTemplateParams( $atomic->getId(). ' has too many template params, expecting ' . $template_type_count, $this->code_location ), $this->suppressed_issues - )) { - // fall through - } + ); } $expected_type_param_keys = \array_keys($expected_type_params); @@ -272,7 +264,7 @@ private function checkGenericParams(TGenericObject $atomic) : void ); if (!UnionTypeComparator::isContainedBy($codebase, $type_param, $expected_type_param)) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new InvalidTemplateParam( 'Extended template param ' . $expected_template_name . ' of ' . $atomic->getId() @@ -282,9 +274,7 @@ private function checkGenericParams(TGenericObject $atomic) : void $this->code_location ), $this->suppressed_issues - )) { - // fall through - } + ); } } } @@ -340,15 +330,13 @@ public function checkScalarClassConstant(TClassConstant $atomic) : void } if (!$is_defined) { - if (\Psalm\IssueBuffer::accepts( + \Psalm\IssueBuffer::maybeAdd( new UndefinedConstant( 'Constant ' . $fq_classlike_name . '::' . $const_name . ' is not defined', $this->code_location ), $this->source->getSuppressedIssues() - )) { - // fall through - } + ); } } @@ -379,16 +367,14 @@ public function checkTemplateParam(\Psalm\Type\Atomic\TTemplateParam $atomic) : ) { // do nothing } else { - if (\Psalm\IssueBuffer::accepts( + \Psalm\IssueBuffer::maybeAdd( new \Psalm\Issue\InvalidTemplateParam( 'Template param ' . $atomic->param_name . ' of ' . $atomic->defining_class . ' is marked covariant and cannot be used here', $this->code_location ), $this->source->getSuppressedIssues() - )) { - // fall through - } + ); } } } @@ -397,16 +383,14 @@ public function checkTemplateParam(\Psalm\Type\Atomic\TTemplateParam $atomic) : public function checkResource(TResource $atomic) : void { if (!$atomic->from_docblock) { - if (\Psalm\IssueBuffer::accepts( + \Psalm\IssueBuffer::maybeAdd( new \Psalm\Issue\ReservedWord( '\'resource\' is a reserved word', $this->code_location, 'resource' ), $this->source->getSuppressedIssues() - )) { - // fall through - } + ); } } } diff --git a/src/Psalm/IssueBuffer.php b/src/Psalm/IssueBuffer.php index c694704bf8f..36792de16dc 100644 --- a/src/Psalm/IssueBuffer.php +++ b/src/Psalm/IssueBuffer.php @@ -114,6 +114,19 @@ public static function accepts(CodeIssue $e, array $suppressed_issues = [], bool return self::add($e, $is_fixable); } + /** + * @param string[] $suppressed_issues + * + */ + public static function maybeAdd(CodeIssue $e, array $suppressed_issues = [], bool $is_fixable = false): void + { + if (self::isSuppressed($e, $suppressed_issues)) { + return; + } + + self::add($e, $is_fixable); + } + public static function addUnusedSuppression(string $file_path, int $offset, string $issue_type) : void { if (\strpos($issue_type, 'Tainted') === 0) { diff --git a/src/Psalm/Type/Reconciler.php b/src/Psalm/Type/Reconciler.php index 760b772008e..7c4da9f8e22 100644 --- a/src/Psalm/Type/Reconciler.php +++ b/src/Psalm/Type/Reconciler.php @@ -895,7 +895,7 @@ protected static function triggerIssueForImpossible( if ($redundant) { if ($existing_var_type->from_property && $assertion === 'isset') { if ($existing_var_type->from_static_property) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantPropertyInitializationCheck( 'Static property ' . $key . ' with type ' . $old_var_type_string @@ -903,23 +903,19 @@ protected static function triggerIssueForImpossible( $code_location ), $suppressed_issues - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantPropertyInitializationCheck( 'Property ' . $key . ' with type ' . $old_var_type_string . ' should already be set in the constructor', $code_location ), $suppressed_issues - )) { - // fall through - } + ); } } elseif ($from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantConditionGivenDocblockType( 'Docblock-defined type ' . $old_var_type_string . ' for ' . $key @@ -928,11 +924,9 @@ protected static function triggerIssueForImpossible( $old_var_type_string . ' ' . $assertion ), $suppressed_issues - )) { - // fall through - } + ); } else { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new RedundantCondition( 'Type ' . $old_var_type_string . ' for ' . $key @@ -941,13 +935,11 @@ protected static function triggerIssueForImpossible( $old_var_type_string . ' ' . $assertion ), $suppressed_issues - )) { - // fall through - } + ); } } else { if ($from_docblock) { - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( new DocblockTypeContradiction( 'Docblock-defined type ' . $old_var_type_string . ' for ' . $key @@ -956,9 +948,7 @@ protected static function triggerIssueForImpossible( $old_var_type_string . ' ' . $assertion ), $suppressed_issues - )) { - // fall through - } + ); } else { if ($assertion === 'null' && !$not) { $issue = new TypeDoesNotContainNull( @@ -978,12 +968,10 @@ protected static function triggerIssueForImpossible( ); } - if (IssueBuffer::accepts( + IssueBuffer::maybeAdd( $issue, $suppressed_issues - )) { - // fall through - } + ); } } }