|
10 | 10 | use Closure; |
11 | 11 | use InvalidArgumentException; |
12 | 12 | use nicoSWD\Rule\Grammar\CallableUserFunctionInterface; |
| 13 | +use nicoSWD\Rule\Parser\Exception\ParserException; |
13 | 14 | use nicoSWD\Rule\TokenStream\Exception\UndefinedVariableException; |
14 | 15 | use nicoSWD\Rule\TokenStream\Token\BaseToken; |
15 | 16 | use nicoSWD\Rule\TokenStream\Token\TokenFactory; |
@@ -49,7 +50,7 @@ public function getStream(string $rule): TokenStream |
49 | 50 | public function getMethod(string $methodName, BaseToken $token): CallableUserFunctionInterface |
50 | 51 | { |
51 | 52 | if ($token instanceof TokenObject) { |
52 | | - return $this->getUserObjectCallable($token, $methodName); |
| 53 | + return $this->getCallableUserObject($token, $methodName); |
53 | 54 | } |
54 | 55 |
|
55 | 56 | if (empty($this->methods)) { |
@@ -126,33 +127,55 @@ private function registerFunctions() |
126 | 127 | } |
127 | 128 | } |
128 | 129 |
|
129 | | - private function getUserObjectCallable(BaseToken $token, string $methodName): CallableUserFunctionInterface |
| 130 | + private function getCallableUserObject(BaseToken $token, string $methodName): CallableUserFunctionInterface |
130 | 131 | { |
131 | | - return new class ($token, $this->tokenFactory, $methodName) implements CallableUserFunctionInterface |
132 | | - { |
133 | | - /** @var BaseToken */ |
134 | | - private $token; |
| 132 | + return new class ($token, $this->tokenFactory, $methodName) implements CallableUserFunctionInterface { |
135 | 133 | /** @var TokenFactory */ |
136 | 134 | private $tokenFactory; |
137 | | - /** @var string */ |
138 | | - private $methodName; |
| 135 | + /** @var Closure */ |
| 136 | + private $callable; |
| 137 | + /** @var array */ |
| 138 | + private $variations = ['get', 'is', '']; |
139 | 139 |
|
140 | 140 | public function __construct(BaseToken $token, TokenFactory $tokenFactory, string $methodName) |
141 | 141 | { |
142 | | - $this->token = $token; |
143 | 142 | $this->tokenFactory = $tokenFactory; |
144 | | - $this->methodName = $methodName; |
| 143 | + $this->callable = $this->getCallable($token, $methodName); |
145 | 144 | } |
146 | 145 |
|
147 | | - public function call(BaseToken $param = null): BaseToken |
| 146 | + private function getCallable(BaseToken $token, string $methodName): Closure |
148 | 147 | { |
149 | | - $object = [$this->token->getValue(), $this->methodName]; |
| 148 | + $object = $token->getValue(); |
150 | 149 |
|
151 | | - if (!is_callable($object)) { |
152 | | - throw new \Exception(); |
| 150 | + if (property_exists($object, $methodName)) { |
| 151 | + return function () use ($object, $methodName) { |
| 152 | + return $object->{$methodName}; |
| 153 | + }; |
153 | 154 | } |
154 | 155 |
|
155 | | - return $this->tokenFactory->createFromPHPType($object()); |
| 156 | + $method[0] = $object; |
| 157 | + $index = 0; |
| 158 | + |
| 159 | + do { |
| 160 | + if (!isset($this->variations[$index])) { |
| 161 | + throw ParserException::undefinedMethod($methodName, $token); |
| 162 | + } |
| 163 | + |
| 164 | + $method[1] = $this->variations[$index] . $methodName; |
| 165 | + } while (!is_callable($method) && isset($this->variations[$index++])); |
| 166 | + |
| 167 | + return function (BaseToken $param = null) use ($method) { |
| 168 | + return $method($param ? $param->getValue() : null); |
| 169 | + }; |
| 170 | + } |
| 171 | + |
| 172 | + public function call(BaseToken $param = null): BaseToken |
| 173 | + { |
| 174 | + $callable = $this->callable; |
| 175 | + |
| 176 | + return $this->tokenFactory->createFromPHPType( |
| 177 | + $callable($param) |
| 178 | + ); |
156 | 179 | } |
157 | 180 | }; |
158 | 181 | } |
|
0 commit comments