Skip to content

Commit ca6d2da

Browse files
feat: AST-based query runner
Co-Authored-By: Roman Steiner <roman@toastlab.ch>
1 parent 0718b62 commit ca6d2da

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+3979
-91
lines changed

src/Query/AST/ArgumentListNode.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Kirby\Query\AST;
4+
5+
use Kirby\Query\Visitors\Visitor;
6+
7+
/**
8+
* Represents a list of (method) arguments
9+
*
10+
* @package Kirby Query
11+
* @author Roman Steiner <roman@toastlab.ch>,
12+
* Nico Hoffmann <nico@getkirby.com>
13+
* @link https://getkirby.com
14+
* @license https://opensource.org/licenses/MIT
15+
* @since 5.1.0
16+
*/
17+
class ArgumentListNode extends Node
18+
{
19+
public function __construct(
20+
public array $arguments = []
21+
) {
22+
}
23+
24+
public function resolve(Visitor $visitor): array|string
25+
{
26+
// Resolve each argument
27+
$arguments = array_map(
28+
fn ($argument) => $argument->resolve($visitor),
29+
$this->arguments
30+
);
31+
32+
// Keep as array or convert to string
33+
// depending on the visitor type
34+
return $visitor->argumentList($arguments);
35+
}
36+
}

src/Query/AST/ArrayListNode.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace Kirby\Query\AST;
4+
5+
use Kirby\Query\Visitors\Visitor;
6+
7+
/**
8+
* @package Kirby Query
9+
* @author Roman Steiner <roman@toastlab.ch>,
10+
* Nico Hoffmann <nico@getkirby.com>
11+
* @link https://getkirby.com
12+
* @license https://opensource.org/licenses/MIT
13+
* @since 5.1.0
14+
*/
15+
class ArrayListNode extends Node
16+
{
17+
public function __construct(
18+
public array $elements,
19+
) {
20+
}
21+
22+
public function resolve(Visitor $visitor): array|string
23+
{
24+
// Resolve each array element
25+
$elements = array_map(
26+
fn ($element) => $element->resolve($visitor),
27+
$this->elements
28+
);
29+
30+
// Keep as array or convert to string
31+
// depending on the visitor type
32+
return $visitor->arrayList($elements);
33+
}
34+
}

src/Query/AST/ClosureNode.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Kirby\Query\AST;
4+
5+
use Kirby\Query\Visitors\Visitor;
6+
7+
/**
8+
* @package Kirby Query
9+
* @author Roman Steiner <roman@toastlab.ch>,
10+
* Nico Hoffmann <nico@getkirby.com>
11+
* @link https://getkirby.com
12+
* @license https://opensource.org/licenses/MIT
13+
* @since 5.1.0
14+
*/
15+
class ClosureNode extends Node
16+
{
17+
/**
18+
* @param string[] $arguments The arguments names
19+
*/
20+
public function __construct(
21+
public array $arguments,
22+
public Node $body,
23+
) {
24+
}
25+
26+
public function resolve(Visitor $visitor): mixed
27+
{
28+
return $visitor->closure($this);
29+
}
30+
}

src/Query/AST/CoalesceNode.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Kirby\Query\AST;
4+
5+
use Kirby\Query\Visitors\Visitor;
6+
7+
/**
8+
* @package Kirby Query
9+
* @author Roman Steiner <roman@toastlab.ch>,
10+
* Nico Hoffmann <nico@getkirby.com>
11+
* @link https://getkirby.com
12+
* @license https://opensource.org/licenses/MIT
13+
* @since 5.1.0
14+
*/
15+
class CoalesceNode extends Node
16+
{
17+
public function __construct(
18+
public Node $left,
19+
public Node $right,
20+
) {
21+
}
22+
23+
public function resolve(Visitor $visitor): mixed
24+
{
25+
return $visitor->coalescence(
26+
left: $this->left->resolve($visitor),
27+
right: $this->right->resolve($visitor)
28+
);
29+
}
30+
}

src/Query/AST/GlobalFunctionNode.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Kirby\Query\AST;
4+
5+
use Kirby\Query\Visitors\Visitor;
6+
7+
/**
8+
* @package Kirby Query
9+
* @author Roman Steiner <roman@toastlab.ch>,
10+
* Nico Hoffmann <nico@getkirby.com>
11+
* @link https://getkirby.com
12+
* @license https://opensource.org/licenses/MIT
13+
* @since 5.1.0
14+
*/
15+
class GlobalFunctionNode extends Node
16+
{
17+
public function __construct(
18+
public string $name,
19+
public ArgumentListNode $arguments,
20+
) {
21+
}
22+
23+
public function resolve(Visitor $visitor): mixed
24+
{
25+
return $visitor->function(
26+
name: $this->name,
27+
arguments: $this->arguments->resolve($visitor)
28+
);
29+
}
30+
}

