From 7e384a335c22088a5ec8f545b457704a57c5b7ca Mon Sep 17 00:00:00 2001 From: Nico Date: Wed, 16 Mar 2022 20:44:59 +0100 Subject: [PATCH 01/13] Use PHP 8.1 features --- .gitignore | 2 + .travis.yml | 2 +- README.md | 24 ++- composer.json | 6 +- src/Compiler/CompilerInterface.php | 6 +- src/Compiler/StandardCompiler.php | 41 ++-- src/Evaluator/Boolean.php | 14 ++ src/Evaluator/Evaluator.php | 41 ++-- .../Exception/UnknownSymbolException.php | 2 +- src/Evaluator/Operator.php | 83 ++++++++ src/Expression/ExpressionFactory.php | 8 +- src/Expression/ExpressionFactoryInterface.php | 4 +- src/Grammar/CallableFunction.php | 5 +- src/Grammar/Definition.php | 20 ++ src/Grammar/Grammar.php | 48 ++++- src/Grammar/InternalFunction.php | 17 ++ src/Grammar/InternalMethod.php | 17 ++ src/Grammar/JavaScript/JavaScript.php | 93 ++++----- src/Grammar/JavaScript/Methods/CharAt.php | 6 +- src/Grammar/JavaScript/Methods/Substr.php | 2 +- src/Grammar/JavaScript/Methods/Test.php | 4 +- src/Highlighter/Highlighter.php | 55 +++-- src/Parser/EvaluatableExpression.php | 68 +++++++ src/Parser/EvaluatableExpressionFactory.php | 20 ++ src/Parser/Exception/ParserException.php | 10 +- src/Parser/Parser.php | 92 ++++----- src/Rule.php | 4 +- src/TokenStream/AST.php | 132 ------------ src/TokenStream/CallableUserMethod.php | 21 +- src/TokenStream/CallableUserMethodFactory.php | 6 +- .../CallableUserMethodFactoryInterface.php | 7 +- src/TokenStream/Node/BaseNode.php | 25 +-- src/TokenStream/Token/BaseToken.php | 50 +---- src/TokenStream/Token/Token.php | 64 +++--- src/TokenStream/Token/TokenAnd.php | 6 +- src/TokenStream/Token/TokenArray.php | 6 +- src/TokenStream/Token/TokenBool.php | 6 +- src/TokenStream/Token/TokenClosingArray.php | 2 +- .../Token/TokenClosingParenthesis.php | 6 +- src/TokenStream/Token/TokenComma.php | 2 +- src/TokenStream/Token/TokenComment.php | 6 +- src/TokenStream/Token/TokenEqual.php | 6 +- src/TokenStream/Token/TokenEqualStrict.php | 6 +- src/TokenStream/Token/TokenFactory.php | 8 +- src/TokenStream/Token/TokenFloat.php | 6 +- src/TokenStream/Token/TokenFunction.php | 6 +- src/TokenStream/Token/TokenGreater.php | 6 +- src/TokenStream/Token/TokenGreaterEqual.php | 6 +- src/TokenStream/Token/TokenIn.php | 6 +- src/TokenStream/Token/TokenInteger.php | 8 +- src/TokenStream/Token/TokenMethod.php | 6 +- src/TokenStream/Token/TokenNewline.php | 6 +- src/TokenStream/Token/TokenNotEqual.php | 6 +- src/TokenStream/Token/TokenNotEqualStrict.php | 6 +- src/TokenStream/Token/TokenNotIn.php | 6 +- src/TokenStream/Token/TokenNull.php | 6 +- src/TokenStream/Token/TokenObject.php | 6 +- src/TokenStream/Token/TokenOpeningArray.php | 6 +- .../Token/TokenOpeningParenthesis.php | 6 +- src/TokenStream/Token/TokenOr.php | 6 +- src/TokenStream/Token/TokenRegex.php | 9 +- src/TokenStream/Token/TokenSmaller.php | 6 +- src/TokenStream/Token/TokenSmallerEqual.php | 6 +- src/TokenStream/Token/TokenSpace.php | 6 +- src/TokenStream/Token/TokenString.php | 9 +- src/TokenStream/Token/TokenType.php | 32 +-- src/TokenStream/Token/TokenUnknown.php | 2 +- src/TokenStream/Token/TokenVariable.php | 9 +- .../Token/Type/Logical.php} | 4 +- src/TokenStream/Token/Type/Method.php | 12 ++ src/TokenStream/Token/Type/Operator.php | 12 ++ src/TokenStream/Token/Type/Parenthesis.php | 12 ++ src/TokenStream/Token/Type/Value.php | 12 ++ src/TokenStream/Token/Type/Whitespace.php | 12 ++ src/TokenStream/TokenIterator.php | 92 +++++++++ ...amFactory.php => TokenIteratorFactory.php} | 8 +- src/TokenStream/TokenStream.php | 132 ++++++++---- src/Tokenizer/Tokenizer.php | 74 ++----- src/Tokenizer/TokenizerInterface.php | 15 +- src/container.php | 26 +-- tests/integration/HighlighterTest.php | 13 -- tests/integration/TokenizerTest.php | 4 +- tests/integration/methods/SyntaxErrorTest.php | 2 +- tests/unit/Grammar/GrammarTest.php | 12 +- tests/unit/Parser/ParserTest.php | 43 +--- tests/unit/Token/TokenFactoryTest.php | 12 +- tests/unit/TokenStream/ASTTest.php | 89 -------- .../unit/TokenStream/Token/BaseTokenTest.php | 101 +-------- tests/unit/TokenStream/TokenIteratorTest.php | 132 ++++++++++++ tests/unit/TokenStream/TokenStreamTest.php | 191 ++++++++++-------- tests/unit/Tokenizer/TokenizerTest.php | 33 +-- 91 files changed, 1251 insertions(+), 1022 deletions(-) create mode 100644 src/Evaluator/Boolean.php create mode 100644 src/Evaluator/Operator.php create mode 100644 src/Grammar/Definition.php create mode 100644 src/Grammar/InternalFunction.php create mode 100644 src/Grammar/InternalMethod.php create mode 100644 src/Parser/EvaluatableExpression.php create mode 100644 src/Parser/EvaluatableExpressionFactory.php delete mode 100644 src/TokenStream/AST.php rename src/{Highlighter/Exception/InvalidGroupException.php => TokenStream/Token/Type/Logical.php} (66%) create mode 100644 src/TokenStream/Token/Type/Method.php create mode 100644 src/TokenStream/Token/Type/Operator.php create mode 100644 src/TokenStream/Token/Type/Parenthesis.php create mode 100644 src/TokenStream/Token/Type/Value.php create mode 100644 src/TokenStream/Token/Type/Whitespace.php create mode 100644 src/TokenStream/TokenIterator.php rename src/TokenStream/{TokenStreamFactory.php => TokenIteratorFactory.php} (57%) delete mode 100755 tests/unit/TokenStream/ASTTest.php create mode 100755 tests/unit/TokenStream/TokenIteratorTest.php diff --git a/.gitignore b/.gitignore index 35f8f3f..3e04865 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ /coverage.clover /.phpunit.result.cache /vendor/ +/.idea +/.composer diff --git a/.travis.yml b/.travis.yml index fa2e489..cf159f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: php php: - - 8.0 + - 8.1 script: - composer install --dev diff --git a/README.md b/README.md index a656d84..00aca1d 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,6 @@ Find me on Twitter: @[nicoSWD](https://twitter.com/nicoSWD) (If you're using PHP 5, you might want to take a look at [version 0.4.0](https://github.com/nicoSWD/php-rule-parser/tree/0.4.0)) -[![SensioLabsInsight](https://insight.sensiolabs.com/projects/67203389-970c-419c-9430-a7f9a005bd94/big.png)](https://insight.sensiolabs.com/projects/67203389-970c-419c-9430-a7f9a005bd94) - ## Install Via Composer @@ -40,23 +38,29 @@ This library works best with one of these bundles below, but they're not require Test if a value is in a given array ```php -$variables = ['foo' => 6]; +$variables = [ + 'coupon_code' => $_POST['coupon_code'], +]; -$rule = new Rule('foo in [4, 6, 7]', $variables); +$rule = new Rule('coupon_code in ["summer_discount", "summer21"]', $variables); var_dump($rule->isTrue()); // bool(true) ``` -Simple array manipulation +Performing a regular expression ```php -$rule = new Rule('[1, 4, 3].join(".") === "1.4.3"'); +$variables = [ + 'coupon_code' => $_POST['coupon_code'], +]; + +$rule = new Rule('coupon_code.test(/^summer20[0-9]{2}$/) == true', $variables); var_dump($rule->isTrue()); // bool(true) ``` Test if a value is between a given range ```php -$variables = ['threshold' => 80]; +$variables = ['points' => 80]; -$rule = new Rule('threshold >= 50 && threshold <= 100', $variables); +$rule = new Rule('points >= 50 && points <= 100', $variables); var_dump($rule->isTrue()); // bool(true) ``` @@ -64,8 +68,6 @@ Call methods on objects from within rules ```php class User { - // ... - public function points(): int { return 1337; @@ -180,7 +182,7 @@ $highlighter = new Rule\Highlighter\Highlighter(new Rule\Tokenizer()); // Optional custom styles $highlighter->setStyle( - Rule\Constants::GROUP_VARIABLE, + TokenType::VARIABLE, 'color: #007694; font-weight: 900;' ); diff --git a/composer.json b/composer.json index eabf79b..8ce7073 100644 --- a/composer.json +++ b/composer.json @@ -33,11 +33,11 @@ } }, "require": { - "php": ">=8.0" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^7.0|^9.0", - "mockery/mockery": "^1.0|^1.4" + "phpunit/phpunit": "^9.5", + "mockery/mockery": "^1.4" }, "scripts": { "test": "vendor/bin/phpunit" diff --git a/src/Compiler/CompilerInterface.php b/src/Compiler/CompilerInterface.php index 90a2121..f60cb76 100644 --- a/src/Compiler/CompilerInterface.php +++ b/src/Compiler/CompilerInterface.php @@ -8,14 +8,16 @@ namespace nicoSWD\Rule\Compiler; use nicoSWD\Rule\TokenStream\Token\BaseToken; +use nicoSWD\Rule\TokenStream\Token\Type\Logical; +use nicoSWD\Rule\TokenStream\Token\Type\Parenthesis; interface CompilerInterface { public function getCompiledRule(): string; - public function addParentheses(BaseToken $token): void; + public function addParentheses(BaseToken & Parenthesis $token): void; - public function addLogical(BaseToken $token): void; + public function addLogical(BaseToken & Logical $token): void; public function addBoolean(bool $bool): void; } diff --git a/src/Compiler/StandardCompiler.php b/src/Compiler/StandardCompiler.php index 2d1d7f4..2202296 100644 --- a/src/Compiler/StandardCompiler.php +++ b/src/Compiler/StandardCompiler.php @@ -8,19 +8,17 @@ namespace nicoSWD\Rule\Compiler; use nicoSWD\Rule\Compiler\Exception\MissingOperatorException; +use nicoSWD\Rule\Evaluator\Boolean; +use nicoSWD\Rule\Evaluator\Operator; use nicoSWD\Rule\Parser\Exception\ParserException; use nicoSWD\Rule\TokenStream\Token\BaseToken; use nicoSWD\Rule\TokenStream\Token\TokenAnd; use nicoSWD\Rule\TokenStream\Token\TokenOpeningParenthesis; +use nicoSWD\Rule\TokenStream\Token\Type\Logical; +use nicoSWD\Rule\TokenStream\Token\Type\Parenthesis; -class StandardCompiler implements CompilerInterface +final class StandardCompiler implements CompilerInterface { - private const BOOL_TRUE = '1'; - private const BOOL_FALSE = '0'; - - private const LOGICAL_AND = '&'; - private const LOGICAL_OR = '|'; - private const OPENING_PARENTHESIS = '('; private const CLOSING_PARENTHESIS = ')'; @@ -58,7 +56,7 @@ private function closeParenthesis(): void } /** @throws ParserException */ - public function addParentheses(BaseToken $token): void + public function addParentheses(BaseToken & Parenthesis $token): void { if ($token instanceof TokenOpeningParenthesis) { if (!$this->expectOpeningParenthesis()) { @@ -71,31 +69,27 @@ public function addParentheses(BaseToken $token): void } /** @throws ParserException */ - public function addLogical(BaseToken $token): void + public function addLogical(BaseToken & Logical $token): void { - $lastChar = $this->getLastChar(); - - if ($lastChar === self::LOGICAL_AND || $lastChar === self::LOGICAL_OR) { + if (Operator::tryFrom($this->getLastChar()) !== null) { throw ParserException::unexpectedToken($token); } if ($token instanceof TokenAnd) { - $this->output .= self::LOGICAL_AND; + $this->output .= Operator::LOGICAL_AND->value; } else { - $this->output .= self::LOGICAL_OR; + $this->output .= Operator::LOGICAL_OR->value; } } /** @throws MissingOperatorException */ public function addBoolean(bool $bool): void { - $lastChar = $this->getLastChar(); - - if ($lastChar === self::BOOL_TRUE || $lastChar === self::BOOL_FALSE) { + if (Boolean::tryFrom($this->getLastChar()) !== null) { throw new MissingOperatorException(); } - $this->output .= $bool ? self::BOOL_TRUE : self::BOOL_FALSE; + $this->output .= Boolean::fromBool($bool)->value; } private function numParenthesesMatch(): bool @@ -105,11 +99,7 @@ private function numParenthesesMatch(): bool private function isIncompleteCondition(): bool { - $lastChar = $this->getLastChar(); - - return - $lastChar === self::LOGICAL_AND || - $lastChar === self::LOGICAL_OR; + return Operator::tryFrom($this->getLastChar()) !== null; } private function expectOpeningParenthesis(): bool @@ -118,9 +108,8 @@ private function expectOpeningParenthesis(): bool return $lastChar === '' || - $lastChar === self::LOGICAL_AND || - $lastChar === self::LOGICAL_OR || - $lastChar === self::OPENING_PARENTHESIS; + $lastChar === self::OPENING_PARENTHESIS || + Operator::tryFrom($lastChar) !== null; } private function getLastChar(): string diff --git a/src/Evaluator/Boolean.php b/src/Evaluator/Boolean.php new file mode 100644 index 0000000..7d068bd --- /dev/null +++ b/src/Evaluator/Boolean.php @@ -0,0 +1,14 @@ + + */ +namespace nicoSWD\Rule\Evaluator; + +enum Operator: string +{ + case LOGICAL_AND = '&'; + case LOGICAL_OR = '|'; +} diff --git a/src/Evaluator/Evaluator.php b/src/Evaluator/Evaluator.php index 4d1797a..badcac1 100644 --- a/src/Evaluator/Evaluator.php +++ b/src/Evaluator/Evaluator.php @@ -7,14 +7,10 @@ */ namespace nicoSWD\Rule\Evaluator; +use Closure; + final class Evaluator implements EvaluatorInterface { - private const LOGICAL_AND = '&'; - private const LOGICAL_OR = '|'; - - private const BOOL_TRUE = '1'; - private const BOOL_FALSE = '0'; - public function evaluate(string $group): bool { $evalGroup = $this->evalGroup(); @@ -22,7 +18,7 @@ public function evaluate(string $group): bool do { $group = preg_replace_callback( - '~\(([^()]+)\)~', + '~\((?[^()]+)\)~', $evalGroup, $group, limit: -1, @@ -30,22 +26,23 @@ public function evaluate(string $group): bool ); } while ($count > 0); - return (bool) $evalGroup([1 => $group]); + return (bool) $evalGroup(['match' => $group]); } - private function evalGroup(): callable + private function evalGroup(): Closure { return function (array $group): ?int { $result = null; $operator = null; $offset = 0; - while (isset($group[1][$offset])) { - $value = $group[1][$offset++]; + while (isset($group['match'][$offset])) { + $value = $group['match'][$offset++]; + $possibleOperator = Operator::tryFrom($value); - if ($this->isLogical($value)) { - $operator = $value; - } elseif ($this->isBoolean($value)) { + if ($possibleOperator) { + $operator = $possibleOperator; + } elseif (Boolean::tryFrom($value)) { $result = $this->setResult($result, (int) $value, $operator); } else { throw new Exception\UnknownSymbolException(sprintf('Unexpected "%s"', $value)); @@ -56,26 +53,16 @@ private function evalGroup(): callable }; } - private function setResult(?int $result, int $value, ?string $operator): int + private function setResult(?int $result, int $value, ?Operator $operator): int { if (!isset($result)) { $result = $value; - } elseif ($operator === self::LOGICAL_AND) { + } elseif (Operator::isAnd($operator)) { $result &= $value; - } elseif ($operator === self::LOGICAL_OR) { + } elseif (Operator::isOr($operator)) { $result |= $value; } return $result; } - - private function isLogical(string $value): bool - { - return $value === self::LOGICAL_AND || $value === self::LOGICAL_OR; - } - - private function isBoolean(string $value): bool - { - return $value === self::BOOL_TRUE || $value === self::BOOL_FALSE; - } } diff --git a/src/Evaluator/Exception/UnknownSymbolException.php b/src/Evaluator/Exception/UnknownSymbolException.php index 0737f50..05b3659 100644 --- a/src/Evaluator/Exception/UnknownSymbolException.php +++ b/src/Evaluator/Exception/UnknownSymbolException.php @@ -7,6 +7,6 @@ */ namespace nicoSWD\Rule\Evaluator\Exception; -class UnknownSymbolException extends \Exception +final class UnknownSymbolException extends \Exception { } diff --git a/src/Evaluator/Operator.php b/src/Evaluator/Operator.php new file mode 100644 index 0000000..55c7c62 --- /dev/null +++ b/src/Evaluator/Operator.php @@ -0,0 +1,83 @@ + + */ +namespace nicoSWD\Rule\Evaluator; + +use Closure; + +final class Evaluator implements EvaluatorInterface +{ + private const LOGICAL_AND = '&'; + private const LOGICAL_OR = '|'; + + private const BOOL_TRUE = '1'; + private const BOOL_FALSE = '0'; + + public function evaluate(string $group): bool + { + $evalGroup = $this->evalGroup(); + $count = 0; + + do { + $group = preg_replace_callback( + '~\((?[^()]+)\)~', + $evalGroup, + $group, + limit: -1, + count: $count + ); + } while ($count > 0); + + return (bool) $evalGroup(['match' => $group]); + } + + private function evalGroup(): Closure + { + return function (array $group): ?int { + $result = null; + $operator = null; + $offset = 0; + + while (isset($group['match'][$offset])) { + $value = $group['match'][$offset++]; + + if ($this->isLogical($value)) { + $operator = $value; + } elseif ($this->isBoolean($value)) { + $result = $this->setResult($result, (int) $value, $operator); + } else { + throw new Exception\UnknownSymbolException(sprintf('Unexpected "%s"', $value)); + } + } + + return $result; + }; + } + + private function setResult(?int $result, int $value, ?string $operator): int + { + if (!isset($result)) { + $result = $value; + } elseif ($operator === self::LOGICAL_AND) { + $result &= $value; + } elseif ($operator === self::LOGICAL_OR) { + $result |= $value; + } + + return $result; + } + + private function isLogical(string $value): bool + { + return $value === self::LOGICAL_AND || $value === self::LOGICAL_OR; + } + + private function isBoolean(string $value): bool + { + return $value === self::BOOL_TRUE || $value === self::BOOL_FALSE; + } +} diff --git a/src/Expression/ExpressionFactory.php b/src/Expression/ExpressionFactory.php index 9a3ba34..e474bd9 100644 --- a/src/Expression/ExpressionFactory.php +++ b/src/Expression/ExpressionFactory.php @@ -9,14 +9,14 @@ use nicoSWD\Rule\Parser\Exception\ParserException; use nicoSWD\Rule\TokenStream\Token; -use nicoSWD\Rule\TokenStream\Token\BaseToken; +use nicoSWD\Rule\TokenStream\Token\Type\Operator; -class ExpressionFactory implements ExpressionFactoryInterface +final class ExpressionFactory implements ExpressionFactoryInterface { /** @throws ParserException */ - public function createFromOperator(BaseToken $operator): BaseExpression + public function createFromOperator(Operator $operator): BaseExpression { - return match (get_class($operator)) { + return match ($operator::class) { Token\TokenEqual::class => new EqualExpression(), Token\TokenEqualStrict::class => new EqualStrictExpression(), Token\TokenNotEqual::class => new NotEqualExpression(), diff --git a/src/Expression/ExpressionFactoryInterface.php b/src/Expression/ExpressionFactoryInterface.php index 0f12bfc..1750cc4 100644 --- a/src/Expression/ExpressionFactoryInterface.php +++ b/src/Expression/ExpressionFactoryInterface.php @@ -7,9 +7,9 @@ */ namespace nicoSWD\Rule\Expression; -use nicoSWD\Rule\TokenStream\Token\BaseToken; +use nicoSWD\Rule\TokenStream\Token\Type\Operator; interface ExpressionFactoryInterface { - public function createFromOperator(BaseToken $operator): BaseExpression; + public function createFromOperator(Operator $operator): BaseExpression; } diff --git a/src/Grammar/CallableFunction.php b/src/Grammar/CallableFunction.php index 5ac80da..6396edc 100644 --- a/src/Grammar/CallableFunction.php +++ b/src/Grammar/CallableFunction.php @@ -11,8 +11,9 @@ abstract class CallableFunction implements CallableUserFunctionInterface { - public function __construct(protected ?BaseToken $token = null) - { + public function __construct( + protected readonly ?BaseToken $token = null, + ) { } protected function parseParameter(array $parameters, int $numParam): ?BaseToken diff --git a/src/Grammar/Definition.php b/src/Grammar/Definition.php new file mode 100644 index 0000000..e2c3157 --- /dev/null +++ b/src/Grammar/Definition.php @@ -0,0 +1,20 @@ + + */ +namespace nicoSWD\Rule\Grammar; + +use nicoSWD\Rule\TokenStream\Token\Token; + +final class Definition +{ + public function __construct( + public readonly Token $token, + public readonly string $regex, + public readonly int $priority, + ) { + } +} diff --git a/src/Grammar/Grammar.php b/src/Grammar/Grammar.php index 63a9572..12822a8 100644 --- a/src/Grammar/Grammar.php +++ b/src/Grammar/Grammar.php @@ -7,20 +7,54 @@ */ namespace nicoSWD\Rule\Grammar; +use SplPriorityQueue; + abstract class Grammar { - /** @return array> */ + private string $compiledRegex = ''; + /** @var Definition[] */ + private array $tokens = []; + + /** @return Definition[] */ abstract public function getDefinition(): array; - /** @return array */ - public function getInternalFunctions(): array + /** @return InternalFunction[] */ + abstract public function getInternalFunctions(): array; + + /** @return InternalMethod[] */ + abstract public function getInternalMethods(): array; + + public function buildRegex(): string + { + if (!$this->compiledRegex) { + $this->registerTokens(); + $regex = []; + + foreach ($this->getQueue() as $token) { + $regex[] = "(?<{$token->token->value}>{$token->regex})"; + } + + $this->compiledRegex = '~(' . implode('|', $regex) . ')~As'; + } + + return $this->compiledRegex; + } + + private function getQueue(): SplPriorityQueue { - return []; + $queue = new SplPriorityQueue(); + + foreach ($this->tokens as $token) { + $queue->insert($token, $token->priority); + } + + return $queue; } - /** @return array */ - public function getInternalMethods(): array + private function registerTokens(): void { - return []; + foreach ($this->getDefinition() as $definition) { + $this->tokens[$definition->token->value] = $definition; + } } } diff --git a/src/Grammar/InternalFunction.php b/src/Grammar/InternalFunction.php new file mode 100644 index 0000000..fcfc6a9 --- /dev/null +++ b/src/Grammar/InternalFunction.php @@ -0,0 +1,17 @@ + + */ +namespace nicoSWD\Rule\Grammar; + +final class InternalFunction +{ + public function __construct( + public readonly string $name, + public readonly string $class, + ) { + } +} diff --git a/src/Grammar/InternalMethod.php b/src/Grammar/InternalMethod.php new file mode 100644 index 0000000..052a0d7 --- /dev/null +++ b/src/Grammar/InternalMethod.php @@ -0,0 +1,17 @@ + + */ +namespace nicoSWD\Rule\Grammar; + +final class InternalMethod +{ + public function __construct( + public readonly string $name, + public readonly string $class, + ) { + } +} diff --git a/src/Grammar/JavaScript/JavaScript.php b/src/Grammar/JavaScript/JavaScript.php index 6314217..10370f7 100644 --- a/src/Grammar/JavaScript/JavaScript.php +++ b/src/Grammar/JavaScript/JavaScript.php @@ -7,7 +7,10 @@ */ namespace nicoSWD\Rule\Grammar\JavaScript; +use nicoSWD\Rule\Grammar\Definition; use nicoSWD\Rule\Grammar\Grammar; +use nicoSWD\Rule\Grammar\InternalFunction; +use nicoSWD\Rule\Grammar\InternalMethod; use nicoSWD\Rule\TokenStream\Token\Token; final class JavaScript extends Grammar @@ -15,63 +18,63 @@ final class JavaScript extends Grammar public function getDefinition(): array { return [ - [Token::AND, '&&', 145], - [Token::OR, '\|\|', 140], - [Token::NOT_EQUAL_STRICT, '!==', 135], - [Token::NOT_EQUAL, '<>|!=', 130], - [Token::EQUAL_STRICT, '===', 125], - [Token::EQUAL, '==', 120], - [Token::IN, '\bin\b', 115], - [Token::NOT_IN, '\bnot\s+in\b', 116], - [Token::BOOL_TRUE, '\btrue\b', 110], - [Token::BOOL_FALSE, '\bfalse\b', 111], - [Token::NULL, '\bnull\b', 105], - [Token::METHOD, '\.\s*[a-zA-Z_]\w*\s*\(', 100], - [Token::FUNCTION, '[a-zA-Z_]\w*\s*\(', 95], - [Token::FLOAT, '-?\d+(?:\.\d+)', 90], - [Token::INTEGER, '-?\d+', 85], - [Token::ENCAPSED_STRING, '"[^"]*"|\'[^\']*\'', 80], - [Token::SMALLER_EQUAL, '<=', 75], - [Token::GREATER_EQUAL, '>=', 70], - [Token::SMALLER, '<', 65], - [Token::GREATER, '>', 60], - [Token::OPENING_PARENTHESIS, '\(', 55], - [Token::CLOSING_PARENTHESIS, '\)', 50], - [Token::OPENING_ARRAY, '\[', 45], - [Token::CLOSING_ARRAY, '\]', 40], - [Token::COMMA, ',', 35], - [Token::REGEX, '/[^/\*].*/[igm]{0,3}', 30], - [Token::COMMENT, '//[^\r\n]*|/\*.*?\*/', 25], - [Token::NEWLINE, '\r?\n', 20], - [Token::SPACE, '\s+', 15], - [Token::VARIABLE, '[a-zA-Z_]\w*', 10], - [Token::UNKNOWN, '.', 5], + new Definition(Token::AND, '&&', 145), + new Definition(Token::OR, '\|\|', 140), + new Definition(Token::NOT_EQUAL_STRICT, '!==', 135), + new Definition(Token::NOT_EQUAL, '<>|!=', 130), + new Definition(Token::EQUAL_STRICT, '===', 125), + new Definition(Token::EQUAL, '==', 120), + new Definition(Token::IN, '\bin\b', 115), + new Definition(Token::NOT_IN, '\bnot\s+in\b', 116), + new Definition(Token::BOOL_TRUE, '\btrue\b', 110), + new Definition(Token::BOOL_FALSE, '\bfalse\b', 111), + new Definition(Token::NULL, '\bnull\b', 105), + new Definition(Token::METHOD, '\.\s*[a-zA-Z_]\w*\s*\(', 100), + new Definition(Token::FUNCTION, '[a-zA-Z_]\w*\s*\(', 95), + new Definition(Token::FLOAT, '-?\d+(?:\.\d+)', 90), + new Definition(Token::INTEGER, '-?\d+', 85), + new Definition(Token::ENCAPSED_STRING, '"[^"]*"|\'[^\']*\'', 80), + new Definition(Token::SMALLER_EQUAL, '<=', 75), + new Definition(Token::GREATER_EQUAL, '>=', 70), + new Definition(Token::SMALLER, '<', 65), + new Definition(Token::GREATER, '>', 60), + new Definition(Token::OPENING_PARENTHESIS, '\(', 55), + new Definition(Token::CLOSING_PARENTHESIS, '\)', 50), + new Definition(Token::OPENING_ARRAY, '\[', 45), + new Definition(Token::CLOSING_ARRAY, '\]', 40), + new Definition(Token::COMMA, ',', 35), + new Definition(Token::REGEX, '/[^/\*].*/[igm]{0,3}', 30), + new Definition(Token::COMMENT, '//[^\r\n]*|/\*.*?\*/', 25), + new Definition(Token::NEWLINE, '\r?\n', 20), + new Definition(Token::SPACE, '\s+', 15), + new Definition(Token::VARIABLE, '[a-zA-Z_]\w*', 10), + new Definition(Token::UNKNOWN, '.', 5), ]; } public function getInternalFunctions(): array { return [ - 'parseInt' => Functions\ParseInt::class, - 'parseFloat' => Functions\ParseFloat::class, + new InternalFunction('parseInt', Functions\ParseInt::class), + new InternalFunction('parseFloat', Functions\ParseFloat::class), ]; } public function getInternalMethods(): array { return [ - 'charAt' => Methods\CharAt::class, - 'concat' => Methods\Concat::class, - 'indexOf' => Methods\IndexOf::class, - 'join' => Methods\Join::class, - 'replace' => Methods\Replace::class, - 'split' => Methods\Split::class, - 'substr' => Methods\Substr::class, - 'test' => Methods\Test::class, - 'toLowerCase' => Methods\ToLowerCase::class, - 'toUpperCase' => Methods\ToUpperCase::class, - 'startsWith' => Methods\StartsWith::class, - 'endsWith' => Methods\EndsWith::class, + new InternalMethod('charAt', Methods\CharAt::class), + new InternalMethod('concat', Methods\Concat::class), + new InternalMethod('indexOf', Methods\IndexOf::class), + new InternalMethod('join', Methods\Join::class), + new InternalMethod('replace', Methods\Replace::class), + new InternalMethod('split', Methods\Split::class), + new InternalMethod('substr', Methods\Substr::class), + new InternalMethod('test', Methods\Test::class), + new InternalMethod('toLowerCase', Methods\ToLowerCase::class), + new InternalMethod('toUpperCase', Methods\ToUpperCase::class), + new InternalMethod('startsWith', Methods\StartsWith::class), + new InternalMethod('endsWith', Methods\EndsWith::class), ]; } } diff --git a/src/Grammar/JavaScript/Methods/CharAt.php b/src/Grammar/JavaScript/Methods/CharAt.php index 2276caa..0bd9f98 100644 --- a/src/Grammar/JavaScript/Methods/CharAt.php +++ b/src/Grammar/JavaScript/Methods/CharAt.php @@ -27,11 +27,7 @@ public function call(?BaseToken ...$parameters): BaseToken $offset = $offset->getValue(); } - if (!isset($tokenValue[$offset])) { - $char = ''; - } else { - $char = $tokenValue[$offset]; - } + $char = $tokenValue[$offset] ?? ''; return new TokenString($char); } diff --git a/src/Grammar/JavaScript/Methods/Substr.php b/src/Grammar/JavaScript/Methods/Substr.php index 14b2722..5902cca 100644 --- a/src/Grammar/JavaScript/Methods/Substr.php +++ b/src/Grammar/JavaScript/Methods/Substr.php @@ -32,6 +32,6 @@ public function call(?BaseToken ...$parameters): BaseToken $value = substr($this->token->getValue(), ...$params); - return new TokenString((string) $value); + return new TokenString($value); } } diff --git a/src/Grammar/JavaScript/Methods/Test.php b/src/Grammar/JavaScript/Methods/Test.php index 1701e77..df7bcc6 100644 --- a/src/Grammar/JavaScript/Methods/Test.php +++ b/src/Grammar/JavaScript/Methods/Test.php @@ -19,7 +19,7 @@ final class Test extends CallableFunction public function call(?BaseToken ...$parameters): BaseToken { if (!$this->token instanceof TokenRegex) { - throw new ParserException('undefined is not a function'); + throw new ParserException('test() is not a function'); } $string = $this->parseParameter($parameters, numParam: 0); @@ -31,7 +31,7 @@ public function call(?BaseToken ...$parameters): BaseToken // It's also irrelevant in .test() but allowed in JS here $pattern = preg_replace_callback( '~/[igm]{0,3}$~', - fn (array $modifiers) => str_replace('g', '', $modifiers[0]), + static fn (array $modifiers): string => str_replace('g', '', $modifiers[0]), $this->token->getValue() ); diff --git a/src/Highlighter/Highlighter.php b/src/Highlighter/Highlighter.php index f1bd01a..f5ddc4a 100644 --- a/src/Highlighter/Highlighter.php +++ b/src/Highlighter/Highlighter.php @@ -9,40 +9,30 @@ use ArrayIterator; use nicoSWD\Rule\Tokenizer\TokenizerInterface; +use nicoSWD\Rule\TokenStream\Token\BaseToken; use nicoSWD\Rule\TokenStream\Token\TokenType; +use SplObjectStorage; final class Highlighter { - /** @var string[] */ - private array $styles = [ - TokenType::COMMENT => 'color: #948a8a; font-style: italic;', - TokenType::LOGICAL => 'color: #c72d2d;', - TokenType::OPERATOR => 'color: #000;', - TokenType::PARENTHESIS => 'color: #000;', - TokenType::SPACE => '', - TokenType::UNKNOWN => '', - TokenType::VALUE => 'color: #e36700; font-style: italic;', - TokenType::VARIABLE => 'color: #007694; font-weight: 900;', - TokenType::METHOD => 'color: #000', - TokenType::SQUARE_BRACKET => '', - TokenType::COMMA => '', - TokenType::FUNCTION => '', - TokenType::INT_VALUE => '', - ]; + private readonly SplObjectStorage $styles; - public function __construct(private TokenizerInterface $tokenizer) - { + public function __construct( + private readonly TokenizerInterface $tokenizer, + ) { + $this->styles = new SplObjectStorage(); + $this->styles[TokenType::COMMENT] = 'color: #948a8a; font-style: italic;'; + $this->styles[TokenType::LOGICAL] = 'color: #c72d2d;'; + $this->styles[TokenType::OPERATOR] = 'color: #000;'; + $this->styles[TokenType::PARENTHESIS] = 'color: #000;'; + $this->styles[TokenType::VALUE] = 'color: #e36700; font-style: italic;'; + $this->styles[TokenType::VARIABLE] = 'color: #007694; font-weight: 900;'; + $this->styles[TokenType::METHOD] = 'color: #000'; } - public function setStyle(int $group, string $style): void + public function setStyle(TokenType $group, string $style): void { - if (!isset($this->styles[$group])) { - throw new Exception\InvalidGroupException( - 'Invalid group' - ); - } - - $this->styles[$group] = (string) $style; + $this->styles[$group] = $style; } public function highlightString(string $string): string @@ -55,9 +45,11 @@ public function highlightTokens(ArrayIterator $tokens): string $string = ''; foreach ($tokens as $token) { - if ($style = $this->styles[$token->getType()]) { - $value = htmlentities($token->getOriginalValue(), ENT_QUOTES, 'utf-8'); - $string .= '' . $value . ''; + /** @var BaseToken $token */ + $tokenType = $token->getType(); + + if (isset($this->styles[$tokenType])) { + $string .= '' . $this->encode($token) . ''; } else { $string .= $token->getOriginalValue(); } @@ -65,4 +57,9 @@ public function highlightTokens(ArrayIterator $tokens): string return '
' . $string . '
'; } + + private function encode(BaseToken $token): string + { + return htmlentities($token->getOriginalValue(), ENT_QUOTES, 'utf-8'); + } } diff --git a/src/Parser/EvaluatableExpression.php b/src/Parser/EvaluatableExpression.php new file mode 100644 index 0000000..c40fdab --- /dev/null +++ b/src/Parser/EvaluatableExpression.php @@ -0,0 +1,68 @@ + + */ +namespace nicoSWD\Rule\Parser; + +use nicoSWD\Rule\Expression\BaseExpression; +use nicoSWD\Rule\Expression\ExpressionFactoryInterface; +use nicoSWD\Rule\TokenStream\Token\Type\Operator; + +final class EvaluatableExpression +{ + public ?Operator $operator = null; + public array $values = []; + + public function __construct( + private readonly ExpressionFactoryInterface $expressionFactory, + ) { + } + + /** @throws Exception\ParserException */ + public function evaluate(): bool + { + $result = $this->expression()->evaluate(...$this->values); + $this->clear(); + + return $result; + } + + public function isComplete(): bool + { + return $this->hasOperator() && $this->hasBothValues(); + } + + public function addValue(mixed $value): void + { + $this->values[] = $value; + } + + public function hasBothValues(): bool + { + return count($this->values) === 2; + } + + public function hasNoValues(): bool + { + return count($this->values) === 0; + } + + public function hasOperator(): bool + { + return $this->operator !== null; + } + + private function clear(): void + { + $this->operator = null; + $this->values = []; + } + + private function expression(): BaseExpression + { + return $this->expressionFactory->createFromOperator($this->operator); + } +} diff --git a/src/Parser/EvaluatableExpressionFactory.php b/src/Parser/EvaluatableExpressionFactory.php new file mode 100644 index 0000000..de42ba1 --- /dev/null +++ b/src/Parser/EvaluatableExpressionFactory.php @@ -0,0 +1,20 @@ + + */ +namespace nicoSWD\Rule\Parser; + +use nicoSWD\Rule\Expression\ExpressionFactory; + +final class EvaluatableExpressionFactory +{ + public function create(): EvaluatableExpression + { + return new EvaluatableExpression( + new ExpressionFactory() + ); + } +} diff --git a/src/Parser/Exception/ParserException.php b/src/Parser/Exception/ParserException.php index 84a909a..c50bbe1 100644 --- a/src/Parser/Exception/ParserException.php +++ b/src/Parser/Exception/ParserException.php @@ -8,8 +8,9 @@ namespace nicoSWD\Rule\Parser\Exception; use nicoSWD\Rule\TokenStream\Token\BaseToken; +use nicoSWD\Rule\TokenStream\Token\Type\Operator; -class ParserException extends \Exception +final class ParserException extends \Exception { public static function unexpectedToken(BaseToken $token): self { @@ -61,15 +62,10 @@ public static function unsupportedType(string $type): self return new self(sprintf('Unsupported PHP type: "%s"', $type)); } - public static function unknownOperator(BaseToken $token): self + public static function unknownOperator(BaseToken & Operator $token): self { return new self( sprintf('Unexpected operator %s at position %d', $token->getOriginalValue(), $token->getOffset()) ); } - - public static function unknownTokenName(string $tokenName): self - { - return new self("Unknown token $tokenName"); - } } diff --git a/src/Parser/Parser.php b/src/Parser/Parser.php index f572781..b1537e4 100644 --- a/src/Parser/Parser.php +++ b/src/Parser/Parser.php @@ -10,111 +10,87 @@ use Closure; use nicoSWD\Rule\Compiler\CompilerFactoryInterface; use nicoSWD\Rule\Compiler\CompilerInterface; -use nicoSWD\Rule\Expression\ExpressionFactoryInterface; -use nicoSWD\Rule\TokenStream\AST; +use nicoSWD\Rule\TokenStream\TokenStream; use nicoSWD\Rule\TokenStream\Token\BaseToken; use nicoSWD\Rule\TokenStream\Token\TokenType; +use nicoSWD\Rule\TokenStream\Token\Type\Operator; -class Parser +final class Parser { - private ?BaseToken $operator; - private array $values = []; - public function __construct( - private AST $ast, - private ExpressionFactoryInterface $expressionFactory, - private CompilerFactoryInterface $compilerFactory + private readonly TokenStream $tokenStream, + private readonly EvaluatableExpressionFactory $expressionFactory, + private readonly CompilerFactoryInterface $compilerFactory, ) { } + /** @throws Exception\ParserException */ public function parse(string $rule): string { $compiler = $this->compilerFactory->create(); - $this->resetState(); + $expression = $this->expressionFactory->create(); - foreach ($this->ast->getStream($rule) as $token) { - $handler = $this->getHandlerForType($token->getType()); - $handler($token, $compiler); + foreach ($this->tokenStream->getStream($rule) as $token) { + $handler = $this->getHandlerForToken($token, $expression); + $handler($compiler); - if ($this->expressionCanBeEvaluated()) { - $this->evaluateExpression($compiler); + if ($expression->isComplete()) { + $compiler->addBoolean($expression->evaluate()); } } return $compiler->getCompiledRule(); } - private function getHandlerForType(int $tokenType): Closure + private function getHandlerForToken(BaseToken $token, EvaluatableExpression $expression): Closure { - return match ($tokenType) { - TokenType::VALUE, TokenType::INT_VALUE => $this->handleValueToken(), - TokenType::OPERATOR => $this->handleOperatorToken(), - TokenType::LOGICAL => $this->handleLogicalToken(), - TokenType::PARENTHESIS => $this->handleParenthesisToken(), + return match ($token->getType()) { + TokenType::VALUE => $this->handleValueToken($token, $expression), + TokenType::OPERATOR => $this->handleOperatorToken($token, $expression), + TokenType::LOGICAL => $this->handleLogicalToken($token), + TokenType::PARENTHESIS => $this->handleParenthesisToken($token), TokenType::COMMENT, TokenType::SPACE => $this->handleDummyToken(), - default => $this->handleUnknownToken(), + default => $this->handleUnknownToken($token), }; } - private function evaluateExpression(CompilerInterface $compiler): void - { - $expression = $this->expressionFactory->createFromOperator($this->operator); - - $compiler->addBoolean( - $expression->evaluate(...$this->values) - ); - - $this->resetState(); - } - - private function expressionCanBeEvaluated(): bool + private function handleValueToken(BaseToken $token, EvaluatableExpression $expression): Closure { - return count($this->values) === 2; + return static fn () => $expression->addValue($token->getValue()); } - private function handleValueToken(): Closure + private function handleLogicalToken(BaseToken $token): Closure { - return fn (BaseToken $token) => $this->values[] = $token->getValue(); + return static fn (CompilerInterface $compiler) => $compiler->addLogical($token); } - private function handleLogicalToken(): Closure + private function handleParenthesisToken(BaseToken $token): Closure { - return fn (BaseToken $token, CompilerInterface $compiler) => $compiler->addLogical($token); + return static fn (CompilerInterface $compiler) => $compiler->addParentheses($token); } - private function handleParenthesisToken(): Closure + private function handleUnknownToken(BaseToken $token): Closure { - return fn (BaseToken $token, CompilerInterface $compiler) => $compiler->addParentheses($token); + return static fn () => throw Exception\ParserException::unknownToken($token); } - private function handleUnknownToken(): Closure + private function handleOperatorToken(BaseToken & Operator $token, EvaluatableExpression $expression): Closure { - return fn (BaseToken $token) => throw Exception\ParserException::unknownToken($token); - } - - private function handleOperatorToken(): Closure - { - return function (BaseToken $token): void { - if (isset($this->operator)) { + return static function () use ($token, $expression): void { + if ($expression->hasOperator()) { throw Exception\ParserException::unexpectedToken($token); - } elseif (empty($this->values)) { + } elseif ($expression->hasNoValues()) { throw Exception\ParserException::incompleteExpression($token); } - $this->operator = $token; + $expression->operator = $token; }; } private function handleDummyToken(): Closure { - return function (): void { + return static function (): void { // Do nothing }; } - - private function resetState(): void - { - $this->operator = null; - $this->values = []; - } } diff --git a/src/Rule.php b/src/Rule.php index b860482..8482a2f 100644 --- a/src/Rule.php +++ b/src/Rule.php @@ -12,8 +12,8 @@ class Rule { + private readonly Parser\Parser $parser; private string $rule; - private Parser\Parser $parser; private string $parsedRule = ''; private string $error = ''; private static object $container; @@ -28,6 +28,7 @@ public function __construct(string $rule, array $variables = []) $this->rule = $rule; } + /** @throws Parser\Exception\ParserException */ public function isTrue(): bool { /** @var EvaluatorInterface $evaluator */ @@ -39,6 +40,7 @@ public function isTrue(): bool ); } + /** @throws Parser\Exception\ParserException */ public function isFalse(): bool { return !$this->isTrue(); diff --git a/src/TokenStream/AST.php b/src/TokenStream/AST.php deleted file mode 100644 index 41b72d0..0000000 --- a/src/TokenStream/AST.php +++ /dev/null @@ -1,132 +0,0 @@ - - */ -namespace nicoSWD\Rule\TokenStream; - -use Closure; -use InvalidArgumentException; -use nicoSWD\Rule\Grammar\CallableUserFunctionInterface; -use nicoSWD\Rule\Parser\Exception\ParserException; -use nicoSWD\Rule\TokenStream\Exception\UndefinedVariableException; -use nicoSWD\Rule\TokenStream\Token\BaseToken; -use nicoSWD\Rule\TokenStream\Token\TokenFactory; -use nicoSWD\Rule\Tokenizer\TokenizerInterface; -use nicoSWD\Rule\TokenStream\Token\TokenObject; - -class AST -{ - private array $functions = []; - private array $methods = []; - private array $variables = []; - - public function __construct( - private TokenizerInterface $tokenizer, - private TokenFactory $tokenFactory, - private TokenStreamFactory $tokenStreamFactory, - private CallableUserMethodFactoryInterface $userMethodFactory - ) { - } - - public function getStream(string $rule): TokenStream - { - return $this->tokenStreamFactory->create($this->tokenizer->tokenize($rule), $this); - } - - /** - * @throws Exception\UndefinedMethodException - * @throws Exception\ForbiddenMethodException - */ - public function getMethod(string $methodName, BaseToken $token): CallableUserFunctionInterface - { - if ($token instanceof TokenObject) { - return $this->getCallableUserMethod($token, $methodName); - } - - if (empty($this->methods)) { - $this->registerMethods(); - } - - if (!isset($this->methods[$methodName])) { - throw new Exception\UndefinedMethodException(); - } - - return new $this->methods[$methodName]($token); - } - - public function setVariables(array $variables): void - { - $this->variables = $variables; - } - - /** - * @throws UndefinedVariableException - * @throws ParserException - */ - public function getVariable(string $variableName): BaseToken - { - if (!$this->variableExists($variableName)) { - throw new UndefinedVariableException($variableName); - } - - return $this->tokenFactory->createFromPHPType($this->variables[$variableName]); - } - - public function variableExists(string $variableName): bool - { - return array_key_exists($variableName, $this->variables); - } - - /** @throws Exception\UndefinedFunctionException */ - public function getFunction(string $functionName): Closure - { - if (empty($this->functions)) { - $this->registerFunctions(); - } - - if (!isset($this->functions[$functionName])) { - throw new Exception\UndefinedFunctionException($functionName); - } - - return $this->functions[$functionName]; - } - - private function registerMethods(): void - { - $this->methods = $this->tokenizer->getGrammar()->getInternalMethods(); - } - - private function registerFunctionClass(string $functionName, string $className): void - { - $this->functions[$functionName] = function (...$args) use ($className) { - $function = new $className(); - - if (!$function instanceof CallableUserFunctionInterface) { - throw new InvalidArgumentException( - sprintf( - "%s must be an instance of %s", - $className, - CallableUserFunctionInterface::class - ) - ); - } - - return $function->call(...$args); - }; - } - - private function registerFunctions(): void - { - foreach ($this->tokenizer->getGrammar()->getInternalFunctions() as $functionName => $className) { - $this->registerFunctionClass($functionName, $className); - } - } - - private function getCallableUserMethod(BaseToken $token, string $methodName): CallableUserFunctionInterface - { - return $this->userMethodFactory->create($token, $this->tokenFactory, $methodName); - } -} diff --git a/src/TokenStream/CallableUserMethod.php b/src/TokenStream/CallableUserMethod.php index 27c14a1..0f1803f 100644 --- a/src/TokenStream/CallableUserMethod.php +++ b/src/TokenStream/CallableUserMethod.php @@ -16,8 +16,9 @@ final class CallableUserMethod implements CallableUserFunctionInterface { private const MAGIC_METHOD_PREFIX = '__'; - private TokenFactory $tokenFactory; - private Closure $callable; + private readonly TokenFactory $tokenFactory; + private readonly Closure $callable; + private array $methodPrefixes = ['', 'get', 'is', 'get_', 'is_']; /** @@ -32,10 +33,10 @@ public function __construct(BaseToken $token, TokenFactory $tokenFactory, string public function call(?BaseToken ...$param): BaseToken { - $callableCopy = $this->callable; + $callable = $this->callable; return $this->tokenFactory->createFromPHPType( - $callableCopy(...$param) + $callable(...$param) ); } @@ -48,12 +49,12 @@ private function getCallable(BaseToken $token, string $methodName): Closure $object = $token->getValue(); if (property_exists($object, $methodName)) { - return fn () => $object->{$methodName}; + return static fn (): mixed => $object->{$methodName}; } $method = $this->findCallableMethod($object, $methodName); - return fn (?BaseToken ...$params) => $method( + return fn (?BaseToken ...$params): mixed => $method( ...$this->getTokenValues($params) ); } @@ -80,13 +81,7 @@ private function findCallableMethod(object $object, string $methodName): callabl private function getTokenValues(array $params): array { - $values = []; - - foreach ($params as $token) { - $values[] = $token->getValue(); - } - - return $values; + return array_map(static fn (BaseToken $token): mixed => $token->getValue(), $params); } /** @throws Exception\ForbiddenMethodException */ diff --git a/src/TokenStream/CallableUserMethodFactory.php b/src/TokenStream/CallableUserMethodFactory.php index cae71bb..067c773 100644 --- a/src/TokenStream/CallableUserMethodFactory.php +++ b/src/TokenStream/CallableUserMethodFactory.php @@ -7,12 +7,16 @@ */ namespace nicoSWD\Rule\TokenStream; +use nicoSWD\Rule\Grammar\CallableUserFunctionInterface; use nicoSWD\Rule\TokenStream\Token\BaseToken; use nicoSWD\Rule\TokenStream\Token\TokenFactory; final class CallableUserMethodFactory implements CallableUserMethodFactoryInterface { - public function create(BaseToken $token, TokenFactory $tokenFactory, string $methodName): CallableUserMethod + /** + * {@inheritDoc} + */ + public function create(BaseToken $token, TokenFactory $tokenFactory, string $methodName): CallableUserFunctionInterface { return new CallableUserMethod($token, $tokenFactory, $methodName); } diff --git a/src/TokenStream/CallableUserMethodFactoryInterface.php b/src/TokenStream/CallableUserMethodFactoryInterface.php index 2601617..e3fc352 100644 --- a/src/TokenStream/CallableUserMethodFactoryInterface.php +++ b/src/TokenStream/CallableUserMethodFactoryInterface.php @@ -7,10 +7,15 @@ */ namespace nicoSWD\Rule\TokenStream; +use nicoSWD\Rule\Grammar\CallableUserFunctionInterface; use nicoSWD\Rule\TokenStream\Token\BaseToken; use nicoSWD\Rule\TokenStream\Token\TokenFactory; interface CallableUserMethodFactoryInterface { - public function create(BaseToken $token, TokenFactory $tokenFactory, string $methodName): CallableUserMethod; + /** + * @throws Exception\ForbiddenMethodException + * @throws Exception\UndefinedMethodException + */ + public function create(BaseToken $token, TokenFactory $tokenFactory, string $methodName): CallableUserFunctionInterface; } diff --git a/src/TokenStream/Node/BaseNode.php b/src/TokenStream/Node/BaseNode.php index c9748e8..9b4e56e 100644 --- a/src/TokenStream/Node/BaseNode.php +++ b/src/TokenStream/Node/BaseNode.php @@ -10,20 +10,21 @@ use Closure; use nicoSWD\Rule\Grammar\CallableUserFunctionInterface; use nicoSWD\Rule\TokenStream\Token\BaseToken; +use nicoSWD\Rule\TokenStream\Token\Type\Method; +use nicoSWD\Rule\TokenStream\Token\Type\Whitespace; use nicoSWD\Rule\TokenStream\TokenCollection; use nicoSWD\Rule\Parser\Exception\ParserException; -use nicoSWD\Rule\TokenStream\TokenStream; +use nicoSWD\Rule\TokenStream\TokenIterator; use nicoSWD\Rule\TokenStream\Token\TokenType; abstract class BaseNode { - protected TokenStream $tokenStream; - private string $methodName = ''; + private string $methodName; private int $methodOffset = 0; - public function __construct(TokenStream $tokenStream) - { - $this->tokenStream = $tokenStream; + public function __construct( + protected readonly TokenIterator $tokenStream, + ) { } /** @throws ParserException */ @@ -43,12 +44,12 @@ protected function hasMethodCall(): bool if (!$token) { break; - } elseif ($token->isMethod()) { + } elseif ($token instanceof Method) { $this->methodName = $token->getValue(); $this->methodOffset = $stack->key(); $hasMethod = true; break; - } elseif (!$token->isWhitespace()) { + } elseif (!$token instanceof Whitespace) { break; } } @@ -100,7 +101,7 @@ protected function getCurrentNode(): BaseToken } /** @throws ParserException */ - private function getCommaSeparatedValues(int $stopAt): TokenCollection + private function getCommaSeparatedValues(TokenType $stopAt): TokenCollection { $items = new TokenCollection(); $commaExpected = false; @@ -108,14 +109,14 @@ private function getCommaSeparatedValues(int $stopAt): TokenCollection do { $token = $this->getNextToken(); - if ($token->isValue()) { + if (TokenType::isValue($token)) { if ($commaExpected) { throw ParserException::unexpectedToken($token); } $commaExpected = true; $items->attach($token); - } elseif ($token->isComma()) { + } elseif ($token->isOfType(TokenType::COMMA)) { if (!$commaExpected) { throw ParserException::unexpectedComma($token); } @@ -123,7 +124,7 @@ private function getCommaSeparatedValues(int $stopAt): TokenCollection $commaExpected = false; } elseif ($token->isOfType($stopAt)) { break; - } elseif (!$token->isWhitespace()) { + } elseif (!$token->canBeIgnored()) { throw ParserException::unexpectedToken($token); } } while (true); diff --git a/src/TokenStream/Token/BaseToken.php b/src/TokenStream/Token/BaseToken.php index 4456fff..2ced4fd 100644 --- a/src/TokenStream/Token/BaseToken.php +++ b/src/TokenStream/Token/BaseToken.php @@ -8,15 +8,15 @@ namespace nicoSWD\Rule\TokenStream\Token; use nicoSWD\Rule\Parser\Exception\ParserException; -use nicoSWD\Rule\TokenStream\TokenStream; +use nicoSWD\Rule\TokenStream\TokenIterator; abstract class BaseToken { - abstract public function getType(): int; + abstract public function getType(): TokenType; public function __construct( - private mixed $value, - private int $offset = 0 + private readonly mixed $value, + private readonly int $offset = 0, ) { } @@ -36,48 +36,20 @@ public function getOffset(): int } /** @throws ParserException */ - public function createNode(TokenStream $tokenStream): self + public function createNode(TokenIterator $tokenStream): self { return $this; } - public function isOfType(int $type): bool + public function isOfType(TokenType $type): bool { - return ($this->getType() | $type) === $type; + return $this->getType() === $type; } - public function isValue(): bool + public function canBeIgnored(): bool { - return $this->isOfType(TokenType::VALUE | TokenType::INT_VALUE); - } - - public function isWhitespace(): bool - { - return $this->isOfType(TokenType::SPACE | TokenType::COMMENT); - } - - public function isMethod(): bool - { - return $this->isOfType(TokenType::METHOD); - } - - public function isComma(): bool - { - return $this->isOfType(TokenType::COMMA); - } - - public function isOperator(): bool - { - return $this->isOfType(TokenType::OPERATOR); - } - - public function isLogical(): bool - { - return $this->isOfType(TokenType::LOGICAL); - } - - public function isParenthesis(): bool - { - return $this->isOfType(TokenType::PARENTHESIS); + return + $this->isOfType(TokenType::SPACE) || + $this->isOfType(TokenType::COMMENT); } } diff --git a/src/TokenStream/Token/Token.php b/src/TokenStream/Token/Token.php index 8112716..2f1bb3f 100644 --- a/src/TokenStream/Token/Token.php +++ b/src/TokenStream/Token/Token.php @@ -7,37 +7,37 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -class Token +enum Token: string { - public const AND = 'And'; - public const OR = 'Or'; - public const NOT_EQUAL_STRICT = 'NotEqualStrict'; - public const NOT_EQUAL = 'NotEqual'; - public const EQUAL_STRICT = 'EqualStrict'; - public const EQUAL = 'Equal'; - public const IN = 'In'; - public const NOT_IN = 'NotIn'; - public const BOOL_TRUE = 'True'; - public const BOOL_FALSE = 'False'; - public const NULL = 'Null'; - public const METHOD = 'Method'; - public const FUNCTION = 'Function'; - public const VARIABLE = 'Variable'; - public const FLOAT = 'Float'; - public const INTEGER = 'Integer'; - public const ENCAPSED_STRING = 'EncapsedString'; - public const SMALLER_EQUAL = 'SmallerEqual'; - public const GREATER_EQUAL = 'GreaterEqual'; - public const SMALLER = 'Smaller'; - public const GREATER = 'Greater'; - public const OPENING_PARENTHESIS = 'OpeningParentheses'; - public const CLOSING_PARENTHESIS = 'ClosingParentheses'; - public const OPENING_ARRAY = 'OpeningArray'; - public const CLOSING_ARRAY = 'ClosingArray'; - public const COMMA = 'Comma'; - public const REGEX = 'Regex'; - public const COMMENT = 'Comment'; - public const NEWLINE = 'Newline'; - public const SPACE = 'Space'; - public const UNKNOWN = 'Unknown'; + case AND = 'And'; + case OR = 'Or'; + case NOT_EQUAL_STRICT = 'NotEqualStrict'; + case NOT_EQUAL = 'NotEqual'; + case EQUAL_STRICT = 'EqualStrict'; + case EQUAL = 'Equal'; + case IN = 'In'; + case NOT_IN = 'NotIn'; + case BOOL_TRUE = 'True'; + case BOOL_FALSE = 'False'; + case NULL = 'Null'; + case METHOD = 'Method'; + case FUNCTION = 'Function'; + case VARIABLE = 'Variable'; + case FLOAT = 'Float'; + case INTEGER = 'Integer'; + case ENCAPSED_STRING = 'EncapsedString'; + case SMALLER_EQUAL = 'SmallerEqual'; + case GREATER_EQUAL = 'GreaterEqual'; + case SMALLER = 'Smaller'; + case GREATER = 'Greater'; + case OPENING_PARENTHESIS = 'OpeningParentheses'; + case CLOSING_PARENTHESIS = 'ClosingParentheses'; + case OPENING_ARRAY = 'OpeningArray'; + case CLOSING_ARRAY = 'ClosingArray'; + case COMMA = 'Comma'; + case REGEX = 'Regex'; + case COMMENT = 'Comment'; + case NEWLINE = 'Newline'; + case SPACE = 'Space'; + case UNKNOWN = 'Unknown'; } diff --git a/src/TokenStream/Token/TokenAnd.php b/src/TokenStream/Token/TokenAnd.php index fc6f7dd..1f0e2e2 100644 --- a/src/TokenStream/Token/TokenAnd.php +++ b/src/TokenStream/Token/TokenAnd.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenAnd extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Logical; + +final class TokenAnd extends BaseToken implements Logical { - public function getType(): int + public function getType(): TokenType { return TokenType::LOGICAL; } diff --git a/src/TokenStream/Token/TokenArray.php b/src/TokenStream/Token/TokenArray.php index 1201b06..4687123 100644 --- a/src/TokenStream/Token/TokenArray.php +++ b/src/TokenStream/Token/TokenArray.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenArray extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Value; + +final class TokenArray extends BaseToken implements Value { - public function getType(): int + public function getType(): TokenType { return TokenType::VALUE; } diff --git a/src/TokenStream/Token/TokenBool.php b/src/TokenStream/Token/TokenBool.php index 1e35584..49fba5d 100644 --- a/src/TokenStream/Token/TokenBool.php +++ b/src/TokenStream/Token/TokenBool.php @@ -7,7 +7,9 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -abstract class TokenBool extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Value; + +abstract class TokenBool extends BaseToken implements Value { public static function fromBool(bool $bool): TokenBool { @@ -17,7 +19,7 @@ public static function fromBool(bool $bool): TokenBool }; } - public function getType(): int + public function getType(): TokenType { return TokenType::VALUE; } diff --git a/src/TokenStream/Token/TokenClosingArray.php b/src/TokenStream/Token/TokenClosingArray.php index 3bae87f..2f209d1 100644 --- a/src/TokenStream/Token/TokenClosingArray.php +++ b/src/TokenStream/Token/TokenClosingArray.php @@ -9,7 +9,7 @@ final class TokenClosingArray extends BaseToken { - public function getType(): int + public function getType(): TokenType { return TokenType::SQUARE_BRACKET; } diff --git a/src/TokenStream/Token/TokenClosingParenthesis.php b/src/TokenStream/Token/TokenClosingParenthesis.php index c77e898..7b378a6 100644 --- a/src/TokenStream/Token/TokenClosingParenthesis.php +++ b/src/TokenStream/Token/TokenClosingParenthesis.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenClosingParenthesis extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Parenthesis; + +final class TokenClosingParenthesis extends BaseToken implements Parenthesis { - public function getType(): int + public function getType(): TokenType { return TokenType::PARENTHESIS; } diff --git a/src/TokenStream/Token/TokenComma.php b/src/TokenStream/Token/TokenComma.php index ff39217..3732e9c 100644 --- a/src/TokenStream/Token/TokenComma.php +++ b/src/TokenStream/Token/TokenComma.php @@ -9,7 +9,7 @@ final class TokenComma extends BaseToken { - public function getType(): int + public function getType(): TokenType { return TokenType::COMMA; } diff --git a/src/TokenStream/Token/TokenComment.php b/src/TokenStream/Token/TokenComment.php index e48c7ff..5b8426d 100644 --- a/src/TokenStream/Token/TokenComment.php +++ b/src/TokenStream/Token/TokenComment.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenComment extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Whitespace; + +final class TokenComment extends BaseToken implements Whitespace { - public function getType(): int + public function getType(): TokenType { return TokenType::COMMENT; } diff --git a/src/TokenStream/Token/TokenEqual.php b/src/TokenStream/Token/TokenEqual.php index 3a2fb64..0fca76a 100644 --- a/src/TokenStream/Token/TokenEqual.php +++ b/src/TokenStream/Token/TokenEqual.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenEqual extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Operator; + +final class TokenEqual extends BaseToken implements Operator { - public function getType(): int + public function getType(): TokenType { return TokenType::OPERATOR; } diff --git a/src/TokenStream/Token/TokenEqualStrict.php b/src/TokenStream/Token/TokenEqualStrict.php index b60e244..b58feb8 100644 --- a/src/TokenStream/Token/TokenEqualStrict.php +++ b/src/TokenStream/Token/TokenEqualStrict.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenEqualStrict extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Operator; + +final class TokenEqualStrict extends BaseToken implements Operator { - public function getType(): int + public function getType(): TokenType { return TokenType::OPERATOR; } diff --git a/src/TokenStream/Token/TokenFactory.php b/src/TokenStream/Token/TokenFactory.php index 4b7a1be..780d95f 100644 --- a/src/TokenStream/Token/TokenFactory.php +++ b/src/TokenStream/Token/TokenFactory.php @@ -23,14 +23,13 @@ public function createFromPHPType(mixed $value): BaseToken 'double' => new TokenFloat($value), 'object' => new TokenObject($value), 'array' => $this->buildTokenCollection($value), - default => throw ParserException::unsupportedType(gettype($value)) + default => throw ParserException::unsupportedType(gettype($value)), }; } - /** @throws ParserException */ - public function createFromTokenName(string $tokenName): string + public function createFromToken(Token $token): string { - return match ($tokenName) { + return match ($token) { Token::AND => TokenAnd::class, Token::OR => TokenOr::class, Token::NOT_EQUAL_STRICT => TokenNotEqualStrict::class, @@ -62,7 +61,6 @@ public function createFromTokenName(string $tokenName): string Token::NEWLINE => TokenNewline::class, Token::SPACE => TokenSpace::class, Token::UNKNOWN => TokenUnknown::class, - default => throw ParserException::unknownTokenName($tokenName) }; } diff --git a/src/TokenStream/Token/TokenFloat.php b/src/TokenStream/Token/TokenFloat.php index 018c92b..d50e26a 100644 --- a/src/TokenStream/Token/TokenFloat.php +++ b/src/TokenStream/Token/TokenFloat.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenFloat extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Value; + +final class TokenFloat extends BaseToken implements Value { - public function getType(): int + public function getType(): TokenType { return TokenType::VALUE; } diff --git a/src/TokenStream/Token/TokenFunction.php b/src/TokenStream/Token/TokenFunction.php index c93fed1..518285c 100644 --- a/src/TokenStream/Token/TokenFunction.php +++ b/src/TokenStream/Token/TokenFunction.php @@ -8,16 +8,16 @@ namespace nicoSWD\Rule\TokenStream\Token; use nicoSWD\Rule\TokenStream\Node\NodeFunction; -use nicoSWD\Rule\TokenStream\TokenStream; +use nicoSWD\Rule\TokenStream\TokenIterator; final class TokenFunction extends BaseToken { - public function getType(): int + public function getType(): TokenType { return TokenType::FUNCTION; } - public function createNode(TokenStream $tokenStream): BaseToken + public function createNode(TokenIterator $tokenStream): BaseToken { return (new NodeFunction($tokenStream))->getNode(); } diff --git a/src/TokenStream/Token/TokenGreater.php b/src/TokenStream/Token/TokenGreater.php index a306b88..2fcae4a 100644 --- a/src/TokenStream/Token/TokenGreater.php +++ b/src/TokenStream/Token/TokenGreater.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenGreater extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Operator; + +final class TokenGreater extends BaseToken implements Operator { - public function getType(): int + public function getType(): TokenType { return TokenType::OPERATOR; } diff --git a/src/TokenStream/Token/TokenGreaterEqual.php b/src/TokenStream/Token/TokenGreaterEqual.php index faed030..c70262f 100644 --- a/src/TokenStream/Token/TokenGreaterEqual.php +++ b/src/TokenStream/Token/TokenGreaterEqual.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenGreaterEqual extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Operator; + +final class TokenGreaterEqual extends BaseToken implements Operator { - public function getType(): int + public function getType(): TokenType { return TokenType::OPERATOR; } diff --git a/src/TokenStream/Token/TokenIn.php b/src/TokenStream/Token/TokenIn.php index 88334b9..692521e 100644 --- a/src/TokenStream/Token/TokenIn.php +++ b/src/TokenStream/Token/TokenIn.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenIn extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Operator; + +final class TokenIn extends BaseToken implements Operator { - public function getType(): int + public function getType(): TokenType { return TokenType::OPERATOR; } diff --git a/src/TokenStream/Token/TokenInteger.php b/src/TokenStream/Token/TokenInteger.php index 45c950e..1f2b90e 100644 --- a/src/TokenStream/Token/TokenInteger.php +++ b/src/TokenStream/Token/TokenInteger.php @@ -7,11 +7,13 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenInteger extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Value; + +final class TokenInteger extends BaseToken implements Value { - public function getType(): int + public function getType(): TokenType { - return TokenType::INT_VALUE; + return TokenType::VALUE; } public function getValue(): int diff --git a/src/TokenStream/Token/TokenMethod.php b/src/TokenStream/Token/TokenMethod.php index 18c0684..e01b971 100644 --- a/src/TokenStream/Token/TokenMethod.php +++ b/src/TokenStream/Token/TokenMethod.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenMethod extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Method; + +final class TokenMethod extends BaseToken implements Method { - public function getType(): int + public function getType(): TokenType { return TokenType::METHOD; } diff --git a/src/TokenStream/Token/TokenNewline.php b/src/TokenStream/Token/TokenNewline.php index 955ba39..f6a6471 100644 --- a/src/TokenStream/Token/TokenNewline.php +++ b/src/TokenStream/Token/TokenNewline.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenNewline extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Whitespace; + +final class TokenNewline extends BaseToken implements Whitespace { - public function getType(): int + public function getType(): TokenType { return TokenType::SPACE; } diff --git a/src/TokenStream/Token/TokenNotEqual.php b/src/TokenStream/Token/TokenNotEqual.php index 163a1b9..48d2922 100644 --- a/src/TokenStream/Token/TokenNotEqual.php +++ b/src/TokenStream/Token/TokenNotEqual.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenNotEqual extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Operator; + +final class TokenNotEqual extends BaseToken implements Operator { - public function getType(): int + public function getType(): TokenType { return TokenType::OPERATOR; } diff --git a/src/TokenStream/Token/TokenNotEqualStrict.php b/src/TokenStream/Token/TokenNotEqualStrict.php index e913d18..fd6da30 100644 --- a/src/TokenStream/Token/TokenNotEqualStrict.php +++ b/src/TokenStream/Token/TokenNotEqualStrict.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenNotEqualStrict extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Operator; + +final class TokenNotEqualStrict extends BaseToken implements Operator { - public function getType(): int + public function getType(): TokenType { return TokenType::OPERATOR; } diff --git a/src/TokenStream/Token/TokenNotIn.php b/src/TokenStream/Token/TokenNotIn.php index 79a213a..a54d8b4 100644 --- a/src/TokenStream/Token/TokenNotIn.php +++ b/src/TokenStream/Token/TokenNotIn.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenNotIn extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Operator; + +final class TokenNotIn extends BaseToken implements Operator { - public function getType(): int + public function getType(): TokenType { return TokenType::OPERATOR; } diff --git a/src/TokenStream/Token/TokenNull.php b/src/TokenStream/Token/TokenNull.php index 452719c..d475b81 100644 --- a/src/TokenStream/Token/TokenNull.php +++ b/src/TokenStream/Token/TokenNull.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenNull extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Value; + +final class TokenNull extends BaseToken implements Value { - public function getType(): int + public function getType(): TokenType { return TokenType::VALUE; } diff --git a/src/TokenStream/Token/TokenObject.php b/src/TokenStream/Token/TokenObject.php index c6c3e0a..adb58cd 100644 --- a/src/TokenStream/Token/TokenObject.php +++ b/src/TokenStream/Token/TokenObject.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenObject extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Value; + +final class TokenObject extends BaseToken implements Value { - public function getType(): int + public function getType(): TokenType { return TokenType::VALUE; } diff --git a/src/TokenStream/Token/TokenOpeningArray.php b/src/TokenStream/Token/TokenOpeningArray.php index b2d5275..e6ba45b 100644 --- a/src/TokenStream/Token/TokenOpeningArray.php +++ b/src/TokenStream/Token/TokenOpeningArray.php @@ -8,16 +8,16 @@ namespace nicoSWD\Rule\TokenStream\Token; use nicoSWD\Rule\TokenStream\Node\NodeArray; -use nicoSWD\Rule\TokenStream\TokenStream; +use nicoSWD\Rule\TokenStream\TokenIterator; final class TokenOpeningArray extends BaseToken { - public function getType(): int + public function getType(): TokenType { return TokenType::SQUARE_BRACKET; } - public function createNode(TokenStream $tokenStream): BaseToken + public function createNode(TokenIterator $tokenStream): BaseToken { return (new NodeArray($tokenStream))->getNode(); } diff --git a/src/TokenStream/Token/TokenOpeningParenthesis.php b/src/TokenStream/Token/TokenOpeningParenthesis.php index a3d4058..cb2efae 100644 --- a/src/TokenStream/Token/TokenOpeningParenthesis.php +++ b/src/TokenStream/Token/TokenOpeningParenthesis.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenOpeningParenthesis extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Parenthesis; + +final class TokenOpeningParenthesis extends BaseToken implements Parenthesis { - public function getType(): int + public function getType(): TokenType { return TokenType::PARENTHESIS; } diff --git a/src/TokenStream/Token/TokenOr.php b/src/TokenStream/Token/TokenOr.php index b4dcfdc..499d305 100644 --- a/src/TokenStream/Token/TokenOr.php +++ b/src/TokenStream/Token/TokenOr.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenOr extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Logical; + +final class TokenOr extends BaseToken implements Logical { - public function getType(): int + public function getType(): TokenType { return TokenType::LOGICAL; } diff --git a/src/TokenStream/Token/TokenRegex.php b/src/TokenStream/Token/TokenRegex.php index ad93008..9e1de40 100644 --- a/src/TokenStream/Token/TokenRegex.php +++ b/src/TokenStream/Token/TokenRegex.php @@ -8,16 +8,17 @@ namespace nicoSWD\Rule\TokenStream\Token; use nicoSWD\Rule\TokenStream\Node\NodeString; -use nicoSWD\Rule\TokenStream\TokenStream; +use nicoSWD\Rule\TokenStream\Token\Type\Value; +use nicoSWD\Rule\TokenStream\TokenIterator; -final class TokenRegex extends BaseToken +final class TokenRegex extends BaseToken implements Value { - public function getType(): int + public function getType(): TokenType { return TokenType::VALUE; } - public function createNode(TokenStream $tokenStream): BaseToken + public function createNode(TokenIterator $tokenStream): BaseToken { return (new NodeString($tokenStream))->getNode(); } diff --git a/src/TokenStream/Token/TokenSmaller.php b/src/TokenStream/Token/TokenSmaller.php index 91b7617..5084fe4 100644 --- a/src/TokenStream/Token/TokenSmaller.php +++ b/src/TokenStream/Token/TokenSmaller.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenSmaller extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Operator; + +final class TokenSmaller extends BaseToken implements Operator { - public function getType(): int + public function getType(): TokenType { return TokenType::OPERATOR; } diff --git a/src/TokenStream/Token/TokenSmallerEqual.php b/src/TokenStream/Token/TokenSmallerEqual.php index 045aac7..a728ecf 100644 --- a/src/TokenStream/Token/TokenSmallerEqual.php +++ b/src/TokenStream/Token/TokenSmallerEqual.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenSmallerEqual extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Operator; + +final class TokenSmallerEqual extends BaseToken implements Operator { - public function getType(): int + public function getType(): TokenType { return TokenType::OPERATOR; } diff --git a/src/TokenStream/Token/TokenSpace.php b/src/TokenStream/Token/TokenSpace.php index 170b17b..30f2afd 100644 --- a/src/TokenStream/Token/TokenSpace.php +++ b/src/TokenStream/Token/TokenSpace.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -final class TokenSpace extends BaseToken +use nicoSWD\Rule\TokenStream\Token\Type\Whitespace; + +final class TokenSpace extends BaseToken implements Whitespace { - public function getType(): int + public function getType(): TokenType { return TokenType::SPACE; } diff --git a/src/TokenStream/Token/TokenString.php b/src/TokenStream/Token/TokenString.php index c320852..a02dfe6 100644 --- a/src/TokenStream/Token/TokenString.php +++ b/src/TokenStream/Token/TokenString.php @@ -8,16 +8,17 @@ namespace nicoSWD\Rule\TokenStream\Token; use nicoSWD\Rule\TokenStream\Node\NodeString; -use nicoSWD\Rule\TokenStream\TokenStream; +use nicoSWD\Rule\TokenStream\Token\Type\Value; +use nicoSWD\Rule\TokenStream\TokenIterator; -class TokenString extends BaseToken +class TokenString extends BaseToken implements Value { - public function getType(): int + public function getType(): TokenType { return TokenType::VALUE; } - public function createNode(TokenStream $tokenStream): BaseToken + public function createNode(TokenIterator $tokenStream): BaseToken { return (new NodeString($tokenStream))->getNode(); } diff --git a/src/TokenStream/Token/TokenType.php b/src/TokenStream/Token/TokenType.php index 76c79e0..0f966ab 100644 --- a/src/TokenStream/Token/TokenType.php +++ b/src/TokenStream/Token/TokenType.php @@ -7,19 +7,23 @@ */ namespace nicoSWD\Rule\TokenStream\Token; -class TokenType +enum TokenType { - public const OPERATOR = 1; - public const INT_VALUE = 2; - public const VALUE = 4; - public const LOGICAL = 8; - public const VARIABLE = 16; - public const COMMENT = 32; - public const SPACE = 64; - public const UNKNOWN = 128; - public const PARENTHESIS = 256; - public const SQUARE_BRACKET = 512; - public const COMMA = 1024; - public const METHOD = 2048; - public const FUNCTION = 4098; + case OPERATOR; + case VALUE; + case LOGICAL; + case VARIABLE; + case COMMENT; + case SPACE; + case UNKNOWN; + case PARENTHESIS; + case SQUARE_BRACKET; + case COMMA; + case METHOD; + case FUNCTION; + + public static function isValue(BaseToken $token): bool + { + return $token->getType() === self::VALUE; + } } diff --git a/src/TokenStream/Token/TokenUnknown.php b/src/TokenStream/Token/TokenUnknown.php index f2747b5..fec4686 100644 --- a/src/TokenStream/Token/TokenUnknown.php +++ b/src/TokenStream/Token/TokenUnknown.php @@ -9,7 +9,7 @@ final class TokenUnknown extends BaseToken { - public function getType(): int + public function getType(): TokenType { return TokenType::UNKNOWN; } diff --git a/src/TokenStream/Token/TokenVariable.php b/src/TokenStream/Token/TokenVariable.php index 6a6b0f1..46db1ba 100644 --- a/src/TokenStream/Token/TokenVariable.php +++ b/src/TokenStream/Token/TokenVariable.php @@ -8,16 +8,17 @@ namespace nicoSWD\Rule\TokenStream\Token; use nicoSWD\Rule\TokenStream\Node\NodeVariable; -use nicoSWD\Rule\TokenStream\TokenStream; +use nicoSWD\Rule\TokenStream\Token\Type\Value; +use nicoSWD\Rule\TokenStream\TokenIterator; -final class TokenVariable extends BaseToken +final class TokenVariable extends BaseToken implements Value { - public function getType(): int + public function getType(): TokenType { return TokenType::VARIABLE; } - public function createNode(TokenStream $tokenStream): BaseToken + public function createNode(TokenIterator $tokenStream): BaseToken { return (new NodeVariable($tokenStream))->getNode(); } diff --git a/src/Highlighter/Exception/InvalidGroupException.php b/src/TokenStream/Token/Type/Logical.php similarity index 66% rename from src/Highlighter/Exception/InvalidGroupException.php rename to src/TokenStream/Token/Type/Logical.php index a06295d..6cad197 100644 --- a/src/Highlighter/Exception/InvalidGroupException.php +++ b/src/TokenStream/Token/Type/Logical.php @@ -5,8 +5,8 @@ * @link https://github.com/nicoSWD * @author Nicolas Oelgart */ -namespace nicoSWD\Rule\Highlighter\Exception; +namespace nicoSWD\Rule\TokenStream\Token\Type; -class InvalidGroupException extends \Exception +interface Logical { } diff --git a/src/TokenStream/Token/Type/Method.php b/src/TokenStream/Token/Type/Method.php new file mode 100644 index 0000000..32dd908 --- /dev/null +++ b/src/TokenStream/Token/Type/Method.php @@ -0,0 +1,12 @@ + + */ +namespace nicoSWD\Rule\TokenStream\Token\Type; + +interface Method +{ +} diff --git a/src/TokenStream/Token/Type/Operator.php b/src/TokenStream/Token/Type/Operator.php new file mode 100644 index 0000000..27dbc59 --- /dev/null +++ b/src/TokenStream/Token/Type/Operator.php @@ -0,0 +1,12 @@ + + */ +namespace nicoSWD\Rule\TokenStream\Token\Type; + +interface Operator +{ +} diff --git a/src/TokenStream/Token/Type/Parenthesis.php b/src/TokenStream/Token/Type/Parenthesis.php new file mode 100644 index 0000000..50c6102 --- /dev/null +++ b/src/TokenStream/Token/Type/Parenthesis.php @@ -0,0 +1,12 @@ + + */ +namespace nicoSWD\Rule\TokenStream\Token\Type; + +interface Parenthesis +{ +} diff --git a/src/TokenStream/Token/Type/Value.php b/src/TokenStream/Token/Type/Value.php new file mode 100644 index 0000000..525f77f --- /dev/null +++ b/src/TokenStream/Token/Type/Value.php @@ -0,0 +1,12 @@ + + */ +namespace nicoSWD\Rule\TokenStream\Token\Type; + +interface Value +{ +} diff --git a/src/TokenStream/Token/Type/Whitespace.php b/src/TokenStream/Token/Type/Whitespace.php new file mode 100644 index 0000000..0391066 --- /dev/null +++ b/src/TokenStream/Token/Type/Whitespace.php @@ -0,0 +1,12 @@ + + */ +namespace nicoSWD\Rule\TokenStream\Token\Type; + +interface Whitespace +{ +} diff --git a/src/TokenStream/TokenIterator.php b/src/TokenStream/TokenIterator.php new file mode 100644 index 0000000..05750ef --- /dev/null +++ b/src/TokenStream/TokenIterator.php @@ -0,0 +1,92 @@ + + */ +namespace nicoSWD\Rule\TokenStream; + +use Closure; +use Iterator; +use nicoSWD\Rule\Parser\Exception\ParserException; +use nicoSWD\Rule\Grammar\CallableUserFunctionInterface; +use nicoSWD\Rule\TokenStream\Token\BaseToken; + +class TokenIterator implements Iterator +{ + public function __construct( + private readonly Iterator $stack, + private readonly TokenStream $tokenStream, + ) { + } + + public function next(): void + { + $this->stack->next(); + } + + public function valid(): bool + { + return $this->stack->valid(); + } + + /** @throws ParserException */ + public function current(): BaseToken + { + return $this->getCurrentToken()->createNode($this); + } + + public function key(): int + { + return $this->stack->key(); + } + + public function rewind(): void + { + $this->stack->rewind(); + } + + /** @return Iterator */ + public function getStack(): Iterator + { + return $this->stack; + } + + private function getCurrentToken(): BaseToken + { + return $this->stack->current(); + } + + /** @throws ParserException */ + public function getVariable(string $variableName): BaseToken + { + try { + return $this->tokenStream->getVariable($variableName); + } catch (Exception\UndefinedVariableException) { + throw ParserException::undefinedVariable($variableName, $this->getCurrentToken()); + } + } + + /** @throws ParserException */ + public function getFunction(string $functionName): Closure + { + try { + return $this->tokenStream->getFunction($functionName); + } catch (Exception\UndefinedFunctionException) { + throw ParserException::undefinedFunction($functionName, $this->getCurrentToken()); + } + } + + /** @throws ParserException */ + public function getMethod(string $methodName, BaseToken $token): CallableUserFunctionInterface + { + try { + return $this->tokenStream->getMethod($methodName, $token); + } catch (Exception\UndefinedMethodException) { + throw ParserException::undefinedMethod($methodName, $this->getCurrentToken()); + } catch (Exception\ForbiddenMethodException) { + throw ParserException::forbiddenMethod($methodName, $this->getCurrentToken()); + } + } +} diff --git a/src/TokenStream/TokenStreamFactory.php b/src/TokenStream/TokenIteratorFactory.php similarity index 57% rename from src/TokenStream/TokenStreamFactory.php rename to src/TokenStream/TokenIteratorFactory.php index 1a1db0b..9f1cf2e 100644 --- a/src/TokenStream/TokenStreamFactory.php +++ b/src/TokenStream/TokenIteratorFactory.php @@ -7,12 +7,12 @@ */ namespace nicoSWD\Rule\TokenStream; -use ArrayIterator; +use Iterator; -class TokenStreamFactory +final class TokenIteratorFactory { - public function create(ArrayIterator $stack, AST $ast): TokenStream + public function create(Iterator $stack, TokenStream $tokenStream): TokenIterator { - return new TokenStream($stack, $ast); + return new TokenIterator($stack, $tokenStream); } } diff --git a/src/TokenStream/TokenStream.php b/src/TokenStream/TokenStream.php index 14ba919..ac6e36d 100644 --- a/src/TokenStream/TokenStream.php +++ b/src/TokenStream/TokenStream.php @@ -7,86 +7,132 @@ */ namespace nicoSWD\Rule\TokenStream; -use ArrayIterator; use Closure; -use nicoSWD\Rule\Parser\Exception\ParserException; +use InvalidArgumentException; use nicoSWD\Rule\Grammar\CallableUserFunctionInterface; +use nicoSWD\Rule\Parser\Exception\ParserException; +use nicoSWD\Rule\TokenStream\Exception\UndefinedVariableException; use nicoSWD\Rule\TokenStream\Token\BaseToken; +use nicoSWD\Rule\TokenStream\Token\TokenFactory; +use nicoSWD\Rule\Tokenizer\TokenizerInterface; +use nicoSWD\Rule\TokenStream\Token\TokenObject; -class TokenStream extends ArrayIterator +class TokenStream { + private array $functions = []; + private array $methods = []; + private array $variables = []; + public function __construct( - private ArrayIterator $stack, - private AST $ast + private readonly TokenizerInterface $tokenizer, + private readonly TokenFactory $tokenFactory, + private readonly TokenIteratorFactory $tokenIteratorFactory, + private readonly CallableUserMethodFactoryInterface $userMethodFactory, ) { } - public function next(): void + public function getStream(string $rule): TokenIterator { - $this->stack->next(); + return $this->tokenIteratorFactory->create($this->tokenizer->tokenize($rule), $this); } - public function valid(): bool + /** + * @throws Exception\UndefinedMethodException + * @throws Exception\ForbiddenMethodException + */ + public function getMethod(string $methodName, BaseToken $token): CallableUserFunctionInterface { - return $this->stack->valid(); + if ($token instanceof TokenObject) { + return $this->getCallableUserMethod($token, $methodName); + } + + if (empty($this->methods)) { + $this->registerMethods(); + } + + if (!isset($this->methods[$methodName])) { + throw new Exception\UndefinedMethodException(); + } + + return new $this->methods[$methodName]($token); } - /** @throws ParserException */ - public function current(): BaseToken + public function setVariables(array $variables): void { - return $this->getCurrentToken()->createNode($this); + $this->variables = $variables; } - public function key(): int + /** + * @throws UndefinedVariableException + * @throws ParserException + */ + public function getVariable(string $variableName): BaseToken { - return $this->stack->key(); + if (!$this->variableExists($variableName)) { + throw new UndefinedVariableException($variableName); + } + + return $this->tokenFactory->createFromPHPType($this->variables[$variableName]); } - public function rewind(): void + public function variableExists(string $variableName): bool { - $this->stack->rewind(); + return array_key_exists($variableName, $this->variables); } - /** @return ArrayIterator */ - public function getStack(): ArrayIterator + /** @throws Exception\UndefinedFunctionException */ + public function getFunction(string $functionName): Closure { - return $this->stack; + if (empty($this->functions)) { + $this->registerFunctions(); + } + + if (!isset($this->functions[$functionName])) { + throw new Exception\UndefinedFunctionException($functionName); + } + + return $this->functions[$functionName]; } - private function getCurrentToken(): BaseToken + private function registerMethods(): void { - return $this->stack->current(); + foreach ($this->tokenizer->grammar->getInternalMethods() as $internalMethod) { + $this->methods[$internalMethod->name] = $internalMethod->class; + } } - /** @throws ParserException */ - public function getVariable(string $variableName): BaseToken + private function registerFunctions(): void { - try { - return $this->ast->getVariable($variableName); - } catch (Exception\UndefinedVariableException) { - throw ParserException::undefinedVariable($variableName, $this->getCurrentToken()); + foreach ($this->tokenizer->grammar->getInternalFunctions() as $function) { + $this->registerFunctionClass($function->name, $function->class); } } - /** @throws ParserException */ - public function getFunction(string $functionName): Closure + private function registerFunctionClass(string $functionName, string $className): void { - try { - return $this->ast->getFunction($functionName); - } catch (Exception\UndefinedFunctionException) { - throw ParserException::undefinedFunction($functionName, $this->getCurrentToken()); - } + $this->functions[$functionName] = function (?BaseToken ...$args) use ($className) { + $function = new $className(); + + if (!$function instanceof CallableUserFunctionInterface) { + throw new InvalidArgumentException( + sprintf( + '%s must be an instance of %s', + $className, + CallableUserFunctionInterface::class + ) + ); + } + + return $function->call(...$args); + }; } - /** @throws ParserException */ - public function getMethod(string $methodName, BaseToken $token): CallableUserFunctionInterface + /** + * @throws Exception\ForbiddenMethodException + * @throws Exception\UndefinedMethodException + */ + private function getCallableUserMethod(BaseToken $token, string $methodName): CallableUserFunctionInterface { - try { - return $this->ast->getMethod($methodName, $token); - } catch (Exception\UndefinedMethodException) { - throw ParserException::undefinedMethod($methodName, $this->getCurrentToken()); - } catch (Exception\ForbiddenMethodException) { - throw ParserException::forbiddenMethod($methodName, $this->getCurrentToken()); - } + return $this->userMethodFactory->create($token, $this->tokenFactory, $methodName); } } diff --git a/src/Tokenizer/Tokenizer.php b/src/Tokenizer/Tokenizer.php index 702394c..2e8a90b 100644 --- a/src/Tokenizer/Tokenizer.php +++ b/src/Tokenizer/Tokenizer.php @@ -8,92 +8,44 @@ namespace nicoSWD\Rule\Tokenizer; use ArrayIterator; +use Iterator; use nicoSWD\Rule\Grammar\Grammar; +use nicoSWD\Rule\TokenStream\Token\Token; use nicoSWD\Rule\TokenStream\Token\TokenFactory; -use SplPriorityQueue; -final class Tokenizer implements TokenizerInterface +final class Tokenizer extends TokenizerInterface { - private array $tokens = []; - private string $compiledRegex = ''; - public function __construct( - private Grammar $grammar, - private TokenFactory $tokenFactory + public readonly Grammar $grammar, + private readonly TokenFactory $tokenFactory, ) { - foreach ($grammar->getDefinition() as [$class, $regex, $priority]) { - $this->registerToken($class, $regex, $priority); - } } - public function tokenize(string $string): ArrayIterator + public function tokenize(string $string): Iterator { - $regex = $this->getRegex(); + $regex = $this->grammar->buildRegex(); $stack = []; $offset = 0; - while (preg_match($regex, $string, $matches, 0, $offset)) { + while (preg_match($regex, $string, $matches, offset: $offset)) { $token = $this->getMatchedToken($matches); - $className = $this->tokenFactory->createFromTokenName($token); + $className = $this->tokenFactory->createFromToken($token); - $stack[] = new $className($matches[$token], $offset); + $stack[] = new $className($matches[$token->value], $offset); $offset += strlen($matches[0]); } return new ArrayIterator($stack); } - public function getGrammar(): Grammar - { - return $this->grammar; - } - - private function registerToken(string $class, string $regex, int $priority): void - { - $this->tokens[$class] = new class($class, $regex, $priority) { - public function __construct( - public string $class, - public string $regex, - public int $priority - ) { - } - }; - } - - private function getMatchedToken(array $matches): string + private function getMatchedToken(array $matches): Token { foreach ($matches as $key => $value) { if ($value !== '' && !is_int($key)) { - return $key; + return Token::from($key); } } - return 'Unknown'; - } - - private function getRegex(): string - { - if (!$this->compiledRegex) { - $regex = []; - - foreach ($this->getQueue() as $token) { - $regex[] = "(?<$token->class>$token->regex)"; - } - - $this->compiledRegex = '~(' . implode('|', $regex) . ')~As'; - } - - return $this->compiledRegex; - } - - private function getQueue(): SplPriorityQueue - { - $queue = new SplPriorityQueue(); - - foreach ($this->tokens as $class) { - $queue->insert($class, $class->priority); - } - - return $queue; + return Token::UNKNOWN; } } diff --git a/src/Tokenizer/TokenizerInterface.php b/src/Tokenizer/TokenizerInterface.php index e49b05d..f3f9a65 100644 --- a/src/Tokenizer/TokenizerInterface.php +++ b/src/Tokenizer/TokenizerInterface.php @@ -1,4 +1,4 @@ - */ - public function tokenize(string $string): ArrayIterator; + public readonly Grammar $grammar; - public function getGrammar(): Grammar; + /** + * @param string $string + * @return Iterator + */ + abstract public function tokenize(string $string): Iterator; } diff --git a/src/container.php b/src/container.php index c356af5..aa273ef 100644 --- a/src/container.php +++ b/src/container.php @@ -8,22 +8,22 @@ namespace nicoSWD\Rule; use nicoSWD\Rule\Grammar\JavaScript\JavaScript; -use nicoSWD\Rule\TokenStream\AST; +use nicoSWD\Rule\Parser\EvaluatableExpressionFactory; +use nicoSWD\Rule\TokenStream\TokenStream; use nicoSWD\Rule\Compiler\CompilerFactory; use nicoSWD\Rule\Evaluator\Evaluator; use nicoSWD\Rule\Evaluator\EvaluatorInterface; -use nicoSWD\Rule\Expression\ExpressionFactory; use nicoSWD\Rule\Tokenizer\Tokenizer; use nicoSWD\Rule\TokenStream\Token\TokenFactory; -use nicoSWD\Rule\TokenStream\TokenStreamFactory; +use nicoSWD\Rule\TokenStream\TokenIteratorFactory; use nicoSWD\Rule\TokenStream\CallableUserMethodFactory; return new class { - private static TokenStreamFactory $tokenStreamFactory; + private static TokenIteratorFactory $tokenStreamFactory; private static TokenFactory $tokenFactory; private static CompilerFactory $compiler; private static JavaScript $javaScript; - private static ExpressionFactory $expressionFactory; + private static EvaluatableExpressionFactory $expressionFactory; private static CallableUserMethodFactory $userMethodFactory; private static Tokenizer $tokenizer; private static Evaluator $evaluator; @@ -64,12 +64,12 @@ private static function compiler(): CompilerFactory return self::$compiler; } - private static function ast(array $variables): AST + private static function ast(array $variables): TokenStream { - $ast = new AST(self::tokenizer(), self::tokenFactory(), self::tokenStreamFactory(), self::userMethodFactory()); - $ast->setVariables($variables); + $tokenStream = new TokenStream(self::tokenizer(), self::tokenFactory(), self::tokenStreamFactory(), self::userMethodFactory()); + $tokenStream->setVariables($variables); - return $ast; + return $tokenStream; } private static function tokenizer(): Tokenizer @@ -90,19 +90,19 @@ private static function javascript(): JavaScript return self::$javaScript; } - private static function tokenStreamFactory(): TokenStreamFactory + private static function tokenStreamFactory(): TokenIteratorFactory { if (!isset(self::$tokenStreamFactory)) { - self::$tokenStreamFactory = new TokenStreamFactory(); + self::$tokenStreamFactory = new TokenIteratorFactory(); } return self::$tokenStreamFactory; } - private static function expressionFactory(): ExpressionFactory + private static function expressionFactory(): EvaluatableExpressionFactory { if (!isset(self::$expressionFactory)) { - self::$expressionFactory = new ExpressionFactory(); + self::$expressionFactory = new EvaluatableExpressionFactory(); } return self::$expressionFactory; diff --git a/tests/integration/HighlighterTest.php b/tests/integration/HighlighterTest.php index 3f44e1a..4c03b01 100755 --- a/tests/integration/HighlighterTest.php +++ b/tests/integration/HighlighterTest.php @@ -7,7 +7,6 @@ */ namespace nicoSWD\Rule\tests\integration; -use Exception; use nicoSWD\Rule; use nicoSWD\Rule\Grammar\JavaScript\JavaScript; use nicoSWD\Rule\Highlighter\Highlighter; @@ -36,16 +35,4 @@ public function givenAStyleForATokenGroupItShouldBeUsed(): void $this->assertStringContainsString('[', $code); } - - /** @test */ - public function invalidGroupThrowsException(): void - { - $this->expectException(Exception::class); - $this->expectExceptionMessage('Invalid group'); - - $this->highlighter->setStyle( - 99, - 'color: test-color;' - ); - } } diff --git a/tests/integration/TokenizerTest.php b/tests/integration/TokenizerTest.php index 614e031..69c5e74 100755 --- a/tests/integration/TokenizerTest.php +++ b/tests/integration/TokenizerTest.php @@ -9,6 +9,7 @@ use nicoSWD\Rule\Grammar\JavaScript\JavaScript; use nicoSWD\Rule\Tokenizer\Tokenizer; +use nicoSWD\Rule\TokenStream\Token\Token; use nicoSWD\Rule\TokenStream\Token\TokenFactory; use PHPUnit\Framework\TestCase; use ReflectionMethod; @@ -26,10 +27,9 @@ protected function setUp(): void public function getMatchedTokenReturnsFalseOnFailure(): void { $reflection = new ReflectionMethod($this->tokenizer, 'getMatchedToken'); - $reflection->setAccessible(true); $result = $reflection->invoke($this->tokenizer, []); - $this->assertSame('Unknown', $result); + $this->assertSame(Token::UNKNOWN, $result); } /** @test */ diff --git a/tests/integration/methods/SyntaxErrorTest.php b/tests/integration/methods/SyntaxErrorTest.php index 6af16a9..31b3da9 100755 --- a/tests/integration/methods/SyntaxErrorTest.php +++ b/tests/integration/methods/SyntaxErrorTest.php @@ -90,6 +90,6 @@ public function exceptionIsThrownOnTypeError(): void $rule = new Rule('"foo".test("foo") === false'); $this->assertFalse($rule->isValid()); - $this->assertSame('undefined is not a function', $rule->getError()); + $this->assertSame('test() is not a function', $rule->getError()); } } diff --git a/tests/unit/Grammar/GrammarTest.php b/tests/unit/Grammar/GrammarTest.php index f0d1b13..cabd738 100755 --- a/tests/unit/Grammar/GrammarTest.php +++ b/tests/unit/Grammar/GrammarTest.php @@ -5,7 +5,7 @@ * @link https://github.com/nicoSWD * @author Nicolas Oelgart */ -namespace nicoSWD\Rule\tests\unit\Parser; +namespace nicoSWD\Rule\tests\unit\Grammar; use nicoSWD\Rule\Grammar\Grammar; use PHPUnit\Framework\TestCase; @@ -19,6 +19,16 @@ public function getDefinition(): array { return []; } + + public function getInternalFunctions(): array + { + return []; + } + + public function getInternalMethods(): array + { + return []; + } }; $this->assertSame([], $grammar->getDefinition()); diff --git a/tests/unit/Parser/ParserTest.php b/tests/unit/Parser/ParserTest.php index 95546c2..956d8bf 100755 --- a/tests/unit/Parser/ParserTest.php +++ b/tests/unit/Parser/ParserTest.php @@ -9,32 +9,30 @@ use Mockery as m; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; -use nicoSWD\Rule\TokenStream\AST; +use nicoSWD\Rule\Compiler\StandardCompiler; +use nicoSWD\Rule\Parser\EvaluatableExpressionFactory; +use nicoSWD\Rule\TokenStream\TokenStream; use nicoSWD\Rule\Compiler\CompilerFactoryInterface; -use nicoSWD\Rule\Compiler\CompilerInterface; -use nicoSWD\Rule\Expression\BaseExpression; -use nicoSWD\Rule\Expression\ExpressionFactoryInterface; use nicoSWD\Rule\Parser\Parser; use nicoSWD\Rule\TokenStream\Token; -use nicoSWD\Rule\TokenStream\TokenStream; +use nicoSWD\Rule\TokenStream\TokenIterator; use PHPUnit\Framework\TestCase; final class ParserTest extends TestCase { use MockeryPHPUnitIntegration; - private AST|m\Mock $ast; - private ExpressionFactoryInterface|m\Mock $expressionFactory; + private TokenStream|m\Mock $tokenStream; + private EvaluatableExpressionFactory $expressionFactory; private CompilerFactoryInterface|m\Mock $compilerFactory; private Parser $parser; protected function setUp(): void { - $this->ast = m::mock(AST::class); - $this->expressionFactory = m::mock(ExpressionFactoryInterface::class); + $this->tokenStream = m::mock(TokenStream::class); $this->compilerFactory = m::mock(CompilerFactoryInterface::class); - $this->parser = new Parser($this->ast, $this->expressionFactory, $this->compilerFactory); + $this->parser = new Parser($this->tokenStream, new EvaluatableExpressionFactory(), $this->compilerFactory); } /** @test */ @@ -54,14 +52,10 @@ public function givenARuleStringWhenValidItShouldReturnTheCompiledRule(): void new Token\TokenComment('// true dat!') ]; - $compiler = m::mock(CompilerInterface::class); - $compiler->shouldReceive('addLogical')->once(); - $compiler->shouldReceive('addParentheses')->twice(); - $compiler->shouldReceive('addBoolean')->twice(); - $compiler->shouldReceive('getCompiledRule')->once()->andReturn('(1)&1'); + $compiler = new StandardCompiler(); /** @var m\MockInterface $tokenStream */ - $tokenStream = \Mockery::mock(TokenStream::class); + $tokenStream = \Mockery::mock(TokenIterator::class); $tokenStream->shouldReceive('rewind')->once(); $tokenStream->shouldReceive('next'); $tokenStream->shouldReceive('current')->andReturn(...$tokens); @@ -70,22 +64,7 @@ public function givenARuleStringWhenValidItShouldReturnTheCompiledRule(): void }); $this->compilerFactory->shouldReceive('create')->once()->andReturn($compiler); - $this->ast->shouldReceive('getStream')->once()->andReturn($tokenStream); - - $equalExpression = m::mock(BaseExpression::class); - $equalExpression->shouldReceive('evaluate')->once()->with(1, '1'); - - $greaterExpression = m::mock(BaseExpression::class); - $greaterExpression->shouldReceive('evaluate')->once()->with(2, 1); - - $this->expressionFactory - ->shouldReceive('createFromOperator') - ->twice() - ->with(m::type(Token\BaseToken::class)) - ->andReturn( - $equalExpression, - $greaterExpression - ); + $this->tokenStream->shouldReceive('getStream')->once()->andReturn($tokenStream); $this->assertSame('(1)&1', $this->parser->parse('(1=="1")&&2>1 // true dat!')); } diff --git a/tests/unit/Token/TokenFactoryTest.php b/tests/unit/Token/TokenFactoryTest.php index fcf59f3..d67ea17 100755 --- a/tests/unit/Token/TokenFactoryTest.php +++ b/tests/unit/Token/TokenFactoryTest.php @@ -14,7 +14,7 @@ final class TokenFactoryTest extends TestCase { - private Token\TokenFactory $tokenFactory; + private readonly Token\TokenFactory $tokenFactory; protected function setUp(): void { @@ -41,17 +41,9 @@ public function unsupportedTypeThrowsException(): void $this->tokenFactory->createFromPHPType(tmpfile()); } - /** @test */ - public function givenAnInvalidTokenNameItShouldThrowAnException(): void - { - $this->expectException(ParserException::class); - - $this->tokenFactory->createFromTokenName('betrunken'); - } - /** @test */ public function givenAValidTokenNameItShouldReturnItsCorrespondingClassName(): void { - $this->assertSame(TokenEqualStrict::class, $this->tokenFactory->createFromTokenName(Token\Token::EQUAL_STRICT)); + $this->assertSame(TokenEqualStrict::class, $this->tokenFactory->createFromToken(Token\Token::EQUAL_STRICT)); } } diff --git a/tests/unit/TokenStream/ASTTest.php b/tests/unit/TokenStream/ASTTest.php deleted file mode 100755 index 04f2281..0000000 --- a/tests/unit/TokenStream/ASTTest.php +++ /dev/null @@ -1,89 +0,0 @@ - - */ -namespace nicoSWD\Rule\tests\unit\TokenStream; - -use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; -use Mockery\MockInterface; -use nicoSWD\Rule\Grammar\CallableUserFunctionInterface; -use nicoSWD\Rule\Grammar\Grammar; -use nicoSWD\Rule\Tokenizer\TokenizerInterface; -use nicoSWD\Rule\TokenStream\AST; -use nicoSWD\Rule\TokenStream\Exception\UndefinedFunctionException; -use nicoSWD\Rule\TokenStream\Node\BaseNode; -use nicoSWD\Rule\TokenStream\Token\BaseToken; -use nicoSWD\Rule\TokenStream\Token\TokenFactory; -use nicoSWD\Rule\TokenStream\TokenStreamFactory; -use nicoSWD\Rule\TokenStream\CallableUserMethodFactory; -use PHPUnit\Framework\TestCase; - -final class ASTTest extends TestCase -{ - use MockeryPHPUnitIntegration; - - private TokenizerInterface|MockInterface $tokenizer; - private TokenFactory|MockInterface $tokenFactory; - private TokenStreamFactory|MockInterface $tokenStreamFactory; - private AST $ast; - private CallableUserMethodFactory $userMethodFactory; - - protected function setUp(): void - { - $this->tokenizer = \Mockery::mock(TokenizerInterface::class); - $this->tokenFactory = \Mockery::mock(TokenFactory::class); - $this->tokenStreamFactory = \Mockery::mock(TokenStreamFactory::class); - $this->userMethodFactory = new CallableUserMethodFactory(); - - $this->ast = new AST( - $this->tokenizer, - $this->tokenFactory, - $this->tokenStreamFactory, - $this->userMethodFactory - ); - } - - /** @test */ - public function givenAFunctionNameWhenValidItShouldReturnTheCorrespondingFunction(): void - { - $grammar = \Mockery::mock(Grammar::class); - $grammar->shouldReceive('getInternalFunctions')->once()->andReturn(['test' => TestFunc::class]); - $this->tokenizer->shouldReceive('getGrammar')->once()->andReturn($grammar); - - /** @var BaseToken $result */ - $result = $this->ast->getFunction('test')->call(\Mockery::mock(BaseNode::class)); - - $this->assertSame(234, $result->getValue()); - } - - /** @test */ - public function givenAFunctionNameWhenItDoesNotImplementTheInterfaceItShouldThrowAnException(): void - { - $this->expectExceptionMessage(sprintf( - 'stdClass must be an instance of %s', - CallableUserFunctionInterface::class - )); - - $grammar = \Mockery::mock(Grammar::class); - $grammar->shouldReceive('getInternalFunctions')->once()->andReturn(['test' => \stdClass::class]); - $this->tokenizer->shouldReceive('getGrammar')->once()->andReturn($grammar); - - $this->ast->getFunction('test')->call(\Mockery::mock(BaseNode::class)); - } - - /** @test */ - public function givenAFunctionNameNotDefinedItShouldThrowAnException(): void - { - $this->expectException(UndefinedFunctionException::class); - $this->expectExceptionMessage('pineapple_pizza'); - - $grammar = \Mockery::mock(Grammar::class); - $grammar->shouldReceive('getInternalFunctions')->once()->andReturn([]); - $this->tokenizer->shouldReceive('getGrammar')->once()->andReturn($grammar); - - $this->ast->getFunction('pineapple_pizza')->call(\Mockery::mock(BaseNode::class)); - } -} diff --git a/tests/unit/TokenStream/Token/BaseTokenTest.php b/tests/unit/TokenStream/Token/BaseTokenTest.php index 0033d3d..d1753d4 100755 --- a/tests/unit/TokenStream/Token/BaseTokenTest.php +++ b/tests/unit/TokenStream/Token/BaseTokenTest.php @@ -5,12 +5,12 @@ * @link https://github.com/nicoSWD * @author Nicolas Oelgart */ -namespace nicoSWD\Rule\tests\unit\TokenStream; +namespace nicoSWD\Rule\tests\unit\TokenStream\Token; use Mockery\MockInterface; use nicoSWD\Rule\TokenStream\Token\BaseToken; use nicoSWD\Rule\TokenStream\Token\TokenType; -use nicoSWD\Rule\TokenStream\TokenStream; +use nicoSWD\Rule\TokenStream\TokenIterator; use PHPUnit\Framework\TestCase; final class BaseTokenTest extends TestCase @@ -21,7 +21,7 @@ final class BaseTokenTest extends TestCase protected function setUp(): void { $this->token = new class('&&', 1337) extends BaseToken { - public function getType(): int + public function getType(): TokenType { return TokenType::LOGICAL; } @@ -49,8 +49,8 @@ public function getOriginalValue(): void /** @test */ public function createNode(): void { - /** @var TokenStream|MockInterface $tokenStream */ - $tokenStream = \Mockery::mock(TokenStream::class); + /** @var TokenIterator|MockInterface $tokenStream */ + $tokenStream = \Mockery::mock(TokenIterator::class); $this->assertSame($this->token, $this->token->createNode($tokenStream)); } @@ -60,95 +60,4 @@ public function isOfType(): void $this->assertTrue($this->token->isOfType(TokenType::LOGICAL)); $this->assertFalse($this->token->isOfType(TokenType::COMMA)); } - - /** @test */ - public function isValue(): void - { - $token = new class('123', 1337) extends BaseToken { - public function getType(): int - { - return TokenType::VALUE; - } - }; - - $this->assertTrue($token->isValue()); - } - - /** @test */ - public function isWhitespace(): void - { - $token = new class(' ', 1337) extends BaseToken { - public function getType(): int - { - return TokenType::SPACE; - } - }; - - $this->assertTrue($token->isWhitespace()); - } - - /** @test */ - public function isMethod(): void - { - $token = new class('.derp(', 1337) extends BaseToken { - public function getType(): int - { - return TokenType::METHOD; - } - }; - - $this->assertTrue($token->isMethod()); - } - - /** @test */ - public function isComma(): void - { - $token = new class(',', 1337) extends BaseToken { - public function getType(): int - { - return TokenType::COMMA; - } - }; - - $this->assertTrue($token->isComma()); - } - - /** @test */ - public function isOperator(): void - { - $token = new class('>', 1337) extends BaseToken { - public function getType(): int - { - return TokenType::OPERATOR; - } - }; - - $this->assertTrue($token->isOperator()); - } - - /** @test */ - public function isLogical(): void - { - $token = new class('&&', 1337) extends BaseToken { - public function getType(): int - { - return TokenType::LOGICAL; - } - }; - - $this->assertTrue($token->isLogical()); - } - - /** @test */ - public function isParenthesis(): void - { - $token = new class('(', 1337) extends BaseToken { - public function getType(): int - { - return TokenType::PARENTHESIS; - } - }; - - $this->assertTrue($token->isParenthesis()); - } } diff --git a/tests/unit/TokenStream/TokenIteratorTest.php b/tests/unit/TokenStream/TokenIteratorTest.php new file mode 100755 index 0000000..8871126 --- /dev/null +++ b/tests/unit/TokenStream/TokenIteratorTest.php @@ -0,0 +1,132 @@ + + */ +namespace nicoSWD\Rule\tests\unit\TokenStream; + +use ArrayIterator; +use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; +use Mockery\MockInterface; +use nicoSWD\Rule\Grammar\CallableFunction; +use nicoSWD\Rule\Parser\Exception\ParserException; +use nicoSWD\Rule\TokenStream\TokenStream; +use nicoSWD\Rule\TokenStream\Exception\UndefinedFunctionException; +use nicoSWD\Rule\TokenStream\Exception\UndefinedMethodException; +use nicoSWD\Rule\TokenStream\Exception\UndefinedVariableException; +use nicoSWD\Rule\TokenStream\Token\BaseToken; +use nicoSWD\Rule\TokenStream\Token\TokenFunction; +use nicoSWD\Rule\TokenStream\Token\TokenMethod; +use nicoSWD\Rule\TokenStream\Token\TokenString; +use nicoSWD\Rule\TokenStream\Token\TokenVariable; +use nicoSWD\Rule\TokenStream\TokenIterator; +use PHPUnit\Framework\TestCase; + +final class TokenIteratorTest extends TestCase +{ + use MockeryPHPUnitIntegration; + + private ArrayIterator|MockInterface $stack; + private TokenStream|MockInterface $tokenStream; + private TokenIterator $tokenIterator; + + protected function setUp(): void + { + $this->stack = \Mockery::mock(ArrayIterator::class); + $this->tokenStream = \Mockery::mock(TokenStream::class); + + $this->tokenIterator = new TokenIterator($this->stack, $this->tokenStream); + } + + /** @test */ + public function givenAStackWhenNotEmptyItShouldBeIterable() + { + $this->stack->shouldReceive('rewind'); + $this->stack->shouldReceive('valid')->andReturn(true, true, true, false); + $this->stack->shouldReceive('key')->andReturn(1, 2, 3); + $this->stack->shouldReceive('next'); + $this->stack->shouldReceive('seek'); + $this->stack->shouldReceive('current')->times(5)->andReturn( + new TokenString('a'), + new TokenMethod('.foo('), + new TokenString('b') + ); + + foreach ($this->tokenIterator as $value) { + $this->assertInstanceOf(BaseToken::class, $value); + } + } + + /** @test */ + public function givenATokenStackItShouldBeAccessibleViaGetter() + { + $this->assertInstanceOf(ArrayIterator::class, $this->tokenIterator->getStack()); + } + + /** @test */ + public function givenAVariableNameWhenFoundItShouldReturnItsValue() + { + $this->tokenStream->shouldReceive('getVariable')->once()->with('foo')->andReturn(new TokenVariable('bar')); + + $token = $this->tokenIterator->getVariable('foo'); + $this->assertInstanceOf(TokenVariable::class, $token); + } + + /** @test */ + public function givenAVariableNameWhenNotFoundItShouldThrowAnException() + { + $this->expectException(ParserException::class); + + $this->tokenStream->shouldReceive('getVariable')->once()->with('foo')->andThrow(new UndefinedVariableException()); + $this->stack->shouldReceive('current')->once()->andReturn(new TokenVariable('nope')); + + $this->tokenIterator->getVariable('foo'); + } + + /** @test */ + public function givenAFunctionNameWhenFoundItShouldACallableClosure() + { + $this->tokenStream->shouldReceive('getFunction')->once()->with('foo')->andReturn(fn () => 42); + + $function = $this->tokenIterator->getFunction('foo'); + $this->assertSame(42, $function()); + } + + /** @test */ + public function givenAFunctionNameWhenNotFoundItShouldThrowAnException() + { + $this->expectException(ParserException::class); + + $this->tokenStream->shouldReceive('getFunction')->once()->with('foo')->andThrow(new UndefinedFunctionException()); + $this->stack->shouldReceive('current')->once()->andReturn(new TokenFunction('nope(')); + + $this->tokenIterator->getFunction('foo'); + } + + /** @test */ + public function givenAMethodNameWhenFoundItShouldReturnAnInstanceOfCallableFunction() + { + $token = new TokenString('bar'); + $callableFunction = \Mockery::mock(CallableFunction::class); + + $this->tokenStream->shouldReceive('getMethod')->once()->with('foo', $token)->andReturn($callableFunction); + + $method = $this->tokenIterator->getMethod('foo', $token); + + $this->assertInstanceOf(CallableFunction::class, $method); + } + + /** @test */ + public function givenAMethodNameWhenNotFoundItShouldThrowAnException() + { + $this->expectException(ParserException::class); + + $token = new TokenString('bar'); + $this->tokenStream->shouldReceive('getMethod')->once()->with('foo', $token)->andThrow(new UndefinedMethodException()); + $this->stack->shouldReceive('current')->once()->andReturn(new TokenFunction('bar')); + + $this->tokenIterator->getMethod('foo', $token); + } +} diff --git a/tests/unit/TokenStream/TokenStreamTest.php b/tests/unit/TokenStream/TokenStreamTest.php index 757a634..815c8de 100755 --- a/tests/unit/TokenStream/TokenStreamTest.php +++ b/tests/unit/TokenStream/TokenStreamTest.php @@ -8,125 +8,156 @@ namespace nicoSWD\Rule\tests\unit\TokenStream; use ArrayIterator; +use Iterator; +use Mockery; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; use Mockery\MockInterface; -use nicoSWD\Rule\Grammar\CallableFunction; -use nicoSWD\Rule\Parser\Exception\ParserException; -use nicoSWD\Rule\TokenStream\AST; +use nicoSWD\Rule\Grammar\CallableUserFunctionInterface; +use nicoSWD\Rule\Grammar\Grammar; +use nicoSWD\Rule\Grammar\InternalFunction; +use nicoSWD\Rule\Tokenizer\Tokenizer; +use nicoSWD\Rule\Tokenizer\TokenizerInterface; +use nicoSWD\Rule\TokenStream\CallableUserMethodFactoryInterface; +use nicoSWD\Rule\TokenStream\TokenStream; use nicoSWD\Rule\TokenStream\Exception\UndefinedFunctionException; -use nicoSWD\Rule\TokenStream\Exception\UndefinedMethodException; -use nicoSWD\Rule\TokenStream\Exception\UndefinedVariableException; +use nicoSWD\Rule\TokenStream\Node\BaseNode; use nicoSWD\Rule\TokenStream\Token\BaseToken; -use nicoSWD\Rule\TokenStream\Token\TokenFunction; -use nicoSWD\Rule\TokenStream\Token\TokenMethod; -use nicoSWD\Rule\TokenStream\Token\TokenString; -use nicoSWD\Rule\TokenStream\Token\TokenVariable; -use nicoSWD\Rule\TokenStream\TokenStream; +use nicoSWD\Rule\TokenStream\Token\TokenFactory; +use nicoSWD\Rule\TokenStream\TokenIteratorFactory; +use nicoSWD\Rule\TokenStream\CallableUserMethodFactory; use PHPUnit\Framework\TestCase; +use stdClass; final class TokenStreamTest extends TestCase { use MockeryPHPUnitIntegration; - - private ArrayIterator|MockInterface $stack; - private AST|MockInterface $ast; - private TokenStream $tokenStream; + + private readonly TokenStream $tokenStream; + private readonly TokenFactory|MockInterface $tokenFactory; + private readonly CallableUserMethodFactory $userMethodFactory; + private readonly TokenIteratorFactory $tokenStreamFactory; protected function setUp(): void { - $this->stack = \Mockery::mock(ArrayIterator::class); - $this->ast = \Mockery::mock(AST::class); - - $this->tokenStream = new TokenStream($this->stack, $this->ast); + $this->tokenFactory = Mockery::mock(TokenFactory::class); + $this->userMethodFactory = new CallableUserMethodFactory(); + $this->tokenStreamFactory = new TokenIteratorFactory(); } /** @test */ - public function givenAStackWhenNotEmptyItShouldBeIterable() + public function givenAFunctionNameWhenValidItShouldReturnTheCorrespondingFunction(): void { - $this->stack->shouldReceive('rewind'); - $this->stack->shouldReceive('valid')->andReturn(true, true, true, false); - $this->stack->shouldReceive('key')->andReturn(1, 2, 3); - $this->stack->shouldReceive('next'); - $this->stack->shouldReceive('seek'); - $this->stack->shouldReceive('current')->times(5)->andReturn( - new TokenString('a'), - new TokenMethod('.foo('), - new TokenString('b') + $grammar = $this->createGrammarWithInternalFunctions([new InternalFunction('test', TestFunc::class)]); + $tokenizer = new Tokenizer($grammar, $this->tokenFactory); + + $tokenStream = new TokenStream( + $tokenizer, + $this->tokenFactory, + $this->tokenStreamFactory, + $this->userMethodFactory ); - foreach ($this->tokenStream as $key => $value) { - $this->assertInstanceOf(BaseToken::class, $value); - } - } + /** @var BaseToken $result */ + $result = $tokenStream->getFunction('test')->call(Mockery::mock(BaseNode::class)); - /** @test */ - public function givenATokenStackItShouldBeAccessibleViaGetter() - { - $this->assertInstanceOf(ArrayIterator::class, $this->tokenStream->getStack()); + $this->assertSame(234, $result->getValue()); } /** @test */ - public function givenAVariableNameWhenFoundItShouldReturnItsValue() + public function givenAFunctionNameWhenItDoesNotImplementTheInterfaceItShouldThrowAnException(): void { - $this->ast->shouldReceive('getVariable')->once()->with('foo')->andReturn(new TokenVariable('bar')); + $this->expectExceptionMessage(sprintf( + 'stdClass must be an instance of %s', + CallableUserFunctionInterface::class + )); + + $grammar = $this->createGrammarWithInternalFunctions([new InternalFunction('test', stdClass::class)]); + $tokenizer = new Tokenizer($grammar, $this->tokenFactory); + + $tokenStream = new TokenStream( + $tokenizer, + $this->tokenFactory, + $this->tokenStreamFactory, + $this->userMethodFactory + ); - $token = $this->tokenStream->getVariable('foo'); - $this->assertInstanceOf(TokenVariable::class, $token); + $tokenStream->getFunction('test')->call(Mockery::mock(BaseNode::class)); } /** @test */ - public function givenAVariableNameWhenNotFoundItShouldThrowAnException() + public function givenAFunctionNameNotDefinedItShouldThrowAnException(): void { - $this->expectException(ParserException::class); - - $this->ast->shouldReceive('getVariable')->once()->with('foo')->andThrow(new UndefinedVariableException()); - $this->stack->shouldReceive('current')->once()->andReturn(new TokenVariable('nope')); + $this->expectException(UndefinedFunctionException::class); + $this->expectExceptionMessage('pineapple_pizza'); - $this->tokenStream->getVariable('foo'); - } + $tokenizer = $this->createDummyTokenizer(); + $userMethodFactory = $this->createCallableUserMethodFactory(); - /** @test */ - public function givenAFunctionNameWhenFoundItShouldACallableClosure() - { - $this->ast->shouldReceive('getFunction')->once()->with('foo')->andReturn(fn () => 42); + $tokenStream = new TokenStream( + $tokenizer, + new TokenFactory(), + $this->tokenStreamFactory, + $userMethodFactory, + ); - $function = $this->tokenStream->getFunction('foo'); - $this->assertSame(42, $function()); + $tokenStream->getFunction('pineapple_pizza'); } - /** @test */ - public function givenAFunctionNameWhenNotFoundItShouldThrowAnException() + private function createDummyTokenizer(): TokenizerInterface { - $this->expectException(ParserException::class); - - $this->ast->shouldReceive('getFunction')->once()->with('foo')->andThrow(new UndefinedFunctionException()); - $this->stack->shouldReceive('current')->once()->andReturn(new TokenFunction('nope(')); - - $this->tokenStream->getFunction('foo'); + return new class ($this->createGrammarWithInternalFunctions()) extends TokenizerInterface { + public function __construct( + public readonly Grammar $grammar, + ) { + } + + public function tokenize(string $string): Iterator + { + return new ArrayIterator([]); + } + }; } - /** @test */ - public function givenAMethodNameWhenFoundItShouldReturnAnInstanceOfCallableFunction() + private function createGrammarWithInternalFunctions(array $internalFunctions = []): Grammar { - $token = new TokenString('bar'); - $callableFunction = \Mockery::mock(CallableFunction::class); - - $this->ast->shouldReceive('getMethod')->once()->with('foo', $token)->andReturn($callableFunction); - - $method = $this->tokenStream->getMethod('foo', $token); - - $this->assertInstanceOf(CallableFunction::class, $method); + return new class ($internalFunctions) extends Grammar { + public function __construct( + private array $internalFunctions, + ) { + } + + public function getDefinition(): array + { + return []; + } + + public function getInternalFunctions(): array + { + return $this->internalFunctions; + } + + public function getInternalMethods(): array + { + return []; + } + }; } - /** @test */ - public function givenAMethodNameWhenNotFoundItShouldThrowAnException() + private function createCallableUserMethodFactory(): CallableUserMethodFactoryInterface { - $this->expectException(ParserException::class); - - $token = new TokenString('bar'); - $this->ast->shouldReceive('getMethod')->once()->with('foo', $token)->andThrow(new UndefinedMethodException()); - $this->stack->shouldReceive('current')->once()->andReturn(new TokenFunction('bar')); - - $this->tokenStream->getMethod('foo', $token); + return new class implements CallableUserMethodFactoryInterface { + public function create( + BaseToken $token, + TokenFactory $tokenFactory, + string $methodName + ): CallableUserFunctionInterface { + return new class implements CallableUserFunctionInterface { + public function call(?BaseToken ...$param): BaseToken + { + return Mockery::mock(BaseToken::class); + } + }; + } + }; } } diff --git a/tests/unit/Tokenizer/TokenizerTest.php b/tests/unit/Tokenizer/TokenizerTest.php index 6d93527..c0565f1 100755 --- a/tests/unit/Tokenizer/TokenizerTest.php +++ b/tests/unit/Tokenizer/TokenizerTest.php @@ -7,6 +7,7 @@ */ namespace nicoSWD\Rule\tests\unit\Tokenizer; +use nicoSWD\Rule\Grammar\Definition; use nicoSWD\Rule\Grammar\Grammar; use nicoSWD\Rule\TokenStream\Token; use nicoSWD\Rule\Tokenizer\Tokenizer; @@ -18,9 +19,9 @@ final class TokenizerTest extends TestCase public function givenAGrammarWithCollidingRegexItShouldTakeThePriorityIntoAccount(): void { $tokens = $this->tokenizeWithGrammar('yes somevar', [ - [Token\Token::BOOL_TRUE, '\byes\b', 20], - [Token\Token::VARIABLE, '\b[a-z]+\b', 10], - [Token\Token::SPACE, '\s+', 5], + new Definition(Token\Token::BOOL_TRUE, '\byes\b', 20), + new Definition(Token\Token::VARIABLE, '\b[a-z]+\b', 10), + new Definition(Token\Token::SPACE, '\s+', 5), ]); $this->assertCount(3, $tokens); @@ -42,9 +43,9 @@ public function givenAGrammarWithCollidingRegexItShouldTakeThePriorityIntoAccoun public function givenAGrammarWithCollidingRegexWhenPriorityIsWrongItShouldNeverMatchTheOneWithLowerPriority(): void { $tokens = $this->tokenizeWithGrammar('somevar yes', [ - [Token\Token::VARIABLE, '\b[a-z]+\b', 20], - [Token\Token::BOOL_TRUE, '\byes\b', 10], - [Token\Token::SPACE, '\s+', 5], + new Definition(Token\Token::VARIABLE, '\b[a-z]+\b', 20), + new Definition(Token\Token::BOOL_TRUE, '\byes\b', 10), + new Definition(Token\Token::SPACE, '\s+', 5), ]); $this->assertCount(3, $tokens); @@ -62,16 +63,6 @@ public function givenAGrammarWithCollidingRegexWhenPriorityIsWrongItShouldNeverM $this->assertInstanceOf(Token\TokenVariable::class, $tokens[2]); } - /** @test */ - public function givenAGrammarItShouldBeAvailableThroughGetter(): void - { - $grammar = $this->getTokenizer([[Token\Token::BOOL_TRUE, '\byes\b', 10]])->getGrammar(); - - $this->assertInstanceOf(Grammar::class, $grammar); - $this->assertIsArray($grammar->getDefinition()); - $this->assertCount(1, $grammar->getDefinition()); - } - /** @return Token\BaseToken[] */ private function tokenizeWithGrammar(string $rule, array $definition): array { @@ -100,6 +91,16 @@ public function getDefinition(): array { return $this->definition; } + + public function getInternalFunctions(): array + { + return []; + } + + public function getInternalMethods(): array + { + return []; + } }; return new Tokenizer($grammar, new Token\TokenFactory()); From d62064b5b29cea6232dd3f436e7e27c6672b44f2 Mon Sep 17 00:00:00 2001 From: Nico Date: Wed, 16 Mar 2022 21:02:30 +0100 Subject: [PATCH 02/13] Use PHP 8.1 features --- .styleci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.styleci.yml b/.styleci.yml index 03b0848..eb60c1b 100644 --- a/.styleci.yml +++ b/.styleci.yml @@ -1,7 +1,7 @@ --- preset: psr2 risky: true -version: 8 +version: 8.1 finder: name: - "*.php" From 7942b6ec8439575824a6a4af6a454ea973328696 Mon Sep 17 00:00:00 2001 From: Nico Date: Wed, 16 Mar 2022 21:05:35 +0100 Subject: [PATCH 03/13] Use PHP 8.1 features --- .scrutinizer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 37f56a0..f52c501 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -36,7 +36,7 @@ tools: excluded_dirs: [tests] build: environment: - php: 8.0.1 + php: 8.1 nodes: analysis: tests: From 04fabef81e261523e805ac7b10400fe562a94c12 Mon Sep 17 00:00:00 2001 From: Nico Date: Wed, 16 Mar 2022 21:22:33 +0100 Subject: [PATCH 04/13] Use PHP 8.1 features --- .scrutinizer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index f52c501..d9aa1b1 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -36,7 +36,7 @@ tools: excluded_dirs: [tests] build: environment: - php: 8.1 + php: 8.1.0 nodes: analysis: tests: From 59bb941ed27d2a2b1340eb5dc9128a2b91298a53 Mon Sep 17 00:00:00 2001 From: Nico Date: Thu, 17 Mar 2022 21:43:00 +0100 Subject: [PATCH 05/13] Use PHP 8.1 features --- .github/workflows/phpqa.yml | 6 +-- src/Evaluator/Boolean.php | 11 ++++-- src/Evaluator/Operator.php | 73 ++++--------------------------------- 3 files changed, 18 insertions(+), 72 deletions(-) diff --git a/.github/workflows/phpqa.yml b/.github/workflows/phpqa.yml index 661b9e4..d626ce2 100644 --- a/.github/workflows/phpqa.yml +++ b/.github/workflows/phpqa.yml @@ -8,14 +8,14 @@ jobs: steps: - uses: actions/checkout@master - name: PHPStan - uses: docker://jakzal/phpqa:php8.0-alpine + uses: docker://jakzal/phpqa:php8.1 with: args: phpstan analyze src/ -l 1 - name: PHP-CS-Fixer - uses: docker://jakzal/phpqa:php8.0-alpine + uses: docker://jakzal/phpqa:php8.1 with: args: php-cs-fixer --dry-run --allow-risky=yes --no-interaction --ansi fix - name: Deptrac - uses: docker://jakzal/phpqa:php8.0-alpine + uses: docker://jakzal/phpqa:php8.1 with: args: deptrac --no-interaction --ansi --formatter-graphviz-display=0 diff --git a/src/Evaluator/Boolean.php b/src/Evaluator/Boolean.php index 7d068bd..26db253 100644 --- a/src/Evaluator/Boolean.php +++ b/src/Evaluator/Boolean.php @@ -7,8 +7,13 @@ */ namespace nicoSWD\Rule\Evaluator; -enum Operator: string +enum Boolean: string { - case LOGICAL_AND = '&'; - case LOGICAL_OR = '|'; + case TRUE = '1'; + case FALSE = '0'; + + final public static function fromBool(bool $bool): self + { + return $bool ? self::TRUE : self::FALSE; + } } diff --git a/src/Evaluator/Operator.php b/src/Evaluator/Operator.php index 55c7c62..e500242 100644 --- a/src/Evaluator/Operator.php +++ b/src/Evaluator/Operator.php @@ -7,77 +7,18 @@ */ namespace nicoSWD\Rule\Evaluator; -use Closure; - -final class Evaluator implements EvaluatorInterface +enum Operator: string { - private const LOGICAL_AND = '&'; - private const LOGICAL_OR = '|'; - - private const BOOL_TRUE = '1'; - private const BOOL_FALSE = '0'; - - public function evaluate(string $group): bool - { - $evalGroup = $this->evalGroup(); - $count = 0; - - do { - $group = preg_replace_callback( - '~\((?[^()]+)\)~', - $evalGroup, - $group, - limit: -1, - count: $count - ); - } while ($count > 0); - - return (bool) $evalGroup(['match' => $group]); - } - - private function evalGroup(): Closure - { - return function (array $group): ?int { - $result = null; - $operator = null; - $offset = 0; - - while (isset($group['match'][$offset])) { - $value = $group['match'][$offset++]; - - if ($this->isLogical($value)) { - $operator = $value; - } elseif ($this->isBoolean($value)) { - $result = $this->setResult($result, (int) $value, $operator); - } else { - throw new Exception\UnknownSymbolException(sprintf('Unexpected "%s"', $value)); - } - } - - return $result; - }; - } - - private function setResult(?int $result, int $value, ?string $operator): int - { - if (!isset($result)) { - $result = $value; - } elseif ($operator === self::LOGICAL_AND) { - $result &= $value; - } elseif ($operator === self::LOGICAL_OR) { - $result |= $value; - } - - return $result; - } + case LOGICAL_AND = '&'; + case LOGICAL_OR = '|'; - private function isLogical(string $value): bool + public static function isAnd(self $operator): bool { - return $value === self::LOGICAL_AND || $value === self::LOGICAL_OR; + return $operator === self::LOGICAL_AND; } - private function isBoolean(string $value): bool + public static function isOr(self $operator): bool { - return $value === self::BOOL_TRUE || $value === self::BOOL_FALSE; + return $operator === self::LOGICAL_OR; } } From e18401e190f93b97559e25b3f12e7837ef8f8a49 Mon Sep 17 00:00:00 2001 From: Nico Date: Thu, 17 Mar 2022 21:48:49 +0100 Subject: [PATCH 06/13] Use PHP 8.1 features --- .styleci.yml | 2 ++ src/TokenStream/TokenStream.php | 2 +- tests/unit/TokenStream/TokenStreamTest.php | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.styleci.yml b/.styleci.yml index eb60c1b..c94744a 100644 --- a/.styleci.yml +++ b/.styleci.yml @@ -8,3 +8,5 @@ finder: enabled: - short_array_syntax - cast_spaces +disabled: + - lowercase_constants diff --git a/src/TokenStream/TokenStream.php b/src/TokenStream/TokenStream.php index ac6e36d..6872822 100644 --- a/src/TokenStream/TokenStream.php +++ b/src/TokenStream/TokenStream.php @@ -103,7 +103,7 @@ private function registerMethods(): void private function registerFunctions(): void { - foreach ($this->tokenizer->grammar->getInternalFunctions() as $function) { + foreach ($this->tokenizer->grammar->getInternalFunctions() as $function) { $this->registerFunctionClass($function->name, $function->class); } } diff --git a/tests/unit/TokenStream/TokenStreamTest.php b/tests/unit/TokenStream/TokenStreamTest.php index 815c8de..2ce5dfe 100755 --- a/tests/unit/TokenStream/TokenStreamTest.php +++ b/tests/unit/TokenStream/TokenStreamTest.php @@ -105,7 +105,7 @@ public function givenAFunctionNameNotDefinedItShouldThrowAnException(): void private function createDummyTokenizer(): TokenizerInterface { - return new class ($this->createGrammarWithInternalFunctions()) extends TokenizerInterface { + return new class($this->createGrammarWithInternalFunctions()) extends TokenizerInterface { public function __construct( public readonly Grammar $grammar, ) { @@ -120,7 +120,7 @@ public function tokenize(string $string): Iterator private function createGrammarWithInternalFunctions(array $internalFunctions = []): Grammar { - return new class ($internalFunctions) extends Grammar { + return new class($internalFunctions) extends Grammar { public function __construct( private array $internalFunctions, ) { From 8fdde942160a30baf6c338b7be7b63edef7f374d Mon Sep 17 00:00:00 2001 From: Nico Date: Sun, 20 Mar 2022 23:09:00 +0100 Subject: [PATCH 07/13] Use PHP 8.1 features --- .scrutinizer.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index d9aa1b1..3511120 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -35,6 +35,7 @@ tools: enabled: true excluded_dirs: [tests] build: + image: default-bionic environment: php: 8.1.0 nodes: From 07c4d8beade2100d240b6e632fd1c44b7b7cc69b Mon Sep 17 00:00:00 2001 From: Nico Date: Sun, 20 Mar 2022 23:20:22 +0100 Subject: [PATCH 08/13] Use PHP 8.1 features --- src/Highlighter/Highlighter.php | 23 ++++++++++++++-------- src/Tokenizer/Tokenizer.php | 2 +- src/Tokenizer/TokenizerInterface.php | 2 +- tests/unit/TokenStream/TokenStreamTest.php | 2 +- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/Highlighter/Highlighter.php b/src/Highlighter/Highlighter.php index f5ddc4a..6e6d9fa 100644 --- a/src/Highlighter/Highlighter.php +++ b/src/Highlighter/Highlighter.php @@ -20,14 +20,7 @@ final class Highlighter public function __construct( private readonly TokenizerInterface $tokenizer, ) { - $this->styles = new SplObjectStorage(); - $this->styles[TokenType::COMMENT] = 'color: #948a8a; font-style: italic;'; - $this->styles[TokenType::LOGICAL] = 'color: #c72d2d;'; - $this->styles[TokenType::OPERATOR] = 'color: #000;'; - $this->styles[TokenType::PARENTHESIS] = 'color: #000;'; - $this->styles[TokenType::VALUE] = 'color: #e36700; font-style: italic;'; - $this->styles[TokenType::VARIABLE] = 'color: #007694; font-weight: 900;'; - $this->styles[TokenType::METHOD] = 'color: #000'; + $this->styles = $this->defaultStyles(); } public function setStyle(TokenType $group, string $style): void @@ -62,4 +55,18 @@ private function encode(BaseToken $token): string { return htmlentities($token->getOriginalValue(), ENT_QUOTES, 'utf-8'); } + + private function defaultStyles(): SplObjectStorage + { + $styles = new SplObjectStorage(); + $styles[TokenType::COMMENT] = 'color: #948a8a; font-style: italic;'; + $styles[TokenType::LOGICAL] = 'color: #c72d2d;'; + $styles[TokenType::OPERATOR] = 'color: #000;'; + $styles[TokenType::PARENTHESIS] = 'color: #000;'; + $styles[TokenType::VALUE] = 'color: #e36700; font-style: italic;'; + $styles[TokenType::VARIABLE] = 'color: #007694; font-weight: 900;'; + $styles[TokenType::METHOD] = 'color: #000'; + + return $styles; + } } diff --git a/src/Tokenizer/Tokenizer.php b/src/Tokenizer/Tokenizer.php index 2e8a90b..62723ae 100644 --- a/src/Tokenizer/Tokenizer.php +++ b/src/Tokenizer/Tokenizer.php @@ -16,7 +16,7 @@ final class Tokenizer extends TokenizerInterface { public function __construct( - public readonly Grammar $grammar, + public Grammar $grammar, private readonly TokenFactory $tokenFactory, ) { } diff --git a/src/Tokenizer/TokenizerInterface.php b/src/Tokenizer/TokenizerInterface.php index f3f9a65..409798c 100644 --- a/src/Tokenizer/TokenizerInterface.php +++ b/src/Tokenizer/TokenizerInterface.php @@ -13,7 +13,7 @@ abstract class TokenizerInterface { - public readonly Grammar $grammar; + public Grammar $grammar; /** * @param string $string diff --git a/tests/unit/TokenStream/TokenStreamTest.php b/tests/unit/TokenStream/TokenStreamTest.php index 2ce5dfe..5d98abd 100755 --- a/tests/unit/TokenStream/TokenStreamTest.php +++ b/tests/unit/TokenStream/TokenStreamTest.php @@ -107,7 +107,7 @@ private function createDummyTokenizer(): TokenizerInterface { return new class($this->createGrammarWithInternalFunctions()) extends TokenizerInterface { public function __construct( - public readonly Grammar $grammar, + public Grammar $grammar, ) { } From f90670c7a37a65c0d560d573c5435d5694a9ead2 Mon Sep 17 00:00:00 2001 From: Nico Oelgart Date: Thu, 2 Oct 2025 14:23:16 +0200 Subject: [PATCH 09/13] Change email --- src/Compiler/CompilerFactory.php | 2 +- src/Compiler/CompilerFactoryInterface.php | 2 +- src/Compiler/CompilerInterface.php | 2 +- src/Compiler/Exception/MissingOperatorException.php | 2 +- src/Compiler/StandardCompiler.php | 2 +- src/Evaluator/Boolean.php | 2 +- src/Evaluator/Evaluator.php | 2 +- src/Evaluator/EvaluatorInterface.php | 2 +- src/Evaluator/Exception/UnknownSymbolException.php | 2 +- src/Evaluator/Operator.php | 2 +- src/Expression/BaseExpression.php | 2 +- src/Expression/EqualExpression.php | 2 +- src/Expression/EqualStrictExpression.php | 2 +- src/Expression/ExpressionFactory.php | 2 +- src/Expression/ExpressionFactoryInterface.php | 2 +- src/Expression/GreaterThanEqualExpression.php | 2 +- src/Expression/GreaterThanExpression.php | 2 +- src/Expression/InExpression.php | 2 +- src/Expression/LessThanEqualExpression.php | 2 +- src/Expression/LessThanExpression.php | 2 +- src/Expression/NotEqualExpression.php | 2 +- src/Expression/NotEqualStrictExpression.php | 2 +- src/Expression/NotInExpression.php | 2 +- src/Grammar/CallableFunction.php | 2 +- src/Grammar/CallableUserFunctionInterface.php | 2 +- src/Grammar/Definition.php | 2 +- src/Grammar/Grammar.php | 2 +- src/Grammar/InternalFunction.php | 2 +- src/Grammar/InternalMethod.php | 2 +- src/Grammar/JavaScript/Functions/ParseFloat.php | 2 +- src/Grammar/JavaScript/Functions/ParseInt.php | 2 +- src/Grammar/JavaScript/JavaScript.php | 2 +- src/Grammar/JavaScript/Methods/CharAt.php | 2 +- src/Grammar/JavaScript/Methods/Concat.php | 2 +- src/Grammar/JavaScript/Methods/EndsWith.php | 2 +- src/Grammar/JavaScript/Methods/IndexOf.php | 2 +- src/Grammar/JavaScript/Methods/Join.php | 2 +- src/Grammar/JavaScript/Methods/Replace.php | 2 +- src/Grammar/JavaScript/Methods/Split.php | 2 +- src/Grammar/JavaScript/Methods/StartsWith.php | 2 +- src/Grammar/JavaScript/Methods/Substr.php | 2 +- src/Grammar/JavaScript/Methods/Test.php | 2 +- src/Grammar/JavaScript/Methods/ToLowerCase.php | 2 +- src/Grammar/JavaScript/Methods/ToUpperCase.php | 2 +- src/Highlighter/Highlighter.php | 2 +- src/Parser/EvaluatableExpression.php | 2 +- src/Parser/EvaluatableExpressionFactory.php | 2 +- src/Parser/Exception/ParserException.php | 2 +- src/Parser/Parser.php | 2 +- src/Rule.php | 2 +- src/TokenStream/CallableUserMethod.php | 2 +- src/TokenStream/CallableUserMethodFactory.php | 2 +- src/TokenStream/CallableUserMethodFactoryInterface.php | 2 +- src/TokenStream/Exception/ForbiddenMethodException.php | 2 +- src/TokenStream/Exception/UndefinedFunctionException.php | 2 +- src/TokenStream/Exception/UndefinedMethodException.php | 2 +- src/TokenStream/Exception/UndefinedVariableException.php | 2 +- src/TokenStream/Node/BaseNode.php | 2 +- src/TokenStream/Node/NodeArray.php | 2 +- src/TokenStream/Node/NodeFunction.php | 2 +- src/TokenStream/Node/NodeString.php | 2 +- src/TokenStream/Node/NodeVariable.php | 2 +- src/TokenStream/Token/BaseToken.php | 2 +- src/TokenStream/Token/Token.php | 2 +- src/TokenStream/Token/TokenAnd.php | 2 +- src/TokenStream/Token/TokenArray.php | 2 +- src/TokenStream/Token/TokenBool.php | 2 +- src/TokenStream/Token/TokenBoolFalse.php | 2 +- src/TokenStream/Token/TokenBoolTrue.php | 2 +- src/TokenStream/Token/TokenClosingArray.php | 2 +- src/TokenStream/Token/TokenClosingParenthesis.php | 2 +- src/TokenStream/Token/TokenComma.php | 2 +- src/TokenStream/Token/TokenComment.php | 2 +- src/TokenStream/Token/TokenEncapsedString.php | 2 +- src/TokenStream/Token/TokenEqual.php | 2 +- src/TokenStream/Token/TokenEqualStrict.php | 2 +- src/TokenStream/Token/TokenFactory.php | 2 +- src/TokenStream/Token/TokenFloat.php | 2 +- src/TokenStream/Token/TokenFunction.php | 2 +- src/TokenStream/Token/TokenGreater.php | 2 +- src/TokenStream/Token/TokenGreaterEqual.php | 2 +- src/TokenStream/Token/TokenIn.php | 2 +- src/TokenStream/Token/TokenInteger.php | 2 +- src/TokenStream/Token/TokenMethod.php | 2 +- src/TokenStream/Token/TokenNewline.php | 2 +- src/TokenStream/Token/TokenNotEqual.php | 2 +- src/TokenStream/Token/TokenNotEqualStrict.php | 2 +- src/TokenStream/Token/TokenNotIn.php | 2 +- src/TokenStream/Token/TokenNull.php | 2 +- src/TokenStream/Token/TokenObject.php | 2 +- src/TokenStream/Token/TokenOpeningArray.php | 2 +- src/TokenStream/Token/TokenOpeningParenthesis.php | 2 +- src/TokenStream/Token/TokenOr.php | 2 +- src/TokenStream/Token/TokenRegex.php | 2 +- src/TokenStream/Token/TokenSmaller.php | 2 +- src/TokenStream/Token/TokenSmallerEqual.php | 2 +- src/TokenStream/Token/TokenSpace.php | 2 +- src/TokenStream/Token/TokenString.php | 2 +- src/TokenStream/Token/TokenType.php | 2 +- src/TokenStream/Token/TokenUnknown.php | 2 +- src/TokenStream/Token/TokenVariable.php | 2 +- src/TokenStream/Token/Type/Logical.php | 2 +- src/TokenStream/Token/Type/Method.php | 2 +- src/TokenStream/Token/Type/Operator.php | 2 +- src/TokenStream/Token/Type/Parenthesis.php | 2 +- src/TokenStream/Token/Type/Value.php | 2 +- src/TokenStream/Token/Type/Whitespace.php | 2 +- src/TokenStream/TokenCollection.php | 2 +- src/TokenStream/TokenIterator.php | 2 +- src/TokenStream/TokenIteratorFactory.php | 2 +- src/TokenStream/TokenStream.php | 2 +- src/Tokenizer/Tokenizer.php | 2 +- src/Tokenizer/TokenizerInterface.php | 2 +- src/container.php | 2 +- tests/integration/AbstractTestBase.php | 2 +- tests/integration/HighlighterTest.php | 2 +- tests/integration/ObjectTest.php | 2 +- tests/integration/ParserTest.php | 2 +- tests/integration/RuleTest.php | 2 +- tests/integration/SyntaxErrorTest.php | 2 +- tests/integration/TokenizerTest.php | 2 +- tests/integration/arrays/ArraysTest.php | 2 +- tests/integration/functions/ParseFloatTest.php | 2 +- tests/integration/functions/ParseIntTest.php | 2 +- tests/integration/functions/SyntaxErrorTest.php | 2 +- tests/integration/methods/CharAtTest.php | 2 +- tests/integration/methods/CombinedTest.php | 2 +- tests/integration/methods/ConcatTest.php | 2 +- tests/integration/methods/EndsWithTest.php | 2 +- tests/integration/methods/IndexOfTest.php | 2 +- tests/integration/methods/JoinTest.php | 2 +- tests/integration/methods/ReplaceTest.php | 2 +- tests/integration/methods/SplitTest.php | 2 +- tests/integration/methods/StartsWithTest.php | 2 +- tests/integration/methods/SubstrTest.php | 2 +- tests/integration/methods/SyntaxErrorTest.php | 2 +- tests/integration/methods/TestTest.php | 2 +- tests/integration/methods/ToUpperCaseTest.php | 2 +- tests/integration/operators/OperatorsTest.php | 2 +- tests/integration/scalars/ScalarTest.php | 2 +- tests/unit/Evaluator/EvaluatorTest.php | 2 +- tests/unit/Expression/ExpressionFactoryTest.php | 2 +- tests/unit/Grammar/GrammarTest.php | 2 +- tests/unit/Parser/ParserTest.php | 2 +- tests/unit/Token/TokenFactoryTest.php | 2 +- tests/unit/TokenStream/CallableUserMethodTest.php | 2 +- tests/unit/TokenStream/TestFunc.php | 2 +- tests/unit/TokenStream/Token/BaseTokenTest.php | 2 +- tests/unit/TokenStream/TokenIteratorTest.php | 2 +- tests/unit/TokenStream/TokenStreamTest.php | 2 +- tests/unit/Tokenizer/TokenizerTest.php | 2 +- 151 files changed, 151 insertions(+), 151 deletions(-) diff --git a/src/Compiler/CompilerFactory.php b/src/Compiler/CompilerFactory.php index c4fea98..0be47bc 100644 --- a/src/Compiler/CompilerFactory.php +++ b/src/Compiler/CompilerFactory.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Compiler; diff --git a/src/Compiler/CompilerFactoryInterface.php b/src/Compiler/CompilerFactoryInterface.php index 1e42aec..69a2ed6 100644 --- a/src/Compiler/CompilerFactoryInterface.php +++ b/src/Compiler/CompilerFactoryInterface.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Compiler; diff --git a/src/Compiler/CompilerInterface.php b/src/Compiler/CompilerInterface.php index f60cb76..832cce6 100644 --- a/src/Compiler/CompilerInterface.php +++ b/src/Compiler/CompilerInterface.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Compiler; diff --git a/src/Compiler/Exception/MissingOperatorException.php b/src/Compiler/Exception/MissingOperatorException.php index ba6d049..e551ffd 100644 --- a/src/Compiler/Exception/MissingOperatorException.php +++ b/src/Compiler/Exception/MissingOperatorException.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Compiler\Exception; diff --git a/src/Compiler/StandardCompiler.php b/src/Compiler/StandardCompiler.php index 2202296..4717c99 100644 --- a/src/Compiler/StandardCompiler.php +++ b/src/Compiler/StandardCompiler.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Compiler; diff --git a/src/Evaluator/Boolean.php b/src/Evaluator/Boolean.php index 26db253..529ee71 100644 --- a/src/Evaluator/Boolean.php +++ b/src/Evaluator/Boolean.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Evaluator; diff --git a/src/Evaluator/Evaluator.php b/src/Evaluator/Evaluator.php index badcac1..e9672ec 100644 --- a/src/Evaluator/Evaluator.php +++ b/src/Evaluator/Evaluator.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Evaluator; diff --git a/src/Evaluator/EvaluatorInterface.php b/src/Evaluator/EvaluatorInterface.php index fc04b08..dee7ecd 100644 --- a/src/Evaluator/EvaluatorInterface.php +++ b/src/Evaluator/EvaluatorInterface.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Evaluator; diff --git a/src/Evaluator/Exception/UnknownSymbolException.php b/src/Evaluator/Exception/UnknownSymbolException.php index 05b3659..85ddec5 100644 --- a/src/Evaluator/Exception/UnknownSymbolException.php +++ b/src/Evaluator/Exception/UnknownSymbolException.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Evaluator\Exception; diff --git a/src/Evaluator/Operator.php b/src/Evaluator/Operator.php index e500242..651fa30 100644 --- a/src/Evaluator/Operator.php +++ b/src/Evaluator/Operator.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Evaluator; diff --git a/src/Expression/BaseExpression.php b/src/Expression/BaseExpression.php index 74a269d..5cff5a4 100644 --- a/src/Expression/BaseExpression.php +++ b/src/Expression/BaseExpression.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Expression; diff --git a/src/Expression/EqualExpression.php b/src/Expression/EqualExpression.php index dbf7a84..89b2eb6 100644 --- a/src/Expression/EqualExpression.php +++ b/src/Expression/EqualExpression.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Expression; diff --git a/src/Expression/EqualStrictExpression.php b/src/Expression/EqualStrictExpression.php index a8f39e6..de98cbe 100644 --- a/src/Expression/EqualStrictExpression.php +++ b/src/Expression/EqualStrictExpression.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Expression; diff --git a/src/Expression/ExpressionFactory.php b/src/Expression/ExpressionFactory.php index e474bd9..a311a9c 100644 --- a/src/Expression/ExpressionFactory.php +++ b/src/Expression/ExpressionFactory.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Expression; diff --git a/src/Expression/ExpressionFactoryInterface.php b/src/Expression/ExpressionFactoryInterface.php index 1750cc4..bf9ad24 100644 --- a/src/Expression/ExpressionFactoryInterface.php +++ b/src/Expression/ExpressionFactoryInterface.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Expression; diff --git a/src/Expression/GreaterThanEqualExpression.php b/src/Expression/GreaterThanEqualExpression.php index 3bffd26..5f413d9 100644 --- a/src/Expression/GreaterThanEqualExpression.php +++ b/src/Expression/GreaterThanEqualExpression.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Expression; diff --git a/src/Expression/GreaterThanExpression.php b/src/Expression/GreaterThanExpression.php index 4814872..d9dedb5 100644 --- a/src/Expression/GreaterThanExpression.php +++ b/src/Expression/GreaterThanExpression.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Expression; diff --git a/src/Expression/InExpression.php b/src/Expression/InExpression.php index 61ab5e2..837e7ce 100644 --- a/src/Expression/InExpression.php +++ b/src/Expression/InExpression.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Expression; diff --git a/src/Expression/LessThanEqualExpression.php b/src/Expression/LessThanEqualExpression.php index f76bbc9..5ca7959 100644 --- a/src/Expression/LessThanEqualExpression.php +++ b/src/Expression/LessThanEqualExpression.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Expression; diff --git a/src/Expression/LessThanExpression.php b/src/Expression/LessThanExpression.php index 8618aa7..89d9f5f 100644 --- a/src/Expression/LessThanExpression.php +++ b/src/Expression/LessThanExpression.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Expression; diff --git a/src/Expression/NotEqualExpression.php b/src/Expression/NotEqualExpression.php index 4c4b3c4..fba4703 100644 --- a/src/Expression/NotEqualExpression.php +++ b/src/Expression/NotEqualExpression.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Expression; diff --git a/src/Expression/NotEqualStrictExpression.php b/src/Expression/NotEqualStrictExpression.php index f839e7e..162f973 100644 --- a/src/Expression/NotEqualStrictExpression.php +++ b/src/Expression/NotEqualStrictExpression.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Expression; diff --git a/src/Expression/NotInExpression.php b/src/Expression/NotInExpression.php index 58e8f5e..518ba9d 100644 --- a/src/Expression/NotInExpression.php +++ b/src/Expression/NotInExpression.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Expression; diff --git a/src/Grammar/CallableFunction.php b/src/Grammar/CallableFunction.php index 6396edc..4694ab8 100644 --- a/src/Grammar/CallableFunction.php +++ b/src/Grammar/CallableFunction.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar; diff --git a/src/Grammar/CallableUserFunctionInterface.php b/src/Grammar/CallableUserFunctionInterface.php index e3f1bd3..55ef2a4 100644 --- a/src/Grammar/CallableUserFunctionInterface.php +++ b/src/Grammar/CallableUserFunctionInterface.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar; diff --git a/src/Grammar/Definition.php b/src/Grammar/Definition.php index e2c3157..3e8202a 100644 --- a/src/Grammar/Definition.php +++ b/src/Grammar/Definition.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar; diff --git a/src/Grammar/Grammar.php b/src/Grammar/Grammar.php index 12822a8..1ce1820 100644 --- a/src/Grammar/Grammar.php +++ b/src/Grammar/Grammar.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar; diff --git a/src/Grammar/InternalFunction.php b/src/Grammar/InternalFunction.php index fcfc6a9..5733dee 100644 --- a/src/Grammar/InternalFunction.php +++ b/src/Grammar/InternalFunction.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MITz< * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar; diff --git a/src/Grammar/InternalMethod.php b/src/Grammar/InternalMethod.php index 052a0d7..c3ef06d 100644 --- a/src/Grammar/InternalMethod.php +++ b/src/Grammar/InternalMethod.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MITz< * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar; diff --git a/src/Grammar/JavaScript/Functions/ParseFloat.php b/src/Grammar/JavaScript/Functions/ParseFloat.php index c9238bc..e627879 100644 --- a/src/Grammar/JavaScript/Functions/ParseFloat.php +++ b/src/Grammar/JavaScript/Functions/ParseFloat.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript\Functions; diff --git a/src/Grammar/JavaScript/Functions/ParseInt.php b/src/Grammar/JavaScript/Functions/ParseInt.php index 08edf11..b693162 100644 --- a/src/Grammar/JavaScript/Functions/ParseInt.php +++ b/src/Grammar/JavaScript/Functions/ParseInt.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript\Functions; diff --git a/src/Grammar/JavaScript/JavaScript.php b/src/Grammar/JavaScript/JavaScript.php index 10370f7..84e84aa 100644 --- a/src/Grammar/JavaScript/JavaScript.php +++ b/src/Grammar/JavaScript/JavaScript.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript; diff --git a/src/Grammar/JavaScript/Methods/CharAt.php b/src/Grammar/JavaScript/Methods/CharAt.php index 0bd9f98..ee0063b 100644 --- a/src/Grammar/JavaScript/Methods/CharAt.php +++ b/src/Grammar/JavaScript/Methods/CharAt.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript\Methods; diff --git a/src/Grammar/JavaScript/Methods/Concat.php b/src/Grammar/JavaScript/Methods/Concat.php index d009a17..5d9678f 100644 --- a/src/Grammar/JavaScript/Methods/Concat.php +++ b/src/Grammar/JavaScript/Methods/Concat.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript\Methods; diff --git a/src/Grammar/JavaScript/Methods/EndsWith.php b/src/Grammar/JavaScript/Methods/EndsWith.php index ed22fd1..eddab8f 100644 --- a/src/Grammar/JavaScript/Methods/EndsWith.php +++ b/src/Grammar/JavaScript/Methods/EndsWith.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript\Methods; diff --git a/src/Grammar/JavaScript/Methods/IndexOf.php b/src/Grammar/JavaScript/Methods/IndexOf.php index d70366b..695e20d 100644 --- a/src/Grammar/JavaScript/Methods/IndexOf.php +++ b/src/Grammar/JavaScript/Methods/IndexOf.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript\Methods; diff --git a/src/Grammar/JavaScript/Methods/Join.php b/src/Grammar/JavaScript/Methods/Join.php index 0ce5f33..348c9ad 100644 --- a/src/Grammar/JavaScript/Methods/Join.php +++ b/src/Grammar/JavaScript/Methods/Join.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript\Methods; diff --git a/src/Grammar/JavaScript/Methods/Replace.php b/src/Grammar/JavaScript/Methods/Replace.php index ca6b683..209aea5 100644 --- a/src/Grammar/JavaScript/Methods/Replace.php +++ b/src/Grammar/JavaScript/Methods/Replace.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript\Methods; diff --git a/src/Grammar/JavaScript/Methods/Split.php b/src/Grammar/JavaScript/Methods/Split.php index 279e70e..c255049 100644 --- a/src/Grammar/JavaScript/Methods/Split.php +++ b/src/Grammar/JavaScript/Methods/Split.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript\Methods; diff --git a/src/Grammar/JavaScript/Methods/StartsWith.php b/src/Grammar/JavaScript/Methods/StartsWith.php index 980d7e2..de47339 100644 --- a/src/Grammar/JavaScript/Methods/StartsWith.php +++ b/src/Grammar/JavaScript/Methods/StartsWith.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript\Methods; diff --git a/src/Grammar/JavaScript/Methods/Substr.php b/src/Grammar/JavaScript/Methods/Substr.php index 5902cca..f544da0 100644 --- a/src/Grammar/JavaScript/Methods/Substr.php +++ b/src/Grammar/JavaScript/Methods/Substr.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript\Methods; diff --git a/src/Grammar/JavaScript/Methods/Test.php b/src/Grammar/JavaScript/Methods/Test.php index df7bcc6..82ff838 100644 --- a/src/Grammar/JavaScript/Methods/Test.php +++ b/src/Grammar/JavaScript/Methods/Test.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript\Methods; diff --git a/src/Grammar/JavaScript/Methods/ToLowerCase.php b/src/Grammar/JavaScript/Methods/ToLowerCase.php index 14b259e..8b61f71 100644 --- a/src/Grammar/JavaScript/Methods/ToLowerCase.php +++ b/src/Grammar/JavaScript/Methods/ToLowerCase.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript\Methods; diff --git a/src/Grammar/JavaScript/Methods/ToUpperCase.php b/src/Grammar/JavaScript/Methods/ToUpperCase.php index dd3eea9..fba4b76 100644 --- a/src/Grammar/JavaScript/Methods/ToUpperCase.php +++ b/src/Grammar/JavaScript/Methods/ToUpperCase.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Grammar\JavaScript\Methods; diff --git a/src/Highlighter/Highlighter.php b/src/Highlighter/Highlighter.php index 6e6d9fa..ae3f5bc 100644 --- a/src/Highlighter/Highlighter.php +++ b/src/Highlighter/Highlighter.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Highlighter; diff --git a/src/Parser/EvaluatableExpression.php b/src/Parser/EvaluatableExpression.php index c40fdab..7adb362 100644 --- a/src/Parser/EvaluatableExpression.php +++ b/src/Parser/EvaluatableExpression.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Parser; diff --git a/src/Parser/EvaluatableExpressionFactory.php b/src/Parser/EvaluatableExpressionFactory.php index de42ba1..9aa8458 100644 --- a/src/Parser/EvaluatableExpressionFactory.php +++ b/src/Parser/EvaluatableExpressionFactory.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Parser; diff --git a/src/Parser/Exception/ParserException.php b/src/Parser/Exception/ParserException.php index c50bbe1..f70e37a 100644 --- a/src/Parser/Exception/ParserException.php +++ b/src/Parser/Exception/ParserException.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Parser\Exception; diff --git a/src/Parser/Parser.php b/src/Parser/Parser.php index b1537e4..250c05b 100644 --- a/src/Parser/Parser.php +++ b/src/Parser/Parser.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Parser; diff --git a/src/Rule.php b/src/Rule.php index 8482a2f..3d3b8e0 100644 --- a/src/Rule.php +++ b/src/Rule.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule; diff --git a/src/TokenStream/CallableUserMethod.php b/src/TokenStream/CallableUserMethod.php index 0f1803f..a59d5ff 100644 --- a/src/TokenStream/CallableUserMethod.php +++ b/src/TokenStream/CallableUserMethod.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream; diff --git a/src/TokenStream/CallableUserMethodFactory.php b/src/TokenStream/CallableUserMethodFactory.php index 067c773..3a18863 100644 --- a/src/TokenStream/CallableUserMethodFactory.php +++ b/src/TokenStream/CallableUserMethodFactory.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream; diff --git a/src/TokenStream/CallableUserMethodFactoryInterface.php b/src/TokenStream/CallableUserMethodFactoryInterface.php index e3fc352..efb85de 100644 --- a/src/TokenStream/CallableUserMethodFactoryInterface.php +++ b/src/TokenStream/CallableUserMethodFactoryInterface.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream; diff --git a/src/TokenStream/Exception/ForbiddenMethodException.php b/src/TokenStream/Exception/ForbiddenMethodException.php index 8742ed5..315930e 100644 --- a/src/TokenStream/Exception/ForbiddenMethodException.php +++ b/src/TokenStream/Exception/ForbiddenMethodException.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Exception; diff --git a/src/TokenStream/Exception/UndefinedFunctionException.php b/src/TokenStream/Exception/UndefinedFunctionException.php index 5f9c317..a4115d7 100644 --- a/src/TokenStream/Exception/UndefinedFunctionException.php +++ b/src/TokenStream/Exception/UndefinedFunctionException.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Exception; diff --git a/src/TokenStream/Exception/UndefinedMethodException.php b/src/TokenStream/Exception/UndefinedMethodException.php index 5a99291..4f27202 100644 --- a/src/TokenStream/Exception/UndefinedMethodException.php +++ b/src/TokenStream/Exception/UndefinedMethodException.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Exception; diff --git a/src/TokenStream/Exception/UndefinedVariableException.php b/src/TokenStream/Exception/UndefinedVariableException.php index 41c07dc..adefc6c 100644 --- a/src/TokenStream/Exception/UndefinedVariableException.php +++ b/src/TokenStream/Exception/UndefinedVariableException.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Exception; diff --git a/src/TokenStream/Node/BaseNode.php b/src/TokenStream/Node/BaseNode.php index 9b4e56e..4724f3e 100644 --- a/src/TokenStream/Node/BaseNode.php +++ b/src/TokenStream/Node/BaseNode.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Node; diff --git a/src/TokenStream/Node/NodeArray.php b/src/TokenStream/Node/NodeArray.php index 02d598e..bb419a9 100644 --- a/src/TokenStream/Node/NodeArray.php +++ b/src/TokenStream/Node/NodeArray.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Node; diff --git a/src/TokenStream/Node/NodeFunction.php b/src/TokenStream/Node/NodeFunction.php index 1d2bbe8..8eba994 100644 --- a/src/TokenStream/Node/NodeFunction.php +++ b/src/TokenStream/Node/NodeFunction.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Node; diff --git a/src/TokenStream/Node/NodeString.php b/src/TokenStream/Node/NodeString.php index 62b6758..9cf630c 100644 --- a/src/TokenStream/Node/NodeString.php +++ b/src/TokenStream/Node/NodeString.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Node; diff --git a/src/TokenStream/Node/NodeVariable.php b/src/TokenStream/Node/NodeVariable.php index 5e23341..7b9600a 100644 --- a/src/TokenStream/Node/NodeVariable.php +++ b/src/TokenStream/Node/NodeVariable.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Node; diff --git a/src/TokenStream/Token/BaseToken.php b/src/TokenStream/Token/BaseToken.php index 2ced4fd..f7c2491 100644 --- a/src/TokenStream/Token/BaseToken.php +++ b/src/TokenStream/Token/BaseToken.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/Token.php b/src/TokenStream/Token/Token.php index 2f1bb3f..95dbb2b 100644 --- a/src/TokenStream/Token/Token.php +++ b/src/TokenStream/Token/Token.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenAnd.php b/src/TokenStream/Token/TokenAnd.php index 1f0e2e2..8930c80 100644 --- a/src/TokenStream/Token/TokenAnd.php +++ b/src/TokenStream/Token/TokenAnd.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenArray.php b/src/TokenStream/Token/TokenArray.php index 4687123..e85fe5f 100644 --- a/src/TokenStream/Token/TokenArray.php +++ b/src/TokenStream/Token/TokenArray.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenBool.php b/src/TokenStream/Token/TokenBool.php index 49fba5d..cb84ed6 100644 --- a/src/TokenStream/Token/TokenBool.php +++ b/src/TokenStream/Token/TokenBool.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenBoolFalse.php b/src/TokenStream/Token/TokenBoolFalse.php index 7451660..3c3ccc4 100644 --- a/src/TokenStream/Token/TokenBoolFalse.php +++ b/src/TokenStream/Token/TokenBoolFalse.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenBoolTrue.php b/src/TokenStream/Token/TokenBoolTrue.php index d6f9965..e6cbf38 100644 --- a/src/TokenStream/Token/TokenBoolTrue.php +++ b/src/TokenStream/Token/TokenBoolTrue.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenClosingArray.php b/src/TokenStream/Token/TokenClosingArray.php index 2f209d1..ff0d105 100644 --- a/src/TokenStream/Token/TokenClosingArray.php +++ b/src/TokenStream/Token/TokenClosingArray.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenClosingParenthesis.php b/src/TokenStream/Token/TokenClosingParenthesis.php index 7b378a6..9ee93f4 100644 --- a/src/TokenStream/Token/TokenClosingParenthesis.php +++ b/src/TokenStream/Token/TokenClosingParenthesis.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenComma.php b/src/TokenStream/Token/TokenComma.php index 3732e9c..fc1ce81 100644 --- a/src/TokenStream/Token/TokenComma.php +++ b/src/TokenStream/Token/TokenComma.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenComment.php b/src/TokenStream/Token/TokenComment.php index 5b8426d..1866e56 100644 --- a/src/TokenStream/Token/TokenComment.php +++ b/src/TokenStream/Token/TokenComment.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenEncapsedString.php b/src/TokenStream/Token/TokenEncapsedString.php index 738858c..962072d 100644 --- a/src/TokenStream/Token/TokenEncapsedString.php +++ b/src/TokenStream/Token/TokenEncapsedString.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenEqual.php b/src/TokenStream/Token/TokenEqual.php index 0fca76a..712da78 100644 --- a/src/TokenStream/Token/TokenEqual.php +++ b/src/TokenStream/Token/TokenEqual.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenEqualStrict.php b/src/TokenStream/Token/TokenEqualStrict.php index b58feb8..5f6c687 100644 --- a/src/TokenStream/Token/TokenEqualStrict.php +++ b/src/TokenStream/Token/TokenEqualStrict.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenFactory.php b/src/TokenStream/Token/TokenFactory.php index 780d95f..187e5f9 100644 --- a/src/TokenStream/Token/TokenFactory.php +++ b/src/TokenStream/Token/TokenFactory.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenFloat.php b/src/TokenStream/Token/TokenFloat.php index d50e26a..eba6bd0 100644 --- a/src/TokenStream/Token/TokenFloat.php +++ b/src/TokenStream/Token/TokenFloat.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenFunction.php b/src/TokenStream/Token/TokenFunction.php index 518285c..7d27e80 100644 --- a/src/TokenStream/Token/TokenFunction.php +++ b/src/TokenStream/Token/TokenFunction.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenGreater.php b/src/TokenStream/Token/TokenGreater.php index 2fcae4a..07920bb 100644 --- a/src/TokenStream/Token/TokenGreater.php +++ b/src/TokenStream/Token/TokenGreater.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenGreaterEqual.php b/src/TokenStream/Token/TokenGreaterEqual.php index c70262f..4e01558 100644 --- a/src/TokenStream/Token/TokenGreaterEqual.php +++ b/src/TokenStream/Token/TokenGreaterEqual.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenIn.php b/src/TokenStream/Token/TokenIn.php index 692521e..43a2f34 100644 --- a/src/TokenStream/Token/TokenIn.php +++ b/src/TokenStream/Token/TokenIn.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenInteger.php b/src/TokenStream/Token/TokenInteger.php index 1f2b90e..3f1f281 100644 --- a/src/TokenStream/Token/TokenInteger.php +++ b/src/TokenStream/Token/TokenInteger.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenMethod.php b/src/TokenStream/Token/TokenMethod.php index e01b971..945fe27 100644 --- a/src/TokenStream/Token/TokenMethod.php +++ b/src/TokenStream/Token/TokenMethod.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenNewline.php b/src/TokenStream/Token/TokenNewline.php index f6a6471..71db1ed 100644 --- a/src/TokenStream/Token/TokenNewline.php +++ b/src/TokenStream/Token/TokenNewline.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenNotEqual.php b/src/TokenStream/Token/TokenNotEqual.php index 48d2922..2ec6f8e 100644 --- a/src/TokenStream/Token/TokenNotEqual.php +++ b/src/TokenStream/Token/TokenNotEqual.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenNotEqualStrict.php b/src/TokenStream/Token/TokenNotEqualStrict.php index fd6da30..1949e7c 100644 --- a/src/TokenStream/Token/TokenNotEqualStrict.php +++ b/src/TokenStream/Token/TokenNotEqualStrict.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenNotIn.php b/src/TokenStream/Token/TokenNotIn.php index a54d8b4..813abef 100644 --- a/src/TokenStream/Token/TokenNotIn.php +++ b/src/TokenStream/Token/TokenNotIn.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenNull.php b/src/TokenStream/Token/TokenNull.php index d475b81..b8f4dba 100644 --- a/src/TokenStream/Token/TokenNull.php +++ b/src/TokenStream/Token/TokenNull.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenObject.php b/src/TokenStream/Token/TokenObject.php index adb58cd..619c72c 100644 --- a/src/TokenStream/Token/TokenObject.php +++ b/src/TokenStream/Token/TokenObject.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenOpeningArray.php b/src/TokenStream/Token/TokenOpeningArray.php index e6ba45b..991b2a7 100644 --- a/src/TokenStream/Token/TokenOpeningArray.php +++ b/src/TokenStream/Token/TokenOpeningArray.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenOpeningParenthesis.php b/src/TokenStream/Token/TokenOpeningParenthesis.php index cb2efae..f180b46 100644 --- a/src/TokenStream/Token/TokenOpeningParenthesis.php +++ b/src/TokenStream/Token/TokenOpeningParenthesis.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenOr.php b/src/TokenStream/Token/TokenOr.php index 499d305..8d2c446 100644 --- a/src/TokenStream/Token/TokenOr.php +++ b/src/TokenStream/Token/TokenOr.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenRegex.php b/src/TokenStream/Token/TokenRegex.php index 9e1de40..c8e2f7c 100644 --- a/src/TokenStream/Token/TokenRegex.php +++ b/src/TokenStream/Token/TokenRegex.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenSmaller.php b/src/TokenStream/Token/TokenSmaller.php index 5084fe4..9be3dee 100644 --- a/src/TokenStream/Token/TokenSmaller.php +++ b/src/TokenStream/Token/TokenSmaller.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenSmallerEqual.php b/src/TokenStream/Token/TokenSmallerEqual.php index a728ecf..cf79a31 100644 --- a/src/TokenStream/Token/TokenSmallerEqual.php +++ b/src/TokenStream/Token/TokenSmallerEqual.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenSpace.php b/src/TokenStream/Token/TokenSpace.php index 30f2afd..6e2279c 100644 --- a/src/TokenStream/Token/TokenSpace.php +++ b/src/TokenStream/Token/TokenSpace.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenString.php b/src/TokenStream/Token/TokenString.php index a02dfe6..cc0459f 100644 --- a/src/TokenStream/Token/TokenString.php +++ b/src/TokenStream/Token/TokenString.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenType.php b/src/TokenStream/Token/TokenType.php index 0f966ab..3f58cf5 100644 --- a/src/TokenStream/Token/TokenType.php +++ b/src/TokenStream/Token/TokenType.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenUnknown.php b/src/TokenStream/Token/TokenUnknown.php index fec4686..367ad21 100644 --- a/src/TokenStream/Token/TokenUnknown.php +++ b/src/TokenStream/Token/TokenUnknown.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/TokenVariable.php b/src/TokenStream/Token/TokenVariable.php index 46db1ba..f390a38 100644 --- a/src/TokenStream/Token/TokenVariable.php +++ b/src/TokenStream/Token/TokenVariable.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token; diff --git a/src/TokenStream/Token/Type/Logical.php b/src/TokenStream/Token/Type/Logical.php index 6cad197..aa49492 100644 --- a/src/TokenStream/Token/Type/Logical.php +++ b/src/TokenStream/Token/Type/Logical.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token\Type; diff --git a/src/TokenStream/Token/Type/Method.php b/src/TokenStream/Token/Type/Method.php index 32dd908..dabe45a 100644 --- a/src/TokenStream/Token/Type/Method.php +++ b/src/TokenStream/Token/Type/Method.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token\Type; diff --git a/src/TokenStream/Token/Type/Operator.php b/src/TokenStream/Token/Type/Operator.php index 27dbc59..ca1667f 100644 --- a/src/TokenStream/Token/Type/Operator.php +++ b/src/TokenStream/Token/Type/Operator.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token\Type; diff --git a/src/TokenStream/Token/Type/Parenthesis.php b/src/TokenStream/Token/Type/Parenthesis.php index 50c6102..865a064 100644 --- a/src/TokenStream/Token/Type/Parenthesis.php +++ b/src/TokenStream/Token/Type/Parenthesis.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token\Type; diff --git a/src/TokenStream/Token/Type/Value.php b/src/TokenStream/Token/Type/Value.php index 525f77f..54d7888 100644 --- a/src/TokenStream/Token/Type/Value.php +++ b/src/TokenStream/Token/Type/Value.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token\Type; diff --git a/src/TokenStream/Token/Type/Whitespace.php b/src/TokenStream/Token/Type/Whitespace.php index 0391066..64bb32a 100644 --- a/src/TokenStream/Token/Type/Whitespace.php +++ b/src/TokenStream/Token/Type/Whitespace.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream\Token\Type; diff --git a/src/TokenStream/TokenCollection.php b/src/TokenStream/TokenCollection.php index 4fe6d56..1ba867e 100644 --- a/src/TokenStream/TokenCollection.php +++ b/src/TokenStream/TokenCollection.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream; diff --git a/src/TokenStream/TokenIterator.php b/src/TokenStream/TokenIterator.php index 05750ef..3260efc 100644 --- a/src/TokenStream/TokenIterator.php +++ b/src/TokenStream/TokenIterator.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream; diff --git a/src/TokenStream/TokenIteratorFactory.php b/src/TokenStream/TokenIteratorFactory.php index 9f1cf2e..18c6dc8 100644 --- a/src/TokenStream/TokenIteratorFactory.php +++ b/src/TokenStream/TokenIteratorFactory.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream; diff --git a/src/TokenStream/TokenStream.php b/src/TokenStream/TokenStream.php index 6872822..d00dcca 100644 --- a/src/TokenStream/TokenStream.php +++ b/src/TokenStream/TokenStream.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\TokenStream; diff --git a/src/Tokenizer/Tokenizer.php b/src/Tokenizer/Tokenizer.php index 62723ae..414726d 100644 --- a/src/Tokenizer/Tokenizer.php +++ b/src/Tokenizer/Tokenizer.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Tokenizer; diff --git a/src/Tokenizer/TokenizerInterface.php b/src/Tokenizer/TokenizerInterface.php index 409798c..c53f5da 100644 --- a/src/Tokenizer/TokenizerInterface.php +++ b/src/Tokenizer/TokenizerInterface.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\Tokenizer; diff --git a/src/container.php b/src/container.php index aa273ef..7bf78c7 100644 --- a/src/container.php +++ b/src/container.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule; diff --git a/tests/integration/AbstractTestBase.php b/tests/integration/AbstractTestBase.php index 30d07a7..74cc63c 100755 --- a/tests/integration/AbstractTestBase.php +++ b/tests/integration/AbstractTestBase.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration; diff --git a/tests/integration/HighlighterTest.php b/tests/integration/HighlighterTest.php index 4c03b01..97f6fea 100755 --- a/tests/integration/HighlighterTest.php +++ b/tests/integration/HighlighterTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration; diff --git a/tests/integration/ObjectTest.php b/tests/integration/ObjectTest.php index f4c7cb1..9aa586c 100755 --- a/tests/integration/ObjectTest.php +++ b/tests/integration/ObjectTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration; diff --git a/tests/integration/ParserTest.php b/tests/integration/ParserTest.php index 609678e..1df0a91 100755 --- a/tests/integration/ParserTest.php +++ b/tests/integration/ParserTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration; diff --git a/tests/integration/RuleTest.php b/tests/integration/RuleTest.php index 29f741d..2efa404 100755 --- a/tests/integration/RuleTest.php +++ b/tests/integration/RuleTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration; diff --git a/tests/integration/SyntaxErrorTest.php b/tests/integration/SyntaxErrorTest.php index 62b8572..de71b82 100755 --- a/tests/integration/SyntaxErrorTest.php +++ b/tests/integration/SyntaxErrorTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration; diff --git a/tests/integration/TokenizerTest.php b/tests/integration/TokenizerTest.php index 69c5e74..62c8cd4 100755 --- a/tests/integration/TokenizerTest.php +++ b/tests/integration/TokenizerTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration; diff --git a/tests/integration/arrays/ArraysTest.php b/tests/integration/arrays/ArraysTest.php index 4409d10..93a1565 100755 --- a/tests/integration/arrays/ArraysTest.php +++ b/tests/integration/arrays/ArraysTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\arrays; diff --git a/tests/integration/functions/ParseFloatTest.php b/tests/integration/functions/ParseFloatTest.php index eae6c70..b247db1 100755 --- a/tests/integration/functions/ParseFloatTest.php +++ b/tests/integration/functions/ParseFloatTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\functions; diff --git a/tests/integration/functions/ParseIntTest.php b/tests/integration/functions/ParseIntTest.php index 0c47cf4..0c5e03b 100755 --- a/tests/integration/functions/ParseIntTest.php +++ b/tests/integration/functions/ParseIntTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\functions; diff --git a/tests/integration/functions/SyntaxErrorTest.php b/tests/integration/functions/SyntaxErrorTest.php index 95fb7c0..c46b017 100755 --- a/tests/integration/functions/SyntaxErrorTest.php +++ b/tests/integration/functions/SyntaxErrorTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\functions; diff --git a/tests/integration/methods/CharAtTest.php b/tests/integration/methods/CharAtTest.php index 95e6a69..f4447db 100755 --- a/tests/integration/methods/CharAtTest.php +++ b/tests/integration/methods/CharAtTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\methods; diff --git a/tests/integration/methods/CombinedTest.php b/tests/integration/methods/CombinedTest.php index f7aadd0..22a5a82 100755 --- a/tests/integration/methods/CombinedTest.php +++ b/tests/integration/methods/CombinedTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\methods; diff --git a/tests/integration/methods/ConcatTest.php b/tests/integration/methods/ConcatTest.php index 1e0c4ac..32f9bb7 100755 --- a/tests/integration/methods/ConcatTest.php +++ b/tests/integration/methods/ConcatTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\methods; diff --git a/tests/integration/methods/EndsWithTest.php b/tests/integration/methods/EndsWithTest.php index 1e98b21..b51f8b7 100755 --- a/tests/integration/methods/EndsWithTest.php +++ b/tests/integration/methods/EndsWithTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\methods; diff --git a/tests/integration/methods/IndexOfTest.php b/tests/integration/methods/IndexOfTest.php index 37ffe85..62fe1f9 100755 --- a/tests/integration/methods/IndexOfTest.php +++ b/tests/integration/methods/IndexOfTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\methods; diff --git a/tests/integration/methods/JoinTest.php b/tests/integration/methods/JoinTest.php index 8363ccb..f1a559f 100755 --- a/tests/integration/methods/JoinTest.php +++ b/tests/integration/methods/JoinTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\methods; diff --git a/tests/integration/methods/ReplaceTest.php b/tests/integration/methods/ReplaceTest.php index cbe1ee0..32ecec8 100755 --- a/tests/integration/methods/ReplaceTest.php +++ b/tests/integration/methods/ReplaceTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\methods; diff --git a/tests/integration/methods/SplitTest.php b/tests/integration/methods/SplitTest.php index c3bf4cd..b4f0f83 100755 --- a/tests/integration/methods/SplitTest.php +++ b/tests/integration/methods/SplitTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\methods; diff --git a/tests/integration/methods/StartsWithTest.php b/tests/integration/methods/StartsWithTest.php index 793eb52..abc1887 100755 --- a/tests/integration/methods/StartsWithTest.php +++ b/tests/integration/methods/StartsWithTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\methods; diff --git a/tests/integration/methods/SubstrTest.php b/tests/integration/methods/SubstrTest.php index 053dc6d..8d86614 100755 --- a/tests/integration/methods/SubstrTest.php +++ b/tests/integration/methods/SubstrTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\methods; diff --git a/tests/integration/methods/SyntaxErrorTest.php b/tests/integration/methods/SyntaxErrorTest.php index 31b3da9..571709c 100755 --- a/tests/integration/methods/SyntaxErrorTest.php +++ b/tests/integration/methods/SyntaxErrorTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\methods; diff --git a/tests/integration/methods/TestTest.php b/tests/integration/methods/TestTest.php index dd905c2..29c314f 100755 --- a/tests/integration/methods/TestTest.php +++ b/tests/integration/methods/TestTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\methods; diff --git a/tests/integration/methods/ToUpperCaseTest.php b/tests/integration/methods/ToUpperCaseTest.php index f17cf2c..365b1d3 100755 --- a/tests/integration/methods/ToUpperCaseTest.php +++ b/tests/integration/methods/ToUpperCaseTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\methods; diff --git a/tests/integration/operators/OperatorsTest.php b/tests/integration/operators/OperatorsTest.php index 226bc2a..cc235a3 100755 --- a/tests/integration/operators/OperatorsTest.php +++ b/tests/integration/operators/OperatorsTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\operators; diff --git a/tests/integration/scalars/ScalarTest.php b/tests/integration/scalars/ScalarTest.php index 8efad67..785eae6 100755 --- a/tests/integration/scalars/ScalarTest.php +++ b/tests/integration/scalars/ScalarTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\integration\scalars; diff --git a/tests/unit/Evaluator/EvaluatorTest.php b/tests/unit/Evaluator/EvaluatorTest.php index 8ce9d36..b4e1640 100755 --- a/tests/unit/Evaluator/EvaluatorTest.php +++ b/tests/unit/Evaluator/EvaluatorTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\unit\Evaluator; diff --git a/tests/unit/Expression/ExpressionFactoryTest.php b/tests/unit/Expression/ExpressionFactoryTest.php index 98758c8..74f4aeb 100755 --- a/tests/unit/Expression/ExpressionFactoryTest.php +++ b/tests/unit/Expression/ExpressionFactoryTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\unit\Expression; diff --git a/tests/unit/Grammar/GrammarTest.php b/tests/unit/Grammar/GrammarTest.php index cabd738..08fbda4 100755 --- a/tests/unit/Grammar/GrammarTest.php +++ b/tests/unit/Grammar/GrammarTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\unit\Grammar; diff --git a/tests/unit/Parser/ParserTest.php b/tests/unit/Parser/ParserTest.php index 956d8bf..8787404 100755 --- a/tests/unit/Parser/ParserTest.php +++ b/tests/unit/Parser/ParserTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\unit\Parser; diff --git a/tests/unit/Token/TokenFactoryTest.php b/tests/unit/Token/TokenFactoryTest.php index d67ea17..c7c747c 100755 --- a/tests/unit/Token/TokenFactoryTest.php +++ b/tests/unit/Token/TokenFactoryTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\unit\Token; diff --git a/tests/unit/TokenStream/CallableUserMethodTest.php b/tests/unit/TokenStream/CallableUserMethodTest.php index fe18bdd..7093f8e 100755 --- a/tests/unit/TokenStream/CallableUserMethodTest.php +++ b/tests/unit/TokenStream/CallableUserMethodTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\unit\TokenStream; diff --git a/tests/unit/TokenStream/TestFunc.php b/tests/unit/TokenStream/TestFunc.php index 966ab13..925e891 100755 --- a/tests/unit/TokenStream/TestFunc.php +++ b/tests/unit/TokenStream/TestFunc.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\unit\TokenStream; diff --git a/tests/unit/TokenStream/Token/BaseTokenTest.php b/tests/unit/TokenStream/Token/BaseTokenTest.php index d1753d4..90132f0 100755 --- a/tests/unit/TokenStream/Token/BaseTokenTest.php +++ b/tests/unit/TokenStream/Token/BaseTokenTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\unit\TokenStream\Token; diff --git a/tests/unit/TokenStream/TokenIteratorTest.php b/tests/unit/TokenStream/TokenIteratorTest.php index 8871126..5820cd9 100755 --- a/tests/unit/TokenStream/TokenIteratorTest.php +++ b/tests/unit/TokenStream/TokenIteratorTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\unit\TokenStream; diff --git a/tests/unit/TokenStream/TokenStreamTest.php b/tests/unit/TokenStream/TokenStreamTest.php index 5d98abd..b7259b5 100755 --- a/tests/unit/TokenStream/TokenStreamTest.php +++ b/tests/unit/TokenStream/TokenStreamTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\unit\TokenStream; diff --git a/tests/unit/Tokenizer/TokenizerTest.php b/tests/unit/Tokenizer/TokenizerTest.php index c0565f1..b90d6eb 100755 --- a/tests/unit/Tokenizer/TokenizerTest.php +++ b/tests/unit/Tokenizer/TokenizerTest.php @@ -3,7 +3,7 @@ /** * @license http://opensource.org/licenses/mit-license.php MIT * @link https://github.com/nicoSWD - * @author Nicolas Oelgart + * @author Nicolas Oelgart */ namespace nicoSWD\Rule\tests\unit\Tokenizer; From 535692ec4b22faa1f3b9eae11f2037d09efd035d Mon Sep 17 00:00:00 2001 From: Nico Oelgart Date: Thu, 2 Oct 2025 14:37:54 +0200 Subject: [PATCH 10/13] Update PHPUnit and fix tests --- .github/workflows/phpqa.yml | 6 ++--- .scrutinizer.yml | 2 +- .styleci.yml | 2 +- .travis.yml | 2 +- README.md | 6 ++--- composer.json | 8 +++--- tests/integration/HighlighterTest.php | 3 ++- tests/integration/ObjectTest.php | 15 ++++++----- tests/integration/ParserTest.php | 16 ++++++----- tests/integration/RuleTest.php | 11 ++++---- tests/integration/SyntaxErrorTest.php | 27 ++++++++++--------- tests/integration/TokenizerTest.php | 5 ++-- tests/integration/arrays/ArraysTest.php | 19 ++++++------- .../integration/functions/ParseFloatTest.php | 11 ++++---- tests/integration/functions/ParseIntTest.php | 11 ++++---- .../integration/functions/SyntaxErrorTest.php | 5 ++-- tests/integration/methods/CharAtTest.php | 9 ++++--- tests/integration/methods/CombinedTest.php | 7 ++--- tests/integration/methods/ConcatTest.php | 5 ++-- tests/integration/methods/EndsWithTest.php | 9 ++++--- tests/integration/methods/IndexOfTest.php | 7 ++--- tests/integration/methods/JoinTest.php | 13 ++++----- tests/integration/methods/ReplaceTest.php | 11 ++++---- tests/integration/methods/SplitTest.php | 17 ++++++------ tests/integration/methods/StartsWithTest.php | 7 ++--- tests/integration/methods/SubstrTest.php | 9 ++++--- tests/integration/methods/SyntaxErrorTest.php | 19 ++++++------- tests/integration/methods/TestTest.php | 13 ++++----- tests/integration/methods/ToUpperCaseTest.php | 9 ++++--- tests/integration/operators/OperatorsTest.php | 15 ++++++----- tests/integration/scalars/ScalarTest.php | 9 ++++--- tests/unit/Evaluator/EvaluatorTest.php | 9 ++++--- .../unit/Expression/ExpressionFactoryTest.php | 10 +++---- tests/unit/Parser/ParserTest.php | 3 ++- tests/unit/Token/TokenFactoryTest.php | 7 ++--- .../TokenStream/CallableUserMethodTest.php | 9 ++++--- .../unit/TokenStream/Token/BaseTokenTest.php | 11 ++++---- tests/unit/TokenStream/TokenIteratorTest.php | 17 ++++++------ tests/unit/TokenStream/TokenStreamTest.php | 7 ++--- tests/unit/Tokenizer/TokenizerTest.php | 5 ++-- 40 files changed, 209 insertions(+), 177 deletions(-) diff --git a/.github/workflows/phpqa.yml b/.github/workflows/phpqa.yml index d626ce2..f28a069 100644 --- a/.github/workflows/phpqa.yml +++ b/.github/workflows/phpqa.yml @@ -8,14 +8,14 @@ jobs: steps: - uses: actions/checkout@master - name: PHPStan - uses: docker://jakzal/phpqa:php8.1 + uses: docker://jakzal/phpqa:php8.4 with: args: phpstan analyze src/ -l 1 - name: PHP-CS-Fixer - uses: docker://jakzal/phpqa:php8.1 + uses: docker://jakzal/phpqa:php8.4 with: args: php-cs-fixer --dry-run --allow-risky=yes --no-interaction --ansi fix - name: Deptrac - uses: docker://jakzal/phpqa:php8.1 + uses: docker://jakzal/phpqa:php8.4 with: args: deptrac --no-interaction --ansi --formatter-graphviz-display=0 diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 3511120..64e37a8 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -37,7 +37,7 @@ tools: build: image: default-bionic environment: - php: 8.1.0 + php: 8.4.0 nodes: analysis: tests: diff --git a/.styleci.yml b/.styleci.yml index c94744a..93c2ae9 100644 --- a/.styleci.yml +++ b/.styleci.yml @@ -1,7 +1,7 @@ --- preset: psr2 risky: true -version: 8.1 +version: 8.4 finder: name: - "*.php" diff --git a/.travis.yml b/.travis.yml index cf159f4..5161ca6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: php php: - - 8.1 + - 8.4 script: - composer install --dev diff --git a/README.md b/README.md index 00aca1d..ad7afe6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ ## PHP Rule Engine - [![Latest Stable Version](https://travis-ci.org/nicoSWD/php-rule-parser.svg?branch=master)](https://travis-ci.org/nicoSWD/php-rule-parser) [![Build status][Master coverage image]][Master coverage] [![Code Quality][Master quality image]][Master quality] @@ -13,7 +12,6 @@ You're looking at a standalone PHP library to parse and evaluate text based rule This library has initially been used to change and configure the behavior of certain "Workflows" (without changing actual code) in an intranet application, but it may serve a purpose elsewhere. - Find me on Twitter: @[nicoSWD](https://twitter.com/nicoSWD) (If you're using PHP 5, you might want to take a look at [version 0.4.0](https://github.com/nicoSWD/php-rule-parser/tree/0.4.0)) @@ -39,7 +37,7 @@ This library works best with one of these bundles below, but they're not require Test if a value is in a given array ```php $variables = [ - 'coupon_code' => $_POST['coupon_code'], + 'coupon_code' => (string) $_POST['coupon_code'], ]; $rule = new Rule('coupon_code in ["summer_discount", "summer21"]', $variables); @@ -49,7 +47,7 @@ var_dump($rule->isTrue()); // bool(true) Performing a regular expression ```php $variables = [ - 'coupon_code' => $_POST['coupon_code'], + 'coupon_code' => (string) $_POST['coupon_code'], ]; $rule = new Rule('coupon_code.test(/^summer20[0-9]{2}$/) == true', $variables); diff --git a/composer.json b/composer.json index 8ce7073..bbcab55 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ { "name": "Nicolas Oelgart", "role": "Developer", - "homepage": "https://nicoswd.com" + "homepage": "https://nico.es" } ], "autoload": { @@ -33,11 +33,11 @@ } }, "require": { - "php": ">=8.1" + "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^9.5", - "mockery/mockery": "^1.4" + "phpunit/phpunit": "^12.3", + "mockery/mockery": "^1.6" }, "scripts": { "test": "vendor/bin/phpunit" diff --git a/tests/integration/HighlighterTest.php b/tests/integration/HighlighterTest.php index 97f6fea..c996899 100755 --- a/tests/integration/HighlighterTest.php +++ b/tests/integration/HighlighterTest.php @@ -13,6 +13,7 @@ use nicoSWD\Rule\Tokenizer\Tokenizer; use nicoSWD\Rule\TokenStream\Token\TokenFactory; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\Test; final class HighlighterTest extends TestCase { @@ -23,7 +24,7 @@ protected function setUp(): void $this->highlighter = new Highlighter(new Tokenizer(new JavaScript(), new TokenFactory())); } - /** @test */ + #[Test] public function givenAStyleForATokenGroupItShouldBeUsed(): void { $this->highlighter->setStyle( diff --git a/tests/integration/ObjectTest.php b/tests/integration/ObjectTest.php index 9aa586c..0fef937 100755 --- a/tests/integration/ObjectTest.php +++ b/tests/integration/ObjectTest.php @@ -9,10 +9,11 @@ use nicoSWD\Rule\Parser\Exception\ParserException; use nicoSWD\Rule\Rule; +use PHPUnit\Framework\Attributes\Test; final class ObjectTest extends AbstractTestBase { - /** @test */ + #[Test] public function givenAnObjectHasMethodsWhenPublicTheyShouldBeAccessible(): void { $myObj = new class { @@ -40,7 +41,7 @@ public function cat() $this->assertTrue($this->evaluate('my_obj.test2().cat() === "meow"', $variables)); } - /** @test */ + #[Test] public function givenAnObjectHasPropertiesWhenPublicTheyShouldBeAccessible(): void { $myObj = new class { @@ -54,7 +55,7 @@ public function givenAnObjectHasPropertiesWhenPublicTheyShouldBeAccessible(): vo $this->assertTrue($this->evaluate('my_obj.test() === "my string"', $variables)); } - /** @test */ + #[Test] public function publicMethodsShouldBeAccessibleMagicallyViaGet(): void { $myObj = new class { @@ -71,7 +72,7 @@ public function getString() $this->assertTrue($this->evaluate('my_obj.string() === "some string"', $variables)); } - /** @test */ + #[Test] public function publicMethodsShouldBeAccessibleMagicallyViaIs(): void { $myObj = new class { @@ -93,7 +94,7 @@ public function yes() $this->assertTrue($this->evaluate('my_obj.string(my_obj.yes()) === "yes"', $variables)); } - /** @test */ + #[Test] public function givenAnObjectWhenMagicMethodCallIsAvailableItShouldBeAccessible(): void { $myObj = new class { @@ -129,7 +130,7 @@ public function givenAnObjectWhenMagicMethodsAreCalledDirectlyItShouldThrowAnExc $this->evaluate("my_obj.{$magicMethod}()", $variables); } - /** @test */ + #[Test] public function undefinedMethodsShouldThrowAnError(): void { $myObj = new class() { @@ -145,7 +146,7 @@ public function undefinedMethodsShouldThrowAnError(): void $this->assertSame('Undefined method "nope" at position 6', $rule->getError()); } - /** @test */ + #[Test] public function givenAnObjectWithMagicMethodGetWhenPropertyDoesNotExistItShouldNotBeCalled(): void { $myObj = new class { diff --git a/tests/integration/ParserTest.php b/tests/integration/ParserTest.php index 1df0a91..f6eca61 100755 --- a/tests/integration/ParserTest.php +++ b/tests/integration/ParserTest.php @@ -7,9 +7,11 @@ */ namespace nicoSWD\Rule\tests\integration; +use PHPUnit\Framework\Attributes\Test; + final class ParserTest extends AbstractTestBase { - /** @test */ + #[Test] public function multipleAnds(): void { $rule = 'foo=="MA" && bar=="EGP" && baz>50000'; @@ -37,7 +39,7 @@ public function multipleAnds(): void ])); } - /** @test */ + #[Test] public function mixedOrsAndAnds(): void { $rule = ' @@ -53,14 +55,14 @@ public function mixedOrsAndAnds(): void ])); } - /** @test */ + #[Test] public function emptyOrIncompleteRuleReturnsFalse(): void { $rule = ''; $this->assertFalse($this->evaluate($rule)); } - /** @test */ + #[Test] public function freakingLongRule(): void { $rule = ' @@ -87,7 +89,7 @@ public function freakingLongRule(): void ])); } - /** @test */ + #[Test] public function negativeComparison(): void { $rule = ' @@ -107,7 +109,7 @@ public function negativeComparison(): void ])); } - /** @test */ + #[Test] public function spacesBetweenStuff(): void { $rule = 'foo != 3 @@ -120,7 +122,7 @@ public function spacesBetweenStuff(): void $this->assertTrue($this->evaluate($rule, ['foo' => '-1'])); } - /** @test */ + #[Test] public function singleLineCommentDoesNotKillTheRest(): void { $rule = ' 2 > 3 diff --git a/tests/integration/RuleTest.php b/tests/integration/RuleTest.php index 2efa404..156d1ba 100755 --- a/tests/integration/RuleTest.php +++ b/tests/integration/RuleTest.php @@ -9,10 +9,11 @@ use nicoSWD\Rule; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\Test; final class RuleTest extends TestCase { - /** @test */ + #[Test] public function basicRuleWithCommentsEvaluatesCorrectly(): void { $string = ' @@ -39,7 +40,7 @@ public function basicRuleWithCommentsEvaluatesCorrectly(): void $this->assertTrue(!$rule->isFalse()); } - /** @test */ + #[Test] public function isValidReturnsFalseOnInvalidSyntax(): void { $ruleStr = '(2 == 2) && (1 < 3 && 3 > 2 (1 == 1))'; @@ -50,7 +51,7 @@ public function isValidReturnsFalseOnInvalidSyntax(): void $this->assertSame('Unexpected "(" at position 28', $rule->getError()); } - /** @test */ + #[Test] public function isValidReturnsTrueOnValidSyntax(): void { $ruleStr = '(2 == 2) && (1 < 3 && 3 > 2 || (1 == 1))'; @@ -61,7 +62,7 @@ public function isValidReturnsTrueOnValidSyntax(): void $this->assertEmpty($rule->getError()); $this->assertTrue($rule->isTrue()); } - /** @test */ + #[Test] public function basicInRule(): void { $ruleStr = '4 in [4, 6, 7]'; @@ -81,7 +82,7 @@ public function basicInRule(): void $this->assertFalse($rule->isTrue()); } - /** @test */ + #[Test] public function basicNotInRule(): void { $ruleStr = '5 not diff --git a/tests/integration/SyntaxErrorTest.php b/tests/integration/SyntaxErrorTest.php index de71b82..f4fae9f 100755 --- a/tests/integration/SyntaxErrorTest.php +++ b/tests/integration/SyntaxErrorTest.php @@ -8,13 +8,14 @@ namespace nicoSWD\Rule\tests\integration; use nicoSWD\Rule\Rule; +use PHPUnit\Framework\Attributes\Test; /** * @SuppressWarnings(PHPMD.TooManyMethods) */ final class SyntaxErrorTest extends AbstractTestBase { - /** @test */ + #[Test] public function emptyParenthesisThrowException(): void { $rule = new Rule('(totalamount != 3) ()', [ @@ -25,7 +26,7 @@ public function emptyParenthesisThrowException(): void $this->assertSame('Unexpected "(" at position 19', $rule->getError()); } - /** @test */ + #[Test] public function doubleOperatorThrowsException(): void { $rule = new Rule('country == == "venezuela"', ['country' => 'spain']); @@ -34,7 +35,7 @@ public function doubleOperatorThrowsException(): void $this->assertSame('Unexpected "==" at position 11', $rule->getError()); } - /** @test */ + #[Test] public function missingLeftValueThrowsException(): void { $rule = new Rule('== "venezuela"'); @@ -43,7 +44,7 @@ public function missingLeftValueThrowsException(): void $this->assertSame('Incomplete expression for token "=="', $rule->getError()); } - /** @test */ + #[Test] public function missingOperatorThrowsException(): void { $rule = new Rule('total == -1 total > 10', ['total' => 12]); @@ -52,7 +53,7 @@ public function missingOperatorThrowsException(): void $this->assertSame('Missing operator', $rule->getError()); } - /** @test */ + #[Test] public function missingOpeningParenthesisThrowsException(): void { $rule = new Rule('1 == 1)'); @@ -61,7 +62,7 @@ public function missingOpeningParenthesisThrowsException(): void $this->assertSame('Missing opening parenthesis', $rule->getError()); } - /** @test */ + #[Test] public function missingClosingParenthesisThrowsException(): void { $rule = new Rule('(1 == 1'); @@ -70,7 +71,7 @@ public function missingClosingParenthesisThrowsException(): void $this->assertSame('Missing closing parenthesis', $rule->getError()); } - /** @test */ + #[Test] public function misplacedMinusThrowsException(): void { $rule = new Rule('1 == 1 && -foo == 1', ['foo' => 1]); @@ -79,7 +80,7 @@ public function misplacedMinusThrowsException(): void $this->assertSame('Unknown token "-" at position 10', $rule->getError()); } - /** @test */ + #[Test] public function undefinedVariableThrowsException(): void { $rule = new Rule(' // new line on purpose @@ -89,7 +90,7 @@ public function undefinedVariableThrowsException(): void $this->assertSame('Undefined variable "foo" at position 36', $rule->getError()); } - /** @test */ + #[Test] public function incompleteExpressionExceptionIsThrownCorrectly(): void { $rule = new Rule('1 == 1 && country', ['country' => 'es']); @@ -98,7 +99,7 @@ public function incompleteExpressionExceptionIsThrownCorrectly(): void $this->assertSame('Incomplete condition', $rule->getError()); } - /** @test */ + #[Test] public function rulesEvaluatesTrueThrowsExceptionsForUndefinedVars(): void { $rule = new Rule('nonono=="MA"'); @@ -107,7 +108,7 @@ public function rulesEvaluatesTrueThrowsExceptionsForUndefinedVars(): void $this->assertSame('Undefined variable "nonono" at position 0', $rule->getError()); } - /** @test */ + #[Test] public function rulesEvaluatesTrueThrowsExceptionsOnSyntaxErrors(): void { $rule = new Rule('country == "MA" &&', ['country' => 'es']); @@ -116,7 +117,7 @@ public function rulesEvaluatesTrueThrowsExceptionsOnSyntaxErrors(): void $this->assertSame('Incomplete condition', $rule->getError()); } - /** @test */ + #[Test] public function multipleLogicalTokensThrowException(): void { $rule = new Rule('country == "MA" && &&', ['country' => 'es']); @@ -125,7 +126,7 @@ public function multipleLogicalTokensThrowException(): void $this->assertSame('Unexpected "&&" at position 19', $rule->getError()); } - /** @test */ + #[Test] public function unknownTokenExceptionIsThrown(): void { $rule = new Rule('country == "MA" ^', ['country' => 'es']); diff --git a/tests/integration/TokenizerTest.php b/tests/integration/TokenizerTest.php index 62c8cd4..0643342 100755 --- a/tests/integration/TokenizerTest.php +++ b/tests/integration/TokenizerTest.php @@ -12,6 +12,7 @@ use nicoSWD\Rule\TokenStream\Token\Token; use nicoSWD\Rule\TokenStream\Token\TokenFactory; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\Test; use ReflectionMethod; final class TokenizerTest extends TestCase @@ -23,7 +24,7 @@ protected function setUp(): void $this->tokenizer = new Tokenizer(new JavaScript(), new TokenFactory()); } - /** @test */ + #[Test] public function getMatchedTokenReturnsFalseOnFailure(): void { $reflection = new ReflectionMethod($this->tokenizer, 'getMatchedToken'); @@ -32,7 +33,7 @@ public function getMatchedTokenReturnsFalseOnFailure(): void $this->assertSame(Token::UNKNOWN, $result); } - /** @test */ + #[Test] public function tokenPositionAndLineAreCorrect(): void { $tokens = $this->tokenizer->tokenize('1'); diff --git a/tests/integration/arrays/ArraysTest.php b/tests/integration/arrays/ArraysTest.php index 93a1565..e7c8a23 100755 --- a/tests/integration/arrays/ArraysTest.php +++ b/tests/integration/arrays/ArraysTest.php @@ -9,10 +9,11 @@ use nicoSWD\Rule\Rule; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class ArraysTest extends AbstractTestBase { - /** @test */ + #[Test] public function arraysEqualUserSuppliedArrays(): void { $this->assertTrue($this->evaluate( @@ -26,20 +27,20 @@ public function arraysEqualUserSuppliedArrays(): void ])); } - /** @test */ + #[Test] public function emptyArrayDoesParseCorrectly(): void { $this->assertTrue($this->evaluate('[] === []')); } - /** @test */ + #[Test] public function literalArrayComparison(): void { $this->assertTrue($this->evaluate('[123, 12] === [123, 12]')); $this->assertFalse($this->evaluate('[123, 12] === [123, 12, 1]')); } - /** @test */ + #[Test] public function commentsAreIgnoredInArray(): void { $this->assertTrue($this->evaluate( @@ -51,7 +52,7 @@ public function commentsAreIgnoredInArray(): void )); } - /** @test */ + #[Test] public function trailingCommaThrowsException(): void { $rule = new Rule('["foo", "bar", ] === ["foo", "bar"]'); @@ -60,7 +61,7 @@ public function trailingCommaThrowsException(): void $this->assertSame('Unexpected "," at position 15', $rule->getError()); } - /** @test */ + #[Test] public function lineIsReportedCorrectlyOnSyntaxError2(): void { $rule = new Rule('["foo", "bar", ,] === ["foo", "bar"]'); @@ -69,7 +70,7 @@ public function lineIsReportedCorrectlyOnSyntaxError2(): void $this->assertSame('Unexpected "," at position 15', $rule->getError()); } - /** @test */ + #[Test] public function missingCommaThrowsException(): void { $rule = new Rule('["foo" "bar"] === ["foo", "bar"]'); @@ -78,7 +79,7 @@ public function missingCommaThrowsException(): void $this->assertSame('Unexpected "bar" at position 8', $rule->getError()); } - /** @test */ + #[Test] public function unexpectedTokenThrowsException(): void { $rule = new Rule('["foo", ===] === ["foo", "bar"]'); @@ -87,7 +88,7 @@ public function unexpectedTokenThrowsException(): void $this->assertSame('Unexpected "===" at position 8', $rule->getError()); } - /** @test */ + #[Test] public function unexpectedEndOfStringThrowsException(): void { $rule = new Rule('["foo", "bar"'); diff --git a/tests/integration/functions/ParseFloatTest.php b/tests/integration/functions/ParseFloatTest.php index b247db1..4a9c396 100755 --- a/tests/integration/functions/ParseFloatTest.php +++ b/tests/integration/functions/ParseFloatTest.php @@ -8,35 +8,36 @@ namespace nicoSWD\Rule\tests\integration\functions; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class ParseFloatTest extends AbstractTestBase { - /** @test */ + #[Test] public function onStringLiteral(): void { $this->assertTrue($this->evaluate('parseFloat("3.1337") === 3.1337')); } - /** @test */ + #[Test] public function onStringLiteralWithSpaces(): void { $this->assertTrue($this->evaluate('parseFloat(" 3.1 ") === 3.1')); } - /** @test */ + #[Test] public function onStringLiteralWithNonNumericChars(): void { $this->assertTrue($this->evaluate('parseFloat("3.12aaa") === 3.12')); } - /** @test */ + #[Test] public function onUserDefinedVariable(): void { $this->assertTrue($this->evaluate('parseFloat(foo) === 3.4', ['foo' => '3.4'])); $this->assertFalse($this->evaluate('parseFloat(foo) === "3.5"', ['foo' => 3.5])); } - /** @test */ + #[Test] public function callWithoutArgsShouldReturnNaN(): void { $this->assertFalse($this->evaluate('parseFloat() === 1')); diff --git a/tests/integration/functions/ParseIntTest.php b/tests/integration/functions/ParseIntTest.php index 0c5e03b..9833ddb 100755 --- a/tests/integration/functions/ParseIntTest.php +++ b/tests/integration/functions/ParseIntTest.php @@ -8,35 +8,36 @@ namespace nicoSWD\Rule\tests\integration\functions; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class ParseIntTest extends AbstractTestBase { - /** @test */ + #[Test] public function onStringLiteral(): void { $this->assertTrue($this->evaluate('parseInt("3") === 3')); } - /** @test */ + #[Test] public function onStringLiteralWithSpaces(): void { $this->assertTrue($this->evaluate('parseInt(" 3 ") === 3')); } - /** @test */ + #[Test] public function onStringLiteralWithNonNumericChars(): void { $this->assertTrue($this->evaluate('parseInt("3aaa") === 3')); } - /** @test */ + #[Test] public function onUserDefinedVariable(): void { $this->assertTrue($this->evaluate('parseInt(foo) === 3', ['foo' => '3'])); $this->assertFalse($this->evaluate('parseInt(foo) === "3"', ['foo' => 3])); } - /** @test */ + #[Test] public function callWithoutArgsShouldReturnNan(): void { $this->assertFalse($this->evaluate('parseInt() === 1')); diff --git a/tests/integration/functions/SyntaxErrorTest.php b/tests/integration/functions/SyntaxErrorTest.php index c46b017..6649b15 100755 --- a/tests/integration/functions/SyntaxErrorTest.php +++ b/tests/integration/functions/SyntaxErrorTest.php @@ -9,10 +9,11 @@ use nicoSWD\Rule\Rule; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class SyntaxErrorTest extends AbstractTestBase { - /** @test */ + #[Test] public function undefinedFunctionThrowsException(): void { $rule = new Rule('nope() === true'); @@ -21,7 +22,7 @@ public function undefinedFunctionThrowsException(): void $this->assertSame('nope is not defined at position 0', $rule->getError()); } - /** @test */ + #[Test] public function incorrectSpellingThrowsException(): void { $rule = new Rule('/* fail */ paRSeInt("2") === 2'); diff --git a/tests/integration/methods/CharAtTest.php b/tests/integration/methods/CharAtTest.php index f4447db..e8b3738 100755 --- a/tests/integration/methods/CharAtTest.php +++ b/tests/integration/methods/CharAtTest.php @@ -8,31 +8,32 @@ namespace nicoSWD\Rule\tests\integration\methods; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class CharAtTest extends AbstractTestBase { - /** @test */ + #[Test] public function ifOmittedPositionFallsBackToZero(): void { $this->assertTrue($this->evaluate('foo.charAt() === "b"', ['foo' => 'bar'])); $this->assertTrue($this->evaluate('"bar".charAt() === "b"')); } - /** @test */ + #[Test] public function callWithValidPosition(): void { $this->assertTrue($this->evaluate('foo.charAt(1) === "a"', ['foo' => 'bar'])); $this->assertTrue($this->evaluate('"bar".charAt(2) === "r"')); } - /** @test */ + #[Test] public function invalidOffsetReturnsEmptyString(): void { $this->assertTrue($this->evaluate('foo.charAt(99) === ""', ['foo' => 'bar'])); $this->assertTrue($this->evaluate('"foo".charAt(99) === ""')); } - /** @test */ + #[Test] public function ifBooleansAndNullAreCastedToOneAndZero(): void { $this->assertTrue($this->evaluate('"foo".charAt(true) === "o"')); diff --git a/tests/integration/methods/CombinedTest.php b/tests/integration/methods/CombinedTest.php index 22a5a82..9ecafec 100755 --- a/tests/integration/methods/CombinedTest.php +++ b/tests/integration/methods/CombinedTest.php @@ -8,10 +8,11 @@ namespace nicoSWD\Rule\tests\integration\methods; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class CombinedTest extends AbstractTestBase { - /** @test */ + #[Test] public function mixedMethodCalls(): void { $this->assertTrue($this->evaluate( @@ -41,7 +42,7 @@ public function mixedMethodCalls(): void )); } - /** @test */ + #[Test] public function chainedMethodCalls(): void { $this->assertTrue($this->evaluate( @@ -69,7 +70,7 @@ public function chainedMethodCalls(): void )); } - /** @test */ + #[Test] public function functionCallInsideMethod(): void { $this->assertTrue($this->evaluate('"abc".substr(parseInt(" 2 ")) === "c"')); diff --git a/tests/integration/methods/ConcatTest.php b/tests/integration/methods/ConcatTest.php index 32f9bb7..028520b 100755 --- a/tests/integration/methods/ConcatTest.php +++ b/tests/integration/methods/ConcatTest.php @@ -8,10 +8,11 @@ namespace nicoSWD\Rule\tests\integration\methods; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class ConcatTest extends AbstractTestBase { - /** @test */ + #[Test] public function allParametersAreConcatenated(): void { $this->assertTrue($this->evaluate('foo.concat("bar", "baz") === "foobarbaz"', ['foo' => 'foo'])); @@ -20,7 +21,7 @@ public function allParametersAreConcatenated(): void $this->assertTrue($this->evaluate('"foo".concat("bar", 1) === "foobar1"')); } - /** @test */ + #[Test] public function arraysAreImplodedByCommaBeforeConcatenating(): void { $this->assertTrue($this->evaluate('"foo".concat("bar", [1, 2]) === "foobar1,2"')); diff --git a/tests/integration/methods/EndsWithTest.php b/tests/integration/methods/EndsWithTest.php index b51f8b7..48075de 100755 --- a/tests/integration/methods/EndsWithTest.php +++ b/tests/integration/methods/EndsWithTest.php @@ -9,29 +9,30 @@ use nicoSWD\Rule\Parser\Exception\ParserException; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class EndsWithTest extends AbstractTestBase { - /** @test */ + #[Test] public function givenAStringWhenEndsWithNeedleItShouldReturnTrue(): void { $this->assertTrue($this->evaluate('foo.endsWith("llo") === true', ['foo' => 'hello'])); $this->assertTrue($this->evaluate('"hello".endsWith("llo") === true')); } - /** @test */ + #[Test] public function givenAStringWhenNotEndsWithNeedleItShouldReturnFalse(): void { $this->assertTrue($this->evaluate('"hello".endsWith("ell") === false')); } - /** @test */ + #[Test] public function givenAStringWhenTestedWithEndsWithWithoutArgsItShouldReturnFalse(): void { $this->assertTrue($this->evaluate('"hello".endsWith() === false')); } - /** @test */ + #[Test] public function givenAStringWhenTestedOnNonStringValuesItShouldThrowAnException(): void { $this->expectException(ParserException::class); diff --git a/tests/integration/methods/IndexOfTest.php b/tests/integration/methods/IndexOfTest.php index 62fe1f9..cad5e12 100755 --- a/tests/integration/methods/IndexOfTest.php +++ b/tests/integration/methods/IndexOfTest.php @@ -8,23 +8,24 @@ namespace nicoSWD\Rule\tests\integration\methods; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class IndexOfTest extends AbstractTestBase { - /** @test */ + #[Test] public function validNeedleReturnsCorrectPosition(): void { $this->assertTrue($this->evaluate('foo.indexOf("a") === 1', ['foo' => 'bar'])); $this->assertTrue($this->evaluate('"bar".indexOf("b") === 0')); } - /** @test */ + #[Test] public function omittedParameterReturnsNegativeOne(): void { $this->assertTrue($this->evaluate('"bar".indexOf() === -1')); } - /** @test */ + #[Test] public function negativeOneIsReturnedIfNeedleNotFound(): void { $this->assertTrue($this->evaluate('"bar".indexOf("foo") === -1')); diff --git a/tests/integration/methods/JoinTest.php b/tests/integration/methods/JoinTest.php index f1a559f..898b9e2 100755 --- a/tests/integration/methods/JoinTest.php +++ b/tests/integration/methods/JoinTest.php @@ -8,24 +8,25 @@ namespace nicoSWD\Rule\tests\integration\methods; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class JoinTest extends AbstractTestBase { protected array $array = ['foo' => ['foo', 'bar']]; - /** @test */ + #[Test] public function ifOmittedDelimiterFallsBackToDefault(): void { $this->assertTrue($this->evaluate('foo.join() === "foo,bar"', $this->array)); } - /** @test */ + #[Test] public function literalStringDelimiter(): void { $this->assertTrue($this->evaluate('foo.join("|") === "foo|bar"', $this->array)); } - /** @test */ + #[Test] public function variableValueAsDelimiter(): void { $this->assertTrue($this->evaluate( @@ -34,20 +35,20 @@ public function variableValueAsDelimiter(): void )); } - /** @test */ + #[Test] public function callOnStringLiteralArray(): void { $this->assertTrue($this->evaluate('[1, 2, 3].join("|") === "1|2|3"')); $this->assertTrue($this->evaluate('[1, 2, 3] . join("|") === "1|2|3"')); } - /** @test */ + #[Test] public function variableInArrayIsJoined(): void { $this->assertTrue($this->evaluate('[1, 2, foo].join("|") === "1|2|3"', ['foo' => 3])); } - /** @test */ + #[Test] public function joinOnEmptyArray(): void { $this->assertTrue($this->evaluate('[].join("|") === ""')); diff --git a/tests/integration/methods/ReplaceTest.php b/tests/integration/methods/ReplaceTest.php index 32ecec8..6720618 100755 --- a/tests/integration/methods/ReplaceTest.php +++ b/tests/integration/methods/ReplaceTest.php @@ -8,35 +8,36 @@ namespace nicoSWD\Rule\tests\integration\methods; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class ReplaceTest extends AbstractTestBase { - /** @test */ + #[Test] public function validNeedleReturnsCorrectPosition(): void { $this->assertTrue($this->evaluate('foo.replace("a", "A") === "bAr"', ['foo' => 'bar'])); $this->assertTrue($this->evaluate('"bar".replace("r", "R") === "baR"')); } - /** @test */ + #[Test] public function omittedParametersDoNotReplaceAnything(): void { $this->assertTrue($this->evaluate('"bar".replace() === "bar"')); } - /** @test */ + #[Test] public function omittedSecondParameterReplacesWithUndefined(): void { $this->assertTrue($this->evaluate('"bar".replace("r") === "baundefined"')); } - /** @test */ + #[Test] public function replaceWithRegularExpression(): void { $this->assertTrue($this->evaluate('"arbar".replace(/ar$/, "") === "arb"')); } - /** @test */ + #[Test] public function regularExpressionWithGModifier(): void { $this->assertTrue($this->evaluate('"foofoo".replace(/foo/, "") === "foo"')); diff --git a/tests/integration/methods/SplitTest.php b/tests/integration/methods/SplitTest.php index b4f0f83..92c7915 100755 --- a/tests/integration/methods/SplitTest.php +++ b/tests/integration/methods/SplitTest.php @@ -8,26 +8,27 @@ namespace nicoSWD\Rule\tests\integration\methods; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class SplitTest extends AbstractTestBase { protected array $var = ['foo' => 'bar,baz,foo']; - /** @test */ + #[Test] public function ifOmittedSeparatorFallsBackToDefault(): void { $this->assertTrue($this->evaluate('foo.split() === ["bar,baz,foo"]', $this->var)); $this->assertTrue($this->evaluate('["bar,baz,foo"] === foo.split()', $this->var)); } - /** @test */ + #[Test] public function splittingLiteralStringAndVariableString(): void { $this->assertTrue($this->evaluate('foo.split(",") === ["bar", "baz", "foo"]', $this->var)); $this->assertTrue($this->evaluate('"bar,baz,foo".split(",") === ["bar", "baz", "foo"]')); } - /** @test */ + #[Test] public function booleansAndNullDoNotSplitAnywhere(): void { $this->assertTrue($this->evaluate('"foo".split(true) === ["foo"]')); @@ -35,7 +36,7 @@ public function booleansAndNullDoNotSplitAnywhere(): void $this->assertTrue($this->evaluate('"foo".split(null) === ["foo"]')); } - /** @test */ + #[Test] public function splitDelimiterAsVariable(): void { $this->assertTrue($this->evaluate( @@ -44,7 +45,7 @@ public function splitDelimiterAsVariable(): void )); } - /** @test */ + #[Test] public function splitDelimiterAsVariableWithMethodCall(): void { $this->assertTrue($this->evaluate( @@ -56,19 +57,19 @@ public function splitDelimiterAsVariableWithMethodCall(): void )); } - /** @test */ + #[Test] public function splitWithRegularExpression(): void { $this->assertTrue($this->evaluate('"foo bar".split(/\s+/) === ["foo", "bar"]')); } - /** @test */ + #[Test] public function splitWithRegexAndLimit(): void { $this->assertTrue($this->evaluate('"foo bar baz".split(/\s+/, 2) === ["foo", "bar baz"]')); } - /** @test */ + #[Test] public function splitWithLimit(): void { $this->assertTrue($this->evaluate('"foo bar baz".split(" ", 2) === ["foo", "bar baz"]')); diff --git a/tests/integration/methods/StartsWithTest.php b/tests/integration/methods/StartsWithTest.php index abc1887..e7651eb 100755 --- a/tests/integration/methods/StartsWithTest.php +++ b/tests/integration/methods/StartsWithTest.php @@ -9,24 +9,25 @@ use nicoSWD\Rule\Parser\Exception\ParserException; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class StartsWithTest extends AbstractTestBase { - /** @test */ + #[Test] public function givenAStringWhenStartsWithNeedleItShouldReturnTrue(): void { $this->assertTrue($this->evaluate('"bar".startsWith("ba") === true')); $this->assertTrue($this->evaluate('foo.startsWith("ar", 1) === true', ['foo' => 'bar'])); } - /** @test */ + #[Test] public function givenAStringWhenNotStartsWithNeedleItShouldReturnTrue(): void { $this->assertTrue($this->evaluate('"bar".startsWith("a") === false')); $this->assertTrue($this->evaluate('foo.startsWith("x") === false', ['foo' => 'bar'])); } - /** @test */ + #[Test] public function givenAStringWhenTestedOnNonStringValuesItShouldThrowAnException(): void { $this->expectException(ParserException::class); diff --git a/tests/integration/methods/SubstrTest.php b/tests/integration/methods/SubstrTest.php index 8d86614..2dfcc0c 100755 --- a/tests/integration/methods/SubstrTest.php +++ b/tests/integration/methods/SubstrTest.php @@ -8,29 +8,30 @@ namespace nicoSWD\Rule\tests\integration\methods; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class SubstrTest extends AbstractTestBase { - /** @test */ + #[Test] public function substrReturnsCorrectPartOfString(): void { $this->assertTrue($this->evaluate('foo.substr(1, 2) === "ar"', ['foo' => 'bar'])); $this->assertTrue($this->evaluate('"bar".substr(0, 1) === "b"')); } - /** @test */ + #[Test] public function outOfBoundsOffsetReturnsEmptyString(): void { $this->assertTrue($this->evaluate('"bar".substr(100) === ""')); } - /** @test */ + #[Test] public function omittedParametersReturnsSameString(): void { $this->assertTrue($this->evaluate('"bar".substr() === "bar"')); } - /** @test */ + #[Test] public function negativeOffsetReturnsEndOfString(): void { $this->assertTrue($this->evaluate('"bar".substr(-1) === "r"')); diff --git a/tests/integration/methods/SyntaxErrorTest.php b/tests/integration/methods/SyntaxErrorTest.php index 571709c..ce9cf0a 100755 --- a/tests/integration/methods/SyntaxErrorTest.php +++ b/tests/integration/methods/SyntaxErrorTest.php @@ -9,10 +9,11 @@ use nicoSWD\Rule\Rule; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class SyntaxErrorTest extends AbstractTestBase { - /** @test */ + #[Test] public function missingCommaInArgumentsThrowsException(): void { $rule = new Rule('"foo".charAt(1 2 ) === "b"'); @@ -21,7 +22,7 @@ public function missingCommaInArgumentsThrowsException(): void $this->assertSame('Unexpected "2" at position 15', $rule->getError()); } - /** @test */ + #[Test] public function missingValueInArgumentsThrowsException(): void { $rule = new Rule('"foo".charAt(1 , ) === "b"'); @@ -30,7 +31,7 @@ public function missingValueInArgumentsThrowsException(): void $this->assertSame('Unexpected "," at position 17', $rule->getError()); } - /** @test */ + #[Test] public function missingValueBetweenCommasInArgumentsThrowsException(): void { $rule = new Rule('"foo".charAt(1 , , ) === "b"'); @@ -39,7 +40,7 @@ public function missingValueBetweenCommasInArgumentsThrowsException(): void $this->assertSame('Unexpected "," at position 17', $rule->getError()); } - /** @test */ + #[Test] public function unexpectedTokenInArgumentsThrowsException(): void { $rule = new Rule('"foo".charAt(1 , < , ) === "b"'); @@ -48,7 +49,7 @@ public function unexpectedTokenInArgumentsThrowsException(): void $this->assertSame('Unexpected "<" at position 17', $rule->getError()); } - /** @test */ + #[Test] public function unexpectedEndOfStringThrowsException(): void { $rule = new Rule('"foo".charAt(1 , '); @@ -57,7 +58,7 @@ public function unexpectedEndOfStringThrowsException(): void $this->assertSame('Unexpected end of string', $rule->getError()); } - /** @test */ + #[Test] public function undefinedMethodThrowsException(): void { $rule = new Rule('/^foo$/.teddst("foo") === true'); @@ -66,7 +67,7 @@ public function undefinedMethodThrowsException(): void $this->assertSame('Undefined method "teddst" at position 7', $rule->getError()); } - /** @test */ + #[Test] public function incorrectSpellingThrowsException(): void { $rule = new Rule('"foo".ChARat(1) === "o"'); @@ -75,7 +76,7 @@ public function incorrectSpellingThrowsException(): void $this->assertSame('Undefined method "ChARat" at position 5', $rule->getError()); } - /** @test */ + #[Test] public function callOnNonArray(): void { $rule = new Rule('"foo".join("|") === ""'); @@ -84,7 +85,7 @@ public function callOnNonArray(): void $this->assertSame('foo.join is not a function', $rule->getError()); } - /** @test */ + #[Test] public function exceptionIsThrownOnTypeError(): void { $rule = new Rule('"foo".test("foo") === false'); diff --git a/tests/integration/methods/TestTest.php b/tests/integration/methods/TestTest.php index 29c314f..8466863 100755 --- a/tests/integration/methods/TestTest.php +++ b/tests/integration/methods/TestTest.php @@ -8,24 +8,25 @@ namespace nicoSWD\Rule\tests\integration\methods; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class TestTest extends AbstractTestBase { - /** @test */ + #[Test] public function basicRegularExpression(): void { $this->assertTrue($this->evaluate('/^foo$/.test("foo") === true')); $this->assertTrue($this->evaluate('/^foo$/.test(foo) === true', ['foo' => 'foo'])); } - /** @test */ + #[Test] public function arrayIsConvertedToString(): void { $this->assertTrue($this->evaluate('/^foo$/.test(["foo"]) === true')); $this->assertTrue($this->evaluate('/1/.test([[[1]]]) === true')); } - /** @test */ + #[Test] public function modifiers(): void { $this->assertTrue($this->evaluate('/^foo$/i.test("FOO") === true')); @@ -34,7 +35,7 @@ public function modifiers(): void $this->assertFalse($this->evaluate('/^foo$/.test("' . "\n\n" .'foo") === true')); } - /** @test */ + #[Test] public function gModifierIsIgnored(): void { $this->assertTrue($this->evaluate('/^foo$/gi.test("foo") === true'), 'gi'); @@ -42,7 +43,7 @@ public function gModifierIsIgnored(): void $this->assertTrue($this->evaluate('/^foo$/g.test("foo") === true'), '"g" modifier alone'); } - /** @test */ + #[Test] public function booleansAndNullsAsSubject(): void { $this->assertTrue($this->evaluate('/^foo$/.test(true) === false')); @@ -51,7 +52,7 @@ public function booleansAndNullsAsSubject(): void $this->assertTrue($this->evaluate('/^true/.test(true) === false')); } - /** @test */ + #[Test] public function withOmittedParameters(): void { $this->assertTrue($this->evaluate('/^foo$/.test() === false')); diff --git a/tests/integration/methods/ToUpperCaseTest.php b/tests/integration/methods/ToUpperCaseTest.php index 365b1d3..ef17cf7 100755 --- a/tests/integration/methods/ToUpperCaseTest.php +++ b/tests/integration/methods/ToUpperCaseTest.php @@ -9,10 +9,11 @@ use nicoSWD\Rule\Rule; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class ToUpperCaseTest extends AbstractTestBase { - /** @test */ + #[Test] public function spacesBetweenVariableAndMethodWork(): void { $this->assertTrue($this->evaluate('foo . toUpperCase() === "BAR"', ['foo' => 'bar'])); @@ -24,20 +25,20 @@ public function spacesBetweenVariableAndMethodWork(): void )); } - /** @test */ + #[Test] public function ifCallOnStringLiteralsWorks(): void { $this->assertTrue($this->evaluate('"bar".toUpperCase() === "BAR"')); $this->assertTrue($this->evaluate('"bar" . toUpperCase() === "BAR"')); } - /** @test */ + #[Test] public function ifMethodCanBeCalledOnVariablesHoldingIntegers(): void { $this->assertTrue($this->evaluate('foo.toUpperCase() === "1"', ['foo' => 1])); } - /** @test */ + #[Test] public function callOnIntegersThrowsException(): void { $rule = new Rule('1.toUpperCase() === "1"', ['foo' => 1]); diff --git a/tests/integration/operators/OperatorsTest.php b/tests/integration/operators/OperatorsTest.php index cc235a3..18cb9a7 100755 --- a/tests/integration/operators/OperatorsTest.php +++ b/tests/integration/operators/OperatorsTest.php @@ -9,10 +9,11 @@ use nicoSWD\Rule\Rule; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class OperatorsTest extends AbstractTestBase { - /** @test */ + #[Test] public function allAvailableOperators(): void { $this->assertTrue($this->evaluate('3 == 3'), 'Equal operator failed on two integers'); @@ -30,7 +31,7 @@ public function allAvailableOperators(): void $this->assertFalse($this->evaluate('2 !== 2')); } - /** @test */ + #[Test] public function strictOperators(): void { $this->assertFalse($this->evaluate('"4" === 4')); @@ -40,7 +41,7 @@ public function strictOperators(): void $this->assertFalse($this->evaluate('4 !== 4')); } - /** @test */ + #[Test] public function inOperator(): void { $this->assertTrue($this->evaluate('123 in foo', ['foo' => [123, 12]])); @@ -49,13 +50,13 @@ public function inOperator(): void $this->assertTrue($this->evaluate('123 in [123, 12]')); } - /** @test */ + #[Test] public function inOperatorOnReturnedValueByMethodCall(): void { $this->assertTrue($this->evaluate('"123" in "321,123".split(",")')); } - /** @test */ + #[Test] public function inOperatorWithNonArrayRightValueThrowsException(): void { $rule = new Rule('"123" in "foo"'); @@ -64,7 +65,7 @@ public function inOperatorWithNonArrayRightValueThrowsException(): void $this->assertSame('Expected array, got "string"', $rule->getError()); } - /** @test */ + #[Test] public function commentsAreIgnoredCorrectly(): void { $this->assertFalse($this->evaluate('1 == 2 // || 1 == 1')); @@ -76,7 +77,7 @@ public function commentsAreIgnoredCorrectly(): void )); } - /** @test */ + #[Test] public function equalOperator(): void { $this->assertTrue($this->evaluate('foo == -1', ['foo' => -1])); diff --git a/tests/integration/scalars/ScalarTest.php b/tests/integration/scalars/ScalarTest.php index 785eae6..2a1de12 100755 --- a/tests/integration/scalars/ScalarTest.php +++ b/tests/integration/scalars/ScalarTest.php @@ -8,10 +8,11 @@ namespace nicoSWD\Rule\tests\integration\scalars; use nicoSWD\Rule\tests\integration\AbstractTestBase; +use PHPUnit\Framework\Attributes\Test; final class ScalarTest extends AbstractTestBase { - /** @test */ + #[Test] public function booleans(): void { $this->assertTrue($this->evaluate('"0" == false')); @@ -25,7 +26,7 @@ public function booleans(): void $this->assertFalse($this->evaluate('foo !== true', ['foo' => true])); } - /** @test */ + #[Test] public function nullValues(): void { $this->assertTrue($this->evaluate('foo === null', ['foo' => null])); @@ -36,7 +37,7 @@ public function nullValues(): void $this->assertFalse($this->evaluate('"" === null', ['foo' => null])); } - /** @test */ + #[Test] public function floatPrecision(): void { $this->assertFalse($this->evaluate('foo === "1.0000034"', ['foo' => 1.0000034])); @@ -47,7 +48,7 @@ public function floatPrecision(): void $this->assertTrue($this->evaluate('2 > 1.0000034')); } - /** @test */ + #[Test] public function negativeNumbers(): void { $rule = 'foo > -1 && foo < 1'; diff --git a/tests/unit/Evaluator/EvaluatorTest.php b/tests/unit/Evaluator/EvaluatorTest.php index b4e1640..f5d6511 100755 --- a/tests/unit/Evaluator/EvaluatorTest.php +++ b/tests/unit/Evaluator/EvaluatorTest.php @@ -10,6 +10,7 @@ use nicoSWD\Rule\Evaluator\Evaluator; use nicoSWD\Rule\Evaluator\Exception\UnknownSymbolException; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\Test; final class EvaluatorTest extends TestCase { @@ -20,7 +21,7 @@ protected function setUp(): void $this->evaluator = new Evaluator(); } - /** @test */ + #[Test] public function givenACompiledRuleWithAnLogicalAndItShouldEvaluateBothOperandsAndReturnTheResult(): void { $this->assertTrue($this->evaluator->evaluate('1&1')); @@ -29,7 +30,7 @@ public function givenACompiledRuleWithAnLogicalAndItShouldEvaluateBothOperandsAn $this->assertFalse($this->evaluator->evaluate('0&0')); } - /** @test */ + #[Test] public function givenACompiledRuleWithAnLogicalOrItShouldEvaluateBothOperandsAndReturnTheResult(): void { $this->assertTrue($this->evaluator->evaluate('1|1')); @@ -38,7 +39,7 @@ public function givenACompiledRuleWithAnLogicalOrItShouldEvaluateBothOperandsAnd $this->assertFalse($this->evaluator->evaluate('0|0')); } - /** @test */ + #[Test] public function givenACompiledRuleWithGroupsTheyShouldBeEvaluatedFirst(): void { $this->assertTrue($this->evaluator->evaluate('0|(1|0)')); @@ -48,7 +49,7 @@ public function givenACompiledRuleWithGroupsTheyShouldBeEvaluatedFirst(): void $this->assertFalse($this->evaluator->evaluate('0|(0|(1&0))')); } - /** @test */ + #[Test] public function givenACharacterWhenUnknownItShouldThrowAnException(): void { $this->expectException(UnknownSymbolException::class); diff --git a/tests/unit/Expression/ExpressionFactoryTest.php b/tests/unit/Expression/ExpressionFactoryTest.php index 74f4aeb..4568966 100755 --- a/tests/unit/Expression/ExpressionFactoryTest.php +++ b/tests/unit/Expression/ExpressionFactoryTest.php @@ -10,7 +10,9 @@ use nicoSWD\Rule\Expression; use nicoSWD\Rule\Expression\ExpressionFactory; use nicoSWD\Rule\TokenStream\Token; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\Test; final class ExpressionFactoryTest extends TestCase { @@ -21,10 +23,8 @@ protected function setUp(): void $this->factory = new ExpressionFactory(); } - /** - * @test - * @dataProvider expressionProvider - */ + #[Test] + #[DataProvider('expressionProvider')] public function givenAnEqualOperatorItShouldCreateAnEqualExpression( string $expressionClass, Token\BaseToken $token @@ -35,7 +35,7 @@ public function givenAnEqualOperatorItShouldCreateAnEqualExpression( ); } - public function expressionProvider(): array + public static function expressionProvider(): array { return [ [Expression\EqualExpression::class, new Token\TokenEqual('==')], diff --git a/tests/unit/Parser/ParserTest.php b/tests/unit/Parser/ParserTest.php index 8787404..8b65e3d 100755 --- a/tests/unit/Parser/ParserTest.php +++ b/tests/unit/Parser/ParserTest.php @@ -17,6 +17,7 @@ use nicoSWD\Rule\TokenStream\Token; use nicoSWD\Rule\TokenStream\TokenIterator; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\Test; final class ParserTest extends TestCase { @@ -35,7 +36,7 @@ protected function setUp(): void $this->parser = new Parser($this->tokenStream, new EvaluatableExpressionFactory(), $this->compilerFactory); } - /** @test */ + #[Test] public function givenARuleStringWhenValidItShouldReturnTheCompiledRule(): void { $tokens = [ diff --git a/tests/unit/Token/TokenFactoryTest.php b/tests/unit/Token/TokenFactoryTest.php index c7c747c..68fc074 100755 --- a/tests/unit/Token/TokenFactoryTest.php +++ b/tests/unit/Token/TokenFactoryTest.php @@ -11,6 +11,7 @@ use nicoSWD\Rule\TokenStream\Token; use nicoSWD\Rule\TokenStream\Token\TokenEqualStrict; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\Test; final class TokenFactoryTest extends TestCase { @@ -21,7 +22,7 @@ protected function setUp(): void $this->tokenFactory = new Token\TokenFactory(); } - /** @test */ + #[Test] public function simpleTypeReturnsCorrectInstance(): void { $this->assertInstanceOf(Token\TokenNull::class, $this->tokenFactory->createFromPHPType(null)); @@ -32,7 +33,7 @@ public function simpleTypeReturnsCorrectInstance(): void $this->assertInstanceOf(Token\TokenArray::class, $this->tokenFactory->createFromPHPType([1, 2])); } - /** @test */ + #[Test] public function unsupportedTypeThrowsException(): void { $this->expectException(ParserException::class); @@ -41,7 +42,7 @@ public function unsupportedTypeThrowsException(): void $this->tokenFactory->createFromPHPType(tmpfile()); } - /** @test */ + #[Test] public function givenAValidTokenNameItShouldReturnItsCorrespondingClassName(): void { $this->assertSame(TokenEqualStrict::class, $this->tokenFactory->createFromToken(Token\Token::EQUAL_STRICT)); diff --git a/tests/unit/TokenStream/CallableUserMethodTest.php b/tests/unit/TokenStream/CallableUserMethodTest.php index 7093f8e..349c218 100755 --- a/tests/unit/TokenStream/CallableUserMethodTest.php +++ b/tests/unit/TokenStream/CallableUserMethodTest.php @@ -12,11 +12,12 @@ use nicoSWD\Rule\TokenStream\Token\TokenFactory; use nicoSWD\Rule\TokenStream\Token\TokenObject; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\Test; use stdClass; final class CallableUserMethodTest extends TestCase { - /** @test */ + #[Test] public function givenAnObjectWithAPublicPropertyItShouldBeAccessible(): void { $object = new stdClass(); @@ -25,7 +26,7 @@ public function givenAnObjectWithAPublicPropertyItShouldBeAccessible(): void $this->assertSame(123, $this->callMethod($object, 'my_test')->getValue()); } - /** @test */ + #[Test] public function givenAnObjectWithAPublicWhenMethodMatchingItShouldBeUsed(): void { $object = new class { @@ -38,7 +39,7 @@ public function my_test() $this->assertSame(123, $this->callMethod($object, 'my_test')->getValue()); } - /** @test */ + #[Test] public function givenAnObjectWithAPublicWhenMethodNameWithIsPrefixMatchesItShouldBeUsed(): void { $object = new class { @@ -57,7 +58,7 @@ public function isMyTest() $this->assertSame(456, $this->callMethod($object, 'myTest')->getValue()); } - /** @test */ + #[Test] public function givenAnObjectWithAPublicWhenMethodNameWithGetPrefixMatchesItShouldBeUsed(): void { $object = new class { diff --git a/tests/unit/TokenStream/Token/BaseTokenTest.php b/tests/unit/TokenStream/Token/BaseTokenTest.php index 90132f0..32fd401 100755 --- a/tests/unit/TokenStream/Token/BaseTokenTest.php +++ b/tests/unit/TokenStream/Token/BaseTokenTest.php @@ -12,6 +12,7 @@ use nicoSWD\Rule\TokenStream\Token\TokenType; use nicoSWD\Rule\TokenStream\TokenIterator; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\Test; final class BaseTokenTest extends TestCase { @@ -28,25 +29,25 @@ public function getType(): TokenType }; } - /** @test */ + #[Test] public function offset(): void { $this->assertSame(1337, $this->token->getOffset()); } - /** @test */ + #[Test] public function getValue(): void { $this->assertSame('&&', $this->token->getValue()); } - /** @test */ + #[Test] public function getOriginalValue(): void { $this->assertSame('&&', $this->token->getOriginalValue()); } - /** @test */ + #[Test] public function createNode(): void { /** @var TokenIterator|MockInterface $tokenStream */ @@ -54,7 +55,7 @@ public function createNode(): void $this->assertSame($this->token, $this->token->createNode($tokenStream)); } - /** @test */ + #[Test] public function isOfType(): void { $this->assertTrue($this->token->isOfType(TokenType::LOGICAL)); diff --git a/tests/unit/TokenStream/TokenIteratorTest.php b/tests/unit/TokenStream/TokenIteratorTest.php index 5820cd9..cd3421d 100755 --- a/tests/unit/TokenStream/TokenIteratorTest.php +++ b/tests/unit/TokenStream/TokenIteratorTest.php @@ -23,6 +23,7 @@ use nicoSWD\Rule\TokenStream\Token\TokenVariable; use nicoSWD\Rule\TokenStream\TokenIterator; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\Test; final class TokenIteratorTest extends TestCase { @@ -40,7 +41,7 @@ protected function setUp(): void $this->tokenIterator = new TokenIterator($this->stack, $this->tokenStream); } - /** @test */ + #[Test] public function givenAStackWhenNotEmptyItShouldBeIterable() { $this->stack->shouldReceive('rewind'); @@ -59,13 +60,13 @@ public function givenAStackWhenNotEmptyItShouldBeIterable() } } - /** @test */ + #[Test] public function givenATokenStackItShouldBeAccessibleViaGetter() { $this->assertInstanceOf(ArrayIterator::class, $this->tokenIterator->getStack()); } - /** @test */ + #[Test] public function givenAVariableNameWhenFoundItShouldReturnItsValue() { $this->tokenStream->shouldReceive('getVariable')->once()->with('foo')->andReturn(new TokenVariable('bar')); @@ -74,7 +75,7 @@ public function givenAVariableNameWhenFoundItShouldReturnItsValue() $this->assertInstanceOf(TokenVariable::class, $token); } - /** @test */ + #[Test] public function givenAVariableNameWhenNotFoundItShouldThrowAnException() { $this->expectException(ParserException::class); @@ -85,7 +86,7 @@ public function givenAVariableNameWhenNotFoundItShouldThrowAnException() $this->tokenIterator->getVariable('foo'); } - /** @test */ + #[Test] public function givenAFunctionNameWhenFoundItShouldACallableClosure() { $this->tokenStream->shouldReceive('getFunction')->once()->with('foo')->andReturn(fn () => 42); @@ -94,7 +95,7 @@ public function givenAFunctionNameWhenFoundItShouldACallableClosure() $this->assertSame(42, $function()); } - /** @test */ + #[Test] public function givenAFunctionNameWhenNotFoundItShouldThrowAnException() { $this->expectException(ParserException::class); @@ -105,7 +106,7 @@ public function givenAFunctionNameWhenNotFoundItShouldThrowAnException() $this->tokenIterator->getFunction('foo'); } - /** @test */ + #[Test] public function givenAMethodNameWhenFoundItShouldReturnAnInstanceOfCallableFunction() { $token = new TokenString('bar'); @@ -118,7 +119,7 @@ public function givenAMethodNameWhenFoundItShouldReturnAnInstanceOfCallableFunct $this->assertInstanceOf(CallableFunction::class, $method); } - /** @test */ + #[Test] public function givenAMethodNameWhenNotFoundItShouldThrowAnException() { $this->expectException(ParserException::class); diff --git a/tests/unit/TokenStream/TokenStreamTest.php b/tests/unit/TokenStream/TokenStreamTest.php index b7259b5..b4db3fc 100755 --- a/tests/unit/TokenStream/TokenStreamTest.php +++ b/tests/unit/TokenStream/TokenStreamTest.php @@ -26,6 +26,7 @@ use nicoSWD\Rule\TokenStream\TokenIteratorFactory; use nicoSWD\Rule\TokenStream\CallableUserMethodFactory; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\Test; use stdClass; final class TokenStreamTest extends TestCase @@ -44,7 +45,7 @@ protected function setUp(): void $this->tokenStreamFactory = new TokenIteratorFactory(); } - /** @test */ + #[Test] public function givenAFunctionNameWhenValidItShouldReturnTheCorrespondingFunction(): void { $grammar = $this->createGrammarWithInternalFunctions([new InternalFunction('test', TestFunc::class)]); @@ -63,7 +64,7 @@ public function givenAFunctionNameWhenValidItShouldReturnTheCorrespondingFunctio $this->assertSame(234, $result->getValue()); } - /** @test */ + #[Test] public function givenAFunctionNameWhenItDoesNotImplementTheInterfaceItShouldThrowAnException(): void { $this->expectExceptionMessage(sprintf( @@ -84,7 +85,7 @@ public function givenAFunctionNameWhenItDoesNotImplementTheInterfaceItShouldThro $tokenStream->getFunction('test')->call(Mockery::mock(BaseNode::class)); } - /** @test */ + #[Test] public function givenAFunctionNameNotDefinedItShouldThrowAnException(): void { $this->expectException(UndefinedFunctionException::class); diff --git a/tests/unit/Tokenizer/TokenizerTest.php b/tests/unit/Tokenizer/TokenizerTest.php index b90d6eb..eb164fc 100755 --- a/tests/unit/Tokenizer/TokenizerTest.php +++ b/tests/unit/Tokenizer/TokenizerTest.php @@ -12,10 +12,11 @@ use nicoSWD\Rule\TokenStream\Token; use nicoSWD\Rule\Tokenizer\Tokenizer; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\Test; final class TokenizerTest extends TestCase { - /** @test */ + #[Test] public function givenAGrammarWithCollidingRegexItShouldTakeThePriorityIntoAccount(): void { $tokens = $this->tokenizeWithGrammar('yes somevar', [ @@ -39,7 +40,7 @@ public function givenAGrammarWithCollidingRegexItShouldTakeThePriorityIntoAccoun $this->assertInstanceOf(Token\TokenVariable::class, $tokens[2]); } - /** @test */ + #[Test] public function givenAGrammarWithCollidingRegexWhenPriorityIsWrongItShouldNeverMatchTheOneWithLowerPriority(): void { $tokens = $this->tokenizeWithGrammar('somevar yes', [ From 3881799568b7fab03b8b63551cfe5efa3c198611 Mon Sep 17 00:00:00 2001 From: Nico Oelgart Date: Wed, 8 Oct 2025 21:28:21 +0200 Subject: [PATCH 11/13] Refactor --- src/Compiler/StandardCompiler.php | 4 +- src/Expression/ExpressionFactory.php | 3 +- src/Expression/ExpressionFactoryInterface.php | 3 +- src/Grammar/Definition.php | 8 +-- src/Grammar/InternalFunction.php | 6 +- src/Grammar/InternalMethod.php | 6 +- src/Grammar/JavaScript/Methods/Substr.php | 8 +-- src/Grammar/JavaScript/Methods/Test.php | 2 +- src/Highlighter/Highlighter.php | 6 +- src/Parser/Parser.php | 8 +-- src/TokenStream/Token/TokenFactory.php | 66 ++++++++++--------- src/TokenStream/TokenIterator.php | 6 +- src/Tokenizer/Tokenizer.php | 4 +- tests/unit/Parser/ParserTest.php | 14 ++-- tests/unit/Token/TokenFactoryTest.php | 2 +- .../unit/TokenStream/Token/BaseTokenTest.php | 22 ++++--- tests/unit/TokenStream/TokenStreamTest.php | 4 +- tests/unit/Tokenizer/TokenizerTest.php | 7 +- 18 files changed, 85 insertions(+), 94 deletions(-) diff --git a/src/Compiler/StandardCompiler.php b/src/Compiler/StandardCompiler.php index 4717c99..4006d39 100644 --- a/src/Compiler/StandardCompiler.php +++ b/src/Compiler/StandardCompiler.php @@ -19,8 +19,8 @@ final class StandardCompiler implements CompilerInterface { - private const OPENING_PARENTHESIS = '('; - private const CLOSING_PARENTHESIS = ')'; + private const string OPENING_PARENTHESIS = '('; + private const string CLOSING_PARENTHESIS = ')'; private string $output = ''; private int $openParenthesis = 0; diff --git a/src/Expression/ExpressionFactory.php b/src/Expression/ExpressionFactory.php index a311a9c..c87dab4 100644 --- a/src/Expression/ExpressionFactory.php +++ b/src/Expression/ExpressionFactory.php @@ -9,12 +9,13 @@ use nicoSWD\Rule\Parser\Exception\ParserException; use nicoSWD\Rule\TokenStream\Token; +use nicoSWD\Rule\TokenStream\Token\BaseToken; use nicoSWD\Rule\TokenStream\Token\Type\Operator; final class ExpressionFactory implements ExpressionFactoryInterface { /** @throws ParserException */ - public function createFromOperator(Operator $operator): BaseExpression + public function createFromOperator(BaseToken & Operator $operator): BaseExpression { return match ($operator::class) { Token\TokenEqual::class => new EqualExpression(), diff --git a/src/Expression/ExpressionFactoryInterface.php b/src/Expression/ExpressionFactoryInterface.php index bf9ad24..488b437 100644 --- a/src/Expression/ExpressionFactoryInterface.php +++ b/src/Expression/ExpressionFactoryInterface.php @@ -7,9 +7,10 @@ */ namespace nicoSWD\Rule\Expression; +use nicoSWD\Rule\TokenStream\Token\BaseToken; use nicoSWD\Rule\TokenStream\Token\Type\Operator; interface ExpressionFactoryInterface { - public function createFromOperator(Operator $operator): BaseExpression; + public function createFromOperator(BaseToken & Operator $operator): BaseExpression; } diff --git a/src/Grammar/Definition.php b/src/Grammar/Definition.php index 3e8202a..324922a 100644 --- a/src/Grammar/Definition.php +++ b/src/Grammar/Definition.php @@ -9,12 +9,12 @@ use nicoSWD\Rule\TokenStream\Token\Token; -final class Definition +final readonly class Definition { public function __construct( - public readonly Token $token, - public readonly string $regex, - public readonly int $priority, + public Token $token, + public string $regex, + public int $priority, ) { } } diff --git a/src/Grammar/InternalFunction.php b/src/Grammar/InternalFunction.php index 5733dee..fbfdf58 100644 --- a/src/Grammar/InternalFunction.php +++ b/src/Grammar/InternalFunction.php @@ -7,11 +7,11 @@ */ namespace nicoSWD\Rule\Grammar; -final class InternalFunction +final readonly class InternalFunction { public function __construct( - public readonly string $name, - public readonly string $class, + public string $name, + public string $class, ) { } } diff --git a/src/Grammar/InternalMethod.php b/src/Grammar/InternalMethod.php index c3ef06d..8bec86d 100644 --- a/src/Grammar/InternalMethod.php +++ b/src/Grammar/InternalMethod.php @@ -7,11 +7,11 @@ */ namespace nicoSWD\Rule\Grammar; -final class InternalMethod +final readonly class InternalMethod { public function __construct( - public readonly string $name, - public readonly string $class, + public string $name, + public string $class, ) { } } diff --git a/src/Grammar/JavaScript/Methods/Substr.php b/src/Grammar/JavaScript/Methods/Substr.php index f544da0..2a4fe73 100644 --- a/src/Grammar/JavaScript/Methods/Substr.php +++ b/src/Grammar/JavaScript/Methods/Substr.php @@ -15,14 +15,8 @@ final class Substr extends CallableFunction { public function call(?BaseToken ...$parameters): BaseToken { - $params = []; $start = $this->parseParameter($parameters, numParam: 0); - - if (!$start) { - $params[] = 0; - } else { - $params[] = (int) $start->getValue(); - } + $params = [(int) $start?->getValue()]; $offset = $this->parseParameter($parameters, numParam: 1); diff --git a/src/Grammar/JavaScript/Methods/Test.php b/src/Grammar/JavaScript/Methods/Test.php index 82ff838..52bcf0b 100644 --- a/src/Grammar/JavaScript/Methods/Test.php +++ b/src/Grammar/JavaScript/Methods/Test.php @@ -27,7 +27,7 @@ public function call(?BaseToken ...$parameters): BaseToken if (!$string) { $bool = false; } else { - // Remove "g" modifier as is does not exist in PHP + // Remove "g" modifier as it does not exist in PHP // It's also irrelevant in .test() but allowed in JS here $pattern = preg_replace_callback( '~/[igm]{0,3}$~', diff --git a/src/Highlighter/Highlighter.php b/src/Highlighter/Highlighter.php index ae3f5bc..b90d28f 100644 --- a/src/Highlighter/Highlighter.php +++ b/src/Highlighter/Highlighter.php @@ -7,7 +7,7 @@ */ namespace nicoSWD\Rule\Highlighter; -use ArrayIterator; +use Iterator; use nicoSWD\Rule\Tokenizer\TokenizerInterface; use nicoSWD\Rule\TokenStream\Token\BaseToken; use nicoSWD\Rule\TokenStream\Token\TokenType; @@ -15,7 +15,7 @@ final class Highlighter { - private readonly SplObjectStorage $styles; + private SplObjectStorage $styles; public function __construct( private readonly TokenizerInterface $tokenizer, @@ -33,7 +33,7 @@ public function highlightString(string $string): string return $this->highlightTokens($this->tokenizer->tokenize($string)); } - public function highlightTokens(ArrayIterator $tokens): string + public function highlightTokens(Iterator $tokens): string { $string = ''; diff --git a/src/Parser/Parser.php b/src/Parser/Parser.php index 250c05b..0fe5d37 100644 --- a/src/Parser/Parser.php +++ b/src/Parser/Parser.php @@ -15,12 +15,12 @@ use nicoSWD\Rule\TokenStream\Token\TokenType; use nicoSWD\Rule\TokenStream\Token\Type\Operator; -final class Parser +final readonly class Parser { public function __construct( - private readonly TokenStream $tokenStream, - private readonly EvaluatableExpressionFactory $expressionFactory, - private readonly CompilerFactoryInterface $compilerFactory, + private TokenStream $tokenStream, + private EvaluatableExpressionFactory $expressionFactory, + private CompilerFactoryInterface $compilerFactory, ) { } diff --git a/src/TokenStream/Token/TokenFactory.php b/src/TokenStream/Token/TokenFactory.php index 187e5f9..80e16b9 100644 --- a/src/TokenStream/Token/TokenFactory.php +++ b/src/TokenStream/Token/TokenFactory.php @@ -27,40 +27,42 @@ public function createFromPHPType(mixed $value): BaseToken }; } - public function createFromToken(Token $token): string + public function createFromToken(Token $token, array $matches, int $offset): BaseToken { + $args = [$matches[$token->value], $offset]; + return match ($token) { - Token::AND => TokenAnd::class, - Token::OR => TokenOr::class, - Token::NOT_EQUAL_STRICT => TokenNotEqualStrict::class, - Token::NOT_EQUAL => TokenNotEqual::class, - Token::EQUAL_STRICT => TokenEqualStrict::class, - Token::EQUAL => TokenEqual::class, - Token::IN => TokenIn::class, - Token::NOT_IN => TokenNotIn::class, - Token::BOOL_TRUE => TokenBoolTrue::class, - Token::BOOL_FALSE => TokenBoolFalse::class, - Token::NULL => TokenNull::class, - Token::METHOD => TokenMethod::class, - Token::FUNCTION => TokenFunction::class, - Token::VARIABLE => TokenVariable::class, - Token::FLOAT => TokenFloat::class, - Token::INTEGER => TokenInteger::class, - Token::ENCAPSED_STRING => TokenEncapsedString::class, - Token::SMALLER_EQUAL => TokenSmallerEqual::class, - Token::GREATER_EQUAL => TokenGreaterEqual::class, - Token::SMALLER => TokenSmaller::class, - Token::GREATER => TokenGreater::class, - Token::OPENING_PARENTHESIS => TokenOpeningParenthesis::class, - Token::CLOSING_PARENTHESIS => TokenClosingParenthesis::class, - Token::OPENING_ARRAY => TokenOpeningArray::class, - Token::CLOSING_ARRAY => TokenClosingArray::class, - Token::COMMA => TokenComma::class, - Token::REGEX => TokenRegex::class, - Token::COMMENT => TokenComment::class, - Token::NEWLINE => TokenNewline::class, - Token::SPACE => TokenSpace::class, - Token::UNKNOWN => TokenUnknown::class, + Token::AND => new TokenAnd(...$args), + Token::OR => new TokenOr(...$args), + Token::NOT_EQUAL_STRICT => new TokenNotEqualStrict(...$args), + Token::NOT_EQUAL => new TokenNotEqual(...$args), + Token::EQUAL_STRICT => new TokenEqualStrict(...$args), + Token::EQUAL => new TokenEqual(...$args), + Token::IN => new TokenIn(...$args), + Token::NOT_IN => new TokenNotIn(...$args), + Token::BOOL_TRUE => new TokenBoolTrue(...$args), + Token::BOOL_FALSE => new TokenBoolFalse(...$args), + Token::NULL => new TokenNull(...$args), + Token::METHOD => new TokenMethod(...$args), + Token::FUNCTION => new TokenFunction(...$args), + Token::VARIABLE => new TokenVariable(...$args), + Token::FLOAT => new TokenFloat(...$args), + Token::INTEGER => new TokenInteger(...$args), + Token::ENCAPSED_STRING => new TokenEncapsedString(...$args), + Token::SMALLER_EQUAL => new TokenSmallerEqual(...$args), + Token::GREATER_EQUAL => new TokenGreaterEqual(...$args), + Token::SMALLER => new TokenSmaller(...$args), + Token::GREATER => new TokenGreater(...$args), + Token::OPENING_PARENTHESIS => new TokenOpeningParenthesis(...$args), + Token::CLOSING_PARENTHESIS => new TokenClosingParenthesis(...$args), + Token::OPENING_ARRAY => new TokenOpeningArray(...$args), + Token::CLOSING_ARRAY => new TokenClosingArray(...$args), + Token::COMMA => new TokenComma(...$args), + Token::REGEX => new TokenRegex(...$args), + Token::COMMENT => new TokenComment(...$args), + Token::NEWLINE => new TokenNewline(...$args), + Token::SPACE => new TokenSpace(...$args), + Token::UNKNOWN => new TokenUnknown(...$args), }; } diff --git a/src/TokenStream/TokenIterator.php b/src/TokenStream/TokenIterator.php index 3260efc..71e5f60 100644 --- a/src/TokenStream/TokenIterator.php +++ b/src/TokenStream/TokenIterator.php @@ -13,11 +13,11 @@ use nicoSWD\Rule\Grammar\CallableUserFunctionInterface; use nicoSWD\Rule\TokenStream\Token\BaseToken; -class TokenIterator implements Iterator +readonly class TokenIterator implements Iterator { public function __construct( - private readonly Iterator $stack, - private readonly TokenStream $tokenStream, + private Iterator $stack, + private TokenStream $tokenStream, ) { } diff --git a/src/Tokenizer/Tokenizer.php b/src/Tokenizer/Tokenizer.php index 414726d..fe2af69 100644 --- a/src/Tokenizer/Tokenizer.php +++ b/src/Tokenizer/Tokenizer.php @@ -29,9 +29,7 @@ public function tokenize(string $string): Iterator while (preg_match($regex, $string, $matches, offset: $offset)) { $token = $this->getMatchedToken($matches); - $className = $this->tokenFactory->createFromToken($token); - - $stack[] = new $className($matches[$token->value], $offset); + $stack[] = $this->tokenFactory->createFromToken($token, $matches, $offset); $offset += strlen($matches[0]); } diff --git a/tests/unit/Parser/ParserTest.php b/tests/unit/Parser/ParserTest.php index 8b65e3d..8629c32 100755 --- a/tests/unit/Parser/ParserTest.php +++ b/tests/unit/Parser/ParserTest.php @@ -7,6 +7,7 @@ */ namespace nicoSWD\Rule\tests\unit\Parser; +use ArrayIterator; use Mockery as m; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; use nicoSWD\Rule\Compiler\StandardCompiler; @@ -54,18 +55,11 @@ public function givenARuleStringWhenValidItShouldReturnTheCompiledRule(): void ]; $compiler = new StandardCompiler(); - - /** @var m\MockInterface $tokenStream */ - $tokenStream = \Mockery::mock(TokenIterator::class); - $tokenStream->shouldReceive('rewind')->once(); - $tokenStream->shouldReceive('next'); - $tokenStream->shouldReceive('current')->andReturn(...$tokens); - $tokenStream->shouldReceive('valid')->andReturnUsing(function () use (&$tokens) { - return !!next($tokens); - }); + $arrayIterator = new ArrayIterator($tokens); + $tokenIterator = new TokenIterator($arrayIterator, $this->tokenStream); $this->compilerFactory->shouldReceive('create')->once()->andReturn($compiler); - $this->tokenStream->shouldReceive('getStream')->once()->andReturn($tokenStream); + $this->tokenStream->shouldReceive('getStream')->once()->andReturn($tokenIterator); $this->assertSame('(1)&1', $this->parser->parse('(1=="1")&&2>1 // true dat!')); } diff --git a/tests/unit/Token/TokenFactoryTest.php b/tests/unit/Token/TokenFactoryTest.php index 68fc074..688dca3 100755 --- a/tests/unit/Token/TokenFactoryTest.php +++ b/tests/unit/Token/TokenFactoryTest.php @@ -45,6 +45,6 @@ public function unsupportedTypeThrowsException(): void #[Test] public function givenAValidTokenNameItShouldReturnItsCorrespondingClassName(): void { - $this->assertSame(TokenEqualStrict::class, $this->tokenFactory->createFromToken(Token\Token::EQUAL_STRICT)); + $this->assertInstanceOf(TokenEqualStrict::class, $this->tokenFactory->createFromToken(Token\Token::EQUAL_STRICT, ['EqualStrict' => '==='], 0)); } } diff --git a/tests/unit/TokenStream/Token/BaseTokenTest.php b/tests/unit/TokenStream/Token/BaseTokenTest.php index 32fd401..95f9ef6 100755 --- a/tests/unit/TokenStream/Token/BaseTokenTest.php +++ b/tests/unit/TokenStream/Token/BaseTokenTest.php @@ -7,12 +7,14 @@ */ namespace nicoSWD\Rule\tests\unit\TokenStream\Token; +use ArrayIterator; use Mockery\MockInterface; use nicoSWD\Rule\TokenStream\Token\BaseToken; use nicoSWD\Rule\TokenStream\Token\TokenType; use nicoSWD\Rule\TokenStream\TokenIterator; -use PHPUnit\Framework\TestCase; +use nicoSWD\Rule\TokenStream\TokenStream; use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\TestCase; final class BaseTokenTest extends TestCase { @@ -30,33 +32,35 @@ public function getType(): TokenType } #[Test] - public function offset(): void + public function givenATokenWhenGettingOffsetItShouldReturnTheExpectedOffset(): void { $this->assertSame(1337, $this->token->getOffset()); } #[Test] - public function getValue(): void + public function givenATokenWhenGettingValueItShouldReturnTheExpectedValue(): void { $this->assertSame('&&', $this->token->getValue()); } #[Test] - public function getOriginalValue(): void + public function givenATokenWhenGettingOriginalValueItShouldReturnTheExpectedOriginalValue(): void { $this->assertSame('&&', $this->token->getOriginalValue()); } #[Test] - public function createNode(): void + public function givenATokenIteratorWhenCreatingNodeItShouldReturnTheSameToken(): void { - /** @var TokenIterator|MockInterface $tokenStream */ - $tokenStream = \Mockery::mock(TokenIterator::class); - $this->assertSame($this->token, $this->token->createNode($tokenStream)); + /** @var TokenStream|MockInterface $tokenStream */ + $tokenStream = \Mockery::mock(TokenStream::class); + $iterator = new TokenIterator(new ArrayIterator([]), $tokenStream); + + $this->assertSame($this->token, $this->token->createNode($iterator)); } #[Test] - public function isOfType(): void + public function givenALogicalTokenWhenCheckingTypeItShouldReturnTrueForLogicalAndFalseForComma(): void { $this->assertTrue($this->token->isOfType(TokenType::LOGICAL)); $this->assertFalse($this->token->isOfType(TokenType::COMMA)); diff --git a/tests/unit/TokenStream/TokenStreamTest.php b/tests/unit/TokenStream/TokenStreamTest.php index b4db3fc..7b2248c 100755 --- a/tests/unit/TokenStream/TokenStreamTest.php +++ b/tests/unit/TokenStream/TokenStreamTest.php @@ -123,7 +123,7 @@ private function createGrammarWithInternalFunctions(array $internalFunctions = [ { return new class($internalFunctions) extends Grammar { public function __construct( - private array $internalFunctions, + private readonly array $internalFunctions, ) { } @@ -150,7 +150,7 @@ private function createCallableUserMethodFactory(): CallableUserMethodFactoryInt public function create( BaseToken $token, TokenFactory $tokenFactory, - string $methodName + string $methodName, ): CallableUserFunctionInterface { return new class implements CallableUserFunctionInterface { public function call(?BaseToken ...$param): BaseToken diff --git a/tests/unit/Tokenizer/TokenizerTest.php b/tests/unit/Tokenizer/TokenizerTest.php index eb164fc..89b0cfe 100755 --- a/tests/unit/Tokenizer/TokenizerTest.php +++ b/tests/unit/Tokenizer/TokenizerTest.php @@ -11,8 +11,8 @@ use nicoSWD\Rule\Grammar\Grammar; use nicoSWD\Rule\TokenStream\Token; use nicoSWD\Rule\Tokenizer\Tokenizer; -use PHPUnit\Framework\TestCase; use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\TestCase; final class TokenizerTest extends TestCase { @@ -81,11 +81,8 @@ private function tokenizeWithGrammar(string $rule, array $definition): array private function getTokenizer(array $definition): Tokenizer { $grammar = new class($definition) extends Grammar { - private array $definition; - - public function __construct(array $definition) + public function __construct(private readonly array $definition) { - $this->definition = $definition; } public function getDefinition(): array From 82b820d758fe8210d75b98e24643a0438d682754 Mon Sep 17 00:00:00 2001 From: Nico Oelgart Date: Wed, 8 Oct 2025 21:58:24 +0200 Subject: [PATCH 12/13] Fix type --- src/Parser/EvaluatableExpression.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Parser/EvaluatableExpression.php b/src/Parser/EvaluatableExpression.php index 7adb362..49e35da 100644 --- a/src/Parser/EvaluatableExpression.php +++ b/src/Parser/EvaluatableExpression.php @@ -9,11 +9,12 @@ use nicoSWD\Rule\Expression\BaseExpression; use nicoSWD\Rule\Expression\ExpressionFactoryInterface; +use nicoSWD\Rule\TokenStream\Token\BaseToken; use nicoSWD\Rule\TokenStream\Token\Type\Operator; final class EvaluatableExpression { - public ?Operator $operator = null; + public (BaseToken & Operator) | null $operator = null; public array $values = []; public function __construct( From 272c16a5b4de1894c3e90535cc986596fbd079ba Mon Sep 17 00:00:00 2001 From: Nico Oelgart Date: Wed, 8 Oct 2025 21:59:02 +0200 Subject: [PATCH 13/13] Update for v12 --- phpunit.xml.dist | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index db6f484..82d373f 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,15 +1,16 @@ - - - src - - + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/12.3/phpunit.xsd" + bootstrap="src/autoload.php" + cacheDirectory=".phpunit.cache"> tests/ + + + src + +