1
0
mirror of https://github.com/danog/amp.git synced 2025-01-22 05:11:42 +01:00

Refactor coroutine return for 5.x

This commit is contained in:
Aaron Piotrowski 2016-05-22 00:11:03 -05:00
parent 9c541b0faa
commit 1864b3cbe6
3 changed files with 74 additions and 5 deletions

View File

@ -53,7 +53,7 @@ final class Coroutine implements Awaitable {
}
// Send the new value and execute to next yield statement.
$this->next($this->generator->send($value), $value);
$this->next($this->generator->send($value));
} catch (\Throwable $exception) {
$this->fail($exception);
} catch (\Exception $exception) {
@ -74,11 +74,10 @@ final class Coroutine implements Awaitable {
* Examines the value yielded from the generator and prepares the next step in iteration.
*
* @param mixed $yielded Value yielded from generator.
* @param mixed $last Prior resolved value. No longer needed when PHP 5.x support is dropped.
*/
private function next($yielded, $last = null) {
private function next($yielded) {
if (!$this->generator->valid()) {
$this->resolve(PHP_MAJOR_VERSION >= 7 ? $this->generator->getReturn() : $last);
$this->resolve(PHP_MAJOR_VERSION >= 7 ? $this->generator->getReturn() : null);
return;
}
@ -86,10 +85,24 @@ final class Coroutine implements Awaitable {
if ($yielded instanceof Awaitable) {
$yielded->when($this->when);
} elseif ($yielded instanceof Internal\CoroutineResult) {
// @todo Necessary for returning values in PHP 5.x. Remove once PHP 7 is required.
$this->resolve($yielded->getValue());
} else {
$this->resolve($yielded);
throw new Exception\InvalidYieldException($this->generator, $yielded);
}
--$this->depth;
}
/**
* Return a value from a coroutine. Required for PHP 5.x only. Use the return keyword in PHP 7.
*
* @param mixed $value
*
* @return \Amp\Awaitable\Internal\CoroutineResult
*/
public static function result($value) {
return new Internal\CoroutineResult($value);
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace Amp\Awaitable\Exception;
class InvalidYieldException extends \DomainException {
public function __construct(\Generator $generator, $yielded) {
$prefix = \sprintf(
"Unexpected yield (Awaitable expected); %s yielded at key %s",
\is_object($yielded) ? \get_class($yielded) : \gettype($yielded),
$generator->key()
);
if (PHP_MAJOR_VERSION < 7 || !$generator->valid()) {
parent::__construct($prefix);
return;
}
$reflGen = new \ReflectionGenerator($generator);
$exeGen = $reflGen->getExecutingGenerator();
if ($isSubgenerator = ($exeGen !== $generator)) {
$reflGen = new \ReflectionGenerator($exeGen);
}
parent::__construct(\sprintf(
"%s on line %s in %s",
$prefix,
$reflGen->getExecutingLine(),
$reflGen->getExecutingFile()
));
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace Amp\Awaitable\Internal;
class CoroutineResult
{
/**
* @var mixed
*/
private $value;
/**
* @param mixed $value Coroutine return value.
*/
public function __construct($value) {
$this->value = $value;
}
/**
* @return mixed Coroutine return value.
*/
public function getValue() {
return $this->value;
}
}