Skip to content

Commit bb0ee07

Browse files
author
Nicolas Oelgart
committed
Add basic support for object method calls
1 parent 1a0005c commit bb0ee07

File tree

8 files changed

+100
-12
lines changed

8 files changed

+100
-12
lines changed

src/TokenStream/AST.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use nicoSWD\Rule\TokenStream\Token\BaseToken;
1515
use nicoSWD\Rule\TokenStream\Token\TokenFactory;
1616
use nicoSWD\Rule\Tokenizer\TokenizerInterface;
17+
use nicoSWD\Rule\TokenStream\Token\TokenObject;
1718

1819
class AST
1920
{
@@ -47,6 +48,10 @@ public function getStream(string $rule): TokenStream
4748

4849
public function getMethod(string $methodName, BaseToken $token): CallableUserFunctionInterface
4950
{
51+
if ($token instanceof TokenObject) {
52+
return $this->getUserObjectCallable($token, $methodName);
53+
}
54+
5055
if (empty($this->methods)) {
5156
$this->registerMethods();
5257
}
@@ -120,4 +125,35 @@ private function registerFunctions()
120125
$this->registerFunctionClass($functionName, $className);
121126
}
122127
}
128+
129+
private function getUserObjectCallable(BaseToken $token, string $methodName): CallableUserFunctionInterface
130+
{
131+
return new class ($token, $this->tokenFactory, $methodName) implements CallableUserFunctionInterface
132+
{
133+
/** @var BaseToken */
134+
private $token;
135+
/** @var TokenFactory */
136+
private $tokenFactory;
137+
/** @var string */
138+
private $methodName;
139+
140+
public function __construct(BaseToken $token, TokenFactory $tokenFactory, string $methodName)
141+
{
142+
$this->token = $token;
143+
$this->tokenFactory = $tokenFactory;
144+
$this->methodName = $methodName;
145+
}
146+
147+
public function call(BaseToken $param = null): BaseToken
148+
{
149+
$object = [$this->token->getValue(), $this->methodName];
150+
151+
if (!is_callable($object)) {
152+
throw new \Exception();
153+
}
154+
155+
return $this->tokenFactory->createFromPHPType($object());
156+
}
157+
};
158+
}
123159
}

src/TokenStream/Node/BaseNode.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
namespace nicoSWD\Rule\TokenStream\Node;
99

1010
use Closure;
11+
use nicoSWD\Rule\Grammar\CallableUserFunctionInterface;
1112
use nicoSWD\Rule\TokenStream\Token\BaseToken;
1213
use nicoSWD\Rule\TokenStream\TokenCollection;
1314
use nicoSWD\Rule\Parser\Exception\ParserException;
14-
use nicoSWD\Rule\Grammar\CallableFunction;
1515
use nicoSWD\Rule\TokenStream\TokenStream;
1616
use nicoSWD\Rule\TokenStream\Token\TokenType;
1717

@@ -59,7 +59,7 @@ protected function hasMethodCall(): bool
5959
return $hasMethod;
6060
}
6161

62-
protected function getMethod(BaseToken $token): CallableFunction
62+
protected function getMethod(BaseToken $token): CallableUserFunctionInterface
6363
{
6464
$this->tokenStream->getStack()->seek($this->methodOffset);
6565

src/TokenStream/Token/TokenFactory.php

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,9 @@ public function createFromPHPType($value): BaseToken
5858
case 'double':
5959
return new TokenFloat($value);
6060
case 'array':
61-
$params = new TokenCollection();
62-
63-
foreach ($value as $item) {
64-
$params->attach($this->createFromPHPType($item));
65-
}
66-
67-
return new TokenArray($params);
61+
return $this->buildTokenCollection($value);
62+
case 'object':
63+
return new TokenObject($value);
6864
default:
6965
throw new ParserException(sprintf(
7066
'Unsupported PHP type: "%s"',
@@ -81,4 +77,15 @@ public function createFromTokenName(string $tokenName): string
8177

8278
return $this->tokenMap[$tokenName];
8379
}
80+
81+
private function buildTokenCollection($value): TokenArray
82+
{
83+
$params = new TokenCollection();
84+
85+
foreach ($value as $item) {
86+
$params->attach($this->createFromPHPType($item));
87+
}
88+
89+
return new TokenArray($params);
90+
}
8491
}

src/TokenStream/Token/TokenObject.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php declare(strict_types=1);
2+
3+
/**
4+
* @license http://opensource.org/licenses/mit-license.php MIT
5+
* @link https://github.com/nicoSWD
6+
* @author Nicolas Oelgart <[email protected]>
7+
*/
8+
namespace nicoSWD\Rule\TokenStream\Token;
9+
10+
final class TokenObject extends BaseToken
11+
{
12+
public function getType() : int
13+
{
14+
return TokenType::OBJECT;
15+
}
16+
}

src/TokenStream/Token/TokenType.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php
1+
<?php declare(strict_types=1);
22

33
/**
44
* @license http://opensource.org/licenses/mit-license.php MIT

src/TokenStream/TokenStream.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
use ArrayIterator;
1111
use Closure;
12+
use nicoSWD\Rule\Grammar\CallableFunction;
1213
use nicoSWD\Rule\Parser\Exception\ParserException;
1314
use nicoSWD\Rule\Grammar\CallableUserFunctionInterface;
1415
use nicoSWD\Rule\TokenStream\Token\BaseToken;

tests/integration/ObjectTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php declare(strict_types=1);
2+
3+
/**
4+
* @license http://opensource.org/licenses/mit-license.php MIT
5+
* @link https://github.com/nicoSWD
6+
* @author Nicolas Oelgart <[email protected]>
7+
*/
8+
use nicoSWD\Rule\tests\integration\AbstractTestBase;
9+
10+
final class ObjectTest extends AbstractTestBase
11+
{
12+
public function testObjects()
13+
{
14+
$myObj = new class {
15+
function test() {
16+
return 'test one two';
17+
}
18+
};
19+
20+
$variables = [
21+
'my_obj' => $myObj,
22+
'my_string' => 'some test'
23+
];
24+
25+
$this->assertTrue($this->evaluate('my_obj.test() === "test one two"', $variables));
26+
$this->assertFalse($this->evaluate('my_obj.test() === "oh no"', $variables));
27+
}
28+
}

tests/unit/Token/TokenFactoryTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ public function testSimpleTypeReturnsCorrectInstance()
3838
public function testUnsupportedTypeThrowsException()
3939
{
4040
$this->expectException(ParserException::class);
41-
$this->expectExceptionMessage('Unsupported PHP type: "object"');
41+
$this->expectExceptionMessage('Unsupported PHP type: "resource"');
4242

43-
$this->tokenFactory->createFromPHPType(new \stdClass());
43+
$this->tokenFactory->createFromPHPType(tmpfile());
4444
}
4545

4646
public function testGivenAnInvalidTokenNameItShouldThrowAnException()

0 commit comments

Comments
 (0)