,error_levels?:string[]}> */ public function providerValidCodeParse(): iterable { return [ 'generator' => [ ' */ function xrange($start, $limit, $step = 1) { for ($i = $start; $i <= $limit; $i += $step) { yield $i; } } $a = null; /* * Note that an array is never created or returned, * which saves memory. */ foreach (xrange(1, 9, 2) as $number) { $a = $number; }', 'assertions' => [ '$a' => 'int|null', ], ], 'generatorReturnType' => [ ' */ function g():Generator { yield new stdClass; } $g = g();', 'assertions' => [ '$g' => 'Generator', ], ], 'generatorWithReturn' => [ ' * @psalm-generator-return string */ function fooFoo(int $i): Generator { if ($i === 1) { return "bash"; } yield 1; }', ], 'generatorSend' => [ ' */ function g(): Generator { $date = yield 1 => "string"; $date->format("m"); } g()->send(new \DateTime("now")); ', ], 'generatorSendInvalidArgument' => [ ' */ function g(): Generator { yield 1 => "string"; } g()->send(1); ', 'assertions' => [], 'error_levels' => ['InvalidArgument'], ], 'generatorDelegation' => [ ' */ function count_to_ten(): Generator { yield 1; yield 2; yield from [3, 4]; yield from new ArrayIterator([5, 6]); yield from seven_eight(); return yield from nine_ten(); } /** * @return Generator */ function seven_eight(): Generator { yield 7; yield from eight(); } /** * @return Generator */ function eight(): Generator { yield 8; } /** * @return Generator */ function nine_ten(): Generator { yield 9; return 10; } $gen = count_to_ten(); foreach ($gen as $num) { echo "$num "; } $gen2 = $gen->getReturn();', 'assertions' => [ '$gen' => 'Generator', '$gen2' => 'int', ], 'error_levels' => ['MixedAssignment'], ], 'yieldFromArray' => [ ' */ function Bar() : Generator { yield from [1]; }', ], 'generatorWithNestedYield' => [ ' [ ' [ ' */ function other_generator() : Generator { yield "traffic"; return 1; } /** * @return Generator */ function foo() : Generator { $a = yield from other_generator(); takesInt($a); } foreach (foo() as $s) { takesString($s); }', ], 'expectNonNullableTypeWithYield' => [ ' [ ' $s * @return Generator */ function foo(iterable $s) : Traversable { yield from $s; }', ], 'yieldWithReturn' => [ ' */ function gen(): Generator { yield 3 => "abc"; $foo = 4; return $foo; }' ], 'echoYield' => [ ' */ function gen(): Generator { echo yield; }' ], 'yieldFromTwiceWithVoidSend' => [ ' */ function test(): \Generator { return yield "value"; } function load(string $rsa_key): \Generator { echo (yield from test()) . (yield from test()); return 5; }' ], 'iteratorUnion' => [ ' [ ' [ ' */ function generator(): Generator { yield "test"; } $iterator = new NoRewindIterator(generator()); ', 'assertions' => [ '$iterator' => 'NoRewindIterator', ] ], 'detectYieldInNew' => [ ' [ '$_a' => 'pure-Closure():Generator', ] ], 'detectYieldInArray' => [ ' [ '$_a' => 'pure-Closure():Generator', ] ], ]; } /** * @return iterable */ public function providerInvalidCodeParse(): iterable { return [ 'shouldWarnAboutNoGeneratorReturn' => [ ' 'InvalidReturnStatement', ], 'expectNonNullableTypeWithNullReturn' => [ ' 'NullableReturnStatement', ], 'invalidIterator' => [ ' 'InvalidIterator', ], 'rawObjectIteration' => [ ' 'RawObjectIteration', ], 'possibleRawObjectIteration' => [ ' 5) { $arr[] = new A; } else { $arr = new B; } yield from $arr; }', 'error_message' => 'PossibleRawObjectIteration', ], 'possibleRawObjectIterationFromIsset' => [ ' 'PossibleRawObjectIteration', ], ]; } }