diff --git a/src/Psalm/Issue/CodeIssue.php b/src/Psalm/Issue/CodeIssue.php index 7e7fc1512..f870e498b 100644 --- a/src/Psalm/Issue/CodeIssue.php +++ b/src/Psalm/Issue/CodeIssue.php @@ -86,20 +86,23 @@ abstract class CodeIssue return $this->message; } + public static function getIssueType(): string + { + $fqcn_parts = explode('\\', static::class); + return array_pop($fqcn_parts); + } + public function toIssueData(string $severity): IssueData { $location = $this->code_location; $selection_bounds = $location->getSelectionBounds(); $snippet_bounds = $location->getSnippetBounds(); - $fqcn_parts = explode('\\', static::class); - $issue_type = array_pop($fqcn_parts); - return new IssueData( $severity, $location->getLineNumber(), $location->getEndLineNumber(), - $issue_type, + static::getIssueType(), $this->message, $location->file_name, $location->file_path, diff --git a/src/Psalm/IssueBuffer.php b/src/Psalm/IssueBuffer.php index b4857dfcc..70b6762eb 100644 --- a/src/Psalm/IssueBuffer.php +++ b/src/Psalm/IssueBuffer.php @@ -326,11 +326,31 @@ class IssueBuffer return true; } + private static function removeRecordedIssue(string $issue_type, int $file_offset): void + { + $recorded_issues = self::$recorded_issues[self::$recording_level]; + $filtered_issues = []; + + foreach ($recorded_issues as $issue) { + [$from] = $issue->code_location->getSelectionBounds(); + + if ($issue::getIssueType() !== $issue_type || $from !== $file_offset) { + $filtered_issues[] = $issue; + } + } + + self::$recorded_issues[self::$recording_level] = $filtered_issues; + } + /** * This will try to remove an issue that has been added for emission */ public static function remove(string $file_path, string $issue_type, int $file_offset): void { + if (self::$recording_level > 0) { + self::removeRecordedIssue($issue_type, $file_offset); + } + if (!isset(self::$issues_data[$file_path])) { return; } diff --git a/tests/Loop/ForeachTest.php b/tests/Loop/ForeachTest.php index ec8bfb754..edd8706aa 100644 --- a/tests/Loop/ForeachTest.php +++ b/tests/Loop/ForeachTest.php @@ -430,6 +430,29 @@ class ForeachTest extends TestCase 'MixedAssignment', ], ], + 'noMixedAssigmentWithIfAssertion' => [ + 'getProperties() as $property) { + $message = $property->getValue($reflection->newInstance()); + + if (!is_string($message)) { + throw new RuntimeException(); + } + }', + ], + 'noMixedAssigmentWithAssertion' => [ + 'getProperties() as $property) { + $message = $property->getValue($reflection->newInstance()); + assert(is_string($message)); + }', + ], 'nullToMixedWithNullCheckAndContinue' => [ '