Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions blink/internal/fixer/rules/symplify_docblock2.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
}
Expand Down
10 changes: 10 additions & 0 deletions blink/internal/fixer/rules/symplify_docblock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
"<?php\nclass A {\n /**\n * @return ($arrayHydration is true ? array<int, mixed> : array<int, LeadList>)\n */\n function f(bool $arrayHydration) {}\n}\n",
"<?php\nclass A {\n /**\n * @return $arrayHydration ? array<int, mixed> : array<int, LeadList>\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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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, []);
Expand Down Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

/**
* @return ($arrayHydration is true ? array<int, array<string, mixed>> : array<int, LeadList>)
*/
function getLists(bool $arrayHydration = false): array
{
}

/**
* @phpstan-return ($isPublic is true ? string : int)
*/
function conditionalWithIs(bool $isPublic): string|int
{
}

/**
* @return $arrayHydration ? array<int, mixed> : array<int, LeadList>
*/
function bareConditional(bool $arrayHydration = false): array
{
}

?>
-----
<?php

/**
* @return ($arrayHydration is true ? array<int, array<string, mixed>> : array<int, LeadList>)
*/
function getLists(bool $arrayHydration = false): array
{
}

/**
* @phpstan-return ($isPublic is true ? string : int)
*/
function conditionalWithIs(bool $isPublic): string|int
{
}

/**
* @return $arrayHydration ? array<int, mixed> : array<int, LeadList>
*/
function bareConditional(bool $arrayHydration = false): array
{
}

?>
Loading