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 src/Node/FunctionReturnStatementsNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ public function __construct(
parent::__construct($function->getAttributes());
}

public function getFunction(): Function_
{
return $this->function;
}

public function getReturnStatements(): array
{
return $this->returnStatements;
Expand Down
5 changes: 5 additions & 0 deletions src/Node/MethodReturnStatementsNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ public function __construct(
$this->classMethod = $method;
}

public function getClassMethod(): ClassMethod
{
return $this->classMethod;
}

public function getReturnStatements(): array
{
return $this->returnStatements;
Expand Down
44 changes: 44 additions & 0 deletions tests/PHPStan/Node/ReturnStatementsNodeParserNodeRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php declare(strict_types = 1);

namespace PHPStan\Node;

use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
use function sprintf;

/**
* @implements Rule<ReturnStatementsNode>
*/
class ReturnStatementsNodeParserNodeRule implements Rule
{

public function getNodeType(): string
{
return ReturnStatementsNode::class;
}

public function processNode(Node $node, Scope $scope): array
{
if ($node instanceof MethodReturnStatementsNode) {
$parserNode = $node->getClassMethod();
} elseif ($node instanceof FunctionReturnStatementsNode) {
$parserNode = $node->getFunction();
} else {
return [];
}

return [
RuleErrorBuilder::message(sprintf(
'%s %s(), lines %d-%d, return type node: %s',
$parserNode->getType(),
$parserNode->name->toString(),
$parserNode->getStartLine(),
$parserNode->getEndLine(),
$parserNode->returnType !== null ? $parserNode->returnType->getType() : 'none',
))->identifier('tests.returnStatementsNodeParserNode')->build(),
];
}

}
37 changes: 37 additions & 0 deletions tests/PHPStan/Node/ReturnStatementsNodeParserNodeRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php declare(strict_types = 1);

namespace PHPStan\Node;

use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;

/**
* @extends RuleTestCase<ReturnStatementsNodeParserNodeRule>
*/
class ReturnStatementsNodeParserNodeRuleTest extends RuleTestCase
{

protected function getRule(): Rule
{
return new ReturnStatementsNodeParserNodeRule();
}

public function testRule(): void
{
$this->analyse([__DIR__ . '/data/return-statements-node-parser-node.php'], [
[
'Stmt_ClassMethod doFoo(), lines 8-11, return type node: NullableType',
8,
],
[
'Stmt_ClassMethod doBar(), lines 13-16, return type node: none',
13,
],
[
'Stmt_Function doBaz(), lines 20-23, return type node: Identifier',
20,
],
]);
}

}
23 changes: 23 additions & 0 deletions tests/PHPStan/Node/data/return-statements-node-parser-node.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace ReturnStatementsNodeParserNode;

class Foo
{

public function doFoo(): ?int
{
return 1;
}

public function doBar()
{
$f = static fn (): int => 1;
}

}

function doBaz(): int
{
return 2;
}
Loading