Merged
Conversation
Welcome to Codecov 🎉Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests. Thanks for integrating Codecov - We've got you covered ☂️ |
Jeckerson
approved these changes
Apr 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR delivers Phase 1 of the Volt parser modernisation effort: replacing loose, C-style PHP with idiomatic PHP 8.1+ constructs, encapsulating internal state, and establishing a comprehensive unit test suite.
What changed
Scanner layer
Opcodeconverted to a backedenum(intcases) — replaces 70+ bare integer constantsTokenconverted to areadonlyclass with constructor promotion — immutable value objectScannerStatusintroduced as a typed enum for scanner result codes (replacing raw integers)Statefully encapsulated: all public properties replaced withprotected/privateand accessor methods (get*,set*,increment*,decrement*,reset*)Scannerupdated to use all new accessorsParser layer
Parserupdated to useStateaccessors throughout;$state->setActiveToken(null)for typed nullable resetParser\Statusproperties tightened toprivate; constructor-promoted; setter return types correctedresources/files/parser.php(lemon-generated) updated to useStategetter methods for EOF error reportingException
$statementproperty added withgetStatement(): arrayaccessor to carry the failing AST node alongside the messageInfrastructure
Tokens.php:nullarray key replaced with''(PHP 8.5 compatibility)phpstan-baseline.neon: PHP 8.5-onlyCompiler.phperrors suppressed withreportUnmatched: falseso 8.1–8.4 runs are unaffectedcoverage: nonefor phpcs job,coverage: xdebugfor tests/coverage jobs, Codecovfile:→files:docker-compose.ymlTest coverage added
tests/unit/Scanner/OpcodeTest.phpOpcodeenum — all cases,fromOpcode(), label lookuptests/unit/Scanner/TokenTest.phpTokenvalue object — all properties, readonly enforcementtests/unit/Scanner/ScannerStatusTest.phpScannerStatusenum — all casestests/unit/Scanner/StateTest.phpState— all getters/setters/incrementerstests/unit/Parser/StatusTest.phpParser\Status— all methods and constantstests/unit/ExceptionTest.phpException— message, statement, codetests/unit/Parser/ParserTest.phpParser— 37 tests covering every statement type, error path, and extends-mode restriction31 files changed, ~3 000 lines added, ~840 removed.
Test plan
composer cspasses on PHP 8.1–8.5composer analyzepasses on PHP 8.1–8.5composer testpasses (372 tests, 3 intentional skips for Phase 2 Compiler work)