Dustin Wilson
3 years ago
18 changed files with 382 additions and 281 deletions
@ -0,0 +1,28 @@ |
|||
<?php |
|||
/** @license MIT |
|||
* Copyright 2021 Dustin Wilson et al. |
|||
* See LICENSE file for details */ |
|||
|
|||
declare(strict_types=1); |
|||
namespace dW\Lit\Scope; |
|||
|
|||
class Composite extends Node { |
|||
protected array $expressions = []; |
|||
protected bool $frozen = false; |
|||
|
|||
|
|||
public function __construct(Selector $parent) { |
|||
$this->_parent = \WeakReference::create($parent); |
|||
} |
|||
|
|||
|
|||
public function add(Expression ...$expressions): bool { |
|||
if ($this->frozen) { |
|||
return false; |
|||
} |
|||
|
|||
$this->expressions = $expressions; |
|||
$this->frozen = true; |
|||
return true; |
|||
} |
|||
} |
@ -0,0 +1,41 @@ |
|||
<?php |
|||
/** @license MIT |
|||
* Copyright 2021 Dustin Wilson et al. |
|||
* See LICENSE file for details */ |
|||
|
|||
declare(strict_types=1); |
|||
namespace dW\Lit\Scope; |
|||
|
|||
class Expression extends Node { |
|||
protected Filter|Group|Path $_child; |
|||
protected bool $frozen = false; |
|||
protected bool $_negate = false; |
|||
protected ?string $_operator; |
|||
|
|||
|
|||
public function __construct(Composite $parent, ?string $operator = null) { |
|||
$this->_operator = $operator; |
|||
$this->_parent = \WeakReference::create($parent); |
|||
|
|||
if ($operator === '-') { |
|||
$this->negate = true; |
|||
} |
|||
} |
|||
|
|||
|
|||
public function __set(string $name, $value) { |
|||
if ($name !== 'child') { |
|||
$trace = debug_backtrace(); |
|||
trigger_error("Cannot set undefined property $name in {$trace[0]['file']} on line {$trace[0]['line']}", E_USER_NOTICE); |
|||
} |
|||
|
|||
if ($this->frozen) { |
|||
$trace = debug_backtrace(); |
|||
trigger_error("Cannot set readonly $name property in {$trace[0]['file']} on line {$trace[0]['line']}", E_USER_NOTICE); |
|||
return; |
|||
} |
|||
|
|||
$this->frozen = true; |
|||
$this->_child = $value; |
|||
} |
|||
} |
@ -0,0 +1,37 @@ |
|||
<?php |
|||
/** @license MIT |
|||
* Copyright 2021 Dustin Wilson et al. |
|||
* See LICENSE file for details */ |
|||
|
|||
declare(strict_types=1); |
|||
namespace dW\Lit\Scope; |
|||
|
|||
class Filter extends Node { |
|||
protected Group|Path $_child; |
|||
protected bool $frozen = false; |
|||
protected string $_operator; |
|||
protected string $_side; |
|||
|
|||
|
|||
public function __construct(Selector $parent, string $side) { |
|||
$this->_parent = \WeakReference::create($parent); |
|||
$this->_side = $side; |
|||
} |
|||
|
|||
|
|||
public function __set(string $name, $value) { |
|||
if ($name !== 'child') { |
|||
$trace = debug_backtrace(); |
|||
trigger_error("Cannot set undefined property $name in {$trace[0]['file']} on line {$trace[0]['line']}", E_USER_NOTICE); |
|||
} |
|||
|
|||
if ($this->frozen) { |
|||
$trace = debug_backtrace(); |
|||
trigger_error("Cannot set readonly $name property in {$trace[0]['file']} on line {$trace[0]['line']}", E_USER_NOTICE); |
|||
return; |
|||
} |
|||
|
|||
$this->frozen = true; |
|||
$this->_child = $value; |
|||
} |
|||
} |
@ -0,0 +1,34 @@ |
|||
<?php |
|||
/** @license MIT |
|||
* Copyright 2021 Dustin Wilson et al. |
|||
* See LICENSE file for details */ |
|||
|
|||
declare(strict_types=1); |
|||
namespace dW\Lit\Scope; |
|||
|
|||
class Group extends Node { |
|||
protected Selector $_child; |
|||
protected bool $frozen = false; |
|||
|
|||
|
|||
public function __construct(Expression $parent) { |
|||
$this->_parent = \WeakReference::create($parent); |
|||
} |
|||
|
|||
|
|||
public function __set(string $name, $value) { |
|||
if ($name !== 'child') { |
|||
$trace = debug_backtrace(); |
|||
trigger_error("Cannot set undefined property $name in {$trace[0]['file']} on line {$trace[0]['line']}", E_USER_NOTICE); |
|||
} |
|||
|
|||
if ($this->frozen) { |
|||
$trace = debug_backtrace(); |
|||
trigger_error("Cannot set readonly $name property in {$trace[0]['file']} on line {$trace[0]['line']}", E_USER_NOTICE); |
|||
return; |
|||
} |
|||
|
|||
$this->frozen = true; |
|||
$this->_child = $value; |
|||
} |
|||
} |
@ -1,37 +0,0 @@ |
|||
<?php |
|||
/** @license MIT |
|||
* Copyright 2021 Dustin Wilson et al. |
|||
* See LICENSE file for details */ |
|||
|
|||
declare(strict_types=1); |
|||
namespace dW\Lit\Scope; |
|||
|
|||
class AndMatcher extends Matcher { |
|||
protected array $matchers = []; |
|||
|
|||
public function __construct(Matcher ...$matchers) { |
|||
$this->matchers = $matchers; |
|||
} |
|||
|
|||
public function add(Matcher $matcher) { |
|||
$this->matchers[] = $matcher; |
|||
} |
|||
|
|||
public function matches(string ...$scopes): bool { |
|||
foreach ($this->matchers as $m) { |
|||
if (!$m->matches(...$scopes)) { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
public function getPrefix(string ...$scopes): string|null|false { |
|||
if ($this->matches(...$scopes)) { |
|||
return $this->matches[0]->getPrefix(...$scopes); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
@ -1,27 +0,0 @@ |
|||
<?php |
|||
/** @license MIT |
|||
* Copyright 2021 Dustin Wilson et al. |
|||
* See LICENSE file for details */ |
|||
|
|||
declare(strict_types=1); |
|||
namespace dW\Lit\Scope; |
|||
|
|||
class GroupMatcher extends Matcher { |
|||
protected ?string $prefix; |
|||
protected Matcher $selector; |
|||
|
|||
public function __construct(?string $prefix, Matcher $selector) { |
|||
$this->prefix = ($prefix !== null) ? $prefix[0] : null; |
|||
$this->selector = $selector; |
|||
} |
|||
|
|||
public function matches(string ...$scopes): bool { |
|||
return $this->selector->matches(...$scopes); |
|||
} |
|||
|
|||
public function getPrefix(string ...$scopes): string|null|false { |
|||
if ($this->selector->matches(...$scopes)) { |
|||
return $this->prefix; |
|||
} |
|||
} |
|||
} |
@ -1,23 +0,0 @@ |
|||
<?php |
|||
/** @license MIT |
|||
* Copyright 2021 Dustin Wilson et al. |
|||
* See LICENSE file for details */ |
|||
|
|||
declare(strict_types=1); |
|||
namespace dW\Lit\Scope; |
|||
|
|||
class NegateMatcher extends Matcher { |
|||
protected Matcher $matcher; |
|||
|
|||
public function __construct(Matcher $matcher) { |
|||
$this->matcher = $matcher; |
|||
} |
|||
|
|||
public function matches(string ...$scopes): bool { |
|||
return !($this->matcher->matches(...$scopes)); |
|||
} |
|||
|
|||
public function getPrefix(string ...$scopes) { |
|||
return null; |
|||
} |
|||
} |
@ -1,40 +0,0 @@ |
|||
<?php |
|||
/** @license MIT |
|||
* Copyright 2021 Dustin Wilson et al. |
|||
* See LICENSE file for details */ |
|||
|
|||
declare(strict_types=1); |
|||
namespace dW\Lit\Scope; |
|||
|
|||
class OrMatcher extends Matcher { |
|||
protected array $matchers = []; |
|||
|
|||
public function __construct(Matcher ...$matchers) { |
|||
$this->matchers = $matchers; |
|||
} |
|||
|
|||
public function add(Matcher $matcher) { |
|||
$this->matchers[] = $matcher; |
|||
} |
|||
|
|||
public function matches(string ...$scopes): bool { |
|||
foreach ($this->matchers as $m) { |
|||
if ($m->matches(...$scopes)) { |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
public function getPrefix(string ...$scopes): string|null|false { |
|||
foreach ($this->matchers as $m) { |
|||
$prefix = $m->getPrefix(...$scopes); |
|||
if ($prefix !== null) { |
|||
return $prefix; |
|||
} |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
@ -1,37 +0,0 @@ |
|||
<?php |
|||
/** @license MIT |
|||
* Copyright 2021 Dustin Wilson et al. |
|||
* See LICENSE file for details */ |
|||
|
|||
declare(strict_types=1); |
|||
namespace dW\Lit\Scope; |
|||
|
|||
class PathMatcher extends Matcher { |
|||
protected ?string $prefix; |
|||
protected array $matchers; |
|||
|
|||
public function __construct(?string $prefix, ScopeMatcher ...$matchers) { |
|||
$this->prefix = ($prefix !== null) ? $prefix[0] : null; |
|||
$this->matchers = $matchers; |
|||
} |
|||
|
|||
public function matches(string ...$scopes): bool { |
|||
$count = 0; |
|||
$matcher = $this->matchers[$count]; |
|||
foreach ($scopes as $scope) { |
|||
if ($matcher->matches($scope)) { |
|||
$matcher = $this->matchers[++$count] ?? null; |
|||
} |
|||
if ($matcher === null) { |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public function getPrefix(string ...$scopes): string|null|false { |
|||
if ($this->matches($scopes)) { |
|||
return $this->prefix; |
|||
} |
|||
} |
|||
} |
@ -1,39 +0,0 @@ |
|||
<?php |
|||
/** @license MIT |
|||
* Copyright 2021 Dustin Wilson et al. |
|||
* See LICENSE file for details */ |
|||
|
|||
declare(strict_types=1); |
|||
namespace dW\Lit\Scope; |
|||
|
|||
class ScopeMatcher extends Matcher { |
|||
protected array $segments; |
|||
|
|||
public function __construct(string ...$segments) { |
|||
$this->segments = $segments; |
|||
} |
|||
|
|||
public function matches(string $scope): bool { |
|||
$scopeSegments = explode('.', $scope); |
|||
|
|||
if (count($this->segments) !== count($scopeSegments)) { |
|||
return false; |
|||
} |
|||
|
|||
foreach ($this->segments as $index => $segment) { |
|||
if ($segment === '*') { |
|||
continue; |
|||
} |
|||
|
|||
if ($segment !== $scopeSegments[$index]) { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
public function getPrefix(string $scope) { |
|||
return null; |
|||
} |
|||
} |
@ -0,0 +1,56 @@ |
|||
<?php |
|||
/** @license MIT |
|||
* Copyright 2021 Dustin Wilson et al. |
|||
* See LICENSE file for details */ |
|||
|
|||
declare(strict_types=1); |
|||
namespace dW\Lit\Scope; |
|||
|
|||
class Path extends Node { |
|||
protected int $_anchor; |
|||
|
|||
protected array $frozen = [ |
|||
'add' => false, |
|||
'anchor' => false |
|||
]; |
|||
|
|||
protected array $scopes = []; |
|||
|
|||
const ANCHOR_NONE = 0; |
|||
const ANCHOR_START = 1; |
|||
const ANCHOR_END = 2; |
|||
const ANCHOR_BOTH = 3; |
|||
|
|||
|
|||
public function __construct(Expression $parent) { |
|||
$this->_parent = \WeakReference::create($parent); |
|||
} |
|||
|
|||
|
|||
public function add(Scope ...$scopes): bool { |
|||
if ($this->frozen['add']) { |
|||
return false; |
|||
} |
|||
|
|||
$this->scopes = $scopes; |
|||
$this->frozen['add'] = true; |
|||
return true; |
|||
} |
|||
|
|||
|
|||
public function __set(string $name, $value) { |
|||
if ($name !== 'anchor') { |
|||
$trace = debug_backtrace(); |
|||
trigger_error("Cannot set undefined property $name in {$trace[0]['file']} on line {$trace[0]['line']}", E_USER_NOTICE); |
|||
} |
|||
|
|||
if ($this->frozen['anchor']) { |
|||
$trace = debug_backtrace(); |
|||
trigger_error("Cannot set readonly $name property in {$trace[0]['file']} on line {$trace[0]['line']}", E_USER_NOTICE); |
|||
return; |
|||
} |
|||
|
|||
$this->frozen['anchor'] = true; |
|||
$this->_anchor = $value; |
|||
} |
|||
} |
@ -0,0 +1,30 @@ |
|||
<?php |
|||
/** @license MIT |
|||
* Copyright 2021 Dustin Wilson et al. |
|||
* See LICENSE file for details */ |
|||
|
|||
declare(strict_types=1); |
|||
namespace dW\Lit\Scope; |
|||
|
|||
class Scope extends Node { |
|||
protected bool $_anchorToPrevious; |
|||
protected array $atoms = []; |
|||
protected bool $frozen = false; |
|||
|
|||
|
|||
public function __construct(Path $parent, bool $anchorToPrevious = false) { |
|||
$this->_anchorToPrevious = $anchorToPrevious; |
|||
$this->_parent = \WeakReference::create($parent); |
|||
} |
|||
|
|||
|
|||
public function add(string ...$atoms): bool { |
|||
if ($this->frozen) { |
|||
return false; |
|||
} |
|||
|
|||
$this->atoms = $atoms; |
|||
$this->frozen = true; |
|||
return true; |
|||
} |
|||
} |
@ -0,0 +1,28 @@ |
|||
<?php |
|||
/** @license MIT |
|||
* Copyright 2021 Dustin Wilson et al. |
|||
* See LICENSE file for details */ |
|||
|
|||
declare(strict_types=1); |
|||
namespace dW\Lit\Scope; |
|||
|
|||
class Selector extends Node { |
|||
protected array $composites = []; |
|||
protected bool $frozen = false; |
|||
|
|||
|
|||
public function __construct(?Group $parent = null) { |
|||
$this->_parent = ($parent === null) ? null : \WeakReference::create($parent); |
|||
} |
|||
|
|||
|
|||
public function add(Composite ...$composites): bool { |
|||
if ($this->frozen) { |
|||
return false; |
|||
} |
|||
|
|||
$this->composites = $this->composites; |
|||
$this->frozen = true; |
|||
return true; |
|||
} |
|||
} |
Loading…
Reference in new issue