|
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