-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathTest.php
More file actions
70 lines (56 loc) · 1.93 KB
/
Test.php
File metadata and controls
70 lines (56 loc) · 1.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?php
/**
* @license http://opensource.org/licenses/mit-license.php MIT
* @link https://github.com/nicoSWD
* @author Nicolas Oelgart <hello@nico.es>
*/
declare(strict_types=1);
namespace nicoSWD\Rule\Grammar\JavaScript\Methods;
use nicoSWD\Rule\Grammar\CallableFunction;
use nicoSWD\Rule\Parser\Exception\ParserException;
use nicoSWD\Rule\TokenStream\Token\BaseToken;
use nicoSWD\Rule\TokenStream\Token\TokenBool;
use nicoSWD\Rule\TokenStream\Token\TokenKind;
final class Test extends CallableFunction
{
public function call(mixed ...$parameters): TokenBool
{
$pattern = $this->getPattern();
if ($pattern === null) {
throw new ParserException('test() is not a function');
}
$subject = $this->parseParameter($parameters, numParam: 0);
if ($subject === null) {
return TokenBool::fromBool(false);
}
while (is_array($subject)) {
$subject = current($subject);
}
$bool = (bool) preg_match($pattern, (string) $subject);
return TokenBool::fromBool($bool);
}
private function getPattern(): ?string
{
// When called from RegexNode, $this->token is a BaseToken
if ($this->token instanceof BaseToken) {
if (!$this->token->isOfKind(TokenKind::REGEX)) {
return null;
}
$pattern = $this->token->getValue();
} elseif (!is_string($this->token)) {
return null;
} else {
$pattern = $this->token;
}
if (!preg_match('~^/.+/[img]{0,3}$~', $pattern)) {
return null;
}
// Remove "g" modifier as it does not exist in PHP
// It's also irrelevant in .test() but allowed in JS here
return preg_replace_callback(
'~/[igm]{0,3}$~',
static fn (array $modifiers): string => str_replace('g', '', $modifiers[0]),
$pattern
);
}
}