Passed
Pull Request — master (#10)
by PHPinnacle
06:17 queued 03:59
created

Subroutine::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of PHPinnacle/Ensign.
4
 *
5
 * (c) PHPinnacle Team <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
declare(strict_types = 1);
12
13
namespace PHPinnacle\Ensign;
14
15
use Amp\Coroutine;
16
use Amp\Promise;
17
18
final class Subroutine implements Promise
19
{
20
    /**
21
     * @var Executor
22
     */
23
    private $generator;
24
25
    /**
26
     * @var callable
27
     */
28
    private $resolver;
29
30
    /**
31
     * @param \Generator $generator
32
     * @param callable   $resolver
33
     */
34 4
    public function __construct(\Generator $generator, callable $resolver)
35
    {
36 4
        $this->generator = $generator;
0 ignored issues
show
Documentation Bug introduced by
It seems like $generator of type Generator is incompatible with the declared type PHPinnacle\Ensign\Executor of property $generator.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
37 4
        $this->resolver  = $resolver;
38 4
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43 4
    public function onResolve(callable $handler)
44
    {
45 4
        $coroutine = new Coroutine($this->recoil());
46 4
        $coroutine->onResolve($handler);
47 4
    }
48
49
    /**
50
     * @return \Generator
51
     */
52 4
    private function recoil(): \Generator
53
    {
54 4
        $step = 0;
55
56 4
        while ($this->generator->valid()) {
0 ignored issues
show
Bug introduced by
The method valid() does not exist on PHPinnacle\Ensign\Executor. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

56
        while ($this->generator->/** @scrutinizer ignore-call */ valid()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
57
            try {
58
                // yield new Promise
59
                // yield [$promiseOne, $promiseTwo]
60
61
                // yield new Signal
62
                // yield new Signal => 'arg'
63
                // yield new Signal => ['arg', 'two']
64
                // yield Signal::class => [new Signal, 'arg', 'two']
65
                // yield 'signal'
66
                // yield 'signal' => 'arg'
67
                // yield 'signal' => ['arg', 'two']
68 4
                $current = $this->generator->current();
0 ignored issues
show
Bug introduced by
The method current() does not exist on PHPinnacle\Ensign\Executor. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

68
                /** @scrutinizer ignore-call */ 
69
                $current = $this->generator->current();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
69 4
                $key     = $this->generator->key();
0 ignored issues
show
Bug introduced by
The method key() does not exist on PHPinnacle\Ensign\Executor. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

69
                /** @scrutinizer ignore-call */ 
70
                $key     = $this->generator->key();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
70
71 4
                if ($key === $step) {
72 4
                    $interrupt = $current;
73 4
                    $arguments = [];
74
                } else {
75 2
                    $interrupt = $key;
76 2
                    $arguments = \is_array($current) ? $current : [$current];
77
78 2
                    $step--;
79
                }
80
81 4
                if (\is_array($interrupt)) {
82
                    $interrupt = Promise\all($interrupt);
0 ignored issues
show
Bug introduced by
The function all was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

82
                    $interrupt = /** @scrutinizer ignore-call */ Promise\all($interrupt);
Loading history...
83
                }
84
85 4
                if (!$interrupt instanceof Promise) {
86 3
                    $interrupt = $this->intercept($interrupt, $arguments);
87
                }
88
89 3
                $this->generator->send(yield $interrupt);
0 ignored issues
show
Bug introduced by
The method send() does not exist on PHPinnacle\Ensign\Executor. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

89
                $this->generator->/** @scrutinizer ignore-call */ 
90
                                  send(yield $interrupt);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
90 2
            } catch (\Throwable $error) {
91 2
                $this->throw($error, $step);
92 3
            } finally {
93 4
                $step++;
94
            }
95
        };
96
97 3
        return $this->generator->getReturn();
0 ignored issues
show
Bug introduced by
The method getReturn() does not exist on PHPinnacle\Ensign\Executor. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

97
        return $this->generator->/** @scrutinizer ignore-call */ getReturn();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
98
    }
99
100
    /**
101
     * @param \Throwable $error
102
     * @param int        $step
103
     *
104
     * @return void
105
     */
106 2
    private function throw(\Throwable $error, int $step): void
107
    {
108
        try {
109 2
            $this->generator->throw($error);
0 ignored issues
show
Bug introduced by
The method throw() does not exist on PHPinnacle\Ensign\Executor. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

109
            $this->generator->/** @scrutinizer ignore-call */ 
110
                              throw($error);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
110 1
        } catch (\Throwable $error) {
111 1
            throw new Exception\BadActionCall($step, $error);
112
        }
113 1
    }
114
115
    /**
116
     * @param mixed $interrupt
117
     * @param array $arguments
118
     *
119
     * @return mixed
120
     */
121 3
    private function intercept($interrupt, array $arguments)
122
    {
123 3
        if (\is_object($interrupt)) {
124 2
            \array_unshift($arguments, $interrupt);
125
126 2
            $interrupt = \get_class($interrupt);
127
        }
128
129 3
        return \call_user_func($this->resolver, $interrupt, $arguments);
130
    }
131
}
132