From b084e2c4bdf4e08f2168fecf556c813a0c6e2a82 Mon Sep 17 00:00:00 2001 From: orklah Date: Fri, 27 Nov 2020 23:05:26 +0100 Subject: [PATCH] add annotation @psalm-param-out (#4717) * add annotation @psalm-param-out * add tag in documentation --- docs/annotating_code/supported_annotations.md | 2 +- src/Psalm/DocComment.php | 4 ++-- .../PhpVisitor/Reflector/FunctionLikeDocblockParser.php | 4 ++-- src/Psalm/Internal/Scanner/DocblockParser.php | 8 ++++++++ tests/UnusedVariableTest.php | 2 +- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/annotating_code/supported_annotations.md b/docs/annotating_code/supported_annotations.md index f2f7b1ee2..3e23bd429 100644 --- a/docs/annotating_code/supported_annotations.md +++ b/docs/annotating_code/supported_annotations.md @@ -51,7 +51,7 @@ function bat(): string { There are a number of custom tags that determine how Psalm treats your code. -### `@param-out` +### `@param-out`, `@psalm-param-out` This is used to specify that a by-ref type is different from the one that entered. In the function below the first param can be null, but once the function has executed the by-ref value is not null. diff --git a/src/Psalm/DocComment.php b/src/Psalm/DocComment.php index 24e90e848..0959630cd 100644 --- a/src/Psalm/DocComment.php +++ b/src/Psalm/DocComment.php @@ -35,8 +35,8 @@ class DocComment 'allow-private-mutation', 'readonly-allow-private-mutation', 'yield', 'trace', 'import-type', 'flow', 'taint-specialize', 'taint-escape', 'taint-unescape', 'self-out', 'consistent-constructor', 'stub-override', - 'require-extends', 'require-implements', - 'if-this-is' + 'if-this-is', + 'require-extends', 'require-implements', 'param-out' ]; /** diff --git a/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockParser.php b/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockParser.php index d09327d4e..0e5d68603 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockParser.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockParser.php @@ -91,8 +91,8 @@ class FunctionLikeDocblockParser } } - if (isset($parsed_docblock->tags['param-out'])) { - foreach ($parsed_docblock->tags['param-out'] as $offset => $param) { + if (isset($parsed_docblock->combined_tags['param-out'])) { + foreach ($parsed_docblock->combined_tags['param-out'] as $offset => $param) { $line_parts = CommentAnalyzer::splitDocLine($param); if (count($line_parts) === 1 && isset($line_parts[0][0]) && $line_parts[0][0] === '$') { diff --git a/src/Psalm/Internal/Scanner/DocblockParser.php b/src/Psalm/Internal/Scanner/DocblockParser.php index 0fd88afc9..ac834fddd 100644 --- a/src/Psalm/Internal/Scanner/DocblockParser.php +++ b/src/Psalm/Internal/Scanner/DocblockParser.php @@ -233,5 +233,13 @@ class DocblockParser + ($docblock->tags['phpstan-var'] ?? []) + ($docblock->tags['psalm-var'] ?? []); } + + if (isset($docblock->tags['param-out']) + || isset($docblock->tags['psalm-param-out']) + ) { + $docblock->combined_tags['param-out'] + = ($docblock->tags['param-out'] ?? []) + + ($docblock->tags['psalm-param-out'] ?? []); + } } } diff --git a/tests/UnusedVariableTest.php b/tests/UnusedVariableTest.php index 60d54c7d5..e91be3c4a 100644 --- a/tests/UnusedVariableTest.php +++ b/tests/UnusedVariableTest.php @@ -2135,7 +2135,7 @@ class UnusedVariableTest extends TestCase } /** - * @param-out int $c + * @psalm-param-out int $c */ function takesByRef(?int &$c) : void { $c = 7;