From 9b0db918f4caeade150882a8ce3fc15385d83d68 Mon Sep 17 00:00:00 2001 From: remorhaz Date: Mon, 12 Feb 2024 13:44:27 +0200 Subject: [PATCH] Dropped PHP 8.0, supported PHP 8.3 --- .github/workflows/build.yml | 6 +- .gitignore | 3 + .phive/phars.xml | 4 + .travis.yml | 28 -- CHANGELOG.md | 6 + LICENSE | 2 +- composer.json | 42 +-- docker-compose.yml | 10 +- php-8.0.Dockerfile | 16 -- php-8.1.Dockerfile | 21 +- php-8.2.Dockerfile | 21 +- php-8.3.Dockerfile | 27 ++ phpunit.xml.dist | 65 ++--- src/AST/EopSymbol.php | 2 +- .../Exception/InvalidAttributeException.php | 12 +- src/AST/Node.php | 8 +- src/AST/Symbol.php | 4 +- src/AST/Translator.php | 4 +- src/AST/Tree.php | 4 +- src/Console/BuildLookupTableCommand.php | 4 +- src/Console/BuildTokenMatcherCommand.php | 5 +- src/Console/PrettyPrinter.php | 4 +- src/Grammar/ContextFree/Grammar.php | 12 +- src/Grammar/ContextFree/GrammarLoader.php | 6 +- src/Grammar/ContextFree/Production.php | 10 +- src/Grammar/ContextFree/TokenFactory.php | 2 +- src/IO/CharBuffer.php | 4 +- src/IO/StringBuffer.php | 2 +- src/Lexer/Token.php | 4 +- src/Lexer/TokenFactory.php | 2 +- src/Lexer/TokenMatcherGenerator.php | 31 ++- src/Lexer/TokenMatcherSpec.php | 4 +- src/Lexer/TokenMatcherSpecParser.php | 61 ++--- src/Lexer/TokenMatcherTemplate.php | 31 ++- src/Lexer/TokenPosition.php | 6 +- src/Lexer/TokenReader.php | 6 +- src/Lexer/TokenSpec.php | 4 +- src/Parser/AttributeListShortcut.php | 2 +- src/Parser/LL1/Lookup/FirstBuilder.php | 2 +- src/Parser/LL1/Lookup/FollowBuilder.php | 4 +- src/Parser/LL1/Lookup/Set.php | 4 +- src/Parser/LL1/Lookup/TableBuilder.php | 2 +- .../LL1/Lookup/TableConflictChecker.php | 16 +- src/Parser/LL1/Parser.php | 20 +- src/Parser/LL1/TranslationSchemeApplier.php | 2 +- src/Parser/LL1/UnexpectedTokenError.php | 8 +- src/Parser/LL1/UnexpectedTokenException.php | 2 +- src/Parser/Production.php | 10 +- src/Parser/Symbol.php | 4 +- src/Parser/SymbolListShortcut.php | 2 +- .../InvalidPropertyConfigException.php | 6 +- .../InvalidPropertyRangeSetException.php | 8 +- .../PropertyFileNotLoadedException.php | 8 +- .../PropertyRangeSetNotFoundException.php | 4 +- src/RegExp/FSM/DfaBuilder.php | 4 +- src/RegExp/FSM/LanguageBuilder.php | 4 +- src/RegExp/FSM/NfaBuilder.php | 6 +- src/RegExp/FSM/NfaCalc.php | 2 +- src/RegExp/FSM/TransitionMap.php | 2 +- .../Grammar/ProductionTranslationScheme.php | 2 +- .../Grammar/SymbolTranslationScheme.php | 2 +- src/RegExp/PropertyIndex.php | 255 ------------------ src/Unicode/CharBuffer.php | 14 +- tests/AST/EopSymbolTest.php | 5 +- tests/AST/NodeTest.php | 5 +- tests/AST/SymbolTest.php | 5 +- tests/AST/TranslatorTest.php | 7 +- tests/AST/TreeTest.php | 5 +- .../Grammar/ContextFree/GrammarLoaderTest.php | 5 +- tests/Grammar/ContextFree/GrammarTest.php | 5 +- tests/Grammar/ContextFree/ProductionTest.php | 5 +- .../Grammar/ContextFree/TokenFactoryTest.php | 5 +- tests/IO/CharBufferTest.php | 5 +- tests/IO/StringBufferTest.php | 5 +- tests/Lexer/TokenMatcherGeneratorTest.php | 32 +-- tests/Lexer/TokenMatcherSpecParserTest.php | 5 +- tests/Lexer/TokenPositionTest.php | 13 +- tests/Lexer/TokenReaderTest.php | 9 +- tests/Lexer/TokenSpecTest.php | 5 +- tests/Lexer/TokenTest.php | 5 +- tests/MemoryLeakTest.php | 9 +- tests/Parser/LL1/Lookup/FirstBuilderTest.php | 25 +- tests/Parser/LL1/Lookup/FirstTest.php | 10 +- tests/Parser/LL1/Lookup/FollowBuilderTest.php | 10 +- tests/Parser/LL1/Lookup/FollowTest.php | 25 +- tests/Parser/LL1/Lookup/TableBuilderTest.php | 17 +- .../LL1/Lookup/TableConflictCheckerTest.php | 5 +- tests/Parser/LL1/Lookup/TableTest.php | 5 +- tests/Parser/LL1/ParserTest.php | 8 +- tests/Parser/SymbolTest.php | 8 +- tests/RegExp/FSM/DfaBuilderTest.php | 5 +- tests/RegExp/FSM/DfaTest.php | 5 +- tests/RegExp/FSM/LanguageBuilderTest.php | 56 ++-- tests/RegExp/FSM/NfaBuilderTest.php | 18 +- tests/RegExp/FSM/NfaCalcTest.php | 16 +- tests/RegExp/FSM/NfaTest.php | 5 +- tests/RegExp/FSM/ParsedFsmTest.php | 88 +++--- tests/RegExp/FSM/StateMapTest.php | 5 +- tests/RegExp/FSM/SymbolTableTest.php | 5 +- tests/RegExp/FSM/TransitionMapTest.php | 49 +--- tests/RegExp/Grammar/GrammarTest.php | 34 ++- tests/RegExp/TokenMatcherTest.php | 13 +- tests/Unicode/CharBufferFactoryTest.php | 5 +- tests/Unicode/CharBufferTest.php | 11 +- tests/Unicode/Grammar/TokenFactoryTest.php | 5 +- .../Unicode/Grammar/Utf8TokenMatcherTest.php | 18 +- vendor-bin/cs/composer.json | 5 + 107 files changed, 582 insertions(+), 887 deletions(-) create mode 100644 .phive/phars.xml delete mode 100644 .travis.yml delete mode 100644 php-8.0.Dockerfile create mode 100644 php-8.3.Dockerfile delete mode 100644 src/RegExp/PropertyIndex.php create mode 100644 vendor-bin/cs/composer.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d12c1fb..a132db9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,13 +12,14 @@ jobs: tests: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: platform-reqs: - use-platform-reqs php-version: - - "8.0" - "8.1" - "8.2" + - "8.3" dependencies: - lowest - highest @@ -32,6 +33,9 @@ jobs: with: php-version: ${{ matrix.php-version }} + - name: Install PHIVE + uses: szepeviktor/phive@v1 + - name: Install lowest dependencies if: ${{ matrix.dependencies == 'lowest' && matrix.platform-reqs == 'use-platform-reqs' }} run: composer update --no-interaction --prefer-lowest diff --git a/.gitignore b/.gitignore index f9968e8..c585ac6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ /build /vendor /composer.lock +/tools/ +/vendor-bin/**/vendor/ +/vendor-bin/**/composer.lock /phpunit.xml /infection.json .phpunit.result.cache diff --git a/.phive/phars.xml b/.phive/phars.xml new file mode 100644 index 0000000..bda539d --- /dev/null +++ b/.phive/phars.xml @@ -0,0 +1,4 @@ + + + + diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 4e21b14..0000000 --- a/.travis.yml +++ /dev/null @@ -1,28 +0,0 @@ -language: php - -env: - global: - - XDEBUG=YES - - XDEBUG_MODE=coverage - - IGNORE_PLATFORM_REQS=NO - -matrix: - include: - - php: '8.0' - - php: '8.1' - - php: '8.2' - -install: - - mkdir -p ./build/logs - - if [ "$IGNORE_PLATFORM_REQS=NO" ]; then composer install --prefer-source --no-interaction; else composer install --ignore-platform-reqs --prefer-source --no-interaction; fi - - composer build - -script: - - vendor/bin/phpcs -sp --report-junit=build/logs/phpcs.xml - - if [ "$XDEBUG" == "YES" ]; then vendor/bin/phpunit --coverage-clover=build/logs/clover.xml --coverage-xml=build/logs/coverage-xml --log-junit=build/logs/junit.xml; else vendor/bin/phpunit; fi - - if [ "$XDEBUG" == "YES" ]; then vendor/bin/infection --coverage=build/logs --threads=4 --no-progress --skip-initial-tests; fi - -after_success: - - if [ "$XDEBUG" == "YES" ]; then bash <(curl -s https://codecov.io/bash -s "build/logs"); fi - - if [ "$XDEBUG" == "YES" ]; then wget https://scrutinizer-ci.com/ocular.phar; fi - - if [ "$XDEBUG" == "YES" ]; then php ocular.phar code-coverage:upload --access-token=$SCRUTINIZER_TOKEN --format=php-clover build/logs/clover.xml; fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 59b4e4c..c918fed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Removed +- Dropped support for PHP 8.0. +### Added +- Added support for PHP 8.3. + ## [0.5.2] - 2023-06-16 ### Fixed - Attribute list works correctly with NULL values now. diff --git a/LICENSE b/LICENSE index 52cf204..4b05d9f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2018-2020 Edward Surov +Copyright (c) 2018-2024 Edward Surov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/composer.json b/composer.json index 806f932..ff85f33 100644 --- a/composer.json +++ b/composer.json @@ -21,19 +21,17 @@ "bin/unilex" ], "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0", "phpdocumentor/reflection-docblock": "^4.3 || ^5", - "nikic/php-parser": "^4.12", - "remorhaz/int-rangesets": "^0.2.1", - "remorhaz/ucd": "^0.2", - "symfony/console": "^5 || ^6", + "nikic/php-parser": "^4.12 || ^5", + "remorhaz/int-rangesets": "^0.3", + "remorhaz/ucd": "^0.3", + "symfony/console": "^6.1 || ^7", "thecodingmachine/safe": "^1.3.1 || ^2" }, "require-dev": { - "infection/infection": "^0.26 || ^0.27", - "phpunit/phpunit": "^9.5 || ^10", - "squizlabs/php_codesniffer": "^3.7.2", - "symplify/coding-standard": "^11" + "bamarni/composer-bin-plugin": "^1.8", + "phpunit/phpunit": "^10.1 || ^11" }, "autoload": { "psr-4": { @@ -50,10 +48,15 @@ } }, "scripts": { + "post-update-cmd": ["@phive-install"], + "post-install-cmd": ["@phive-install"], + "phive-install": [ + "`if [ -f tools/phive ]; then echo 'tools/'; fi`phive install --trust-gpg-keys C5095986493B4AA0" + ], "build-example-brainfuck": [ "php bin/unilex build-token-matcher examples/Brainfuck/spec/LexerSpec.php examples/Brainfuck/src/Grammar/TokenMatcher.php --desc='Brainfuck token matcher.'", "php bin/unilex build-lookup-table examples/Brainfuck/src/Grammar/Config.php examples/Brainfuck/src/Grammar/LookupTable.php --type=ll-1 --desc='Brainfuck LL(1) parser lookup table.' --symbol=Remorhaz\\\\UniLex\\\\Example\\\\Brainfuck\\\\Grammar\\\\SymbolType --token=Remorhaz\\\\UniLex\\\\Example\\\\Brainfuck\\\\Grammar\\\\TokenType", - "vendor/bin/phpcbf -p examples/Brainfuck/src/Grammar/LookupTable.php examples/Brainfuck/src/Grammar/TokenMatcher.php; if [ $? -eq 1 ]; then exit 0; fi" + "vendor-bin/cs/vendor/bin/phpcbf -p examples/Brainfuck/src/Grammar/LookupTable.php examples/Brainfuck/src/Grammar/TokenMatcher.php; if [ $? -eq 1 ]; then exit 0; fi" ], "build-examples": [ "@build-example-brainfuck" @@ -61,11 +64,11 @@ "build-regexp": [ "php bin/unilex build-token-matcher spec/RegExp/LexerSpec.php src/RegExp/Grammar/TokenMatcher.php --desc='RegExp token matcher.'", "php bin/unilex build-lookup-table src/RegExp/Grammar/Config.php src/RegExp/Grammar/LookupTable.php --type=ll-1 --desc='RegExp LL(1) parser lookup table.' --symbol=Remorhaz\\\\UniLex\\\\RegExp\\\\Grammar\\\\SymbolType --token=Remorhaz\\\\UniLex\\\\RegExp\\\\Grammar\\\\TokenType", - "vendor/bin/phpcbf -p src/RegExp/Grammar/LookupTable.php src/RegExp/Grammar/TokenMatcher.php; if [ $? -eq 1 ]; then exit 0; fi" + "vendor-bin/cs/vendor/bin/phpcbf -p src/RegExp/Grammar/LookupTable.php src/RegExp/Grammar/TokenMatcher.php; if [ $? -eq 1 ]; then exit 0; fi" ], "build-unicode": [ "php bin/unilex build-token-matcher spec/Unicode/Utf8LexerSpec.php src/Unicode/Grammar/Utf8TokenMatcher.php --desc='Unicode UTF-8 token matcher.'", - "vendor/bin/phpcbf -p src/Unicode/Grammar/Utf8TokenMatcher.php; if [ $? -eq 1 ]; then exit 0; fi" + "vendor-bin/cs/vendor/bin/phpcbf -p src/Unicode/Grammar/Utf8TokenMatcher.php; if [ $? -eq 1 ]; then exit 0; fi" ], "build-core": [ "@build-regexp", @@ -76,7 +79,7 @@ "@build-examples" ], "test-cs": [ - "vendor/bin/phpcs -sp" + "vendor-bin/cs/vendor/bin/phpcs -sp" ], "test-unit": [ "vendor/bin/phpunit --coverage-xml=build/logs/coverage-xml --coverage-clover=build/logs/clover.xml --log-junit=build/logs/junit.xml" @@ -87,7 +90,7 @@ ], "infection": [ "mkdir -p build/logs/infection", - "vendor/bin/infection --threads=4 --coverage=build/logs --no-progress --skip-initial-tests" + "tools/infection --threads=4 --coverage=build/logs --no-progress --skip-initial-tests" ], "test-infection": [ "@test-unit", @@ -95,9 +98,16 @@ ] }, "config": { - "process-timeout": 0, "allow-plugins": { - "infection/*": true + "bamarni/composer-bin-plugin": true + }, + "process-timeout": 0, + "sort-packages": true + }, + "extra": { + "bamarni-bin": { + "bin-links": false, + "forward-command": true } } } diff --git a/docker-compose.yml b/docker-compose.yml index d74423c..bc8757b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,23 +4,23 @@ services: php: build: context: . - dockerfile: php-8.0.Dockerfile + dockerfile: php-8.1.Dockerfile volumes: - .:/app - ./docker/php.ini:/usr/local/etc/php/conf.d/memory_limit.ini working_dir: /app - php8.1: + php8.2: build: context: . - dockerfile: php-8.1.Dockerfile + dockerfile: php-8.2.Dockerfile volumes: - .:/app - ./docker/php.ini:/usr/local/etc/php/conf.d/memory_limit.ini working_dir: /app - php8.2: + php8.3: build: context: . - dockerfile: php-8.2.Dockerfile + dockerfile: php-8.3.Dockerfile volumes: - .:/app - ./docker/php.ini:/usr/local/etc/php/conf.d/memory_limit.ini diff --git a/php-8.0.Dockerfile b/php-8.0.Dockerfile deleted file mode 100644 index ee85c13..0000000 --- a/php-8.0.Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM php:8.0-cli - -RUN apt-get update && apt-get install -y \ - zip \ - git \ - libicu-dev && \ - pecl install xdebug && \ - docker-php-ext-enable xdebug && \ - docker-php-ext-configure intl --enable-intl && \ - docker-php-ext-install intl && \ - echo "xdebug.mode = develop,coverage,debug" >> "$PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini" - -ENV COMPOSER_ALLOW_SUPERUSER=1 - -RUN curl --silent --show-error https://getcomposer.org/installer | php -- \ - --install-dir=/usr/bin --filename=composer diff --git a/php-8.1.Dockerfile b/php-8.1.Dockerfile index 3c16f25..36b4f89 100644 --- a/php-8.1.Dockerfile +++ b/php-8.1.Dockerfile @@ -1,16 +1,27 @@ FROM php:8.1-cli RUN apt-get update && apt-get install -y \ - zip \ - git \ - libicu-dev && \ + zip \ + git \ + wget \ + gpg \ + libicu-dev && \ pecl install -o -f xdebug && \ docker-php-ext-enable xdebug && \ docker-php-ext-configure intl --enable-intl && \ docker-php-ext-install intl && \ echo "xdebug.mode = develop,coverage,debug" >> "$PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini" -ENV COMPOSER_ALLOW_SUPERUSER=1 +ENV COMPOSER_ALLOW_SUPERUSER=1 \ + COMPOSER_PROCESS_TIMEOUT=1200 RUN curl --silent --show-error https://getcomposer.org/installer | php -- \ - --install-dir=/usr/bin --filename=composer + --install-dir=/usr/bin --filename=composer && \ + git config --global --add safe.directory "*" + +RUN wget -O phive.phar https://phar.io/releases/phive.phar && \ + wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc && \ + gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 && \ + gpg --verify phive.phar.asc phive.phar && \ + chmod +x phive.phar && \ + mv phive.phar /usr/local/bin/phive diff --git a/php-8.2.Dockerfile b/php-8.2.Dockerfile index 224296d..5616045 100644 --- a/php-8.2.Dockerfile +++ b/php-8.2.Dockerfile @@ -1,16 +1,27 @@ FROM php:8.2-cli RUN apt-get update && apt-get install -y \ - zip \ - git \ - libicu-dev && \ + zip \ + git \ + wget \ + gpg \ + libicu-dev && \ pecl install -o -f xdebug && \ docker-php-ext-enable xdebug && \ docker-php-ext-configure intl --enable-intl && \ docker-php-ext-install intl && \ echo "xdebug.mode = develop,coverage,debug" >> "$PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini" -ENV COMPOSER_ALLOW_SUPERUSER=1 +ENV COMPOSER_ALLOW_SUPERUSER=1 \ + COMPOSER_PROCESS_TIMEOUT=1200 RUN curl --silent --show-error https://getcomposer.org/installer | php -- \ - --install-dir=/usr/bin --filename=composer + --install-dir=/usr/bin --filename=composer && \ + git config --global --add safe.directory "*" + +RUN wget -O phive.phar https://phar.io/releases/phive.phar && \ + wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc && \ + gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 && \ + gpg --verify phive.phar.asc phive.phar && \ + chmod +x phive.phar && \ + mv phive.phar /usr/local/bin/phive diff --git a/php-8.3.Dockerfile b/php-8.3.Dockerfile new file mode 100644 index 0000000..ed4baa6 --- /dev/null +++ b/php-8.3.Dockerfile @@ -0,0 +1,27 @@ +FROM php:8.3-cli + +RUN apt-get update && apt-get install -y \ + zip \ + git \ + wget \ + gpg \ + libicu-dev && \ + pecl install -o -f xdebug && \ + docker-php-ext-enable xdebug && \ + docker-php-ext-configure intl --enable-intl && \ + docker-php-ext-install intl && \ + echo "xdebug.mode = develop,coverage,debug" >> "$PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini" + +ENV COMPOSER_ALLOW_SUPERUSER=1 \ + COMPOSER_PROCESS_TIMEOUT=1200 + +RUN curl --silent --show-error https://getcomposer.org/installer | php -- \ + --install-dir=/usr/bin --filename=composer && \ + git config --global --add safe.directory "*" + +RUN wget -O phive.phar https://phar.io/releases/phive.phar && \ + wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc && \ + gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 && \ + gpg --verify phive.phar.asc phive.phar && \ + chmod +x phive.phar && \ + mv phive.phar /usr/local/bin/phive diff --git a/phpunit.xml.dist b/phpunit.xml.dist index d5a0e76..05f40b2 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,33 +1,34 @@ - + - - - tests/ - examples/Brainfuck/tests/ - examples/SimpleExpr/tests/ - - - examples/Brainfuck/tests/ - examples/SimpleExpr/tests/ - - - tests/ - - - - - src/ - examples/Brainfuck/src/ - examples/SimpleExpr/src/ - - - src/RegExp/PropertyIndex.php - src/RegExp/Properties/ - - - \ No newline at end of file + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.1/phpunit.xsd" + backupGlobals="true" + defaultTestSuite="all" + cacheDirectory="build/.phpunit.cache" + requireCoverageMetadata="true"> + + + tests/ + examples/Brainfuck/tests/ + examples/SimpleExpr/tests/ + + + examples/Brainfuck/tests/ + examples/SimpleExpr/tests/ + + + tests/ + + + + + src/ + examples/Brainfuck/src/ + examples/SimpleExpr/src/ + + + src/RegExp/PropertyIndex.php + src/RegExp/Properties/ + + + diff --git a/src/AST/EopSymbol.php b/src/AST/EopSymbol.php index 00e8b80..b53f4d8 100644 --- a/src/AST/EopSymbol.php +++ b/src/AST/EopSymbol.php @@ -9,7 +9,7 @@ class EopSymbol implements StackableSymbolInterface { public function __construct( - private Node $node, + private readonly Node $node, ) { } diff --git a/src/AST/Exception/InvalidAttributeException.php b/src/AST/Exception/InvalidAttributeException.php index 8c5fbc8..4d7c894 100644 --- a/src/AST/Exception/InvalidAttributeException.php +++ b/src/AST/Exception/InvalidAttributeException.php @@ -12,16 +12,16 @@ final class InvalidAttributeException extends DomainException implements ExceptionInterface { public function __construct( - private string $name, - private mixed $value, - private string $expectedType, + private readonly string $name, + private readonly mixed $value, + private readonly string $expectedType, ?Throwable $previous = null, ) { $actualType = gettype($this->value); parent::__construct( - "Node attribute '$this->name' has invalid type: $actualType instead of expected $this->expectedType", - 0, - $previous, + message: "Node attribute '$this->name' has invalid type: " . + "$actualType instead of expected $this->expectedType", + previous: $previous, ); } } diff --git a/src/AST/Node.php b/src/AST/Node.php index fba229e..a4af63a 100644 --- a/src/AST/Node.php +++ b/src/AST/Node.php @@ -24,8 +24,8 @@ class Node implements StackableSymbolInterface private array $childMap = []; public function __construct( - private int $id, - private string $name, + private readonly int $id, + private readonly string $name, ) { } @@ -121,8 +121,8 @@ public function addChild(Node $node): self */ public function getChild(int $index): Node { - return $this->childMap[$index] - ?? throw new UniLexException("Child node at index {$index} in node {$this->getId()} is not defined"); + return $this->childMap[$index] ?? + throw new UniLexException("Child node at index {$index} in node {$this->getId()} is not defined"); } /** diff --git a/src/AST/Symbol.php b/src/AST/Symbol.php index 868bba8..5edc9f0 100644 --- a/src/AST/Symbol.php +++ b/src/AST/Symbol.php @@ -12,8 +12,8 @@ class Symbol implements StackableSymbolInterface private ?Node $symbol = null; public function __construct( - private Node $header, - private int $index, + private readonly Node $header, + private readonly int $index, ) { } diff --git a/src/AST/Translator.php b/src/AST/Translator.php index 5ce9054..3bbd4e7 100644 --- a/src/AST/Translator.php +++ b/src/AST/Translator.php @@ -12,8 +12,8 @@ class Translator private SymbolStack $stack; public function __construct( - private Tree $tree, - private TranslatorListenerInterface $listener, + private readonly Tree $tree, + private readonly TranslatorListenerInterface $listener, ) { $this->stack = new SymbolStack(); } diff --git a/src/AST/Tree.php b/src/AST/Tree.php index 3bb08b7..d6081b5 100644 --- a/src/AST/Tree.php +++ b/src/AST/Tree.php @@ -30,8 +30,8 @@ public function createNode(string $name, int $id = null): Node */ public function getNode(int $id): Node { - return $this->nodeMap[$id] - ?? throw new Exception("Node $id is not defined in syntax tree"); + return $this->nodeMap[$id] ?? + throw new Exception("Node $id is not defined in syntax tree"); } /** diff --git a/src/Console/BuildLookupTableCommand.php b/src/Console/BuildLookupTableCommand.php index d6bbca3..2b895e1 100644 --- a/src/Console/BuildLookupTableCommand.php +++ b/src/Console/BuildLookupTableCommand.php @@ -19,6 +19,7 @@ use Remorhaz\UniLex\Parser\LL1\Lookup\TableBuilder; use RuntimeException; use Safe; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Exception\InvalidOptionException; use Symfony\Component\Console\Input\InputArgument; @@ -33,12 +34,11 @@ use const SORT_ASC; use const SORT_STRING; +#[AsCommand('build-lookup-table')] final class BuildLookupTableCommand extends Command { private const TYPE_LL_1 = 'll-1'; - protected static $defaultName = 'build-lookup-table'; - private BuilderFactory $builder; public function __construct( diff --git a/src/Console/BuildTokenMatcherCommand.php b/src/Console/BuildTokenMatcherCommand.php index 3463f28..bdae0f9 100644 --- a/src/Console/BuildTokenMatcherCommand.php +++ b/src/Console/BuildTokenMatcherCommand.php @@ -11,6 +11,7 @@ use Remorhaz\UniLex\Lexer\TokenMatcherSpecParser; use RuntimeException; use Safe; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Exception\InvalidOptionException; use Symfony\Component\Console\Input\InputArgument; @@ -21,14 +22,12 @@ use function array_merge; use function file_put_contents; -use function realpath; use function strlen; use function substr_count; +#[AsCommand('build-token-matcher')] final class BuildTokenMatcherCommand extends Command { - protected static $defaultName = 'build-token-matcher'; - protected function configure(): void { $this diff --git a/src/Console/PrettyPrinter.php b/src/Console/PrettyPrinter.php index f4042bb..391f43e 100644 --- a/src/Console/PrettyPrinter.php +++ b/src/Console/PrettyPrinter.php @@ -11,9 +11,11 @@ final class PrettyPrinter extends Standard { protected function pExpr_Array(Expr\Array_ $node): string { + // $this->options was replaced by set of specific properties in 5.0 + $shortArraySyntax = $this->options['shortArraySyntax'] ?? $this->shortArraySyntax ?? false; $syntax = $node->getAttribute( 'kind', - $this->options['shortArraySyntax'] ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG, + $shortArraySyntax ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG, ); return $syntax === Expr\Array_::KIND_SHORT diff --git a/src/Grammar/ContextFree/Grammar.php b/src/Grammar/ContextFree/Grammar.php index 4ed1892..2f380f2 100644 --- a/src/Grammar/ContextFree/Grammar.php +++ b/src/Grammar/ContextFree/Grammar.php @@ -22,9 +22,9 @@ class Grammar implements GrammarInterface * Constructor. Accepts non-empty maps of terminal and non-terminal productions separately. */ public function __construct( - private int $rootSymbol, - private int $startSymbol, - private int $eoiSymbol, + private readonly int $rootSymbol, + private readonly int $startSymbol, + private readonly int $eoiSymbol, ) { } @@ -79,7 +79,7 @@ public function isTerminal(int $symbolId): bool return false; } - throw new Exception("Symbol {$symbolId} is not defined"); + throw new Exception("Symbol $symbolId is not defined"); } /** @@ -157,8 +157,8 @@ public function getProduction(int $symbolId, int $productionIndex): Production $productionList = $this->getProductionList($symbolId); - return $productionList[$productionIndex] - ?? throw new Exception("Symbol $symbolId has no production at index $productionIndex"); + return $productionList[$productionIndex] ?? + throw new Exception("Symbol $symbolId has no production at index $productionIndex"); } /** diff --git a/src/Grammar/ContextFree/GrammarLoader.php b/src/Grammar/ContextFree/GrammarLoader.php index 693bd60..4cb26db 100644 --- a/src/Grammar/ContextFree/GrammarLoader.php +++ b/src/Grammar/ContextFree/GrammarLoader.php @@ -55,11 +55,7 @@ private static function getConfigValue(mixed $config, string $key): mixed throw new Exception("Config should be an array"); } - if (!isset($config[$key])) { - throw new Exception("Key '$key' not found in config"); - } - - return $config[$key]; + return $config[$key] ?? throw new Exception("Key '$key' not found in config"); } /** diff --git a/src/Grammar/ContextFree/Production.php b/src/Grammar/ContextFree/Production.php index 0ebb19e..b222f19 100644 --- a/src/Grammar/ContextFree/Production.php +++ b/src/Grammar/ContextFree/Production.php @@ -6,6 +6,8 @@ use Stringable; +use function array_values; + class Production implements Stringable { /** @@ -14,14 +16,14 @@ class Production implements Stringable private array $symbolList; public function __construct( - private int $headerId, - private int $index, + private readonly int $headerId, + private readonly int $index, int ...$symbolList, ) { - $this->symbolList = $symbolList; + $this->symbolList = array_values($symbolList); } - public function __toString() + public function __toString(): string { return "$this->headerId:$this->index"; } diff --git a/src/Grammar/ContextFree/TokenFactory.php b/src/Grammar/ContextFree/TokenFactory.php index 0bc10ca..cc3630f 100644 --- a/src/Grammar/ContextFree/TokenFactory.php +++ b/src/Grammar/ContextFree/TokenFactory.php @@ -10,7 +10,7 @@ class TokenFactory implements TokenFactoryInterface { public function __construct( - private GrammarInterface $grammar, + private readonly GrammarInterface $grammar, ) { } diff --git a/src/IO/CharBuffer.php b/src/IO/CharBuffer.php index 5f64a2d..843a59c 100644 --- a/src/IO/CharBuffer.php +++ b/src/IO/CharBuffer.php @@ -8,6 +8,8 @@ use Remorhaz\UniLex\Lexer\Token; use Remorhaz\UniLex\Lexer\TokenPosition; +use function array_values; + class CharBuffer implements CharBufferInterface, TokenExtractInterface { /** @@ -23,7 +25,7 @@ class CharBuffer implements CharBufferInterface, TokenExtractInterface public function __construct(int ...$data) { - $this->data = $data; + $this->data = array_values($data); $this->length = count($data); } diff --git a/src/IO/StringBuffer.php b/src/IO/StringBuffer.php index 1b3b5c4..a37790b 100644 --- a/src/IO/StringBuffer.php +++ b/src/IO/StringBuffer.php @@ -17,7 +17,7 @@ class StringBuffer implements CharBufferInterface, TokenExtractInterface private int $previewOffset = 0; public function __construct( - private string $data, + private readonly string $data, ) { $this->length = strlen($data); } diff --git a/src/Lexer/Token.php b/src/Lexer/Token.php index 1229ec5..aad8d27 100644 --- a/src/Lexer/Token.php +++ b/src/Lexer/Token.php @@ -16,8 +16,8 @@ class Token implements AttributeListInterface private array $attributeList = []; public function __construct( - private int $type, - private bool $isEoi, + private readonly int $type, + private readonly bool $isEoi, ) { } diff --git a/src/Lexer/TokenFactory.php b/src/Lexer/TokenFactory.php index 43b128a..1e0efdf 100644 --- a/src/Lexer/TokenFactory.php +++ b/src/Lexer/TokenFactory.php @@ -7,7 +7,7 @@ class TokenFactory implements TokenFactoryInterface { public function __construct( - private int $eoiTokenId, + private readonly int $eoiTokenId, ) { } diff --git a/src/Lexer/TokenMatcherGenerator.php b/src/Lexer/TokenMatcherGenerator.php index 193aadd..d5da260 100644 --- a/src/Lexer/TokenMatcherGenerator.php +++ b/src/Lexer/TokenMatcherGenerator.php @@ -32,16 +32,25 @@ class TokenMatcherGenerator { - private $output; + private ?string $output = null; - private $dfa; + /** + * @var array + */ + private array $dfa = []; - private $regExpFinishMap = []; + /** + * @var array> + */ + private array $regExpFinishMap = []; - private $conditionFunctions = []; + /** + * @var array + */ + private array $conditionFunctions = []; public function __construct( - private TokenMatcherSpec $spec, + private readonly TokenMatcherSpec $spec, ) { } @@ -108,7 +117,7 @@ private function buildFileComment(): string $comment = "/**\n"; $commentLineList = explode("\n", $content); foreach ($commentLineList as $commentLine) { - $comment .= rtrim(" * {$commentLine}") . "\n"; + $comment .= rtrim(" * $commentLine") . "\n"; } $comment .= " */\n"; @@ -123,7 +132,7 @@ public function buildHeader(): string $headerParts = []; $namespace = $this->spec->getTargetNamespaceName(); if ($namespace != '') { - $headerParts[] = $this->buildMethodPart("namespace {$namespace};", 0); + $headerParts[] = $this->buildMethodPart("namespace $namespace;", 0); } $useList = $this->buildUseList(); if ('' != $useList) { @@ -144,8 +153,8 @@ private function buildUseList(): string { $result = ''; foreach ($this->spec->getUsedClassList() as $alias => $className) { - $classWithAlias = is_string($alias) ? "{$className} {$alias}" : $className; - $result .= $this->buildMethodPart("use {$classWithAlias};", 0); + $classWithAlias = is_string($alias) ? "$className $alias" : $className; + $result .= $this->buildMethodPart("use $classWithAlias;", 0); } return $result; @@ -185,7 +194,7 @@ private function buildMatchBody(): string continue; } $result .= - $this->buildMethodPart("if (\$context->getMode() == '{$mode}') {") . + $this->buildMethodPart("if (\$context->getMode() == '$mode') {") . $this->buildFsmEntry($mode, 3) . $this->buildMethodPart("}"); } @@ -373,7 +382,7 @@ private function buildConditionFunctions(): string foreach ($this->conditionFunctions as $method => $conditionList) { $result .= - "\n private function {$method}(int \$char): bool\n {\n" . + "\n private function $method(int \$char): bool\n {\n" . $this->buildMethodPart("return") . $this->buildMethodPart(rtrim($conditionList) . ';') . " }\n"; diff --git a/src/Lexer/TokenMatcherSpec.php b/src/Lexer/TokenMatcherSpec.php index 0b13bb6..8fb4cdd 100644 --- a/src/Lexer/TokenMatcherSpec.php +++ b/src/Lexer/TokenMatcherSpec.php @@ -50,8 +50,8 @@ class TokenMatcherSpec private array $tokenSpecList = []; public function __construct( - private string $targetClassName, - private string $templateClassName, + private readonly string $targetClassName, + private readonly string $templateClassName, ) { } diff --git a/src/Lexer/TokenMatcherSpecParser.php b/src/Lexer/TokenMatcherSpecParser.php index 3bfda2b..a4da9cd 100644 --- a/src/Lexer/TokenMatcherSpecParser.php +++ b/src/Lexer/TokenMatcherSpecParser.php @@ -25,31 +25,41 @@ class TokenMatcherSpecParser private const LEX_TOKEN_REGEXP = 'token_regexp'; private const LEX_TOKEN_CONTEXT = 'token_context'; - private $source; + private ?TokenMatcherSpec $matcherSpec = null; - private $matcherSpec; + private ?string $targetClassName = null; - private $targetClassName; + private ?string $templateClassName = null; - private $templateClassName; + private ?DocBlockFactoryInterface $docBlockFactory = null; - private $docBlockFactory; - - private $codeBlockList = []; + /** + * @var array + */ + private array $codeBlockList = []; - private $codeBlockKey; + private ?string $codeBlockKey = null; - private $codeBlockStack = []; + /** + * @var list + */ + private array $codeBlockStack = []; - private $skipToken = false; + private bool $skipToken = false; - private $usedClassList = []; + /** + * @var array + */ + private array $usedClassList = []; - private $tokenSpecList = []; + /** + * @var array> + */ + private array $tokenSpecList = []; - public function __construct(string $source) - { - $this->source = $source; + public function __construct( + private readonly string $source, + ) { } /** @@ -60,11 +70,10 @@ public function __construct(string $source) public static function loadFromFile(string $fileName): self { $source = @file_get_contents($fileName); - if (false === $source) { - throw new Exception("Failed to read lexer specification from file {$fileName}"); - } - return new self($source); + return false === $source + ? throw new Exception("Failed to read lexer specification from file {$fileName}") + : new self($source); } /** @@ -74,11 +83,7 @@ public static function loadFromFile(string $fileName): self */ public function getMatcherSpec(): TokenMatcherSpec { - if (!isset($this->matcherSpec)) { - $this->matcherSpec = $this->buildMatcherSpec(); - } - - return $this->matcherSpec; + return $this->matcherSpec ??= $this->buildMatcherSpec(); } /** @@ -171,7 +176,7 @@ private function afterProcessingSource(): void /** * @param string $usedClass - * @return array + * @return array{string, string|null} * @throws Exception */ private function parseUsedClass(string $usedClass): array @@ -308,11 +313,7 @@ private function detectTokenRegExp(DocBlock $docBlock): void private function getDocBlockFactory(): DocBlockFactoryInterface { - if (!isset($this->docBlockFactory)) { - $this->docBlockFactory = DocBlockFactory::createInstance(); - } - - return $this->docBlockFactory; + return $this->docBlockFactory ??= DocBlockFactory::createInstance(); } private function switchCurrentCodeBlock(string $key): void diff --git a/src/Lexer/TokenMatcherTemplate.php b/src/Lexer/TokenMatcherTemplate.php index 4d6d23d..65a6a94 100644 --- a/src/Lexer/TokenMatcherTemplate.php +++ b/src/Lexer/TokenMatcherTemplate.php @@ -4,7 +4,6 @@ namespace Remorhaz\UniLex\Lexer; -use Closure; use Remorhaz\UniLex\Exception; use Remorhaz\UniLex\IO\CharBufferInterface; use Remorhaz\UniLex\IO\TokenExtractInterface; @@ -38,7 +37,7 @@ protected function createContext( $onSetMode = function (string $mode): void { $this->mode = $mode; }; - $onGetMode = fn (): string => $this->mode; + $onGetMode = fn (): string => $this->mode; return new class ( $buffer, @@ -50,24 +49,24 @@ protected function createContext( ) implements TokenMatcherContextInterface { /** - * @var Closure(int):void + * @var callable(int):void */ - private Closure $onSetNewToken; + private mixed $onSetNewToken; /** - * @var Closure():Token + * @var callable():Token */ - private Closure $onGetToken; + private mixed $onGetToken; /** - * @var Closure(string):void + * @var callable(string):void */ - private Closure $onSetMode; + private mixed $onSetMode; /** - * @var Closure():string + * @var callable():string */ - private Closure $onGetMode; + private mixed $onGetMode; /** * @param CharBufferInterface $buffer @@ -78,17 +77,17 @@ protected function createContext( * @param callable():string $onGetMode */ public function __construct( - private CharBufferInterface $buffer, + private readonly CharBufferInterface $buffer, callable $onConstruct, callable $onSetNewToken, callable $onGetToken, callable $onSetMode, - callable $onGetMode + callable $onGetMode, ) { - $this->onSetNewToken = Closure::fromCallable($onSetNewToken); - $this->onGetToken = Closure::fromCallable($onGetToken); - $this->onSetMode = Closure::fromCallable($onSetMode); - $this->onGetMode = Closure::fromCallable($onGetMode); + $this->onSetNewToken = $onSetNewToken; + $this->onGetToken = $onGetToken; + $this->onSetMode = $onSetMode; + $this->onGetMode = $onGetMode; $onConstruct(); } diff --git a/src/Lexer/TokenPosition.php b/src/Lexer/TokenPosition.php index fba7086..69996a4 100644 --- a/src/Lexer/TokenPosition.php +++ b/src/Lexer/TokenPosition.php @@ -12,15 +12,13 @@ class TokenPosition { /** - * Constructor. - * . * @param int $startOffset Offset of the first symbol of token. * @param int $finishOffset Offset of the next symbol after token. * @throws Exception */ public function __construct( - private int $startOffset, - private int $finishOffset, + private readonly int $startOffset, + private readonly int $finishOffset, ) { if ($this->startOffset < 0) { throw new Exception("Negative start offset in token position: $this->startOffset"); diff --git a/src/Lexer/TokenReader.php b/src/Lexer/TokenReader.php index 7ea04fd..0128603 100644 --- a/src/Lexer/TokenReader.php +++ b/src/Lexer/TokenReader.php @@ -12,9 +12,9 @@ class TokenReader implements TokenReaderInterface private bool $isEnd = false; public function __construct( - private CharBufferInterface $buffer, - private TokenMatcherInterface $matcher, - private TokenFactoryInterface $tokenFactory, + private readonly CharBufferInterface $buffer, + private readonly TokenMatcherInterface $matcher, + private readonly TokenFactoryInterface $tokenFactory, ) { } diff --git a/src/Lexer/TokenSpec.php b/src/Lexer/TokenSpec.php index 27464a3..8811301 100644 --- a/src/Lexer/TokenSpec.php +++ b/src/Lexer/TokenSpec.php @@ -7,8 +7,8 @@ class TokenSpec { public function __construct( - private string $regExp, - private string $code, + private readonly string $regExp, + private readonly string $code, ) { } diff --git a/src/Parser/AttributeListShortcut.php b/src/Parser/AttributeListShortcut.php index 68beacb..ad93ecc 100644 --- a/src/Parser/AttributeListShortcut.php +++ b/src/Parser/AttributeListShortcut.php @@ -17,7 +17,7 @@ class AttributeListShortcut implements ArrayAccess { public function __construct( - private AttributeListInterface $attributeList, + private readonly AttributeListInterface $attributeList, ) { } diff --git a/src/Parser/LL1/Lookup/FirstBuilder.php b/src/Parser/LL1/Lookup/FirstBuilder.php index 30b1b5c..2d644a4 100644 --- a/src/Parser/LL1/Lookup/FirstBuilder.php +++ b/src/Parser/LL1/Lookup/FirstBuilder.php @@ -11,7 +11,7 @@ class FirstBuilder private ?FirstInterface $first = null; public function __construct( - private GrammarInterface $grammar, + private readonly GrammarInterface $grammar, ) { } diff --git a/src/Parser/LL1/Lookup/FollowBuilder.php b/src/Parser/LL1/Lookup/FollowBuilder.php index fe9992b..59101d6 100644 --- a/src/Parser/LL1/Lookup/FollowBuilder.php +++ b/src/Parser/LL1/Lookup/FollowBuilder.php @@ -12,8 +12,8 @@ class FollowBuilder private ?FollowInterface $follow = null; public function __construct( - private GrammarInterface $grammar, - private FirstInterface $first, + private readonly GrammarInterface $grammar, + private readonly FirstInterface $first, ) { } diff --git a/src/Parser/LL1/Lookup/Set.php b/src/Parser/LL1/Lookup/Set.php index 3355a7c..e88f8be 100644 --- a/src/Parser/LL1/Lookup/Set.php +++ b/src/Parser/LL1/Lookup/Set.php @@ -4,6 +4,8 @@ namespace Remorhaz\UniLex\Parser\LL1\Lookup; +use function array_values; + abstract class Set { /** @@ -26,7 +28,7 @@ public function addToken(int $symbolId, int ...$tokenIdList): void } if (!isset($this->tokenMap[$symbolId])) { - $this->tokenMap[$symbolId] = $tokenIdList; + $this->tokenMap[$symbolId] = array_values($tokenIdList); $this->increaseChangeCount(count($tokenIdList)); return; diff --git a/src/Parser/LL1/Lookup/TableBuilder.php b/src/Parser/LL1/Lookup/TableBuilder.php index 8f1abf9..6c8b010 100644 --- a/src/Parser/LL1/Lookup/TableBuilder.php +++ b/src/Parser/LL1/Lookup/TableBuilder.php @@ -17,7 +17,7 @@ class TableBuilder private ?TableInterface $table = null; public function __construct( - private GrammarInterface $grammar, + private readonly GrammarInterface $grammar, ) { } diff --git a/src/Parser/LL1/Lookup/TableConflictChecker.php b/src/Parser/LL1/Lookup/TableConflictChecker.php index 360ec91..b45d41d 100644 --- a/src/Parser/LL1/Lookup/TableConflictChecker.php +++ b/src/Parser/LL1/Lookup/TableConflictChecker.php @@ -11,9 +11,9 @@ class TableConflictChecker { public function __construct( - private GrammarInterface $grammar, - private FirstInterface $first, - private FollowInterface $follow, + private readonly GrammarInterface $grammar, + private readonly FirstInterface $first, + private readonly FollowInterface $follow, ) { } @@ -59,9 +59,7 @@ private function checkProductionConflicts(Production $alpha, Production $beta): */ private function checkMultipleEpsilons(int $symbolId, Production ...$productionList): void { - $isEpsilonProduction = function (Production $production): bool { - return $production->isEpsilon(); - }; + $isEpsilonProduction = fn (Production $production): bool => $production->isEpsilon(); $epsilonProductionList = array_filter($productionList, $isEpsilonProduction); if (count($epsilonProductionList) > 1) { @@ -76,7 +74,7 @@ private function checkFirstFirstConflict(Production $alpha, Production $beta): v { $firstAlpha = $this->first->getProductionTokens(...$alpha->getSymbolList()); $firstBeta = $this->first->getProductionTokens(...$beta->getSymbolList()); - $message = "FIRST({$alpha})/FIRST({$beta}) conflict"; + $message = "FIRST($alpha)/FIRST($beta) conflict"; $this->checkConflict($firstAlpha, $firstBeta, $message); } @@ -91,7 +89,7 @@ private function checkFirstFollowConflict(Production $alpha, Production $beta): $follow = $this->follow->getTokens($alpha->getHeaderId()); $firstAlpha = $this->first->getProductionTokens(...$alpha->getSymbolList()); - $message = "FIRST({$alpha})/FOLLOW({$alpha->getHeaderId()}) conflict (ε ∈ {$beta})"; + $message = "FIRST($alpha)/FOLLOW({$alpha->getHeaderId()}) conflict (ε ∈ $beta)"; $this->checkConflict($follow, $firstAlpha, $message); } @@ -106,7 +104,7 @@ private function checkConflict(array $tokenListA, array $tokenListB, string $mes $conflict = array_intersect($tokenListA, $tokenListB); if (!empty($conflict)) { $conflictText = implode(', ', $conflict); - throw new Exception("{$message}: {$conflictText}"); + throw new Exception("$message: $conflictText"); } } } diff --git a/src/Parser/LL1/Parser.php b/src/Parser/LL1/Parser.php index b3c05c6..adfcdad 100644 --- a/src/Parser/LL1/Parser.php +++ b/src/Parser/LL1/Parser.php @@ -19,23 +19,23 @@ class Parser { - private $lookupTable; + private ?TableInterface $lookupTable = null; private SymbolStack $symbolStack; - private $token; + private ?Token $token = null; - private $nextSymbolIndex = 0; + private int $nextSymbolIndex = 0; /** - * @var Production[] + * @var array */ private array $productionMap = []; public function __construct( - private GrammarInterface $grammar, - private TokenReaderInterface $tokenReader, - private ParserListenerInterface $listener, + private readonly GrammarInterface $grammar, + private readonly TokenReaderInterface $tokenReader, + private readonly ParserListenerInterface $listener, ) { $this->symbolStack = new SymbolStack(); } @@ -125,8 +125,8 @@ private function popSymbol(): StackableSymbolInterface */ private function onSymbol(Symbol $symbol): void { - [$symbolIndex, $production] = $this->productionMap[$symbol->getIndex()] - ?? throw new Exception("No production in map for symbol {$symbol->getIndex()}"); + [$symbolIndex, $production] = $this->productionMap[$symbol->getIndex()] ?? + throw new Exception("No production in map for symbol {$symbol->getIndex()}"); $this->listener->onSymbol($symbolIndex, $production); } @@ -179,7 +179,7 @@ private function getMatchingProduction(Symbol $symbol, Token $token): Production } catch (Throwable $e) { $expectedTokenList = $lookupTable->getExpectedTokenList($symbol->getSymbolId()); $error = new UnexpectedTokenError($token, $symbol, ...$expectedTokenList); - throw new UnexpectedTokenException($error, 0, $e); + throw new UnexpectedTokenException($error, previous: $e); } return $this->createParsedProduction($symbol, $productionIndex); diff --git a/src/Parser/LL1/TranslationSchemeApplier.php b/src/Parser/LL1/TranslationSchemeApplier.php index 09ff529..c260a67 100644 --- a/src/Parser/LL1/TranslationSchemeApplier.php +++ b/src/Parser/LL1/TranslationSchemeApplier.php @@ -12,7 +12,7 @@ class TranslationSchemeApplier extends AbstractParserListener { public function __construct( - private TranslationSchemeInterface $scheme, + private readonly TranslationSchemeInterface $scheme, ) { } diff --git a/src/Parser/LL1/UnexpectedTokenError.php b/src/Parser/LL1/UnexpectedTokenError.php index 2ac4d17..6ffc4be 100644 --- a/src/Parser/LL1/UnexpectedTokenError.php +++ b/src/Parser/LL1/UnexpectedTokenError.php @@ -7,6 +7,8 @@ use Remorhaz\UniLex\Lexer\Token; use Remorhaz\UniLex\Parser\Symbol; +use function array_values; + class UnexpectedTokenError implements UnexpectedTokenErrorInterface { /** @@ -15,11 +17,11 @@ class UnexpectedTokenError implements UnexpectedTokenErrorInterface private array $expectedTokenTypeList; public function __construct( - private Token $unexpectedToken, - private Symbol $productionHeader, + private readonly Token $unexpectedToken, + private readonly Symbol $productionHeader, int ...$expectedTokenTypeList, ) { - $this->expectedTokenTypeList = $expectedTokenTypeList; + $this->expectedTokenTypeList = array_values($expectedTokenTypeList); } public function getUnexpectedToken(): Token diff --git a/src/Parser/LL1/UnexpectedTokenException.php b/src/Parser/LL1/UnexpectedTokenException.php index 037d52e..bb93e36 100644 --- a/src/Parser/LL1/UnexpectedTokenException.php +++ b/src/Parser/LL1/UnexpectedTokenException.php @@ -10,7 +10,7 @@ class UnexpectedTokenException extends Exception { public function __construct( - private UnexpectedTokenErrorInterface $error, + private readonly UnexpectedTokenErrorInterface $error, int $code = 0, ?Throwable $previous = null, ) { diff --git a/src/Parser/Production.php b/src/Parser/Production.php index 9c50d68..edec47d 100644 --- a/src/Parser/Production.php +++ b/src/Parser/Production.php @@ -16,16 +16,16 @@ class Production implements StackableSymbolInterface, Stringable private array $symbolList; public function __construct( - private Symbol $header, - private int $index, + private readonly Symbol $header, + private readonly int $index, Symbol ...$symbolList, ) { - $this->symbolList = $symbolList; + $this->symbolList = \array_values($symbolList); } - public function __toString() + public function __toString(): string { - return "{$this->header->getSymbolId()}:{$this->index}"; + return "{$this->header->getSymbolId()}:$this->index"; } public function getHeaderShortcut(): AttributeListShortcut diff --git a/src/Parser/Symbol.php b/src/Parser/Symbol.php index e29f3e7..bb0491e 100644 --- a/src/Parser/Symbol.php +++ b/src/Parser/Symbol.php @@ -18,8 +18,8 @@ class Symbol implements StackableSymbolInterface, AttributeListInterface private array $attributeList = []; public function __construct( - private int $index, - private int $symbolId, + private readonly int $index, + private readonly int $symbolId, ) { } diff --git a/src/Parser/SymbolListShortcut.php b/src/Parser/SymbolListShortcut.php index ede6179..62608fc 100644 --- a/src/Parser/SymbolListShortcut.php +++ b/src/Parser/SymbolListShortcut.php @@ -15,7 +15,7 @@ class SymbolListShortcut implements ArrayAccess { public function __construct( - private Production $production, + private readonly Production $production, ) { } diff --git a/src/RegExp/Exception/InvalidPropertyConfigException.php b/src/RegExp/Exception/InvalidPropertyConfigException.php index c85b3e9..ff8b64b 100644 --- a/src/RegExp/Exception/InvalidPropertyConfigException.php +++ b/src/RegExp/Exception/InvalidPropertyConfigException.php @@ -12,11 +12,11 @@ final class InvalidPropertyConfigException extends DomainException implements ExceptionInterface { public function __construct( - private string $propertyName, - private mixed $propertyFile, + private readonly string $propertyName, + private readonly mixed $propertyFile, ?Throwable $previous = null, ) { - parent::__construct($this->buildMessage(), 0, $previous); + parent::__construct($this->buildMessage(), previous: $previous); } private function buildMessage(): string diff --git a/src/RegExp/Exception/InvalidPropertyRangeSetException.php b/src/RegExp/Exception/InvalidPropertyRangeSetException.php index 2b37db1..3fe4524 100644 --- a/src/RegExp/Exception/InvalidPropertyRangeSetException.php +++ b/src/RegExp/Exception/InvalidPropertyRangeSetException.php @@ -15,12 +15,12 @@ final class InvalidPropertyRangeSetException extends UnexpectedValueException implements ExceptionInterface { public function __construct( - private string $propertyName, - private string $propertyFile, - private mixed $rangeSet, + private readonly string $propertyName, + private readonly string $propertyFile, + private readonly mixed $rangeSet, ?Throwable $previous = null, ) { - parent::__construct($this->buildMessage(), 0, $previous); + parent::__construct($this->buildMessage(), previous: $previous); } private function buildMessage(): string diff --git a/src/RegExp/Exception/PropertyFileNotLoadedException.php b/src/RegExp/Exception/PropertyFileNotLoadedException.php index 5e2792a..523bec5 100644 --- a/src/RegExp/Exception/PropertyFileNotLoadedException.php +++ b/src/RegExp/Exception/PropertyFileNotLoadedException.php @@ -10,12 +10,12 @@ final class PropertyFileNotLoadedException extends RuntimeException implements ExceptionInterface { public function __construct( - private string $propertyName, - private string $propertyFile, - private ?string $errorMessage, + private readonly string $propertyName, + private readonly string $propertyFile, + private readonly ?string $errorMessage, ?Throwable $previous = null, ) { - parent::__construct($this->buildMessage(), 0, $previous); + parent::__construct($this->buildMessage(), previous: $previous); } private function buildMessage(): string diff --git a/src/RegExp/Exception/PropertyRangeSetNotFoundException.php b/src/RegExp/Exception/PropertyRangeSetNotFoundException.php index 467af00..7fc9c3c 100644 --- a/src/RegExp/Exception/PropertyRangeSetNotFoundException.php +++ b/src/RegExp/Exception/PropertyRangeSetNotFoundException.php @@ -10,10 +10,10 @@ final class PropertyRangeSetNotFoundException extends OutOfRangeException implements ExceptionInterface { public function __construct( - private string $propertyName, + private readonly string $propertyName, ?Throwable $previous = null, ) { - parent::__construct("Range set not found for Unicode property '$this->propertyName'", 0, $previous); + parent::__construct("Range set not found for Unicode property '$this->propertyName'", previous: $previous); } public function getPropertyName(): string diff --git a/src/RegExp/FSM/DfaBuilder.php b/src/RegExp/FSM/DfaBuilder.php index 70a7732..35bd26b 100644 --- a/src/RegExp/FSM/DfaBuilder.php +++ b/src/RegExp/FSM/DfaBuilder.php @@ -22,8 +22,8 @@ class DfaBuilder private array $stateBuffer = []; public function __construct( - private Dfa $dfa, - private Nfa $nfa, + private readonly Dfa $dfa, + private readonly Nfa $nfa, ) { } diff --git a/src/RegExp/FSM/LanguageBuilder.php b/src/RegExp/FSM/LanguageBuilder.php index 1f2c3d5..3b3af31 100644 --- a/src/RegExp/FSM/LanguageBuilder.php +++ b/src/RegExp/FSM/LanguageBuilder.php @@ -11,8 +11,8 @@ class LanguageBuilder { public function __construct( - private SymbolTable $symbolTable, - private TransitionMap $transitionMap, + private readonly SymbolTable $symbolTable, + private readonly TransitionMap $transitionMap, ) { } diff --git a/src/RegExp/FSM/NfaBuilder.php b/src/RegExp/FSM/NfaBuilder.php index 8f3799d..16f747e 100644 --- a/src/RegExp/FSM/NfaBuilder.php +++ b/src/RegExp/FSM/NfaBuilder.php @@ -26,11 +26,11 @@ class NfaBuilder extends AbstractTranslatorListener private ?LanguageBuilder $languageBuilder = null; - private $startState; + private ?int $startState = null; public function __construct( - private Nfa $nfa, - private PropertyRangeLoaderInterface $propertyLoader, + private readonly Nfa $nfa, + private readonly PropertyRangeLoaderInterface $propertyLoader, ) { } diff --git a/src/RegExp/FSM/NfaCalc.php b/src/RegExp/FSM/NfaCalc.php index 8c34239..fdacf32 100644 --- a/src/RegExp/FSM/NfaCalc.php +++ b/src/RegExp/FSM/NfaCalc.php @@ -7,7 +7,7 @@ class NfaCalc { public function __construct( - private Nfa $nfa, + private readonly Nfa $nfa, ) { } diff --git a/src/RegExp/FSM/TransitionMap.php b/src/RegExp/FSM/TransitionMap.php index 600d8a9..72b9516 100644 --- a/src/RegExp/FSM/TransitionMap.php +++ b/src/RegExp/FSM/TransitionMap.php @@ -14,7 +14,7 @@ class TransitionMap private array $transitionMap = []; public function __construct( - private StateMapInterface $stateMap, + private readonly StateMapInterface $stateMap, ) { } diff --git a/src/RegExp/Grammar/ProductionTranslationScheme.php b/src/RegExp/Grammar/ProductionTranslationScheme.php index 7a127a8..4a599a2 100644 --- a/src/RegExp/Grammar/ProductionTranslationScheme.php +++ b/src/RegExp/Grammar/ProductionTranslationScheme.php @@ -12,7 +12,7 @@ class ProductionTranslationScheme { public function __construct( - private Tree $tree, + private readonly Tree $tree, ) { } diff --git a/src/RegExp/Grammar/SymbolTranslationScheme.php b/src/RegExp/Grammar/SymbolTranslationScheme.php index b49467a..da03f7c 100644 --- a/src/RegExp/Grammar/SymbolTranslationScheme.php +++ b/src/RegExp/Grammar/SymbolTranslationScheme.php @@ -12,7 +12,7 @@ class SymbolTranslationScheme { public function __construct( - private Tree $tree, + private readonly Tree $tree, ) { } diff --git a/src/RegExp/PropertyIndex.php b/src/RegExp/PropertyIndex.php deleted file mode 100644 index 32cb93b..0000000 --- a/src/RegExp/PropertyIndex.php +++ /dev/null @@ -1,255 +0,0 @@ - '/Properties/Cc.php', - 'Zs' => '/Properties/Zs.php', - 'Po' => '/Properties/Po.php', - 'Sc' => '/Properties/Sc.php', - 'Ps' => '/Properties/Ps.php', - 'Pe' => '/Properties/Pe.php', - 'Sm' => '/Properties/Sm.php', - 'Pd' => '/Properties/Pd.php', - 'Nd' => '/Properties/Nd.php', - 'Lu' => '/Properties/Lu.php', - 'Sk' => '/Properties/Sk.php', - 'Pc' => '/Properties/Pc.php', - 'Ll' => '/Properties/Ll.php', - 'So' => '/Properties/So.php', - 'Lo' => '/Properties/Lo.php', - 'Pi' => '/Properties/Pi.php', - 'Cf' => '/Properties/Cf.php', - 'No' => '/Properties/No.php', - 'Pf' => '/Properties/Pf.php', - 'Lt' => '/Properties/Lt.php', - 'Lm' => '/Properties/Lm.php', - 'Mn' => '/Properties/Mn.php', - 'Me' => '/Properties/Me.php', - 'Mc' => '/Properties/Mc.php', - 'Nl' => '/Properties/Nl.php', - 'Zl' => '/Properties/Zl.php', - 'Zp' => '/Properties/Zp.php', - 'Cs' => '/Properties/Cs.php', - 'Co' => '/Properties/Co.php', - 'C' => '/Properties/C.php', - 'L' => '/Properties/L.php', - 'L&' => '/Properties/L&.php', - 'M' => '/Properties/M.php', - 'N' => '/Properties/N.php', - 'P' => '/Properties/P.php', - 'S' => '/Properties/S.php', - 'Z' => '/Properties/Z.php', - 'Any' => '/Properties/Any.php', - 'Cn' => '/Properties/Cn.php', - 'Common' => '/Properties/Common.php', - 'Latin' => '/Properties/Latin.php', - 'Greek' => '/Properties/Greek.php', - 'Cyrillic' => '/Properties/Cyrillic.php', - 'Armenian' => '/Properties/Armenian.php', - 'Hebrew' => '/Properties/Hebrew.php', - 'Arabic' => '/Properties/Arabic.php', - 'Syriac' => '/Properties/Syriac.php', - 'Thaana' => '/Properties/Thaana.php', - 'Devanagari' => '/Properties/Devanagari.php', - 'Bengali' => '/Properties/Bengali.php', - 'Gurmukhi' => '/Properties/Gurmukhi.php', - 'Gujarati' => '/Properties/Gujarati.php', - 'Oriya' => '/Properties/Oriya.php', - 'Tamil' => '/Properties/Tamil.php', - 'Telugu' => '/Properties/Telugu.php', - 'Kannada' => '/Properties/Kannada.php', - 'Malayalam' => '/Properties/Malayalam.php', - 'Sinhala' => '/Properties/Sinhala.php', - 'Thai' => '/Properties/Thai.php', - 'Lao' => '/Properties/Lao.php', - 'Tibetan' => '/Properties/Tibetan.php', - 'Myanmar' => '/Properties/Myanmar.php', - 'Georgian' => '/Properties/Georgian.php', - 'Hangul' => '/Properties/Hangul.php', - 'Ethiopic' => '/Properties/Ethiopic.php', - 'Cherokee' => '/Properties/Cherokee.php', - 'Canadian_Aboriginal' => '/Properties/Canadian_Aboriginal.php', - 'Ogham' => '/Properties/Ogham.php', - 'Runic' => '/Properties/Runic.php', - 'Khmer' => '/Properties/Khmer.php', - 'Mongolian' => '/Properties/Mongolian.php', - 'Hiragana' => '/Properties/Hiragana.php', - 'Katakana' => '/Properties/Katakana.php', - 'Bopomofo' => '/Properties/Bopomofo.php', - 'Han' => '/Properties/Han.php', - 'Yi' => '/Properties/Yi.php', - 'Old_Italic' => '/Properties/Old_Italic.php', - 'Gothic' => '/Properties/Gothic.php', - 'Deseret' => '/Properties/Deseret.php', - 'Inherited' => '/Properties/Inherited.php', - 'Tagalog' => '/Properties/Tagalog.php', - 'Hanunoo' => '/Properties/Hanunoo.php', - 'Buhid' => '/Properties/Buhid.php', - 'Tagbanwa' => '/Properties/Tagbanwa.php', - 'Limbu' => '/Properties/Limbu.php', - 'Tai_Le' => '/Properties/Tai_Le.php', - 'Linear_B' => '/Properties/Linear_B.php', - 'Ugaritic' => '/Properties/Ugaritic.php', - 'Shavian' => '/Properties/Shavian.php', - 'Osmanya' => '/Properties/Osmanya.php', - 'Cypriot' => '/Properties/Cypriot.php', - 'Braille' => '/Properties/Braille.php', - 'Buginese' => '/Properties/Buginese.php', - 'Coptic' => '/Properties/Coptic.php', - 'New_Tai_Lue' => '/Properties/New_Tai_Lue.php', - 'Glagolitic' => '/Properties/Glagolitic.php', - 'Tifinagh' => '/Properties/Tifinagh.php', - 'Syloti_Nagri' => '/Properties/Syloti_Nagri.php', - 'Old_Persian' => '/Properties/Old_Persian.php', - 'Kharoshthi' => '/Properties/Kharoshthi.php', - 'Balinese' => '/Properties/Balinese.php', - 'Cuneiform' => '/Properties/Cuneiform.php', - 'Phoenician' => '/Properties/Phoenician.php', - 'Phags_Pa' => '/Properties/Phags_Pa.php', - 'Nko' => '/Properties/Nko.php', - 'Sundanese' => '/Properties/Sundanese.php', - 'Lepcha' => '/Properties/Lepcha.php', - 'Ol_Chiki' => '/Properties/Ol_Chiki.php', - 'Vai' => '/Properties/Vai.php', - 'Saurashtra' => '/Properties/Saurashtra.php', - 'Kayah_Li' => '/Properties/Kayah_Li.php', - 'Rejang' => '/Properties/Rejang.php', - 'Lycian' => '/Properties/Lycian.php', - 'Carian' => '/Properties/Carian.php', - 'Lydian' => '/Properties/Lydian.php', - 'Cham' => '/Properties/Cham.php', - 'Tai_Tham' => '/Properties/Tai_Tham.php', - 'Tai_Viet' => '/Properties/Tai_Viet.php', - 'Avestan' => '/Properties/Avestan.php', - 'Egyptian_Hieroglyphs' => '/Properties/Egyptian_Hieroglyphs.php', - 'Samaritan' => '/Properties/Samaritan.php', - 'Lisu' => '/Properties/Lisu.php', - 'Bamum' => '/Properties/Bamum.php', - 'Javanese' => '/Properties/Javanese.php', - 'Meetei_Mayek' => '/Properties/Meetei_Mayek.php', - 'Imperial_Aramaic' => '/Properties/Imperial_Aramaic.php', - 'Old_South_Arabian' => '/Properties/Old_South_Arabian.php', - 'Inscriptional_Parthian' => '/Properties/Inscriptional_Parthian.php', - 'Inscriptional_Pahlavi' => '/Properties/Inscriptional_Pahlavi.php', - 'Old_Turkic' => '/Properties/Old_Turkic.php', - 'Kaithi' => '/Properties/Kaithi.php', - 'Batak' => '/Properties/Batak.php', - 'Brahmi' => '/Properties/Brahmi.php', - 'Mandaic' => '/Properties/Mandaic.php', - 'Chakma' => '/Properties/Chakma.php', - 'Meroitic_Cursive' => '/Properties/Meroitic_Cursive.php', - 'Meroitic_Hieroglyphs' => '/Properties/Meroitic_Hieroglyphs.php', - 'Miao' => '/Properties/Miao.php', - 'Sharada' => '/Properties/Sharada.php', - 'Sora_Sompeng' => '/Properties/Sora_Sompeng.php', - 'Takri' => '/Properties/Takri.php', - 'Caucasian_Albanian' => '/Properties/Caucasian_Albanian.php', - 'Bassa_Vah' => '/Properties/Bassa_Vah.php', - 'Duployan' => '/Properties/Duployan.php', - 'Elbasan' => '/Properties/Elbasan.php', - 'Grantha' => '/Properties/Grantha.php', - 'Pahawh_Hmong' => '/Properties/Pahawh_Hmong.php', - 'Khojki' => '/Properties/Khojki.php', - 'Linear_A' => '/Properties/Linear_A.php', - 'Mahajani' => '/Properties/Mahajani.php', - 'Manichaean' => '/Properties/Manichaean.php', - 'Mende_Kikakui' => '/Properties/Mende_Kikakui.php', - 'Modi' => '/Properties/Modi.php', - 'Mro' => '/Properties/Mro.php', - 'Old_North_Arabian' => '/Properties/Old_North_Arabian.php', - 'Nabataean' => '/Properties/Nabataean.php', - 'Palmyrene' => '/Properties/Palmyrene.php', - 'Pau_Cin_Hau' => '/Properties/Pau_Cin_Hau.php', - 'Old_Permic' => '/Properties/Old_Permic.php', - 'Psalter_Pahlavi' => '/Properties/Psalter_Pahlavi.php', - 'Siddham' => '/Properties/Siddham.php', - 'Khudawadi' => '/Properties/Khudawadi.php', - 'Tirhuta' => '/Properties/Tirhuta.php', - 'Warang_Citi' => '/Properties/Warang_Citi.php', - 'Ahom' => '/Properties/Ahom.php', - 'Anatolian_Hieroglyphs' => '/Properties/Anatolian_Hieroglyphs.php', - 'Hatran' => '/Properties/Hatran.php', - 'Multani' => '/Properties/Multani.php', - 'Old_Hungarian' => '/Properties/Old_Hungarian.php', - 'SignWriting' => '/Properties/SignWriting.php', - 'Adlam' => '/Properties/Adlam.php', - 'Bhaiksuki' => '/Properties/Bhaiksuki.php', - 'Marchen' => '/Properties/Marchen.php', - 'Newa' => '/Properties/Newa.php', - 'Osage' => '/Properties/Osage.php', - 'Tangut' => '/Properties/Tangut.php', - 'Masaram_Gondi' => '/Properties/Masaram_Gondi.php', - 'Nushu' => '/Properties/Nushu.php', - 'Soyombo' => '/Properties/Soyombo.php', - 'Zanabazar_Square' => '/Properties/Zanabazar_Square.php', - 'Dogra' => '/Properties/Dogra.php', - 'Gunjala_Gondi' => '/Properties/Gunjala_Gondi.php', - 'Makasar' => '/Properties/Makasar.php', - 'Medefaidrin' => '/Properties/Medefaidrin.php', - 'Hanifi_Rohingya' => '/Properties/Hanifi_Rohingya.php', - 'Sogdian' => '/Properties/Sogdian.php', - 'Old_Sogdian' => '/Properties/Old_Sogdian.php', - 'Elymaic' => '/Properties/Elymaic.php', - 'Nandinagari' => '/Properties/Nandinagari.php', - 'Nyiakeng_Puachue_Hmong' => '/Properties/Nyiakeng_Puachue_Hmong.php', - 'Wancho' => '/Properties/Wancho.php', - 'Chorasmian' => '/Properties/Chorasmian.php', - 'Dives_Akuru' => '/Properties/Dives_Akuru.php', - 'Khitan_Small_Script' => '/Properties/Khitan_Small_Script.php', - 'Yezidi' => '/Properties/Yezidi.php', - 'Unknown' => '/Properties/Unknown.php', - 'White_Space' => '/Properties/White_Space.php', - 'Bidi_Control' => '/Properties/Bidi_Control.php', - 'Join_Control' => '/Properties/Join_Control.php', - 'Dash' => '/Properties/Dash.php', - 'Hyphen' => '/Properties/Hyphen.php', - 'Quotation_Mark' => '/Properties/Quotation_Mark.php', - 'Terminal_Punctuation' => '/Properties/Terminal_Punctuation.php', - 'Other_Math' => '/Properties/Other_Math.php', - 'Hex_Digit' => '/Properties/Hex_Digit.php', - 'ASCII_Hex_Digit' => '/Properties/ASCII_Hex_Digit.php', - 'Other_Alphabetic' => '/Properties/Other_Alphabetic.php', - 'Ideographic' => '/Properties/Ideographic.php', - 'Diacritic' => '/Properties/Diacritic.php', - 'Extender' => '/Properties/Extender.php', - 'Other_Lowercase' => '/Properties/Other_Lowercase.php', - 'Other_Uppercase' => '/Properties/Other_Uppercase.php', - 'Noncharacter_Code_Point' => '/Properties/Noncharacter_Code_Point.php', - 'Other_Grapheme_Extend' => '/Properties/Other_Grapheme_Extend.php', - 'IDS_Binary_Operator' => '/Properties/IDS_Binary_Operator.php', - 'IDS_Trinary_Operator' => '/Properties/IDS_Trinary_Operator.php', - 'Radical' => '/Properties/Radical.php', - 'Unified_Ideograph' => '/Properties/Unified_Ideograph.php', - 'Other_Default_Ignorable_Code_Point' => '/Properties/Other_Default_Ignorable_Code_Point.php', - 'Deprecated' => '/Properties/Deprecated.php', - 'Soft_Dotted' => '/Properties/Soft_Dotted.php', - 'Logical_Order_Exception' => '/Properties/Logical_Order_Exception.php', - 'Other_ID_Start' => '/Properties/Other_ID_Start.php', - 'Other_ID_Continue' => '/Properties/Other_ID_Continue.php', - 'Sentence_Terminal' => '/Properties/Sentence_Terminal.php', - 'Variation_Selector' => '/Properties/Variation_Selector.php', - 'Pattern_White_Space' => '/Properties/Pattern_White_Space.php', - 'Pattern_Syntax' => '/Properties/Pattern_Syntax.php', - 'Prepended_Concatenation_Mark' => '/Properties/Prepended_Concatenation_Mark.php', - 'Regional_Indicator' => '/Properties/Regional_Indicator.php', - 'Math' => '/Properties/Math.php', - 'Alphabetic' => '/Properties/Alphabetic.php', - 'Lowercase' => '/Properties/Lowercase.php', - 'Uppercase' => '/Properties/Uppercase.php', - 'Cased' => '/Properties/Cased.php', - 'Case_Ignorable' => '/Properties/Case_Ignorable.php', - 'Changes_When_Lowercased' => '/Properties/Changes_When_Lowercased.php', - 'Changes_When_Uppercased' => '/Properties/Changes_When_Uppercased.php', - 'Changes_When_Titlecased' => '/Properties/Changes_When_Titlecased.php', - 'Changes_When_Casefolded' => '/Properties/Changes_When_Casefolded.php', - 'Changes_When_Casemapped' => '/Properties/Changes_When_Casemapped.php', - 'ID_Start' => '/Properties/ID_Start.php', - 'ID_Continue' => '/Properties/ID_Continue.php', - 'XID_Start' => '/Properties/XID_Start.php', - 'XID_Continue' => '/Properties/XID_Continue.php', - 'Default_Ignorable_Code_Point' => '/Properties/Default_Ignorable_Code_Point.php', - 'Grapheme_Extend' => '/Properties/Grapheme_Extend.php', - 'Grapheme_Base' => '/Properties/Grapheme_Base.php', - 'Grapheme_Link' => '/Properties/Grapheme_Link.php', -); diff --git a/src/Unicode/CharBuffer.php b/src/Unicode/CharBuffer.php index 287e536..a250ce5 100644 --- a/src/Unicode/CharBuffer.php +++ b/src/Unicode/CharBuffer.php @@ -36,7 +36,7 @@ class CharBuffer implements CharBufferInterface, TokenExtractInterface private int $sourcePreviewOffset = 0; public function __construct( - private CharBufferInterface $source, + private readonly CharBufferInterface $source, ) { } @@ -180,19 +180,11 @@ public function getTokenAsArray(): array private function getMatcher(): TokenMatcherInterface { - if (!isset($this->matcher)) { - $this->matcher = new Utf8TokenMatcher(); - } - - return $this->matcher; + return $this->matcher ??= new Utf8TokenMatcher(); } private function getTokenFactory(): TokenFactoryInterface { - if (!isset($this->tokenFactory)) { - $this->tokenFactory = new TokenFactory(); - } - - return $this->tokenFactory; + return $this->tokenFactory ??= new TokenFactory(); } } diff --git a/tests/AST/EopSymbolTest.php b/tests/AST/EopSymbolTest.php index d9a872d..c6fd517 100644 --- a/tests/AST/EopSymbolTest.php +++ b/tests/AST/EopSymbolTest.php @@ -4,13 +4,12 @@ namespace Remorhaz\UniLex\Test\AST; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\AST\EopSymbol; use Remorhaz\UniLex\AST\Node; -/** - * @covers \Remorhaz\UniLex\AST\EopSymbol - */ +#[CoversClass(EopSymbol::class)] class EopSymbolTest extends TestCase { public function testGetNode_CreatedWithValue_ReturnsSameValue(): void diff --git a/tests/AST/NodeTest.php b/tests/AST/NodeTest.php index 7d11318..2207c60 100644 --- a/tests/AST/NodeTest.php +++ b/tests/AST/NodeTest.php @@ -4,14 +4,13 @@ namespace Remorhaz\UniLex\Test\AST; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\AST\Exception\InvalidAttributeException; use Remorhaz\UniLex\AST\Node; use Remorhaz\UniLex\Exception as UniLexException; -/** - * @covers \Remorhaz\UniLex\AST\Node - */ +#[CoversClass(Node::class)] class NodeTest extends TestCase { public function testGetId_ConstructedWithValue_ReturnsSameValue(): void diff --git a/tests/AST/SymbolTest.php b/tests/AST/SymbolTest.php index e3fd31b..18cf69a 100644 --- a/tests/AST/SymbolTest.php +++ b/tests/AST/SymbolTest.php @@ -4,14 +4,13 @@ namespace Remorhaz\UniLex\Test\AST; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\AST\Node; use Remorhaz\UniLex\AST\Symbol; use Remorhaz\UniLex\Exception; -/** - * @covers \Remorhaz\UniLex\AST\Symbol - */ +#[CoversClass(Symbol::class)] class SymbolTest extends TestCase { public function testGetHeader_ConstructedWithValue_ReturnsSameValue(): void diff --git a/tests/AST/TranslatorTest.php b/tests/AST/TranslatorTest.php index 9f9dc06..851ac1c 100644 --- a/tests/AST/TranslatorTest.php +++ b/tests/AST/TranslatorTest.php @@ -4,6 +4,7 @@ namespace Remorhaz\UniLex\Test\AST; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\AST\AbstractTranslatorListener; use Remorhaz\UniLex\AST\Node; @@ -13,9 +14,7 @@ use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\Stack\PushInterface; -/** - * @covers \Remorhaz\UniLex\AST\Translator - */ +#[CoversClass(Translator::class)] class TranslatorTest extends TestCase { /** @@ -72,7 +71,7 @@ public function testRun_ListenerPushesRootChild_TriggersOnSymbolWithNodeOnce(): $listener ->expects($this->any()) ->method('onBeginProduction') - ->will($this->returnCallback($onBeginProduction)); + ->willReturnCallback($onBeginProduction); $listener ->expects($this->once()) ->method('onSymbol') diff --git a/tests/AST/TreeTest.php b/tests/AST/TreeTest.php index feda6be..1652a20 100644 --- a/tests/AST/TreeTest.php +++ b/tests/AST/TreeTest.php @@ -4,13 +4,12 @@ namespace Remorhaz\UniLex\Test\AST; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\AST\Tree; use Remorhaz\UniLex\Exception as UniLexException; -/** - * @covers \Remorhaz\UniLex\AST\Tree - */ +#[CoversClass(Tree::class)] class TreeTest extends TestCase { /** diff --git a/tests/Grammar/ContextFree/GrammarLoaderTest.php b/tests/Grammar/ContextFree/GrammarLoaderTest.php index e724302..0feebed 100644 --- a/tests/Grammar/ContextFree/GrammarLoaderTest.php +++ b/tests/Grammar/ContextFree/GrammarLoaderTest.php @@ -4,15 +4,14 @@ namespace Remorhaz\UniLex\Test\Grammar\ContextFree; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Example\SimpleExpr\Grammar\ConfigFile; use Remorhaz\UniLex\Example\SimpleExpr\Grammar\TokenType; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\Grammar\ContextFree\GrammarLoader; -/** - * @covers \Remorhaz\UniLex\Grammar\ContextFree\GrammarLoader - */ +#[CoversClass(GrammarLoader::class)] class GrammarLoaderTest extends TestCase { /** diff --git a/tests/Grammar/ContextFree/GrammarTest.php b/tests/Grammar/ContextFree/GrammarTest.php index 98720de..f35972f 100644 --- a/tests/Grammar/ContextFree/GrammarTest.php +++ b/tests/Grammar/ContextFree/GrammarTest.php @@ -4,13 +4,12 @@ namespace Remorhaz\UniLex\Test\Grammar\ContextFree; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\Grammar\ContextFree\Grammar; -/** - * @covers \Remorhaz\UniLex\Grammar\ContextFree\Grammar - */ +#[CoversClass(Grammar::class)] class GrammarTest extends TestCase { public function testGetRootSymbol_ConstructWithValue_ReturnsSameValue(): void diff --git a/tests/Grammar/ContextFree/ProductionTest.php b/tests/Grammar/ContextFree/ProductionTest.php index f88b779..e61625c 100644 --- a/tests/Grammar/ContextFree/ProductionTest.php +++ b/tests/Grammar/ContextFree/ProductionTest.php @@ -4,12 +4,11 @@ namespace Remorhaz\UniLex\Test\Grammar\ContextFree; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Grammar\ContextFree\Production; -/** - * @covers \Remorhaz\UniLex\Grammar\ContextFree\Production - */ +#[CoversClass(Production::class)] class ProductionTest extends TestCase { public function testCastToString_Constructed_ReturnsMatchingString(): void diff --git a/tests/Grammar/ContextFree/TokenFactoryTest.php b/tests/Grammar/ContextFree/TokenFactoryTest.php index 62afd9b..58c278c 100644 --- a/tests/Grammar/ContextFree/TokenFactoryTest.php +++ b/tests/Grammar/ContextFree/TokenFactoryTest.php @@ -4,13 +4,12 @@ namespace Remorhaz\UniLex\Test\Grammar\ContextFree; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Grammar\ContextFree\Grammar; use Remorhaz\UniLex\Grammar\ContextFree\TokenFactory; -/** - * @covers \Remorhaz\UniLex\Grammar\ContextFree\TokenFactory - */ +#[CoversClass(TokenFactory::class)] class TokenFactoryTest extends TestCase { public function testCreateEoiToken_EoiTokenAddedToGrammar_TokenIsEoiReturnsTrue(): void diff --git a/tests/IO/CharBufferTest.php b/tests/IO/CharBufferTest.php index dbc5866..8924420 100644 --- a/tests/IO/CharBufferTest.php +++ b/tests/IO/CharBufferTest.php @@ -4,14 +4,13 @@ namespace Remorhaz\UniLex\Test\IO; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\Lexer\Token; use Remorhaz\UniLex\IO\CharBuffer; -/** - * @covers \Remorhaz\UniLex\IO\CharBuffer - */ +#[CoversClass(CharBuffer::class)] class CharBufferTest extends TestCase { public function testIsEnd_EmptyBuffer_ReturnsTrue(): void diff --git a/tests/IO/StringBufferTest.php b/tests/IO/StringBufferTest.php index 5ae0067..6babf1c 100644 --- a/tests/IO/StringBufferTest.php +++ b/tests/IO/StringBufferTest.php @@ -4,14 +4,13 @@ namespace Remorhaz\UniLex\Test\IO; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\Lexer\Token; use Remorhaz\UniLex\IO\StringBuffer; -/** - * @covers \Remorhaz\UniLex\IO\StringBuffer - */ +#[CoversClass(StringBuffer::class)] class StringBufferTest extends TestCase { public function testIsEnd_EmptyBuffer_ReturnsTrue(): void diff --git a/tests/Lexer/TokenMatcherGeneratorTest.php b/tests/Lexer/TokenMatcherGeneratorTest.php index 1079413..2b46420 100644 --- a/tests/Lexer/TokenMatcherGeneratorTest.php +++ b/tests/Lexer/TokenMatcherGeneratorTest.php @@ -4,6 +4,8 @@ namespace Remorhaz\UniLex\Test\Lexer; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use ReflectionException; use Remorhaz\UniLex\Exception as UniLexException; @@ -17,9 +19,7 @@ use Remorhaz\UniLex\Lexer\TokenMatcherTemplate; use Remorhaz\UniLex\Unicode\CharBufferFactory; -/** - * @covers \Remorhaz\UniLex\Lexer\TokenMatcherGenerator - */ +#[CoversClass(TokenMatcherGenerator::class)] class TokenMatcherGeneratorTest extends TestCase { /** @@ -143,12 +143,9 @@ public function testLoad_InvalidOutput_ThrowsException(): void } /** - * @param string $text - * @param string $regExp - * @param string $expectedValue * @throws UniLexException - * @dataProvider providerValidRegExpInput */ + #[DataProvider('providerValidRegExpInput')] public function testLoad_ValidInput_MatchesValidToken(string $text, string $regExp, string $expectedValue): void { $matcherClass = $this->createTokenMatcherClassName(); @@ -188,20 +185,15 @@ public static function providerValidRegExpInput(): iterable } /** - * @param string $text - * @param string $firstRegExp - * @param string $secondRegExp - * @param int $token - * @param string $expectedValue * @throws UniLexException - * @dataProvider providerTwoRegExpSpecsInSameMode */ + #[DataProvider('providerTwoRegExpSpecsInSameMode')] public function testLoad_TwoRegExpSpecsInSameMode_MatchesValidToken( string $text, string $firstRegExp, string $secondRegExp, int $token, - string $expectedValue + string $expectedValue, ): void { $matcherClass = $this->createTokenMatcherClassName(); $spec = new TokenMatcherSpec($matcherClass, TokenMatcherTemplate::class); @@ -231,7 +223,7 @@ public function testLoad_TwoRegExpSpecsInSameMode_MatchesValidToken( /** * @return iterable */ - public function providerTwoRegExpSpecsInSameMode(): iterable + public static function providerTwoRegExpSpecsInSameMode(): iterable { return [ 'Different latin chars' => ['ab', 'a', 'b', 1, 'a'], @@ -243,18 +235,14 @@ public function providerTwoRegExpSpecsInSameMode(): iterable } /** - * @param string $text - * @param string $prefixRegExp - * @param string $regExp - * @param string $expectedValue - * @dataProvider providerValidRegExpInputWithPrefix * @throws UniLexException */ + #[DataProvider('providerValidRegExpInputWithPrefix')] public function testLoad_ValidInputWithPrefix_MatchesValidToken( string $text, string $prefixRegExp, string $regExp, - string $expectedValue + string $expectedValue, ): void { $matcherClass = $this->createTokenMatcherClassName(); $spec = new TokenMatcherSpec($matcherClass, TokenMatcherTemplate::class); @@ -291,6 +279,6 @@ private function createTokenMatcherClassName(): string { static $nextMatcherClassIndex = 1; - return __CLASS__ . '\TokenMatcher' . (string) $nextMatcherClassIndex++; + return __CLASS__ . '\TokenMatcher' . $nextMatcherClassIndex++; } } diff --git a/tests/Lexer/TokenMatcherSpecParserTest.php b/tests/Lexer/TokenMatcherSpecParserTest.php index fcc12ac..d57b20b 100644 --- a/tests/Lexer/TokenMatcherSpecParserTest.php +++ b/tests/Lexer/TokenMatcherSpecParserTest.php @@ -4,6 +4,7 @@ namespace Remorhaz\UniLex\Test\Lexer; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use ReflectionException; use Remorhaz\UniLex\Exception as UniLexException; @@ -11,9 +12,7 @@ use Remorhaz\UniLex\Lexer\TokenMatcherSpecParser; use Remorhaz\UniLex\Lexer\TokenMatcherTemplate; -/** - * @covers \Remorhaz\UniLex\Lexer\TokenMatcherSpecParser - */ +#[CoversClass(TokenMatcherSpecParser::class)] class TokenMatcherSpecParserTest extends TestCase { /** diff --git a/tests/Lexer/TokenPositionTest.php b/tests/Lexer/TokenPositionTest.php index 68c08bf..c4f5d3f 100644 --- a/tests/Lexer/TokenPositionTest.php +++ b/tests/Lexer/TokenPositionTest.php @@ -4,13 +4,13 @@ namespace Remorhaz\UniLex\Test\Lexer; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\Lexer\TokenPosition; -/** - * @covers \Remorhaz\UniLex\Lexer\TokenPosition - */ +#[CoversClass(TokenPosition::class)] class TokenPositionTest extends TestCase { /** @@ -34,16 +34,13 @@ public function testGetFinishOffset_ConstructWithValue_ReturnsSameValue(): void } /** - * @param int $startOffset - * @param int $finishOffset - * @param int $expectedLength - * @dataProvider providerOffsetsWithLength * @throws UniLexException */ + #[DataProvider('providerOffsetsWithLength')] public function testGetLength_Constructed_ReturnsCorrectSize( int $startOffset, int $finishOffset, - int $expectedLength + int $expectedLength, ): void { $position = new TokenPosition($startOffset, $finishOffset); $actualValue = $position->getLength(); diff --git a/tests/Lexer/TokenReaderTest.php b/tests/Lexer/TokenReaderTest.php index 72e5cfb..d9f3006 100644 --- a/tests/Lexer/TokenReaderTest.php +++ b/tests/Lexer/TokenReaderTest.php @@ -4,6 +4,7 @@ namespace Remorhaz\UniLex\Test\Lexer; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\IO\CharBufferInterface; @@ -17,9 +18,7 @@ use Remorhaz\UniLex\Unicode\Grammar\TokenFactory; use Remorhaz\UniLex\Unicode\Grammar\Utf8TokenMatcher; -/** - * @covers \Remorhaz\UniLex\Lexer\TokenReader - */ +#[CoversClass(TokenReader::class)] class TokenReaderTest extends TestCase { /** @@ -128,7 +127,7 @@ public function testRead_MatcherFailsAtEnd_ThrowsException(): void private function createFailingMatcher(): TokenMatcherInterface { - return new class implements TokenMatcherInterface + return new class () implements TokenMatcherInterface { public function getToken(): Token { @@ -144,7 +143,7 @@ public function match(CharBufferInterface $buffer, TokenFactoryInterface $tokenF private function createFailingAtEndMatcher(): TokenMatcherInterface { - return new class implements TokenMatcherInterface + return new class () implements TokenMatcherInterface { public function getToken(): Token { diff --git a/tests/Lexer/TokenSpecTest.php b/tests/Lexer/TokenSpecTest.php index 6e74900..2811764 100644 --- a/tests/Lexer/TokenSpecTest.php +++ b/tests/Lexer/TokenSpecTest.php @@ -4,12 +4,11 @@ namespace Remorhaz\UniLex\Test\Lexer; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Lexer\TokenSpec; -/** - * @covers \Remorhaz\UniLex\Lexer\TokenSpec - */ +#[CoversClass(TokenSpec::class)] class TokenSpecTest extends TestCase { public function testGetRegExp_ConstructWithValue_ReturnsSameValue(): void diff --git a/tests/Lexer/TokenTest.php b/tests/Lexer/TokenTest.php index 3ef4600..f953e9f 100644 --- a/tests/Lexer/TokenTest.php +++ b/tests/Lexer/TokenTest.php @@ -4,13 +4,12 @@ namespace Remorhaz\UniLex\Test\Lexer; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\Lexer\Token; -/** - * @covers \Remorhaz\UniLex\Lexer\Token - */ +#[CoversClass(Token::class)] class TokenTest extends TestCase { public function testGetType_ConstructedWithValue_ReturnsSameValue(): void diff --git a/tests/MemoryLeakTest.php b/tests/MemoryLeakTest.php index b7f4000..79441c3 100644 --- a/tests/MemoryLeakTest.php +++ b/tests/MemoryLeakTest.php @@ -4,6 +4,7 @@ namespace Remorhaz\UniLex\Test; +use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Example\SimpleExpr\Grammar\ConfigFile; use Remorhaz\UniLex\Example\SimpleExpr\Grammar\TokenType; @@ -25,9 +26,7 @@ use function memory_get_usage; use function var_export; -/** - * @coversNothing - */ +#[CoversNothing] class MemoryLeakTest extends TestCase { /** @@ -42,7 +41,7 @@ public function testMemoryLeak(): void $tableBuilder = new TableBuilder($grammar); $lookupTable = __DIR__ . '/../build/SimpleExprLookup.php'; $lookupTableDump = var_export($tableBuilder->getTable()->exportMap(), true); - $content = "loadLookupTable($lookupTable); $parser->run(); - $memory[$i] = memory_get_usage(); + $memory[$i] = memory_get_usage(true); } self::assertCount(1, array_unique($memory)); } diff --git a/tests/Parser/LL1/Lookup/FirstBuilderTest.php b/tests/Parser/LL1/Lookup/FirstBuilderTest.php index 1bd552c..9f87f1b 100644 --- a/tests/Parser/LL1/Lookup/FirstBuilderTest.php +++ b/tests/Parser/LL1/Lookup/FirstBuilderTest.php @@ -4,6 +4,8 @@ namespace Remorhaz\UniLex\Test\Parser\LL1\Lookup; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Example\SimpleExpr\Grammar\ConfigFile; use Remorhaz\UniLex\Example\SimpleExpr\Grammar\SymbolType; @@ -12,9 +14,7 @@ use Remorhaz\UniLex\Grammar\ContextFree\GrammarLoader; use Remorhaz\UniLex\Parser\LL1\Lookup\FirstBuilder; -/** - * @covers \Remorhaz\UniLex\Parser\LL1\Lookup\FirstBuilder - */ +#[CoversClass(FirstBuilder::class)] class FirstBuilderTest extends TestCase { /** @@ -22,12 +22,12 @@ class FirstBuilderTest extends TestCase * @param int $symbolId * @param list $expectedValue * @throws UnilexException - * @dataProvider providerValidGrammarFirsts */ + #[DataProvider('providerValidGrammarFirsts')] public function testGetFirst_ValidGrammar_ResultGetTokensReturnsMatchingValue( string $configFile, int $symbolId, - array $expectedValue + array $expectedValue, ): void { $grammar = GrammarLoader::loadFile($configFile); $first = (new FirstBuilder($grammar))->getFirst(); @@ -41,13 +41,11 @@ public function testGetFirst_ValidGrammar_ResultGetTokensReturnsMatchingValue( */ public static function providerValidGrammarFirsts(): iterable { - $data = []; foreach (self::getSimpleExprGrammarFirstList() as $key => $firsts) { [$symbolId, $expectedFirst] = $firsts; - $data["Grammar from SimpleExpr example, symbol {$key}"] = + yield "Grammar from SimpleExpr example, symbol $key" => [ConfigFile::getPath(), $symbolId, $expectedFirst]; } - return $data; } /** @@ -71,16 +69,13 @@ private static function getSimpleExprGrammarFirstList(): array } /** - * @param string $configFile - * @param int $symbolId - * @param bool $expectedValue * @throws UnilexException - * @dataProvider providerValidGrammarEpsilons */ + #[DataProvider('providerValidGrammarEpsilons')] public function testGetFirst_ValidGrammar_ResultHasEpsilonReturnsMatchingValue( string $configFile, int $symbolId, - bool $expectedValue + bool $expectedValue, ): void { $grammar = GrammarLoader::loadFile($configFile); $first = (new FirstBuilder($grammar))->getFirst(); @@ -93,13 +88,11 @@ public function testGetFirst_ValidGrammar_ResultHasEpsilonReturnsMatchingValue( */ public static function providerValidGrammarEpsilons(): iterable { - $data = []; foreach (self::getSimpleExprGrammarEpsilonList() as $key => $epsilon) { [$symbolId, $expectedValue] = $epsilon; - $data["Grammar from SimpleExpr example, symbol $key"] = + yield "Grammar from SimpleExpr example, symbol $key" => [ConfigFile::getPath(), $symbolId, $expectedValue]; } - return $data; } /** diff --git a/tests/Parser/LL1/Lookup/FirstTest.php b/tests/Parser/LL1/Lookup/FirstTest.php index ddf8ded..40a6e18 100644 --- a/tests/Parser/LL1/Lookup/FirstTest.php +++ b/tests/Parser/LL1/Lookup/FirstTest.php @@ -4,12 +4,12 @@ namespace Remorhaz\UniLex\Test\Parser\LL1\Lookup; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Parser\LL1\Lookup\First; -/** - * @covers \Remorhaz\UniLex\Parser\LL1\Lookup\First - */ +#[CoversClass(First::class)] class FirstTest extends TestCase { public function testGetProductionTokens_Constructed_ReturnsEmptyArray(): void @@ -66,19 +66,19 @@ public function testAddEpsilon_CalledTwiceForDifferentProductions_CounterTrigger } /** - * @dataProvider providerMergeProductionTokens * @param int $sourceProductionId * @param list $sourceTokenIdList * @param int $targetProductionId * @param list $targetTokenIdList * @param list $expectedValue */ + #[DataProvider('providerMergeProductionTokens')] public function testMergeProductionTokens_TokensSet_TargetGetTokensReturnsMergedTokens( int $sourceProductionId, array $sourceTokenIdList, int $targetProductionId, array $targetTokenIdList, - array $expectedValue + array $expectedValue, ): void { $lookupFirst = new First(); $lookupFirst->addToken($sourceProductionId, ...$sourceTokenIdList); diff --git a/tests/Parser/LL1/Lookup/FollowBuilderTest.php b/tests/Parser/LL1/Lookup/FollowBuilderTest.php index 3871a44..2383f3f 100644 --- a/tests/Parser/LL1/Lookup/FollowBuilderTest.php +++ b/tests/Parser/LL1/Lookup/FollowBuilderTest.php @@ -4,6 +4,8 @@ namespace Remorhaz\UniLex\Test\Parser\LL1\Lookup; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Example\SimpleExpr\Grammar\ConfigFile; use Remorhaz\UniLex\Example\SimpleExpr\Grammar\SymbolType; @@ -13,9 +15,7 @@ use Remorhaz\UniLex\Parser\LL1\Lookup\FirstBuilder; use Remorhaz\UniLex\Parser\LL1\Lookup\FollowBuilder; -/** - * @covers \Remorhaz\UniLex\Parser\LL1\Lookup\FollowBuilder - */ +#[CoversClass(FollowBuilder::class)] class FollowBuilderTest extends TestCase { /** @@ -23,12 +23,12 @@ class FollowBuilderTest extends TestCase * @param int $symbolId * @param list $expectedValue * @throws UnilexException - * @dataProvider providerValidGrammars */ + #[DataProvider('providerValidGrammars')] public function testGetFollow_ValidGrammar_ResultGetReturnsMatchingValue( string $configFile, int $symbolId, - array $expectedValue + array $expectedValue, ): void { $grammar = GrammarLoader::loadFile($configFile); $first = (new FirstBuilder($grammar))->getFirst(); diff --git a/tests/Parser/LL1/Lookup/FollowTest.php b/tests/Parser/LL1/Lookup/FollowTest.php index fa6bfd2..6a0318e 100644 --- a/tests/Parser/LL1/Lookup/FollowTest.php +++ b/tests/Parser/LL1/Lookup/FollowTest.php @@ -4,13 +4,16 @@ namespace Remorhaz\UniLex\Test\Parser\LL1\Lookup; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Parser\LL1\Lookup\Follow; +use Remorhaz\UniLex\Parser\LL1\Lookup\Set; -/** - * @covers \Remorhaz\UniLex\Parser\LL1\Lookup\Follow - * @covers \Remorhaz\UniLex\Parser\LL1\Lookup\Set - */ +#[ + CoversClass(Follow::class), + CoversClass(Set::class), +] class FollowTest extends TestCase { public function testGetTokens_Constructed_ReturnsEmptyArray(): void @@ -21,8 +24,8 @@ public function testGetTokens_Constructed_ReturnsEmptyArray(): void /** * @param list $tokenIdList - * @dataProvider providerAddTokenCalledOnce */ + #[DataProvider('providerAddTokenCalledOnce')] public function testAddToken_CalledOnce_GetTokenReturnsAddedTokens(array $tokenIdList): void { $lookupFirst = new Follow(); @@ -48,12 +51,12 @@ public static function providerAddTokenCalledOnce(): iterable * @param list $firstTokenIdList * @param list $secondTokenIdList * @param list $expectedValue - * @dataProvider providerAddTokenCalledTwice */ + #[DataProvider('providerAddTokenCalledTwice')] public function testAddToken_CalledTwice_GetTokenReturnsMergedTokens( array $firstTokenIdList, array $secondTokenIdList, - array $expectedValue + array $expectedValue, ): void { $lookupFirst = new Follow(); $lookupFirst->addToken(1, ...$firstTokenIdList); @@ -67,12 +70,12 @@ public function testAddToken_CalledTwice_GetTokenReturnsMergedTokens( * @param list $firstTokenIdList * @param list $secondTokenIdList * @param list $mergedList - * @dataProvider providerAddTokenCalledTwice */ + #[DataProvider('providerAddTokenCalledTwice')] public function testAddToken_CalledTwice_GetChangeCountReturnsMergedTokensAmount( array $firstTokenIdList, array $secondTokenIdList, - array $mergedList + array $mergedList, ): void { $lookupFirst = new Follow(); $lookupFirst->addToken(1, ...$firstTokenIdList); @@ -112,19 +115,19 @@ public function testResetChangeCount_CounterTriggered_GetChangeCountReturnsZero( } /** - * @dataProvider providerMergeTokens * @param int $sourceProductionId * @param list $sourceTokenIdList * @param int $targetProductionId * @param list $targetTokenIdList * @param list $expectedValue */ + #[DataProvider('providerMergeTokens')] public function testMergeTokens_TokensSet_TargetGetTokensReturnsMergedTokens( int $sourceProductionId, array $sourceTokenIdList, int $targetProductionId, array $targetTokenIdList, - array $expectedValue + array $expectedValue, ): void { $lookupFirst = new Follow(); $lookupFirst->addToken($sourceProductionId, ...$sourceTokenIdList); diff --git a/tests/Parser/LL1/Lookup/TableBuilderTest.php b/tests/Parser/LL1/Lookup/TableBuilderTest.php index c01507a..f4b7e44 100644 --- a/tests/Parser/LL1/Lookup/TableBuilderTest.php +++ b/tests/Parser/LL1/Lookup/TableBuilderTest.php @@ -4,6 +4,8 @@ namespace Remorhaz\UniLex\Test\Parser\LL1\Lookup; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Example\SimpleExpr\Grammar\ConfigFile; use Remorhaz\UniLex\Example\SimpleExpr\Grammar\SymbolType; @@ -11,22 +13,21 @@ use Remorhaz\UniLex\Exception; use Remorhaz\UniLex\Grammar\ContextFree\GrammarLoader; use Remorhaz\UniLex\Parser\LL1\Lookup\TableBuilder; +use Remorhaz\UniLex\Parser\LL1\Lookup\TableConflictChecker; -/** - * @covers \Remorhaz\UniLex\Parser\LL1\Lookup\TableBuilder - * @covers \Remorhaz\UniLex\Parser\LL1\Lookup\TableConflictChecker - */ +#[ + CoversClass(TableBuilder::class), + CoversClass(TableConflictChecker::class), +] class TableBuilderTest extends TestCase { /** - * @param string $configFile - * @param array $expectedValue * @throws Exception - * @dataProvider providerValidGrammarTables */ + #[DataProvider('providerValidGrammarTables')] public function testGetFirst_ValidGrammar_ResultGetTokensReturnsMatchingValue( string $configFile, - array $expectedValue + array $expectedValue, ): void { $grammar = GrammarLoader::loadFile($configFile); $actualValue = (new TableBuilder($grammar))->getTable()->exportMap(); diff --git a/tests/Parser/LL1/Lookup/TableConflictCheckerTest.php b/tests/Parser/LL1/Lookup/TableConflictCheckerTest.php index ca73d0c..2c9a639 100644 --- a/tests/Parser/LL1/Lookup/TableConflictCheckerTest.php +++ b/tests/Parser/LL1/Lookup/TableConflictCheckerTest.php @@ -4,6 +4,7 @@ namespace Remorhaz\UniLex\Test\Parser\LL1\Lookup; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\Grammar\ContextFree\GrammarLoader; @@ -11,9 +12,7 @@ use Remorhaz\UniLex\Parser\LL1\Lookup\FollowBuilder; use Remorhaz\UniLex\Parser\LL1\Lookup\TableConflictChecker; -/** - * @covers \Remorhaz\UniLex\Parser\LL1\Lookup\TableConflictChecker - */ +#[CoversClass(TableConflictChecker::class)] class TableConflictCheckerTest extends TestCase { /** diff --git a/tests/Parser/LL1/Lookup/TableTest.php b/tests/Parser/LL1/Lookup/TableTest.php index c7b634c..d0b1096 100644 --- a/tests/Parser/LL1/Lookup/TableTest.php +++ b/tests/Parser/LL1/Lookup/TableTest.php @@ -4,13 +4,12 @@ namespace Remorhaz\UniLex\Test\Parser\LL1\Lookup; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\Parser\LL1\Lookup\Table; -/** - * @covers \Remorhaz\UniLex\Parser\LL1\Lookup\Table - */ +#[CoversClass(Table::class)] class TableTest extends TestCase { /** diff --git a/tests/Parser/LL1/ParserTest.php b/tests/Parser/LL1/ParserTest.php index 2449d9d..990985a 100644 --- a/tests/Parser/LL1/ParserTest.php +++ b/tests/Parser/LL1/ParserTest.php @@ -4,6 +4,8 @@ namespace Remorhaz\UniLex\Test\Parser\LL1; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Example\SimpleExpr\Grammar\ConfigFile; use Remorhaz\UniLex\Example\SimpleExpr\Grammar\TokenType; @@ -19,17 +21,15 @@ use Remorhaz\UniLex\Lexer\TokenMatcherByType; use Remorhaz\UniLex\Parser\LL1\UnexpectedTokenException; -/** - * @covers \Remorhaz\UniLex\Parser\LL1\Parser - */ +#[CoversClass(Parser::class)] class ParserTest extends TestCase { /** * @param string $configFile * @param list $input * @throws UniLexException - * @dataProvider providerValidGrammarInput */ + #[DataProvider('providerValidGrammarInput')] public function testRun_ValidBuffer_OnTokenTriggeredForEachToken(string $configFile, array $input): void { $grammar = GrammarLoader::loadFile($configFile); diff --git a/tests/Parser/SymbolTest.php b/tests/Parser/SymbolTest.php index 857f9f9..d386d54 100644 --- a/tests/Parser/SymbolTest.php +++ b/tests/Parser/SymbolTest.php @@ -4,13 +4,13 @@ namespace Remorhaz\UniLex\Test\Parser; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception; use Remorhaz\UniLex\Parser\Symbol; -/** - * @covers \Remorhaz\UniLex\Parser\Symbol - */ +#[CoversClass(Symbol::class)] class SymbolTest extends TestCase { public function testGetIndex_ConstructedWithIndex_ReturnsSameValue(): void @@ -35,8 +35,8 @@ public function testGetAttribute_AttributeNotSet_ThrowsException(): void /** * @throws Exception - * @dataProvider providerAttribute */ + #[DataProvider('providerAttribute')] public function testGetAttribute_AttributeSet_ReturnsSameValue(mixed $value, mixed $expectedValue): void { $symbol = new Symbol(1, 2); diff --git a/tests/RegExp/FSM/DfaBuilderTest.php b/tests/RegExp/FSM/DfaBuilderTest.php index 25cc0f7..f29ac55 100644 --- a/tests/RegExp/FSM/DfaBuilderTest.php +++ b/tests/RegExp/FSM/DfaBuilderTest.php @@ -4,6 +4,7 @@ namespace Remorhaz\UniLex\Test\RegExp\FSM; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\IntRangeSets\Range; use Remorhaz\IntRangeSets\RangeInterface; @@ -16,9 +17,7 @@ use function array_map; -/** - * @covers \Remorhaz\UniLex\RegExp\FSM\DfaBuilder - */ +#[CoversClass(DfaBuilder::class)] class DfaBuilderTest extends TestCase { /** diff --git a/tests/RegExp/FSM/DfaTest.php b/tests/RegExp/FSM/DfaTest.php index 5e3da4f..e3da585 100644 --- a/tests/RegExp/FSM/DfaTest.php +++ b/tests/RegExp/FSM/DfaTest.php @@ -4,14 +4,13 @@ namespace Remorhaz\UniLex\Test\RegExp\FSM; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\RegExp\FSM\Dfa; use Remorhaz\UniLex\RegExp\FSM\SymbolTable; -/** - * @covers \Remorhaz\UniLex\RegExp\FSM\Dfa - */ +#[CoversClass(Dfa::class)] class DfaTest extends TestCase { public function testGetStateMap_CalledTwice_ReturnsSameInstance(): void diff --git a/tests/RegExp/FSM/LanguageBuilderTest.php b/tests/RegExp/FSM/LanguageBuilderTest.php index f04878a..20aea7d 100644 --- a/tests/RegExp/FSM/LanguageBuilderTest.php +++ b/tests/RegExp/FSM/LanguageBuilderTest.php @@ -4,6 +4,8 @@ namespace Remorhaz\UniLex\Test\RegExp\FSM; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Remorhaz\IntRangeSets\RangeInterface; use Remorhaz\IntRangeSets\RangeSetInterface; @@ -17,9 +19,7 @@ use function array_map; -/** - * @covers \Remorhaz\UniLex\RegExp\FSM\LanguageBuilder - */ +#[CoversClass(LanguageBuilder::class)] class LanguageBuilderTest extends TestCase { /** @@ -65,16 +65,13 @@ public function testAddTransition_NoTransitionsAdded_TransitionMapContainsMatchi } /** - * @param array $firstTransitionData - * @param array $secondTransitionData - * @param array $expectedValue * @throws UniLexException - * @dataProvider providerAddTransitionCalledTwiceTransitions */ + #[DataProvider('providerAddTransitionCalledTwiceTransitions')] public function testAddTransition_TransitionWithSameRangeAdded_TransitionMapContainsMatchingList( array $firstTransitionData, array $secondTransitionData, - array $expectedValue + array $expectedValue, ): void { $symbolTable = new SymbolTable(); $transitionMap = new TransitionMap($this->createStateMap()); @@ -112,20 +109,15 @@ public static function providerAddTransitionCalledTwiceTransitions(): iterable } /** - * @param array $firstTransitionData - * @param array $secondTransitionData - * @param array $firstRangeData - * @param array $secondRangeData - * @param array $expectedValue * @throws UniLexException - * @dataProvider providerAddTransitionCalledTwiceSymbols */ + #[DataProvider('providerAddTransitionCalledTwiceSymbols')] public function testAddTransition_TransitionWithSameRangeAdded_GetSymbolMapReturnsMatchingValue( array $firstTransitionData, array $secondTransitionData, array $firstRangeData, array $secondRangeData, - array $expectedValue + array $expectedValue, ): void { $symbolTable = new SymbolTable(); $transitionMap = new TransitionMap($this->createStateMap()); @@ -134,13 +126,13 @@ public function testAddTransition_TransitionWithSameRangeAdded_GetSymbolMapRetur $languageBuilder->addTransition( $stateIn, $stateOut, - ...array_map([$this, 'importRange'], $firstRangeData) + ...array_map($this->importRange(...), $firstRangeData), ); [$stateIn, $stateOut] = $secondTransitionData; $languageBuilder->addTransition( $stateIn, $stateOut, - ...array_map([$this, 'importRange'], $secondRangeData) + ...array_map($this->importRange(...), $secondRangeData), ); $actualValue = $this->exportSymbolMap($symbolTable->getRangeSetList()); self::assertEquals($expectedValue, $actualValue); @@ -190,41 +182,55 @@ public function stateExists(int $stateId): bool } /** - * @param RangeSetInterface[] $symbolMap - * @return array + * @param array $symbolMap + * @return array> */ private function exportSymbolMap(array $symbolMap): array { $result = []; foreach ($symbolMap as $symbolId => $rangeSet) { $result[$symbolId] = array_map( - function (RangeInterface $range): array { - return [$range->getStart(), $range->getFinish()]; - }, - $rangeSet->getRanges() + fn (RangeInterface $range): array => [$range->getStart(), $range->getFinish()], + $rangeSet->getRanges(), ); } return $result; } + /** + * @param array{int, int|null} $rangeData + * @return RangeInterface + */ private function importRange(array $rangeData): RangeInterface { return new Range(...$rangeData); } + /** + * @param list ...$rangeDataList + * @return list + */ private function importRanges(array ...$rangeDataList): array { - return array_map([$this, 'importRange'], $rangeDataList); + return array_map($this->importRange(...), $rangeDataList); } + /** + * @param RangeInterface $range + * @return array{int, int} + */ private function exportRange(RangeInterface $range): array { return [$range->getStart(), $range->getFinish()]; } + /** + * @param RangeSetInterface $rangeSet + * @return list> + */ private function exportRangeSet(RangeSetInterface $rangeSet): array { - return array_map([$this, 'exportRange'], $rangeSet->getRanges()); + return array_map($this->exportRange(...), $rangeSet->getRanges()); } } diff --git a/tests/RegExp/FSM/NfaBuilderTest.php b/tests/RegExp/FSM/NfaBuilderTest.php index ea1ab89..3f4abee 100644 --- a/tests/RegExp/FSM/NfaBuilderTest.php +++ b/tests/RegExp/FSM/NfaBuilderTest.php @@ -4,6 +4,8 @@ namespace Remorhaz\UniLex\Test\RegExp\FSM; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Remorhaz\UCD\PropertyRangeLoaderInterface; use Remorhaz\UniLex\AST\Node; @@ -13,9 +15,7 @@ use Remorhaz\UniLex\RegExp\FSM\NfaBuilder; use Remorhaz\UniLex\Stack\SymbolStack; -/** - * @covers \Remorhaz\UniLex\RegExp\FSM\NfaBuilder - */ +#[CoversClass(NfaBuilder::class)] class NfaBuilderTest extends TestCase { /** @@ -52,10 +52,9 @@ public function testOnBeginProduction_TerminalNodeWithChild_ThrowsException(stri } /** - * @param string $name * @throws UniLexException - * @dataProvider providerNotTerminalNodeNames */ + #[DataProvider('providerNotTerminalNodeNames')] public function testOnBeginProduction_NotTerminalNodeWithoutChildren_ThrowsException(string $name): void { $node = new Node(1, $name); @@ -81,10 +80,9 @@ public static function providerNotTerminalNodeNames(): iterable } /** - * @param string $name * @throws UniLexException - * @dataProvider providerTerminalNodeNames */ + #[DataProvider('providerTerminalNodeNames')] public function testOnBeginProduction_TerminalNode_PushesNothingToStack(string $name): void { $node = new Node(1, $name); @@ -178,10 +176,9 @@ public function testOnFinishProduction_ControlSymbolWithInvalidCode_ThrowsExcept } /** - * @param string $name * @throws UniLexException - * @dataProvider providerNotImplementedNodeNames */ + #[DataProvider('providerNotImplementedNodeNames')] public function testOnBeginProduction_NotImplementedNode_ThrowsException(string $name): void { $propertyLoader = $this->createMock(PropertyRangeLoaderInterface::class); @@ -375,10 +372,9 @@ public function testOnFinishProduction_SymbolAnyNodeInRange_ThrowsException(): v } /** - * @param int $code * @throws UniLexException - * @dataProvider providerNotImplementedSimpleEscapeCodes */ + #[DataProvider('providerNotImplementedSimpleEscapeCodes')] public function testOnFinishProduction_SimpleEscapeWithNotImplementedCode_ThrowsException(int $code): void { $propertyLoader = $this->createMock(PropertyRangeLoaderInterface::class); diff --git a/tests/RegExp/FSM/NfaCalcTest.php b/tests/RegExp/FSM/NfaCalcTest.php index f26511b..07fc8f4 100644 --- a/tests/RegExp/FSM/NfaCalcTest.php +++ b/tests/RegExp/FSM/NfaCalcTest.php @@ -4,6 +4,7 @@ namespace Remorhaz\UniLex\Test\RegExp\FSM; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\IntRangeSets\Range; use Remorhaz\IntRangeSets\RangeInterface; @@ -14,9 +15,7 @@ use function array_map; -/** - * @covers \Remorhaz\UniLex\RegExp\FSM\NfaCalc - */ +#[CoversClass(NfaCalc::class)] class NfaCalcTest extends TestCase { /** @@ -41,7 +40,6 @@ public function testGetSymbolMoves_ValidNfa_ReturnsMatchingStateList(): void } /** - * @return Nfa * @throws UniLexException */ private function createNfa(): Nfa @@ -66,12 +64,10 @@ private function createNfa(): Nfa $symbolId, RangeSet::createUnsafe( ...array_map( - function (array $rangeData): RangeInterface { - return new Range(...$rangeData); - }, - $rangeSetData - ) - ) + fn (array $rangeData): RangeInterface => new Range(...$rangeData), + $rangeSetData, + ), + ), ); } $symbolTransitionList = [[2, 3, [0]], [4, 5, [1]], [7, 8, [0]], [8, 9, [1]], [9, 10, [1]]]; diff --git a/tests/RegExp/FSM/NfaTest.php b/tests/RegExp/FSM/NfaTest.php index 2bef2c2..165c9c3 100644 --- a/tests/RegExp/FSM/NfaTest.php +++ b/tests/RegExp/FSM/NfaTest.php @@ -4,12 +4,11 @@ namespace Remorhaz\UniLex\Test\RegExp\FSM; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\RegExp\FSM\Nfa; -/** - * @covers \Remorhaz\UniLex\RegExp\FSM\Nfa - */ +#[CoversClass(Nfa::class)] class NfaTest extends TestCase { public function testGetStateMap_CalledTwice_ReturnsSameInstance(): void diff --git a/tests/RegExp/FSM/ParsedFsmTest.php b/tests/RegExp/FSM/ParsedFsmTest.php index 8ee0ec3..18e8440 100644 --- a/tests/RegExp/FSM/ParsedFsmTest.php +++ b/tests/RegExp/FSM/ParsedFsmTest.php @@ -4,6 +4,8 @@ namespace Remorhaz\UniLex\Test\RegExp\FSM; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Remorhaz\IntRangeSets\RangeInterface; use Remorhaz\IntRangeSets\RangeSetInterface; @@ -15,24 +17,18 @@ use function array_map; -/** - * @covers \Remorhaz\UniLex\RegExp\FSM\NfaBuilder - */ +#[CoversClass(NfaBuilder::class)] class ParsedFsmTest extends TestCase { /** - * @dataProvider providerRegExpStateMaps - * @param string $text - * @param array $expectedSymbolTransitionList - * @param array $expectedEpsilonTransitionList - * @param array $expectedSymbolTable * @throws UniLexException */ + #[DataProvider('providerRegExpStateMaps')] public function testStateMapBuilder_ValidAST_BuildsMatchingStateMap( string $text, array $expectedSymbolTransitionList, array $expectedEpsilonTransitionList, - array $expectedSymbolTable + array $expectedSymbolTable, ): void { $buffer = CharBufferFactory::createFromString($text); $tree = new Tree(); @@ -47,31 +43,29 @@ public function testStateMapBuilder_ValidAST_BuildsMatchingStateMap( } /** - * @return iterable}> + * @return iterable */ public static function providerRegExpStateMaps(): iterable { - $data = []; - $rangeTransitionList = []; $epsilonTransitionList = []; $epsilonTransitionList[1][2] = true; $symbolTable = []; - $data["Empty string"] = ['', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Empty string" => ['', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[1][2] = [0]; $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x61, 0x61]]; - $data["Single symbol"] = ['a', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Single symbol" => ['a', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[1][2] = [0]; $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x00, 0x10FFFF]]; - $data["Single dot"] = ['.', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Single dot" => ['.', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[3][4] = [0]; @@ -84,7 +78,7 @@ public static function providerRegExpStateMaps(): iterable $symbolTable = []; $symbolTable[0] = [[0x61, 0x61]]; $symbolTable[1] = [[0x62, 0x62]]; - $data["Alternative of two symbols"] = ['a|b', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Alternative of two symbols" => ['a|b', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[3][4] = [0]; @@ -96,7 +90,7 @@ public static function providerRegExpStateMaps(): iterable $epsilonTransitionList[6][2] = true; $symbolTable = []; $symbolTable[0] = [[0x61, 0x61]]; - $data["Alternative of symbol and empty string"] = + yield "Alternative of symbol and empty string" => ['a|', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; @@ -112,7 +106,7 @@ public static function providerRegExpStateMaps(): iterable $epsilonTransitionList[8][2] = true; $symbolTable = []; $symbolTable[0] = [[0x61, 0x61]]; - $data["Alternative of symbol and two empty strings"] = + yield "Alternative of symbol and two empty strings" => ['|a|', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; @@ -122,7 +116,7 @@ public static function providerRegExpStateMaps(): iterable $symbolTable = []; $symbolTable[0] = [[0x61, 0x61]]; $symbolTable[1] = [[0x62, 0x62]]; - $data["Concatenation of two symbols"] = ['ab', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Concatenation of two symbols" => ['ab', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[1][3] = [0]; @@ -132,13 +126,13 @@ public static function providerRegExpStateMaps(): iterable $symbolTable = []; $symbolTable[0] = [[0x61, 0x61]]; $symbolTable[1] = [[0x62, 0x62]]; - $data["Concatenation of symbol and repeated symbol"] = + yield "Concatenation of symbol and repeated symbol" => ['ab{2}', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $epsilonTransitionList = []; $symbolTable = []; - $data["Single zero repeat"] = ['a{0}', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Single zero repeat" => ['a{0}', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[1][3] = [0]; @@ -155,7 +149,7 @@ public static function providerRegExpStateMaps(): iterable $symbolTable[1] = [[0x62, 0x62]]; $symbolTable[2] = [[0x63, 0x63]]; $symbolTable[3] = [[0x64, 0x64]]; - $data["Concatenation of two symbols and grouped alternative of two symbols"] = + yield "Concatenation of two symbols and grouped alternative of two symbols" => ['a(b|c)d', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; @@ -170,7 +164,7 @@ public static function providerRegExpStateMaps(): iterable $epsilonTransitionList[6][2] = true; $symbolTable = []; $symbolTable[0] = [[0x61, 0x61]]; - $data["Symbol with finite limit"] = ['a{2,5}', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Symbol with finite limit" => ['a{2,5}', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[1][2] = [0]; @@ -178,7 +172,7 @@ public static function providerRegExpStateMaps(): iterable $epsilonTransitionList[1][2] = true; $symbolTable = []; $symbolTable[0] = [[0x61, 0x61]]; - $data["Optional symbol"] = ['a?', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Optional symbol" => ['a?', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[1][3] = [0]; @@ -191,7 +185,7 @@ public static function providerRegExpStateMaps(): iterable $epsilonTransitionList[6][5] = true; $symbolTable = []; $symbolTable[0] = [[0x61, 0x61]]; - $data["Symbol with infinite limit"] = ['a{2,}', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Symbol with infinite limit" => ['a{2,}', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[3][4] = [0]; @@ -202,49 +196,49 @@ public static function providerRegExpStateMaps(): iterable $epsilonTransitionList[4][3] = true; $symbolTable = []; $symbolTable[0] = [[0x61, 0x61]]; - $data["Kleene star applied to symbol"] = ['a*', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Kleene star applied to symbol" => ['a*', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[1][2] = [0]; $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x61, 0x61]]; - $data["Escaped Unicode symbol"] = ['\\u0061', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Escaped Unicode symbol" => ['\\u0061', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[1][2] = [0]; $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x7F, 0x7F]]; - $data["Escaped Unicode symbol"] = ['\\c?', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Escaped control symbol" => ['\\c?', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[1][2] = [0]; $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x07, 0x07]]; - $data["Escaped non-printable symbol"] = ['\\a', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Escaped non-printable symbol" => ['\\a', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[1][2] = [0]; $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x46, 0x46]]; - $data["Escaped arbitrary symbol"] = ['\\F', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Escaped arbitrary symbol" => ['\\F', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[1][2] = [0]; $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x2E, 0x2E]]; - $data["Escaped meta-symbol"] = ['\\.', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Escaped meta-symbol" => ['\\.', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[1][2] = [0]; $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x61, 0x62]]; - $data["Two neighbour symbols in a class"] = + yield "Two neighbour symbols in a class" => ['[ab]', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; @@ -252,14 +246,14 @@ public static function providerRegExpStateMaps(): iterable $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x61, 0x61]]; - $data["Two equal symbols in a class"] = ['[aa]', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Two equal symbols in a class" => ['[aa]', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[1][2] = [0]; $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x61, 0x61], [0x63, 0x63]]; - $data["Two not neighbour symbols in a class in inverted order"] = + yield "Two not neighbour symbols in a class in inverted order" => ['[ca]', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; @@ -267,14 +261,14 @@ public static function providerRegExpStateMaps(): iterable $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x00, 0x60], [0x62, 0x62], [0x64, 0x10FFFF]]; - $data["Two symbols in inverted class"] = ['[^ac]', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; + yield "Two symbols in inverted class" => ['[^ac]', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; $rangeTransitionList[1][2] = [0]; $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x61, 0x63]]; - $data["Single range between symbols in class"] = + yield "Single range between symbols in class" => ['[a-c]', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; @@ -282,7 +276,7 @@ public static function providerRegExpStateMaps(): iterable $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x46, 0x4B]]; - $data["Single range between ordinary escape and symbol in class"] = + yield "Single range between ordinary escape and symbol in class" => ['[\\F-K]', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; @@ -290,7 +284,7 @@ public static function providerRegExpStateMaps(): iterable $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x7F, 0x0429]]; - $data["Single range between control and Unicode escapes in class"] = + yield "Single range between control and Unicode escapes in class" => ['[\\c?-\\u0429]', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; @@ -298,7 +292,7 @@ public static function providerRegExpStateMaps(): iterable $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x0410, 0x0429]]; - $data["Single range between ordinary non-ASCII escape and raw non-ASCII symbol in class"] = + yield "Single range between ordinary non-ASCII escape and raw non-ASCII symbol in class" => ['[\\А-Щ]', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; @@ -306,7 +300,7 @@ public static function providerRegExpStateMaps(): iterable $epsilonTransitionList = []; $symbolTable = []; $symbolTable[0] = [[0x09, 0x7A]]; - $data["Two intersecting ranges in class"] = + yield "Two intersecting ranges in class" => ['[\\t-aA-z]', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; $rangeTransitionList = []; @@ -322,25 +316,21 @@ public static function providerRegExpStateMaps(): iterable $symbolTable[0] = [[0x35, 0x35]]; $symbolTable[1] = [[0x61, 0x61]]; $symbolTable[2] = [[0x30, 0x34], [0x36, 0x39]]; - $data["One alternative is a part of another's class"] = + yield "One alternative is a part of another's class" => ['5|a[0-9]', $rangeTransitionList, $epsilonTransitionList, $symbolTable]; - - return $data; } /** - * @param RangeSetInterface[] $rangeSetList - * @return array + * @param array $rangeSetList + * @return array> */ private function exportRangeSetList(array $rangeSetList): array { $result = []; foreach ($rangeSetList as $symbolId => $rangeSet) { $result[$symbolId] = array_map( - function (RangeInterface $range): array { - return [$range->getStart(), $range->getFinish()]; - }, - $rangeSet->getRanges() + fn (RangeInterface $range): array => [$range->getStart(), $range->getFinish()], + $rangeSet->getRanges(), ); } return $result; diff --git a/tests/RegExp/FSM/StateMapTest.php b/tests/RegExp/FSM/StateMapTest.php index bc18dc8..9dbcf51 100644 --- a/tests/RegExp/FSM/StateMapTest.php +++ b/tests/RegExp/FSM/StateMapTest.php @@ -4,13 +4,12 @@ namespace Remorhaz\UniLex\Test\RegExp\FSM; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\RegExp\FSM\StateMap; -/** - * @covers \Remorhaz\UniLex\RegExp\FSM\StateMap - */ +#[CoversClass(StateMap::class)] class StateMapTest extends TestCase { /** diff --git a/tests/RegExp/FSM/SymbolTableTest.php b/tests/RegExp/FSM/SymbolTableTest.php index 065ae27..c05357a 100644 --- a/tests/RegExp/FSM/SymbolTableTest.php +++ b/tests/RegExp/FSM/SymbolTableTest.php @@ -4,15 +4,14 @@ namespace Remorhaz\UniLex\Test\RegExp\FSM; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\IntRangeSets\Range; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\IntRangeSets\RangeSet; use Remorhaz\UniLex\RegExp\FSM\SymbolTable; -/** - * @covers \Remorhaz\UniLex\RegExp\FSM\SymbolTable - */ +#[CoversClass(SymbolTable::class)] class SymbolTableTest extends TestCase { public function testAddSymbol_NoSymbolAdded_ReturnsZero(): void diff --git a/tests/RegExp/FSM/TransitionMapTest.php b/tests/RegExp/FSM/TransitionMapTest.php index f0b1411..12f5d3c 100644 --- a/tests/RegExp/FSM/TransitionMapTest.php +++ b/tests/RegExp/FSM/TransitionMapTest.php @@ -5,14 +5,13 @@ namespace Remorhaz\UniLex\Test\RegExp\FSM; use Closure; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\RegExp\FSM\StateMapInterface; use Remorhaz\UniLex\RegExp\FSM\TransitionMap; -/** - * @covers \Remorhaz\UniLex\RegExp\FSM\TransitionMap - */ +#[CoversClass(TransitionMap::class)] class TransitionMapTest extends TestCase { /** @@ -84,9 +83,7 @@ public function testTransitionExists_ToStateNotExists_ThrowsException(): void */ public function testTransitionExists_TransitionAdded_ReturnsTrue(): void { - $stateExists = function (): bool { - return true; - }; + $stateExists = fn (): bool => true; $stateMap = $this->createStateExistenceProvider($stateExists); $transitionMap = new TransitionMap($stateMap); $transitionMap->addTransition(1, 2, true); @@ -99,9 +96,7 @@ public function testTransitionExists_TransitionAdded_ReturnsTrue(): void */ public function testTransitionExists_TransitionNotAdded_ReturnsFalse(): void { - $stateExists = function (): bool { - return true; - }; + $stateExists = fn (): bool => true; $stateMap = $this->createStateExistenceProvider($stateExists); $transitionMap = new TransitionMap($stateMap); $actualValue = $transitionMap->transitionExists(1, 2); @@ -114,9 +109,7 @@ public function testTransitionExists_TransitionNotAdded_ReturnsFalse(): void */ public function testGetTransition_FromStateNotExists_ThrowsException(): void { - $stateExists = function (int $stateId): bool { - return 1 == $stateId; - }; + $stateExists = fn (int $stateId): bool => 1 == $stateId; $stateMap = $this->createStateExistenceProvider($stateExists); $transitionMap = new TransitionMap($stateMap); @@ -130,9 +123,7 @@ public function testGetTransition_FromStateNotExists_ThrowsException(): void */ public function testGetTransition_ToStateNotExists_ThrowsException(): void { - $stateExists = function (int $stateId): bool { - return 1 == $stateId; - }; + $stateExists = fn (int $stateId): bool => 1 == $stateId; $stateMap = $this->createStateExistenceProvider($stateExists); $transitionMap = new TransitionMap($stateMap); @@ -146,9 +137,7 @@ public function testGetTransition_ToStateNotExists_ThrowsException(): void */ public function testGetTransition_TransitionAdded_ReturnsMatchingData(): void { - $stateExists = function (): bool { - return true; - }; + $stateExists = fn (): bool => true; $stateMap = $this->createStateExistenceProvider($stateExists); $transitionMap = new TransitionMap($stateMap); $transitionMap->addTransition(1, 2, 3); @@ -161,9 +150,7 @@ public function testGetTransition_TransitionAdded_ReturnsMatchingData(): void */ public function testGetTransition_TransitionNotAdded_ThrowsException(): void { - $stateExists = function (): bool { - return true; - }; + $stateExists = fn (): bool => true; $stateMap = $this->createStateExistenceProvider($stateExists); $transitionMap = new TransitionMap($stateMap); @@ -177,9 +164,7 @@ public function testGetTransition_TransitionNotAdded_ThrowsException(): void */ public function testAddTransition_TransitionAdded_ThrowsException(): void { - $stateExists = function (): bool { - return true; - }; + $stateExists = fn (): bool => true; $stateMap = $this->createStateExistenceProvider($stateExists); $transitionMap = new TransitionMap($stateMap); $transitionMap->addTransition(1, 2, 3); @@ -194,9 +179,7 @@ public function testAddTransition_TransitionAdded_ThrowsException(): void */ public function testReplaceTransition_TransitionAdded_GetTransitionReturnsNewData(): void { - $stateExists = function (): bool { - return true; - }; + $stateExists = fn (): bool => true; $stateMap = $this->createStateExistenceProvider($stateExists); $transitionMap = new TransitionMap($stateMap); $transitionMap->addTransition(1, 2, 3); @@ -210,9 +193,7 @@ public function testReplaceTransition_TransitionAdded_GetTransitionReturnsNewDat */ public function testReplaceTransition_TransitionNotAdded_GetTransitionReturnsData(): void { - $stateExists = function (): bool { - return true; - }; + $stateExists = fn (): bool => true; $stateMap = $this->createStateExistenceProvider($stateExists); $transitionMap = new TransitionMap($stateMap); $transitionMap->replaceTransition(1, 2, 3); @@ -222,9 +203,7 @@ public function testReplaceTransition_TransitionNotAdded_GetTransitionReturnsDat public function testGetTransitionList_TransitionNotAdded_ReturnsEmptyArray(): void { - $stateExists = function (): bool { - return true; - }; + $stateExists = fn (): bool => true; $stateMap = $this->createStateExistenceProvider($stateExists); $actualValue = (new TransitionMap($stateMap))->getTransitionList(); self::assertSame([], $actualValue); @@ -235,9 +214,7 @@ public function testGetTransitionList_TransitionNotAdded_ReturnsEmptyArray(): vo */ public function testGetTransitionList_TransitionAdded_ReturnsArrayWithTransition(): void { - $stateExists = function (): bool { - return true; - }; + $stateExists = fn (): bool => true; $stateMap = $this->createStateExistenceProvider($stateExists); $transitionMap = new TransitionMap($stateMap); $transitionMap->addTransition(1, 2, 3); diff --git a/tests/RegExp/Grammar/GrammarTest.php b/tests/RegExp/Grammar/GrammarTest.php index a412684..dda32f0 100644 --- a/tests/RegExp/Grammar/GrammarTest.php +++ b/tests/RegExp/Grammar/GrammarTest.php @@ -4,29 +4,33 @@ namespace Remorhaz\UniLex\Test\RegExp\Grammar; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\AST\Node; use Remorhaz\UniLex\AST\Tree; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\RegExp\AST\NodeType; +use Remorhaz\UniLex\RegExp\Grammar\ProductionTranslationScheme; +use Remorhaz\UniLex\RegExp\Grammar\SymbolTranslationScheme; +use Remorhaz\UniLex\RegExp\Grammar\TokenTranslationScheme; +use Remorhaz\UniLex\RegExp\Grammar\TranslationScheme; use Remorhaz\UniLex\RegExp\ParserFactory; use Remorhaz\UniLex\Unicode\CharBufferFactory; -/** - * @covers \Remorhaz\UniLex\RegExp\Grammar\TranslationScheme - * @covers \Remorhaz\UniLex\RegExp\Grammar\SymbolTranslationScheme - * @covers \Remorhaz\UniLex\RegExp\Grammar\ProductionTranslationScheme - * @covers \Remorhaz\UniLex\RegExp\Grammar\TokenTranslationScheme - */ +#[ + CoversClass(TranslationScheme::class), + CoversClass(SymbolTranslationScheme::class), + CoversClass(ProductionTranslationScheme::class), + CoversClass(TokenTranslationScheme::class), +] class GrammarTest extends TestCase { /** - * @param string $text - * @param $expectedValue * @throws UniLexException - * @dataProvider providerSyntaxTree */ - public function testRun_ValidBuffer_CreatesMatchingSyntaxTree(string $text, $expectedValue): void + #[DataProvider('providerSyntaxTree')] + public function testRun_ValidBuffer_CreatesMatchingSyntaxTree(string $text, object $expectedValue): void { $buffer = CharBufferFactory::createFromString($text); $tree = new Tree(); @@ -415,20 +419,14 @@ public static function providerSyntaxTree(): iterable } /** - * @param Tree $tree - * @return mixed * @throws UniLexException */ - private function exportSyntaxTree(Tree $tree) + private function exportSyntaxTree(Tree $tree): object { return $this->exportSyntaxTreeNode($tree->getRootNode()); } - /** - * @param Node $node - * @return mixed - */ - private function exportSyntaxTreeNode(Node $node) + private function exportSyntaxTreeNode(Node $node): object { $data = [ 'name' => $node->getName(), diff --git a/tests/RegExp/TokenMatcherTest.php b/tests/RegExp/TokenMatcherTest.php index d8885b3..8183061 100644 --- a/tests/RegExp/TokenMatcherTest.php +++ b/tests/RegExp/TokenMatcherTest.php @@ -4,6 +4,8 @@ namespace Remorhaz\UniLex\Test\RegExp; +use PHPUnit\Framework\Attributes\CoversNothing; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\IO\CharBuffer; @@ -14,17 +16,13 @@ use Remorhaz\UniLex\RegExp\Grammar\TokenMatcher; use Remorhaz\UniLex\RegExp\Grammar\TokenType; -/** - * @coversNothing - */ +#[CoversNothing] class TokenMatcherTest extends TestCase { /** - * @param int $expectedType - * @param int $symbol - * @dataProvider providerValidTokenType * @throws UniLexException */ + #[DataProvider('providerValidTokenType')] public function testMatch_ValidBuffer_ReturnsTokenWithMatchingType(int $expectedType, int $symbol): void { $buffer = new CharBuffer($symbol); @@ -89,10 +87,9 @@ public static function providerValidTokenType(): iterable } /** - * @param int $symbol - * @dataProvider providerValidTokenSymbol * @throws UniLexException */ + #[DataProvider('providerValidTokenSymbol')] public function testMatch_ValidBuffer_ReturnsTokenWithMatchingSymbolAttribute(int $symbol): void { $buffer = new CharBuffer($symbol); diff --git a/tests/Unicode/CharBufferFactoryTest.php b/tests/Unicode/CharBufferFactoryTest.php index 2471d72..4122519 100644 --- a/tests/Unicode/CharBufferFactoryTest.php +++ b/tests/Unicode/CharBufferFactoryTest.php @@ -4,14 +4,13 @@ namespace Remorhaz\UniLex\Test\Unicode; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\IO\StringBuffer; use Remorhaz\UniLex\Unicode\CharBufferFactory; use Remorhaz\UniLex\Unicode\Grammar\Utf8TokenMatcher; -/** - * @covers \Remorhaz\UniLex\Unicode\CharBufferFactory - */ +#[CoversClass(CharBufferFactory::class)] class CharBufferFactoryTest extends TestCase { public function testCreateFromBuffer_BufferWithCharacter_ResultGetSymbolReturnsCharacterCode(): void diff --git a/tests/Unicode/CharBufferTest.php b/tests/Unicode/CharBufferTest.php index db3f5e1..d134cf4 100644 --- a/tests/Unicode/CharBufferTest.php +++ b/tests/Unicode/CharBufferTest.php @@ -5,6 +5,7 @@ namespace Remorhaz\UniLex\Test\Unicode; use Exception; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\IO\CharBufferInterface; @@ -16,9 +17,7 @@ use Remorhaz\UniLex\Unicode\Grammar\TokenAttribute; use Remorhaz\UniLex\Unicode\Grammar\TokenType; -/** - * @covers \Remorhaz\UniLex\Unicode\CharBuffer - */ +#[CoversClass(CharBuffer::class)] class CharBufferTest extends TestCase { public function testIsEnd_EmptySourceBuffer_ReturnsTrue(): void @@ -371,7 +370,7 @@ public function testPrevSymbol_Always_ThrowsException(): void private function createTokenMatcherThatNeverMatches(): TokenMatcherInterface { - return new class implements TokenMatcherInterface + return new class () implements TokenMatcherInterface { public function match(CharBufferInterface $buffer, TokenFactoryInterface $tokenFactory): bool { @@ -379,7 +378,6 @@ public function match(CharBufferInterface $buffer, TokenFactoryInterface $tokenF } /** - * @return Token * @throws Exception */ public function getToken(): Token @@ -391,7 +389,7 @@ public function getToken(): Token private function createTokenFactoryThatCreatesInvalidBytesTokens(): TokenFactoryInterface { - return new class implements TokenFactoryInterface + return new class () implements TokenFactoryInterface { public function createToken(int $tokenId): Token { @@ -399,7 +397,6 @@ public function createToken(int $tokenId): Token } /** - * @return Token * @throws Exception */ public function createEoiToken(): Token diff --git a/tests/Unicode/Grammar/TokenFactoryTest.php b/tests/Unicode/Grammar/TokenFactoryTest.php index 21c96a5..b7a1438 100644 --- a/tests/Unicode/Grammar/TokenFactoryTest.php +++ b/tests/Unicode/Grammar/TokenFactoryTest.php @@ -4,13 +4,12 @@ namespace Remorhaz\UniLex\Test\Unicode\Grammar; +use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Unicode\Grammar\TokenFactory; use Remorhaz\UniLex\Unicode\Grammar\TokenType; -/** - * @covers \Remorhaz\UniLex\Unicode\Grammar\TokenFactory - */ +#[CoversClass(TokenFactory::class)] class TokenFactoryTest extends TestCase { public function testCreateEoiToken_Constructed_ResultIsEoiReturnsTrue(): void diff --git a/tests/Unicode/Grammar/Utf8TokenMatcherTest.php b/tests/Unicode/Grammar/Utf8TokenMatcherTest.php index 89c299d..ec45dd3 100644 --- a/tests/Unicode/Grammar/Utf8TokenMatcherTest.php +++ b/tests/Unicode/Grammar/Utf8TokenMatcherTest.php @@ -4,6 +4,8 @@ namespace Remorhaz\UniLex\Test\Unicode\Grammar; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Remorhaz\UniLex\Exception as UniLexException; use Remorhaz\UniLex\IO\StringBuffer; @@ -12,16 +14,13 @@ use Remorhaz\UniLex\Unicode\Grammar\TokenFactory; use Remorhaz\UniLex\Unicode\Grammar\Utf8TokenMatcher; -/** - * @covers \Remorhaz\UniLex\Unicode\Grammar\Utf8TokenMatcher - */ +#[CoversClass(Utf8TokenMatcher::class)] class Utf8TokenMatcherTest extends TestCase { /** - * @param string $text - * @dataProvider providerValidSymbolList * @throws UniLexException */ + #[DataProvider('providerValidSymbolList')] public function testMatch_ValidText_ReturnsSymbolToken(string $text): void { $buffer = new StringBuffer($text); @@ -32,14 +31,12 @@ public function testMatch_ValidText_ReturnsSymbolToken(string $text): void } /** - * @param string $text - * @param int $expectedSymbol - * @dataProvider providerValidSymbolList * @throws UniLexException */ + #[DataProvider('providerValidSymbolList')] public function testMatch_ValidText_ReturnsTokenWithMatchingSymbolAttribute( string $text, - int $expectedSymbol + int $expectedSymbol, ): void { $buffer = new StringBuffer($text); $matcher = new Utf8TokenMatcher(); @@ -65,10 +62,9 @@ public static function providerValidSymbolList(): iterable } /** - * @param string $text - * @dataProvider providerInvalidText * @throws UniLexException */ + #[DataProvider('providerInvalidText')] public function testMatch_InvalidText_ReturnsInvalidBytesToken(string $text): void { $buffer = new StringBuffer($text); diff --git a/vendor-bin/cs/composer.json b/vendor-bin/cs/composer.json new file mode 100644 index 0000000..05a4dfe --- /dev/null +++ b/vendor-bin/cs/composer.json @@ -0,0 +1,5 @@ +{ + "require-dev": { + "squizlabs/php_codesniffer": "^3.8.1" + } +}