diff --git a/blink/internal/fixer/rules/symplify_docblock2.go b/blink/internal/fixer/rules/symplify_docblock2.go index 4642dc9242..ebb88f07ee 100644 --- a/blink/internal/fixer/rules/symplify_docblock2.go +++ b/blink/internal/fixer/rules/symplify_docblock2.go @@ -104,6 +104,8 @@ type RemoveSuperfluousReturnName struct{} var ( returnVarNameRe = regexp.MustCompile(`(@(?:psalm-|phpstan-)?return)(\s+[|\\\w]+)?(\s+)(\$[\w]+)`) docVariableNameRe = regexp.MustCompile(`\$\w+`) + // PHPStan conditional return type, e.g. "@return $var ? TypeA : TypeB" + conditionalReturnRe = regexp.MustCompile(`@(?:psalm-|phpstan-)?return\s+\$\w+\s*(?:\?|is\b)`) ) func (RemoveSuperfluousReturnName) Name() string { @@ -125,6 +127,9 @@ func (RemoveSuperfluousReturnName) Fix(s *tokens.Stream) bool { if m[4] == "$this" { continue } + if conditionalReturnRe.MatchString(line) { + continue + } if len(docVariableNameRe.FindAllString(line, -1)) >= 2 { continue } diff --git a/blink/internal/fixer/rules/symplify_docblock_test.go b/blink/internal/fixer/rules/symplify_docblock_test.go index 647a5192d0..c420cb365d 100644 --- a/blink/internal/fixer/rules/symplify_docblock_test.go +++ b/blink/internal/fixer/rules/symplify_docblock_test.go @@ -88,6 +88,16 @@ func TestRemoveSuperfluousReturnName(t *testing.T) { t.Fatalf("changed=%v got=%q want=%q", changed, got, want) } idempotent(t, RemoveSuperfluousReturnName{}, got) + + // a PHPStan conditional return type is left alone; the variable is the condition, not a name + for _, cond := range []string{ + " : array)\n */\n function f(bool $arrayHydration) {}\n}\n", + " : array\n */\n function f(bool $arrayHydration) {}\n}\n", + } { + if got, changed := apply(t, RemoveSuperfluousReturnName{}, cond); changed || got != cond { + t.Fatalf("conditional return type changed=%v got=%q", changed, got) + } + } } // TestRemoveSuperfluousVarName drops the variable name from a property @var. diff --git a/packages/coding-standard/src/Fixer/Commenting/RemoveSuperfluousReturnNameFixer.php b/packages/coding-standard/src/Fixer/Commenting/RemoveSuperfluousReturnNameFixer.php index 99b1c55aba..87075cbd6c 100644 --- a/packages/coding-standard/src/Fixer/Commenting/RemoveSuperfluousReturnNameFixer.php +++ b/packages/coding-standard/src/Fixer/Commenting/RemoveSuperfluousReturnNameFixer.php @@ -35,6 +35,9 @@ final class RemoveSuperfluousReturnNameFixer extends AbstractDocBlockFixer private const string VARIABLE_NAME_PART = 'variableName'; + // PHPStan conditional return type, e.g. "@return $var ? TypeA : TypeB" + private const string CONDITIONAL_RETURN_REGEX = '#@(?:psalm-|phpstan-)?return\s+\$\w+\s*(?:\?|is\b)#'; + public function getDefinition(): FixerDefinitionInterface { return new FixerDefinition(self::ERROR_MESSAGE, []); @@ -86,6 +89,10 @@ private function shouldSkip(array $match, string $content): bool return true; } + if (Regex::match($content, self::CONDITIONAL_RETURN_REGEX) !== null) { + return true; + } + // has multiple return values? "@return array $one, $two" return count(Regex::matchAll($content, self::VARIABLE_NAME_REGEX)) >= 2; } diff --git a/packages/coding-standard/tests/Fixer/Commenting/RemoveSuperfluousReturnNameFixer/Fixture/skip_conditional_return_type.php.inc b/packages/coding-standard/tests/Fixer/Commenting/RemoveSuperfluousReturnNameFixer/Fixture/skip_conditional_return_type.php.inc new file mode 100644 index 0000000000..0317b412ca --- /dev/null +++ b/packages/coding-standard/tests/Fixer/Commenting/RemoveSuperfluousReturnNameFixer/Fixture/skip_conditional_return_type.php.inc @@ -0,0 +1,49 @@ +> : array) + */ +function getLists(bool $arrayHydration = false): array +{ +} + +/** + * @phpstan-return ($isPublic is true ? string : int) + */ +function conditionalWithIs(bool $isPublic): string|int +{ +} + +/** + * @return $arrayHydration ? array : array + */ +function bareConditional(bool $arrayHydration = false): array +{ +} + +?> +----- +> : array) + */ +function getLists(bool $arrayHydration = false): array +{ +} + +/** + * @phpstan-return ($isPublic is true ? string : int) + */ +function conditionalWithIs(bool $isPublic): string|int +{ +} + +/** + * @return $arrayHydration ? array : array + */ +function bareConditional(bool $arrayHydration = false): array +{ +} + +?>