src/Query/AST/LiteralNode.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Kirby\Query\AST;
4+
5+
use Kirby\Query\Visitors\Visitor;
6+
7+
/**
8+
* Represents literal values (e.g. string, int, bool)
9+
*
10+
* @package Kirby Query
11+
* @author Roman Steiner <roman@toastlab.ch>,
12+
* Nico Hoffmann <nico@getkirby.com>
13+
* @link https://getkirby.com
14+
* @license https://opensource.org/licenses/MIT
15+
* @since 5.1.0
16+
*/
17+
class LiteralNode extends Node
18+
{
19+
public function __construct(
20+
public mixed $value,
21+
) {
22+
}
23+
24+
public function resolve(Visitor $visitor): mixed
25+
{
26+
return $visitor->literal($this->value);
27+
}
28+
}

src/Query/AST/MemberAccessNode.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Kirby\Query\AST;
4+
5+
use Kirby\Query\Visitors\Visitor;
6+
7+
/**
8+
* Represents the access (e.g. method call) on a node
9+
*
10+
* @package Kirby Query
11+
* @author Roman Steiner <roman@toastlab.ch>,
12+
* Nico Hoffmann <nico@getkirby.com>
13+
* @link https://getkirby.com
14+
* @license https://opensource.org/licenses/MIT
15+
* @since 5.1.0
16+
*/
17+
class MemberAccessNode extends Node
18+
{
19+
public function __construct(
20+
public Node $object,
21+
public Node $member,
22+
public ArgumentListNode|null $arguments = null,
23+
public bool $nullSafe = false,
24+
) {
25+
}
26+
27+
public function resolve(Visitor $visitor): mixed
28+
{
29+
return $visitor->memberAccess(
30+
object: $this->object->resolve($visitor),
31+
member: $this->member->resolve($visitor),
32+
arguments: $this->arguments?->resolve($visitor),
33+
nullSafe: $this->nullSafe
34+
);
35+
}
36+
}

src/Query/AST/Node.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Kirby\Query\AST;
4+
5+
use Kirby\Query\Visitors\Visitor;
6+
7+
/**
8+
* Basic query node representation
9+
*
10+
* @package Kirby Query
11+
* @author Roman Steiner <roman@toastlab.ch>,
12+
* Nico Hoffmann <nico@getkirby.com>
13+
* @link https://getkirby.com
14+
* @license https://opensource.org/licenses/MIT
15+
* @since 5.1.0
16+
*
17+
* @codeCoverageIgnore
18+
*/
19+
abstract class Node
20+
{
21+
abstract public function resolve(Visitor $visitor);
22+
}

src/Query/AST/TernaryNode.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Kirby\Query\AST;
4+
5+
use Kirby\Query\Visitors\Visitor;
6+
7+
/**
8+
* Represents a ternary condition
9+
* with a value for when the condition is true
10+
* and another value for when the condition is false
11+
*
12+
* @package Kirby Query
13+
* @author Roman Steiner <roman@toastlab.ch>
14+
* @link https://getkirby.com
15+
* @license https://opensource.org/licenses/MIT
16+
* @since 5.1.0
17+
*/
18+
class TernaryNode extends Node
19+
{
20+
public function __construct(
21+
public Node $condition,
22+
public Node $false,
23+
public Node|null $true = null
24+
) {
25+
}
26+
27+
public function resolve(Visitor $visitor): mixed
28+
{
29+
return $visitor->ternary(
30+
condition: $this->condition->resolve($visitor),
31+
true: $this->true?->resolve($visitor),
32+
false: $this->false->resolve($visitor)
33+
);
34+
}
35+
}

src/Query/AST/VariableNode.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Kirby\Query\AST;
4+
5+
use Kirby\Query\Visitors\Visitor;
6+
7+
/**
8+
* Represents a variable (e.g. an object)
9+
*
10+
* @package Kirby Query
11+
* @author Roman Steiner <roman@toastlab.ch>,
12+
* Nico Hoffmann <nico@getkirby.com>
13+
* @link https://getkirby.com
14+
* @license https://opensource.org/licenses/MIT
15+
* @since 5.1.0
16+
*/
17+
class VariableNode extends Node
18+
{
19+
public function __construct(
20+
public string $name,
21+
) {
22+
}
23+
24+
public function resolve(Visitor $visitor): mixed
25+
{
26+
return $visitor->variable($this->name);
27+
}
28+
}

0 commit comments

Comments
 (0)