Skip to content

Commit 94783c8

Browse files
committed
Function with yield returns value
1 parent 5df7966 commit 94783c8

File tree

3 files changed

+51
-9
lines changed

3 files changed

+51
-9
lines changed

SlevomatCodingStandard/Helpers/FunctionHelper.php

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -125,19 +125,28 @@ public static function returnsValue(\PHP_CodeSniffer_File $codeSnifferFile, int
125125
{
126126
$tokens = $codeSnifferFile->getTokens();
127127

128-
for ($i = $tokens[$functionPointer]['scope_opener'] + 1; $i < $tokens[$functionPointer]['scope_closer']; $i++) {
129-
if ($tokens[$i]['code'] !== T_RETURN) {
130-
continue;
131-
}
132-
133-
foreach (array_reverse($tokens[$i]['conditions'], true) as $conditionPointer => $conditionTokenCode) {
128+
$isInSameLevel = function (int $pointer) use ($functionPointer, $tokens): bool {
129+
foreach (array_reverse($tokens[$pointer]['conditions'], true) as $conditionPointer => $conditionTokenCode) {
134130
if ($conditionTokenCode === T_CLOSURE || $conditionTokenCode === T_ANON_CLASS) {
135-
continue 2;
131+
return false;
136132
} elseif ($conditionPointer === $functionPointer) {
137-
$nextEffectiveTokenPointer = TokenHelper::findNextEffective($codeSnifferFile, $i + 1);
138-
return $tokens[$nextEffectiveTokenPointer]['code'] !== T_SEMICOLON;
133+
break;
139134
}
140135
}
136+
return true;
137+
};
138+
139+
for ($i = $tokens[$functionPointer]['scope_opener'] + 1; $i < $tokens[$functionPointer]['scope_closer']; $i++) {
140+
if ($tokens[$i]['code'] === T_YIELD && $isInSameLevel($i)) {
141+
return true;
142+
}
143+
}
144+
145+
for ($i = $tokens[$functionPointer]['scope_opener'] + 1; $i < $tokens[$functionPointer]['scope_closer']; $i++) {
146+
if ($tokens[$i]['code'] === T_RETURN && $isInSameLevel($i)) {
147+
$nextEffectiveTokenPointer = TokenHelper::findNextEffective($codeSnifferFile, $i + 1);
148+
return $tokens[$nextEffectiveTokenPointer]['code'] !== T_SEMICOLON;
149+
}
141150
}
142151

143152
return false;

tests/Helpers/FunctionHelperTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,10 @@ public function dataReturnsValueOrNot(): array
247247
['returnsValue', true],
248248
['returnsVariable', true],
249249
['returnsValueInCondition', true],
250+
['returnsGenerator', true],
251+
['returnsGeneratorWithEarlyTermination', true],
252+
['returnsGeneratorWithVeryEarlyTermination', true],
253+
['generatorIsInClosure', false],
250254
['noReturn', false],
251255
['returnsVoid', false],
252256
['containsClosure', false],

tests/Helpers/data/functionReturnsValueOrNot.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,35 @@ public function returnsValueInCondition()
2323
}
2424
}
2525

26+
public function returnsGenerator(): \Generator
27+
{
28+
yield [];
29+
}
30+
31+
public function returnsGeneratorWithEarlyTermination(): \Generator
32+
{
33+
if (true) {
34+
yield [];
35+
return;
36+
}
37+
38+
yield [];
39+
}
40+
41+
public function returnsGeneratorWithVeryEarlyTermination()
42+
{
43+
return;
44+
45+
yield [];
46+
}
47+
48+
public function generatorIsInClosure()
49+
{
50+
$x = function (): \Generator {
51+
yield [];
52+
};
53+
}
54+
2655
public function noReturn()
2756
{
2857
// Nothing

0 commit comments

Comments
 (0)