diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f87b6f4..35c965d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,4 +17,4 @@ jobs: ci: uses: codenamephp/workflows.php/.github/workflows/ci.yml@1 with: - php-versions: '["8.1","8.2","8.3"]' + php-versions: '["8.2","8.3"]' diff --git a/.idea/deployer.crontab.iml b/.idea/deployer.crontab.iml index 072c4c1..e9e65a4 100644 --- a/.idea/deployer.crontab.iml +++ b/.idea/deployer.crontab.iml @@ -4,7 +4,6 @@ - diff --git a/.idea/php.xml b/.idea/php.xml index f4f21ad..13eed7b 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -130,7 +130,7 @@ - + diff --git a/composer.json b/composer.json index 0809e2b..6bc0075 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ } ], "require": { - "php": "^8.1", + "php": "^8.2", "codenamephp/deployer.base": "^3.0", "codenamephp/deployer.command": "^1.0" }, diff --git a/phive.xml b/phive.xml index 1d90e76..94af6fb 100644 --- a/phive.xml +++ b/phive.xml @@ -16,9 +16,9 @@ ~ --> - + - - - + + + diff --git a/test/phpunit.dist.xml b/test/phpunit.dist.xml index cd63c0a..5644f57 100644 --- a/test/phpunit.dist.xml +++ b/test/phpunit.dist.xml @@ -15,17 +15,13 @@ ~ limitations under the License. ~ --> - - - - ./../src - - . @@ -34,4 +30,9 @@ + + + ./../src + + diff --git a/tools/composer-require-checker b/tools/composer-require-checker index 2af0801..aaa35df 100755 Binary files a/tools/composer-require-checker and b/tools/composer-require-checker differ diff --git a/tools/composer-unused b/tools/composer-unused index 98d213e..017a7ca 100755 Binary files a/tools/composer-unused and b/tools/composer-unused differ diff --git a/tools/infection b/tools/infection index aef3460..257191b 100755 Binary files a/tools/infection and b/tools/infection differ diff --git a/tools/phpunit.phar b/tools/phpunit.phar index e1c645f..678daa9 100755 --- a/tools/phpunit.phar +++ b/tools/phpunit.phar @@ -19,7 +19,7 @@ if (version_compare('8.1.0', PHP_VERSION, '>')) { fwrite( STDERR, sprintf( - 'PHPUnit 10.0.16 by Sebastian Bergmann and contributors.' . PHP_EOL . PHP_EOL . + 'PHPUnit 10.5.8 by Sebastian Bergmann and contributors.' . PHP_EOL . PHP_EOL . 'This version of PHPUnit requires PHP >= 8.1.' . PHP_EOL . 'You are using PHP %s (%s).' . PHP_EOL, PHP_VERSION, @@ -30,31 +30,42 @@ if (version_compare('8.1.0', PHP_VERSION, '>')) { die(1); } -foreach (['dom', 'json', 'libxml', 'mbstring', 'tokenizer', 'xml', 'xmlwriter'] as $extension) { - if (extension_loaded($extension)) { - continue; +$requiredExtensions = ['ctype', 'dom', 'json', 'libxml', 'mbstring', 'tokenizer', 'xml', 'xmlwriter']; + +$unavailableExtensions = array_filter( + $requiredExtensions, + static function ($extension) { + return !extension_loaded($extension); } +); +if ([] !== $unavailableExtensions) { fwrite( STDERR, sprintf( - 'PHPUnit requires the "%s" extension.' . PHP_EOL, - $extension + 'PHPUnit requires the "%s" extensions, but the "%s" %s not available.' . PHP_EOL, + implode('", "', $requiredExtensions), + implode('", "', $unavailableExtensions), + count($unavailableExtensions) === 1 ? 'extension is' : 'extensions are' ) ); die(1); } +unset($requiredExtensions, $unavailableExtensions); + if (__FILE__ === realpath($_SERVER['SCRIPT_NAME'])) { $execute = true; } else { $execute = false; } -$options = getopt('', array('manifest', 'sbom')); +$options = getopt('', array('composer-lock', 'manifest', 'sbom')); -if (isset($options['manifest'])) { +if (isset($options['composer-lock'])) { + $printComposerLock = true; +} elseif (isset($options['manifest'])) { $printManifest = true; } elseif (isset($options['sbom'])) { $printSbom = true; @@ -63,9 +74,9 @@ if (isset($options['manifest'])) { unset($options); define('__PHPUNIT_PHAR__', str_replace(DIRECTORY_SEPARATOR, '/', __FILE__)); -define('__PHPUNIT_PHAR_ROOT__', 'phar://phpunit-10.0.16.phar'); +define('__PHPUNIT_PHAR_ROOT__', 'phar://phpunit-10.5.8.phar'); -Phar::mapPhar('phpunit-10.0.16.phar'); +Phar::mapPhar('phpunit-10.5.8.phar'); spl_autoload_register( function ($class) { @@ -104,6 +115,7 @@ spl_autoload_register( 'PHPUnit\\Event\\Code\\ClassMethod' => '/phpunit/Event/Value/ClassMethod.php', 'PHPUnit\\Event\\Code\\ComparisonFailure' => '/phpunit/Event/Value/ComparisonFailure.php', 'PHPUnit\\Event\\Code\\ComparisonFailureBuilder' => '/phpunit/Event/Value/ComparisonFailureBuilder.php', + 'PHPUnit\\Event\\Code\\NoTestCaseObjectOnCallStackException' => '/phpunit/Event/Exception/NoTestCaseObjectOnCallStackException.php', 'PHPUnit\\Event\\Code\\Phpt' => '/phpunit/Event/Value/Test/Phpt.php', 'PHPUnit\\Event\\Code\\Test' => '/phpunit/Event/Value/Test/Test.php', 'PHPUnit\\Event\\Code\\TestCollection' => '/phpunit/Event/Value/Test/TestCollection.php', @@ -141,10 +153,14 @@ spl_autoload_register( 'PHPUnit\\Event\\Subscriber' => '/phpunit/Event/Subscriber.php', 'PHPUnit\\Event\\SubscriberTypeAlreadyRegisteredException' => '/phpunit/Event/Exception/SubscriberTypeAlreadyRegisteredException.php', 'PHPUnit\\Event\\Telemetry\\Duration' => '/phpunit/Event/Value/Telemetry/Duration.php', + 'PHPUnit\\Event\\Telemetry\\GarbageCollectorStatus' => '/phpunit/Event/Value/Telemetry/GarbageCollectorStatus.php', + 'PHPUnit\\Event\\Telemetry\\GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/GarbageCollectorStatusProvider.php', 'PHPUnit\\Event\\Telemetry\\HRTime' => '/phpunit/Event/Value/Telemetry/HRTime.php', 'PHPUnit\\Event\\Telemetry\\Info' => '/phpunit/Event/Value/Telemetry/Info.php', 'PHPUnit\\Event\\Telemetry\\MemoryMeter' => '/phpunit/Event/Value/Telemetry/MemoryMeter.php', 'PHPUnit\\Event\\Telemetry\\MemoryUsage' => '/phpunit/Event/Value/Telemetry/MemoryUsage.php', + 'PHPUnit\\Event\\Telemetry\\Php81GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/Php81GarbageCollectorStatusProvider.php', + 'PHPUnit\\Event\\Telemetry\\Php83GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/Php83GarbageCollectorStatusProvider.php', 'PHPUnit\\Event\\Telemetry\\Snapshot' => '/phpunit/Event/Value/Telemetry/Snapshot.php', 'PHPUnit\\Event\\Telemetry\\StopWatch' => '/phpunit/Event/Value/Telemetry/StopWatch.php', 'PHPUnit\\Event\\Telemetry\\System' => '/phpunit/Event/Value/Telemetry/System.php', @@ -166,6 +182,8 @@ spl_autoload_register( 'PHPUnit\\Event\\TestRunner\\DeprecationTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/DeprecationTriggeredSubscriber.php', 'PHPUnit\\Event\\TestRunner\\EventFacadeSealed' => '/phpunit/Event/Events/TestRunner/EventFacadeSealed.php', 'PHPUnit\\Event\\TestRunner\\EventFacadeSealedSubscriber' => '/phpunit/Event/Events/TestRunner/EventFacadeSealedSubscriber.php', + 'PHPUnit\\Event\\TestRunner\\ExecutionAborted' => '/phpunit/Event/Events/TestRunner/ExecutionAborted.php', + 'PHPUnit\\Event\\TestRunner\\ExecutionAbortedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionAbortedSubscriber.php', 'PHPUnit\\Event\\TestRunner\\ExecutionFinished' => '/phpunit/Event/Events/TestRunner/ExecutionFinished.php', 'PHPUnit\\Event\\TestRunner\\ExecutionFinishedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionFinishedSubscriber.php', 'PHPUnit\\Event\\TestRunner\\ExecutionStarted' => '/phpunit/Event/Events/TestRunner/ExecutionStarted.php', @@ -176,6 +194,12 @@ spl_autoload_register( 'PHPUnit\\Event\\TestRunner\\ExtensionLoadedFromPharSubscriber' => '/phpunit/Event/Events/TestRunner/ExtensionLoadedFromPharSubscriber.php', 'PHPUnit\\Event\\TestRunner\\Finished' => '/phpunit/Event/Events/TestRunner/Finished.php', 'PHPUnit\\Event\\TestRunner\\FinishedSubscriber' => '/phpunit/Event/Events/TestRunner/FinishedSubscriber.php', + 'PHPUnit\\Event\\TestRunner\\GarbageCollectionDisabled' => '/phpunit/Event/Events/TestRunner/GarbageCollectionDisabled.php', + 'PHPUnit\\Event\\TestRunner\\GarbageCollectionDisabledSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionDisabledSubscriber.php', + 'PHPUnit\\Event\\TestRunner\\GarbageCollectionEnabled' => '/phpunit/Event/Events/TestRunner/GarbageCollectionEnabled.php', + 'PHPUnit\\Event\\TestRunner\\GarbageCollectionEnabledSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionEnabledSubscriber.php', + 'PHPUnit\\Event\\TestRunner\\GarbageCollectionTriggered' => '/phpunit/Event/Events/TestRunner/GarbageCollectionTriggered.php', + 'PHPUnit\\Event\\TestRunner\\GarbageCollectionTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionTriggeredSubscriber.php', 'PHPUnit\\Event\\TestRunner\\Started' => '/phpunit/Event/Events/TestRunner/Started.php', 'PHPUnit\\Event\\TestRunner\\StartedSubscriber' => '/phpunit/Event/Events/TestRunner/StartedSubscriber.php', 'PHPUnit\\Event\\TestRunner\\WarningTriggered' => '/phpunit/Event/Events/TestRunner/WarningTriggered.php', @@ -223,6 +247,10 @@ spl_autoload_register( 'PHPUnit\\Event\\Test\\ComparatorRegisteredSubscriber' => '/phpunit/Event/Events/Test/ComparatorRegisteredSubscriber.php', 'PHPUnit\\Event\\Test\\ConsideredRisky' => '/phpunit/Event/Events/Test/Issue/ConsideredRisky.php', 'PHPUnit\\Event\\Test\\ConsideredRiskySubscriber' => '/phpunit/Event/Events/Test/Issue/ConsideredRiskySubscriber.php', + 'PHPUnit\\Event\\Test\\DataProviderMethodCalled' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalled.php', + 'PHPUnit\\Event\\Test\\DataProviderMethodCalledSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalledSubscriber.php', + 'PHPUnit\\Event\\Test\\DataProviderMethodFinished' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinished.php', + 'PHPUnit\\Event\\Test\\DataProviderMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinishedSubscriber.php', 'PHPUnit\\Event\\Test\\DeprecationTriggered' => '/phpunit/Event/Events/Test/Issue/DeprecationTriggered.php', 'PHPUnit\\Event\\Test\\DeprecationTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/DeprecationTriggeredSubscriber.php', 'PHPUnit\\Event\\Test\\ErrorTriggered' => '/phpunit/Event/Events/Test/Issue/ErrorTriggered.php', @@ -272,6 +300,8 @@ spl_autoload_register( 'PHPUnit\\Event\\Test\\PreConditionCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PreConditionCalledSubscriber.php', 'PHPUnit\\Event\\Test\\PreConditionFinished' => '/phpunit/Event/Events/Test/HookMethod/PreConditionFinished.php', 'PHPUnit\\Event\\Test\\PreConditionFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PreConditionFinishedSubscriber.php', + 'PHPUnit\\Event\\Test\\PreparationFailed' => '/phpunit/Event/Events/Test/Lifecycle/PreparationFailed.php', + 'PHPUnit\\Event\\Test\\PreparationFailedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparationFailedSubscriber.php', 'PHPUnit\\Event\\Test\\PreparationStarted' => '/phpunit/Event/Events/Test/Lifecycle/PreparationStarted.php', 'PHPUnit\\Event\\Test\\PreparationStartedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparationStartedSubscriber.php', 'PHPUnit\\Event\\Test\\Prepared' => '/phpunit/Event/Events/Test/Lifecycle/Prepared.php', @@ -323,6 +353,10 @@ spl_autoload_register( 'PHPUnit\\Framework\\Attributes\\ExcludeGlobalVariableFromBackup' => '/phpunit/Framework/Attributes/ExcludeGlobalVariableFromBackup.php', 'PHPUnit\\Framework\\Attributes\\ExcludeStaticPropertyFromBackup' => '/phpunit/Framework/Attributes/ExcludeStaticPropertyFromBackup.php', 'PHPUnit\\Framework\\Attributes\\Group' => '/phpunit/Framework/Attributes/Group.php', + 'PHPUnit\\Framework\\Attributes\\IgnoreClassForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreClassForCodeCoverage.php', + 'PHPUnit\\Framework\\Attributes\\IgnoreDeprecations' => '/phpunit/Framework/Attributes/IgnoreDeprecations.php', + 'PHPUnit\\Framework\\Attributes\\IgnoreFunctionForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreFunctionForCodeCoverage.php', + 'PHPUnit\\Framework\\Attributes\\IgnoreMethodForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreMethodForCodeCoverage.php', 'PHPUnit\\Framework\\Attributes\\Large' => '/phpunit/Framework/Attributes/Large.php', 'PHPUnit\\Framework\\Attributes\\Medium' => '/phpunit/Framework/Attributes/Medium.php', 'PHPUnit\\Framework\\Attributes\\PostCondition' => '/phpunit/Framework/Attributes/PostCondition.php', @@ -347,6 +381,7 @@ spl_autoload_register( 'PHPUnit\\Framework\\Attributes\\Ticket' => '/phpunit/Framework/Attributes/Ticket.php', 'PHPUnit\\Framework\\Attributes\\UsesClass' => '/phpunit/Framework/Attributes/UsesClass.php', 'PHPUnit\\Framework\\Attributes\\UsesFunction' => '/phpunit/Framework/Attributes/UsesFunction.php', + 'PHPUnit\\Framework\\Attributes\\WithoutErrorHandler' => '/phpunit/Framework/Attributes/WithoutErrorHandler.php', 'PHPUnit\\Framework\\CodeCoverageException' => '/phpunit/Framework/Exception/CodeCoverageException.php', 'PHPUnit\\Framework\\ComparisonMethodDoesNotAcceptParameterTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotAcceptParameterTypeException.php', 'PHPUnit\\Framework\\ComparisonMethodDoesNotDeclareBoolReturnTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareBoolReturnTypeException.php', @@ -390,7 +425,8 @@ spl_autoload_register( 'PHPUnit\\Framework\\Constraint\\LogicalNot' => '/phpunit/Framework/Constraint/Operator/LogicalNot.php', 'PHPUnit\\Framework\\Constraint\\LogicalOr' => '/phpunit/Framework/Constraint/Operator/LogicalOr.php', 'PHPUnit\\Framework\\Constraint\\LogicalXor' => '/phpunit/Framework/Constraint/Operator/LogicalXor.php', - 'PHPUnit\\Framework\\Constraint\\ObjectEquals' => '/phpunit/Framework/Constraint/ObjectEquals.php', + 'PHPUnit\\Framework\\Constraint\\ObjectEquals' => '/phpunit/Framework/Constraint/Object/ObjectEquals.php', + 'PHPUnit\\Framework\\Constraint\\ObjectHasProperty' => '/phpunit/Framework/Constraint/Object/ObjectHasProperty.php', 'PHPUnit\\Framework\\Constraint\\Operator' => '/phpunit/Framework/Constraint/Operator/Operator.php', 'PHPUnit\\Framework\\Constraint\\RegularExpression' => '/phpunit/Framework/Constraint/String/RegularExpression.php', 'PHPUnit\\Framework\\Constraint\\SameSize' => '/phpunit/Framework/Constraint/Cardinality/SameSize.php', @@ -406,7 +442,6 @@ spl_autoload_register( 'PHPUnit\\Framework\\Constraint\\UnaryOperator' => '/phpunit/Framework/Constraint/Operator/UnaryOperator.php', 'PHPUnit\\Framework\\DataProviderTestSuite' => '/phpunit/Framework/DataProviderTestSuite.php', 'PHPUnit\\Framework\\EmptyStringException' => '/phpunit/Framework/Exception/EmptyStringException.php', - 'PHPUnit\\Framework\\Error' => '/phpunit/Framework/Exception/Error.php', 'PHPUnit\\Framework\\Exception' => '/phpunit/Framework/Exception/Exception.php', 'PHPUnit\\Framework\\ExecutionOrderDependency' => '/phpunit/Framework/ExecutionOrderDependency.php', 'PHPUnit\\Framework\\ExpectationFailedException' => '/phpunit/Framework/Exception/ExpectationFailedException.php', @@ -417,77 +452,83 @@ spl_autoload_register( 'PHPUnit\\Framework\\InvalidCoversTargetException' => '/phpunit/Framework/Exception/InvalidCoversTargetException.php', 'PHPUnit\\Framework\\InvalidDataProviderException' => '/phpunit/Framework/Exception/InvalidDataProviderException.php', 'PHPUnit\\Framework\\InvalidDependencyException' => '/phpunit/Framework/Exception/InvalidDependencyException.php', - 'PHPUnit\\Framework\\MockObject\\Api' => '/phpunit/Framework/MockObject/Api/Api.php', 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => '/phpunit/Framework/MockObject/Exception/BadMethodCallException.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => '/phpunit/Framework/MockObject/Builder/Identity.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => '/phpunit/Framework/MockObject/Builder/InvocationMocker.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationStubber' => '/phpunit/Framework/MockObject/Builder/InvocationStubber.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => '/phpunit/Framework/MockObject/Builder/MethodNameMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => '/phpunit/Framework/MockObject/Builder/ParametersMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => '/phpunit/Framework/MockObject/Builder/Stub.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => '/phpunit/Framework/MockObject/Runtime/Builder/Identity.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => '/phpunit/Framework/MockObject/Runtime/Builder/InvocationMocker.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationStubber' => '/phpunit/Framework/MockObject/Runtime/Builder/InvocationStubber.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => '/phpunit/Framework/MockObject/Runtime/Builder/MethodNameMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => '/phpunit/Framework/MockObject/Runtime/Builder/ParametersMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => '/phpunit/Framework/MockObject/Runtime/Builder/Stub.php', 'PHPUnit\\Framework\\MockObject\\CannotUseAddMethodsException' => '/phpunit/Framework/MockObject/Exception/CannotUseAddMethodsException.php', 'PHPUnit\\Framework\\MockObject\\CannotUseOnlyMethodsException' => '/phpunit/Framework/MockObject/Exception/CannotUseOnlyMethodsException.php', - 'PHPUnit\\Framework\\MockObject\\ClassAlreadyExistsException' => '/phpunit/Framework/MockObject/Exception/ClassAlreadyExistsException.php', - 'PHPUnit\\Framework\\MockObject\\ClassIsEnumerationException' => '/phpunit/Framework/MockObject/Exception/ClassIsEnumerationException.php', - 'PHPUnit\\Framework\\MockObject\\ClassIsFinalException' => '/phpunit/Framework/MockObject/Exception/ClassIsFinalException.php', - 'PHPUnit\\Framework\\MockObject\\ClassIsReadonlyException' => '/phpunit/Framework/MockObject/Exception/ClassIsReadonlyException.php', 'PHPUnit\\Framework\\MockObject\\ConfigurableMethod' => '/phpunit/Framework/MockObject/ConfigurableMethod.php', - 'PHPUnit\\Framework\\MockObject\\ConfigurableMethodsAlreadyInitializedException' => '/phpunit/Framework/MockObject/Exception/ConfigurableMethodsAlreadyInitializedException.php', - 'PHPUnit\\Framework\\MockObject\\DuplicateMethodException' => '/phpunit/Framework/MockObject/Exception/DuplicateMethodException.php', + 'PHPUnit\\Framework\\MockObject\\DoubledCloneMethod' => '/phpunit/Framework/MockObject/Runtime/Api/DoubledCloneMethod.php', 'PHPUnit\\Framework\\MockObject\\Exception' => '/phpunit/Framework/MockObject/Exception/Exception.php', - 'PHPUnit\\Framework\\MockObject\\Generator' => '/phpunit/Framework/MockObject/Generator.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\ClassAlreadyExistsException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassAlreadyExistsException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsEnumerationException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsEnumerationException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsFinalException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsFinalException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsReadonlyException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsReadonlyException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\DuplicateMethodException' => '/phpunit/Framework/MockObject/Generator/Exception/DuplicateMethodException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\Exception' => '/phpunit/Framework/MockObject/Generator/Exception/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\Generator' => '/phpunit/Framework/MockObject/Generator/Generator.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\InvalidMethodNameException' => '/phpunit/Framework/MockObject/Generator/Exception/InvalidMethodNameException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\MockClass' => '/phpunit/Framework/MockObject/Generator/MockClass.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\MockMethod' => '/phpunit/Framework/MockObject/Generator/MockMethod.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\MockMethodSet' => '/phpunit/Framework/MockObject/Generator/MockMethodSet.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\MockTrait' => '/phpunit/Framework/MockObject/Generator/MockTrait.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\MockType' => '/phpunit/Framework/MockObject/Generator/MockType.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\OriginalConstructorInvocationRequiredException' => '/phpunit/Framework/MockObject/Generator/Exception/OriginalConstructorInvocationRequiredException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\ReflectionException' => '/phpunit/Framework/MockObject/Generator/Exception/ReflectionException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\RuntimeException' => '/phpunit/Framework/MockObject/Generator/Exception/RuntimeException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\SoapExtensionNotAvailableException' => '/phpunit/Framework/MockObject/Generator/Exception/SoapExtensionNotAvailableException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\TemplateLoader' => '/phpunit/Framework/MockObject/Generator/TemplateLoader.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownClassException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownClassException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownTraitException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownTraitException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownTypeException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownTypeException.php', 'PHPUnit\\Framework\\MockObject\\IncompatibleReturnValueException' => '/phpunit/Framework/MockObject/Exception/IncompatibleReturnValueException.php', - 'PHPUnit\\Framework\\MockObject\\InvalidMethodNameException' => '/phpunit/Framework/MockObject/Exception/InvalidMethodNameException.php', - 'PHPUnit\\Framework\\MockObject\\Invocation' => '/phpunit/Framework/MockObject/Invocation.php', - 'PHPUnit\\Framework\\MockObject\\InvocationHandler' => '/phpunit/Framework/MockObject/InvocationHandler.php', + 'PHPUnit\\Framework\\MockObject\\Invocation' => '/phpunit/Framework/MockObject/Runtime/Invocation.php', + 'PHPUnit\\Framework\\MockObject\\InvocationHandler' => '/phpunit/Framework/MockObject/Runtime/InvocationHandler.php', 'PHPUnit\\Framework\\MockObject\\MatchBuilderNotFoundException' => '/phpunit/Framework/MockObject/Exception/MatchBuilderNotFoundException.php', - 'PHPUnit\\Framework\\MockObject\\Matcher' => '/phpunit/Framework/MockObject/Matcher.php', + 'PHPUnit\\Framework\\MockObject\\Matcher' => '/phpunit/Framework/MockObject/Runtime/Matcher.php', 'PHPUnit\\Framework\\MockObject\\MatcherAlreadyRegisteredException' => '/phpunit/Framework/MockObject/Exception/MatcherAlreadyRegisteredException.php', - 'PHPUnit\\Framework\\MockObject\\Method' => '/phpunit/Framework/MockObject/Api/Method.php', + 'PHPUnit\\Framework\\MockObject\\Method' => '/phpunit/Framework/MockObject/Runtime/Api/Method.php', 'PHPUnit\\Framework\\MockObject\\MethodCannotBeConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodCannotBeConfiguredException.php', 'PHPUnit\\Framework\\MockObject\\MethodNameAlreadyConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodNameAlreadyConfiguredException.php', - 'PHPUnit\\Framework\\MockObject\\MethodNameConstraint' => '/phpunit/Framework/MockObject/MethodNameConstraint.php', + 'PHPUnit\\Framework\\MockObject\\MethodNameConstraint' => '/phpunit/Framework/MockObject/Runtime/MethodNameConstraint.php', 'PHPUnit\\Framework\\MockObject\\MethodNameNotConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodNameNotConfiguredException.php', 'PHPUnit\\Framework\\MockObject\\MethodParametersAlreadyConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodParametersAlreadyConfiguredException.php', 'PHPUnit\\Framework\\MockObject\\MockBuilder' => '/phpunit/Framework/MockObject/MockBuilder.php', - 'PHPUnit\\Framework\\MockObject\\MockClass' => '/phpunit/Framework/MockObject/MockClass.php', - 'PHPUnit\\Framework\\MockObject\\MockMethod' => '/phpunit/Framework/MockObject/MockMethod.php', - 'PHPUnit\\Framework\\MockObject\\MockMethodSet' => '/phpunit/Framework/MockObject/MockMethodSet.php', - 'PHPUnit\\Framework\\MockObject\\MockObject' => '/phpunit/Framework/MockObject/MockObject.php', - 'PHPUnit\\Framework\\MockObject\\MockTrait' => '/phpunit/Framework/MockObject/MockTrait.php', - 'PHPUnit\\Framework\\MockObject\\MockType' => '/phpunit/Framework/MockObject/MockType.php', - 'PHPUnit\\Framework\\MockObject\\MockedCloneMethod' => '/phpunit/Framework/MockObject/Api/MockedCloneMethod.php', - 'PHPUnit\\Framework\\MockObject\\OriginalConstructorInvocationRequiredException' => '/phpunit/Framework/MockObject/Exception/OriginalConstructorInvocationRequiredException.php', + 'PHPUnit\\Framework\\MockObject\\MockObject' => '/phpunit/Framework/MockObject/Runtime/Interface/MockObject.php', + 'PHPUnit\\Framework\\MockObject\\MockObjectApi' => '/phpunit/Framework/MockObject/Runtime/Api/MockObjectApi.php', + 'PHPUnit\\Framework\\MockObject\\MockObjectInternal' => '/phpunit/Framework/MockObject/Runtime/Interface/MockObjectInternal.php', + 'PHPUnit\\Framework\\MockObject\\NeverReturningMethodException' => '/phpunit/Framework/MockObject/Exception/NeverReturningMethodException.php', + 'PHPUnit\\Framework\\MockObject\\ProxiedCloneMethod' => '/phpunit/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php', 'PHPUnit\\Framework\\MockObject\\ReflectionException' => '/phpunit/Framework/MockObject/Exception/ReflectionException.php', + 'PHPUnit\\Framework\\MockObject\\ReturnValueGenerator' => '/phpunit/Framework/MockObject/Runtime/ReturnValueGenerator.php', 'PHPUnit\\Framework\\MockObject\\ReturnValueNotConfiguredException' => '/phpunit/Framework/MockObject/Exception/ReturnValueNotConfiguredException.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\AnyInvokedCount' => '/phpunit/Framework/MockObject/Rule/AnyInvokedCount.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\AnyParameters' => '/phpunit/Framework/MockObject/Rule/AnyParameters.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\InvocationOrder' => '/phpunit/Framework/MockObject/Rule/InvocationOrder.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastCount' => '/phpunit/Framework/MockObject/Rule/InvokedAtLeastCount.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastOnce' => '/phpunit/Framework/MockObject/Rule/InvokedAtLeastOnce.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtMostCount' => '/phpunit/Framework/MockObject/Rule/InvokedAtMostCount.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedCount' => '/phpunit/Framework/MockObject/Rule/InvokedCount.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\MethodName' => '/phpunit/Framework/MockObject/Rule/MethodName.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\Parameters' => '/phpunit/Framework/MockObject/Rule/Parameters.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\ParametersRule' => '/phpunit/Framework/MockObject/Rule/ParametersRule.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\AnyInvokedCount' => '/phpunit/Framework/MockObject/Runtime/Rule/AnyInvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\AnyParameters' => '/phpunit/Framework/MockObject/Runtime/Rule/AnyParameters.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvocationOrder' => '/phpunit/Framework/MockObject/Runtime/Rule/InvocationOrder.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastOnce' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastOnce.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtMostCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtMostCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\MethodName' => '/phpunit/Framework/MockObject/Runtime/Rule/MethodName.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\Parameters' => '/phpunit/Framework/MockObject/Runtime/Rule/Parameters.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\ParametersRule' => '/phpunit/Framework/MockObject/Runtime/Rule/ParametersRule.php', 'PHPUnit\\Framework\\MockObject\\RuntimeException' => '/phpunit/Framework/MockObject/Exception/RuntimeException.php', - 'PHPUnit\\Framework\\MockObject\\SoapExtensionNotAvailableException' => '/phpunit/Framework/MockObject/Exception/SoapExtensionNotAvailableException.php', - 'PHPUnit\\Framework\\MockObject\\Stub' => '/phpunit/Framework/MockObject/Stub.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => '/phpunit/Framework/MockObject/Stub/ConsecutiveCalls.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => '/phpunit/Framework/MockObject/Stub/Exception.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => '/phpunit/Framework/MockObject/Stub/ReturnArgument.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => '/phpunit/Framework/MockObject/Stub/ReturnCallback.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => '/phpunit/Framework/MockObject/Stub/ReturnReference.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => '/phpunit/Framework/MockObject/Stub/ReturnSelf.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => '/phpunit/Framework/MockObject/Stub/ReturnStub.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => '/phpunit/Framework/MockObject/Stub/ReturnValueMap.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\Stub' => '/phpunit/Framework/MockObject/Stub/Stub.php', - 'PHPUnit\\Framework\\MockObject\\TemplateLoader' => '/phpunit/Framework/MockObject/TemplateLoader.php', - 'PHPUnit\\Framework\\MockObject\\UnknownClassException' => '/phpunit/Framework/MockObject/Exception/UnknownClassException.php', - 'PHPUnit\\Framework\\MockObject\\UnknownTraitException' => '/phpunit/Framework/MockObject/Exception/UnknownTraitException.php', - 'PHPUnit\\Framework\\MockObject\\UnknownTypeException' => '/phpunit/Framework/MockObject/Exception/UnknownTypeException.php', - 'PHPUnit\\Framework\\MockObject\\UnmockedCloneMethod' => '/phpunit/Framework/MockObject/Api/UnmockedCloneMethod.php', - 'PHPUnit\\Framework\\MockObject\\Verifiable' => '/phpunit/Framework/MockObject/Verifiable.php', + 'PHPUnit\\Framework\\MockObject\\Stub' => '/phpunit/Framework/MockObject/Runtime/Interface/Stub.php', + 'PHPUnit\\Framework\\MockObject\\StubApi' => '/phpunit/Framework/MockObject/Runtime/Api/StubApi.php', + 'PHPUnit\\Framework\\MockObject\\StubInternal' => '/phpunit/Framework/MockObject/Runtime/Interface/StubInternal.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => '/phpunit/Framework/MockObject/Runtime/Stub/ConsecutiveCalls.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => '/phpunit/Framework/MockObject/Runtime/Stub/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnArgument.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnCallback.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnReference.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnSelf.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnStub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnValueMap.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\Stub' => '/phpunit/Framework/MockObject/Runtime/Stub/Stub.php', 'PHPUnit\\Framework\\NoChildTestSuiteException' => '/phpunit/Framework/Exception/NoChildTestSuiteException.php', 'PHPUnit\\Framework\\PhptAssertionFailedError' => '/phpunit/Framework/Exception/PhptAssertionFailedError.php', 'PHPUnit\\Framework\\ProcessIsolationException' => '/phpunit/Framework/Exception/ProcessIsolationException.php', @@ -520,7 +561,6 @@ spl_autoload_register( 'PHPUnit\\Framework\\TestStatus\\Warning' => '/phpunit/Framework/TestStatus/Warning.php', 'PHPUnit\\Framework\\TestSuite' => '/phpunit/Framework/TestSuite.php', 'PHPUnit\\Framework\\TestSuiteIterator' => '/phpunit/Framework/TestSuiteIterator.php', - 'PHPUnit\\Framework\\UnknownClassException' => '/phpunit/Framework/Exception/UnknownClassException.php', 'PHPUnit\\Framework\\UnknownClassOrInterfaceException' => '/phpunit/Framework/Exception/UnknownClassOrInterfaceException.php', 'PHPUnit\\Framework\\UnknownTypeException' => '/phpunit/Framework/Exception/UnknownTypeException.php', 'PHPUnit\\Logging\\EventLogger' => '/phpunit/Logging/EventLogger.php', @@ -531,6 +571,8 @@ spl_autoload_register( 'PHPUnit\\Logging\\JUnit\\TestFailedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestFailedSubscriber.php', 'PHPUnit\\Logging\\JUnit\\TestFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestFinishedSubscriber.php', 'PHPUnit\\Logging\\JUnit\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestMarkedIncompleteSubscriber.php', + 'PHPUnit\\Logging\\JUnit\\TestPreparationFailedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparationFailedSubscriber.php', + 'PHPUnit\\Logging\\JUnit\\TestPreparationStartedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparationStartedSubscriber.php', 'PHPUnit\\Logging\\JUnit\\TestPreparedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparedSubscriber.php', 'PHPUnit\\Logging\\JUnit\\TestRunnerExecutionFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestRunnerExecutionFinishedSubscriber.php', 'PHPUnit\\Logging\\JUnit\\TestSkippedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestSkippedSubscriber.php', @@ -551,26 +593,28 @@ spl_autoload_register( 'PHPUnit\\Logging\\TestDox\\HtmlRenderer' => '/phpunit/Logging/TestDox/HtmlRenderer.php', 'PHPUnit\\Logging\\TestDox\\NamePrettifier' => '/phpunit/Logging/TestDox/NamePrettifier.php', 'PHPUnit\\Logging\\TestDox\\PlainTextRenderer' => '/phpunit/Logging/TestDox/PlainTextRenderer.php', - 'PHPUnit\\Logging\\TestDox\\Subscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/Subscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestConsideredRiskySubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestConsideredRiskySubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestCreatedMockObjectForAbstractClassSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedMockObjectForAbstractClassSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestCreatedMockObjectForTraitSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedMockObjectForTraitSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestCreatedMockObjectFromWsdlSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedMockObjectFromWsdlSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestCreatedMockObjectSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedMockObjectSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestCreatedPartialMockObjectSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedPartialMockObjectSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestCreatedTestProxySubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedTestProxySubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestCreatedTestStubSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedTestStubSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestErroredSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestErroredSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestFailedSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestFailedSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestFinishedSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestFinishedSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestMarkedIncompleteSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestPassedSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestPassedSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestPreparedSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestPreparedSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestResult' => '/phpunit/Logging/TestDox/TestMethod/TestResult.php', - 'PHPUnit\\Logging\\TestDox\\TestResultCollection' => '/phpunit/Logging/TestDox/TestMethod/TestResultCollection.php', - 'PHPUnit\\Logging\\TestDox\\TestResultCollectionIterator' => '/phpunit/Logging/TestDox/TestMethod/TestResultCollectionIterator.php', - 'PHPUnit\\Logging\\TestDox\\TestResultCollector' => '/phpunit/Logging/TestDox/TestMethod/TestResultCollector.php', - 'PHPUnit\\Logging\\TestDox\\TestSkippedSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestSkippedSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\Subscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/Subscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestConsideredRiskySubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestConsideredRiskySubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestErroredSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestErroredSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestFailedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestFailedSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestFinishedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestFinishedSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestMarkedIncompleteSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestPassedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestPassedSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestPreparedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestPreparedSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestResult' => '/phpunit/Logging/TestDox/TestResult/TestResult.php', + 'PHPUnit\\Logging\\TestDox\\TestResultCollection' => '/phpunit/Logging/TestDox/TestResult/TestResultCollection.php', + 'PHPUnit\\Logging\\TestDox\\TestResultCollectionIterator' => '/phpunit/Logging/TestDox/TestResult/TestResultCollectionIterator.php', + 'PHPUnit\\Logging\\TestDox\\TestResultCollector' => '/phpunit/Logging/TestDox/TestResult/TestResultCollector.php', + 'PHPUnit\\Logging\\TestDox\\TestSkippedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestSkippedSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredNoticeSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredNoticeSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitErrorSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredWarningSubscriber.php', 'PHPUnit\\Metadata\\After' => '/phpunit/Metadata/After.php', 'PHPUnit\\Metadata\\AfterClass' => '/phpunit/Metadata/AfterClass.php', 'PHPUnit\\Metadata\\Annotation\\Parser\\DocBlock' => '/phpunit/Metadata/Parser/Annotation/DocBlock.php', @@ -599,6 +643,10 @@ spl_autoload_register( 'PHPUnit\\Metadata\\ExcludeGlobalVariableFromBackup' => '/phpunit/Metadata/ExcludeGlobalVariableFromBackup.php', 'PHPUnit\\Metadata\\ExcludeStaticPropertyFromBackup' => '/phpunit/Metadata/ExcludeStaticPropertyFromBackup.php', 'PHPUnit\\Metadata\\Group' => '/phpunit/Metadata/Group.php', + 'PHPUnit\\Metadata\\IgnoreClassForCodeCoverage' => '/phpunit/Metadata/IgnoreClassForCodeCoverage.php', + 'PHPUnit\\Metadata\\IgnoreDeprecations' => '/phpunit/Metadata/IgnoreDeprecations.php', + 'PHPUnit\\Metadata\\IgnoreFunctionForCodeCoverage' => '/phpunit/Metadata/IgnoreFunctionForCodeCoverage.php', + 'PHPUnit\\Metadata\\IgnoreMethodForCodeCoverage' => '/phpunit/Metadata/IgnoreMethodForCodeCoverage.php', 'PHPUnit\\Metadata\\InvalidVersionRequirementException' => '/phpunit/Metadata/Exception/InvalidVersionRequirementException.php', 'PHPUnit\\Metadata\\Metadata' => '/phpunit/Metadata/Metadata.php', 'PHPUnit\\Metadata\\MetadataCollection' => '/phpunit/Metadata/MetadataCollection.php', @@ -635,6 +683,7 @@ spl_autoload_register( 'PHPUnit\\Metadata\\Version\\ComparisonRequirement' => '/phpunit/Metadata/Version/ComparisonRequirement.php', 'PHPUnit\\Metadata\\Version\\ConstraintRequirement' => '/phpunit/Metadata/Version/ConstraintRequirement.php', 'PHPUnit\\Metadata\\Version\\Requirement' => '/phpunit/Metadata/Version/Requirement.php', + 'PHPUnit\\Metadata\\WithoutErrorHandler' => '/phpunit/Metadata/WithoutErrorHandler.php', 'PHPUnit\\PharIo\\Manifest\\Application' => '/phar-io-manifest/values/Application.php', 'PHPUnit\\PharIo\\Manifest\\ApplicationName' => '/phar-io-manifest/values/ApplicationName.php', 'PHPUnit\\PharIo\\Manifest\\Author' => '/phar-io-manifest/values/Author.php', @@ -736,24 +785,22 @@ spl_autoload_register( 'PHPUnit\\PhpParser\\Internal\\DiffElem' => '/nikic-php-parser/PhpParser/Internal/DiffElem.php', 'PHPUnit\\PhpParser\\Internal\\Differ' => '/nikic-php-parser/PhpParser/Internal/Differ.php', 'PHPUnit\\PhpParser\\Internal\\PrintableNewAnonClassNode' => '/nikic-php-parser/PhpParser/Internal/PrintableNewAnonClassNode.php', + 'PHPUnit\\PhpParser\\Internal\\TokenPolyfill' => '/nikic-php-parser/PhpParser/Internal/TokenPolyfill.php', 'PHPUnit\\PhpParser\\Internal\\TokenStream' => '/nikic-php-parser/PhpParser/Internal/TokenStream.php', 'PHPUnit\\PhpParser\\JsonDecoder' => '/nikic-php-parser/PhpParser/JsonDecoder.php', 'PHPUnit\\PhpParser\\Lexer' => '/nikic-php-parser/PhpParser/Lexer.php', 'PHPUnit\\PhpParser\\Lexer\\Emulative' => '/nikic-php-parser/PhpParser/Lexer/Emulative.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\AttributeEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php', - 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\CoaleseEqualTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/CoaleseEqualTokenEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\EnumTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\ExplicitOctalEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php', - 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\FlexibleDocStringEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/FlexibleDocStringEmulator.php', - 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\FnTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/FnTokenEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\KeywordEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\MatchTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\NullsafeTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php', - 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\NumericLiteralSeparatorEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/NumericLiteralSeparatorEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyFunctionTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\ReverseEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\TokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/TokenEmulator.php', + 'PHPUnit\\PhpParser\\Modifiers' => '/nikic-php-parser/PhpParser/Modifiers.php', 'PHPUnit\\PhpParser\\NameContext' => '/nikic-php-parser/PhpParser/NameContext.php', 'PHPUnit\\PhpParser\\Node' => '/nikic-php-parser/PhpParser/Node.php', 'PHPUnit\\PhpParser\\NodeAbstract' => '/nikic-php-parser/PhpParser/NodeAbstract.php', @@ -764,19 +811,22 @@ spl_autoload_register( 'PHPUnit\\PhpParser\\NodeVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor.php', 'PHPUnit\\PhpParser\\NodeVisitorAbstract' => '/nikic-php-parser/PhpParser/NodeVisitorAbstract.php', 'PHPUnit\\PhpParser\\NodeVisitor\\CloningVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/CloningVisitor.php', + 'PHPUnit\\PhpParser\\NodeVisitor\\CommentAnnotatingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/CommentAnnotatingVisitor.php', 'PHPUnit\\PhpParser\\NodeVisitor\\FindingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/FindingVisitor.php', 'PHPUnit\\PhpParser\\NodeVisitor\\FirstFindingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/FirstFindingVisitor.php', 'PHPUnit\\PhpParser\\NodeVisitor\\NameResolver' => '/nikic-php-parser/PhpParser/NodeVisitor/NameResolver.php', 'PHPUnit\\PhpParser\\NodeVisitor\\NodeConnectingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/NodeConnectingVisitor.php', 'PHPUnit\\PhpParser\\NodeVisitor\\ParentConnectingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/ParentConnectingVisitor.php', 'PHPUnit\\PhpParser\\Node\\Arg' => '/nikic-php-parser/PhpParser/Node/Arg.php', + 'PHPUnit\\PhpParser\\Node\\ArrayItem' => '/nikic-php-parser/PhpParser/Node/ArrayItem.php', 'PHPUnit\\PhpParser\\Node\\Attribute' => '/nikic-php-parser/PhpParser/Node/Attribute.php', 'PHPUnit\\PhpParser\\Node\\AttributeGroup' => '/nikic-php-parser/PhpParser/Node/AttributeGroup.php', + 'PHPUnit\\PhpParser\\Node\\ClosureUse' => '/nikic-php-parser/PhpParser/Node/ClosureUse.php', 'PHPUnit\\PhpParser\\Node\\ComplexType' => '/nikic-php-parser/PhpParser/Node/ComplexType.php', 'PHPUnit\\PhpParser\\Node\\Const_' => '/nikic-php-parser/PhpParser/Node/Const_.php', + 'PHPUnit\\PhpParser\\Node\\DeclareItem' => '/nikic-php-parser/PhpParser/Node/DeclareItem.php', 'PHPUnit\\PhpParser\\Node\\Expr' => '/nikic-php-parser/PhpParser/Node/Expr.php', 'PHPUnit\\PhpParser\\Node\\Expr\\ArrayDimFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ArrayDimFetch.php', - 'PHPUnit\\PhpParser\\Node\\Expr\\ArrayItem' => '/nikic-php-parser/PhpParser/Node/Expr/ArrayItem.php', 'PHPUnit\\PhpParser\\Node\\Expr\\Array_' => '/nikic-php-parser/PhpParser/Node/Expr/Array_.php', 'PHPUnit\\PhpParser\\Node\\Expr\\ArrowFunction' => '/nikic-php-parser/PhpParser/Node/Expr/ArrowFunction.php', 'PHPUnit\\PhpParser\\Node\\Expr\\Assign' => '/nikic-php-parser/PhpParser/Node/Expr/Assign.php', @@ -837,7 +887,6 @@ spl_autoload_register( 'PHPUnit\\PhpParser\\Node\\Expr\\ClassConstFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ClassConstFetch.php', 'PHPUnit\\PhpParser\\Node\\Expr\\Clone_' => '/nikic-php-parser/PhpParser/Node/Expr/Clone_.php', 'PHPUnit\\PhpParser\\Node\\Expr\\Closure' => '/nikic-php-parser/PhpParser/Node/Expr/Closure.php', - 'PHPUnit\\PhpParser\\Node\\Expr\\ClosureUse' => '/nikic-php-parser/PhpParser/Node/Expr/ClosureUse.php', 'PHPUnit\\PhpParser\\Node\\Expr\\ConstFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ConstFetch.php', 'PHPUnit\\PhpParser\\Node\\Expr\\Empty_' => '/nikic-php-parser/PhpParser/Node/Expr/Empty_.php', 'PHPUnit\\PhpParser\\Node\\Expr\\Error' => '/nikic-php-parser/PhpParser/Node/Expr/Error.php', @@ -872,6 +921,7 @@ spl_autoload_register( 'PHPUnit\\PhpParser\\Node\\Expr\\Yield_' => '/nikic-php-parser/PhpParser/Node/Expr/Yield_.php', 'PHPUnit\\PhpParser\\Node\\FunctionLike' => '/nikic-php-parser/PhpParser/Node/FunctionLike.php', 'PHPUnit\\PhpParser\\Node\\Identifier' => '/nikic-php-parser/PhpParser/Node/Identifier.php', + 'PHPUnit\\PhpParser\\Node\\InterpolatedStringPart' => '/nikic-php-parser/PhpParser/Node/InterpolatedStringPart.php', 'PHPUnit\\PhpParser\\Node\\IntersectionType' => '/nikic-php-parser/PhpParser/Node/IntersectionType.php', 'PHPUnit\\PhpParser\\Node\\MatchArm' => '/nikic-php-parser/PhpParser/Node/MatchArm.php', 'PHPUnit\\PhpParser\\Node\\Name' => '/nikic-php-parser/PhpParser/Node/Name.php', @@ -879,11 +929,11 @@ spl_autoload_register( 'PHPUnit\\PhpParser\\Node\\Name\\Relative' => '/nikic-php-parser/PhpParser/Node/Name/Relative.php', 'PHPUnit\\PhpParser\\Node\\NullableType' => '/nikic-php-parser/PhpParser/Node/NullableType.php', 'PHPUnit\\PhpParser\\Node\\Param' => '/nikic-php-parser/PhpParser/Node/Param.php', + 'PHPUnit\\PhpParser\\Node\\PropertyItem' => '/nikic-php-parser/PhpParser/Node/PropertyItem.php', 'PHPUnit\\PhpParser\\Node\\Scalar' => '/nikic-php-parser/PhpParser/Node/Scalar.php', - 'PHPUnit\\PhpParser\\Node\\Scalar\\DNumber' => '/nikic-php-parser/PhpParser/Node/Scalar/DNumber.php', - 'PHPUnit\\PhpParser\\Node\\Scalar\\Encapsed' => '/nikic-php-parser/PhpParser/Node/Scalar/Encapsed.php', - 'PHPUnit\\PhpParser\\Node\\Scalar\\EncapsedStringPart' => '/nikic-php-parser/PhpParser/Node/Scalar/EncapsedStringPart.php', - 'PHPUnit\\PhpParser\\Node\\Scalar\\LNumber' => '/nikic-php-parser/PhpParser/Node/Scalar/LNumber.php', + 'PHPUnit\\PhpParser\\Node\\Scalar\\Float_' => '/nikic-php-parser/PhpParser/Node/Scalar/Float_.php', + 'PHPUnit\\PhpParser\\Node\\Scalar\\Int_' => '/nikic-php-parser/PhpParser/Node/Scalar/Int_.php', + 'PHPUnit\\PhpParser\\Node\\Scalar\\InterpolatedString' => '/nikic-php-parser/PhpParser/Node/Scalar/InterpolatedString.php', 'PHPUnit\\PhpParser\\Node\\Scalar\\MagicConst' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst.php', 'PHPUnit\\PhpParser\\Node\\Scalar\\MagicConst\\Class_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Class_.php', 'PHPUnit\\PhpParser\\Node\\Scalar\\MagicConst\\Dir' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Dir.php', @@ -894,7 +944,9 @@ spl_autoload_register( 'PHPUnit\\PhpParser\\Node\\Scalar\\MagicConst\\Namespace_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Namespace_.php', 'PHPUnit\\PhpParser\\Node\\Scalar\\MagicConst\\Trait_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Trait_.php', 'PHPUnit\\PhpParser\\Node\\Scalar\\String_' => '/nikic-php-parser/PhpParser/Node/Scalar/String_.php', + 'PHPUnit\\PhpParser\\Node\\StaticVar' => '/nikic-php-parser/PhpParser/Node/StaticVar.php', 'PHPUnit\\PhpParser\\Node\\Stmt' => '/nikic-php-parser/PhpParser/Node/Stmt.php', + 'PHPUnit\\PhpParser\\Node\\Stmt\\Block' => '/nikic-php-parser/PhpParser/Node/Stmt/Block.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Break_' => '/nikic-php-parser/PhpParser/Node/Stmt/Break_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Case_' => '/nikic-php-parser/PhpParser/Node/Stmt/Case_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Catch_' => '/nikic-php-parser/PhpParser/Node/Stmt/Catch_.php', @@ -904,7 +956,6 @@ spl_autoload_register( 'PHPUnit\\PhpParser\\Node\\Stmt\\Class_' => '/nikic-php-parser/PhpParser/Node/Stmt/Class_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Const_' => '/nikic-php-parser/PhpParser/Node/Stmt/Const_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Continue_' => '/nikic-php-parser/PhpParser/Node/Stmt/Continue_.php', - 'PHPUnit\\PhpParser\\Node\\Stmt\\DeclareDeclare' => '/nikic-php-parser/PhpParser/Node/Stmt/DeclareDeclare.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Declare_' => '/nikic-php-parser/PhpParser/Node/Stmt/Declare_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Do_' => '/nikic-php-parser/PhpParser/Node/Stmt/Do_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Echo_' => '/nikic-php-parser/PhpParser/Node/Stmt/Echo_.php', @@ -928,12 +979,9 @@ spl_autoload_register( 'PHPUnit\\PhpParser\\Node\\Stmt\\Namespace_' => '/nikic-php-parser/PhpParser/Node/Stmt/Namespace_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Nop' => '/nikic-php-parser/PhpParser/Node/Stmt/Nop.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Property' => '/nikic-php-parser/PhpParser/Node/Stmt/Property.php', - 'PHPUnit\\PhpParser\\Node\\Stmt\\PropertyProperty' => '/nikic-php-parser/PhpParser/Node/Stmt/PropertyProperty.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Return_' => '/nikic-php-parser/PhpParser/Node/Stmt/Return_.php', - 'PHPUnit\\PhpParser\\Node\\Stmt\\StaticVar' => '/nikic-php-parser/PhpParser/Node/Stmt/StaticVar.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Static_' => '/nikic-php-parser/PhpParser/Node/Stmt/Static_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Switch_' => '/nikic-php-parser/PhpParser/Node/Stmt/Switch_.php', - 'PHPUnit\\PhpParser\\Node\\Stmt\\Throw_' => '/nikic-php-parser/PhpParser/Node/Stmt/Throw_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\TraitUse' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUse.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\TraitUseAdaptation' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Alias' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php', @@ -941,28 +989,44 @@ spl_autoload_register( 'PHPUnit\\PhpParser\\Node\\Stmt\\Trait_' => '/nikic-php-parser/PhpParser/Node/Stmt/Trait_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\TryCatch' => '/nikic-php-parser/PhpParser/Node/Stmt/TryCatch.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Unset_' => '/nikic-php-parser/PhpParser/Node/Stmt/Unset_.php', - 'PHPUnit\\PhpParser\\Node\\Stmt\\UseUse' => '/nikic-php-parser/PhpParser/Node/Stmt/UseUse.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Use_' => '/nikic-php-parser/PhpParser/Node/Stmt/Use_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\While_' => '/nikic-php-parser/PhpParser/Node/Stmt/While_.php', 'PHPUnit\\PhpParser\\Node\\UnionType' => '/nikic-php-parser/PhpParser/Node/UnionType.php', + 'PHPUnit\\PhpParser\\Node\\UseItem' => '/nikic-php-parser/PhpParser/Node/UseItem.php', 'PHPUnit\\PhpParser\\Node\\VarLikeIdentifier' => '/nikic-php-parser/PhpParser/Node/VarLikeIdentifier.php', 'PHPUnit\\PhpParser\\Node\\VariadicPlaceholder' => '/nikic-php-parser/PhpParser/Node/VariadicPlaceholder.php', 'PHPUnit\\PhpParser\\Parser' => '/nikic-php-parser/PhpParser/Parser.php', 'PHPUnit\\PhpParser\\ParserAbstract' => '/nikic-php-parser/PhpParser/ParserAbstract.php', 'PHPUnit\\PhpParser\\ParserFactory' => '/nikic-php-parser/PhpParser/ParserFactory.php', - 'PHPUnit\\PhpParser\\Parser\\Multiple' => '/nikic-php-parser/PhpParser/Parser/Multiple.php', - 'PHPUnit\\PhpParser\\Parser\\Php5' => '/nikic-php-parser/PhpParser/Parser/Php5.php', 'PHPUnit\\PhpParser\\Parser\\Php7' => '/nikic-php-parser/PhpParser/Parser/Php7.php', - 'PHPUnit\\PhpParser\\Parser\\Tokens' => '/nikic-php-parser/PhpParser/Parser/Tokens.php', + 'PHPUnit\\PhpParser\\Parser\\Php8' => '/nikic-php-parser/PhpParser/Parser/Php8.php', + 'PHPUnit\\PhpParser\\PhpVersion' => '/nikic-php-parser/PhpParser/PhpVersion.php', + 'PHPUnit\\PhpParser\\PrettyPrinter' => '/nikic-php-parser/PhpParser/PrettyPrinter.php', 'PHPUnit\\PhpParser\\PrettyPrinterAbstract' => '/nikic-php-parser/PhpParser/PrettyPrinterAbstract.php', 'PHPUnit\\PhpParser\\PrettyPrinter\\Standard' => '/nikic-php-parser/PhpParser/PrettyPrinter/Standard.php', + 'PHPUnit\\PhpParser\\Token' => '/nikic-php-parser/PhpParser/Token.php', + 'PHPUnit\\Runner\\Baseline\\Baseline' => '/phpunit/Runner/Baseline/Baseline.php', + 'PHPUnit\\Runner\\Baseline\\CannotLoadBaselineException' => '/phpunit/Runner/Baseline/Exception/CannotLoadBaselineException.php', + 'PHPUnit\\Runner\\Baseline\\FileDoesNotHaveLineException' => '/phpunit/Runner/Baseline/Exception/FileDoesNotHaveLineException.php', + 'PHPUnit\\Runner\\Baseline\\Generator' => '/phpunit/Runner/Baseline/Generator.php', + 'PHPUnit\\Runner\\Baseline\\Issue' => '/phpunit/Runner/Baseline/Issue.php', + 'PHPUnit\\Runner\\Baseline\\Reader' => '/phpunit/Runner/Baseline/Reader.php', + 'PHPUnit\\Runner\\Baseline\\RelativePathCalculator' => '/phpunit/Runner/Baseline/RelativePathCalculator.php', + 'PHPUnit\\Runner\\Baseline\\Subscriber' => '/phpunit/Runner/Baseline/Subscriber/Subscriber.php', + 'PHPUnit\\Runner\\Baseline\\TestTriggeredDeprecationSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredDeprecationSubscriber.php', + 'PHPUnit\\Runner\\Baseline\\TestTriggeredNoticeSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredNoticeSubscriber.php', + 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpDeprecationSubscriber.php', + 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpNoticeSubscriber.php', + 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpWarningSubscriber.php', + 'PHPUnit\\Runner\\Baseline\\TestTriggeredWarningSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredWarningSubscriber.php', + 'PHPUnit\\Runner\\Baseline\\Writer' => '/phpunit/Runner/Baseline/Writer.php', 'PHPUnit\\Runner\\ClassCannotBeFoundException' => '/phpunit/Runner/Exception/ClassCannotBeFoundException.php', - 'PHPUnit\\Runner\\ClassCannotBeInstantiatedException' => '/phpunit/Runner/Exception/ClassCannotBeInstantiatedException.php', - 'PHPUnit\\Runner\\ClassDoesNotExistException' => '/phpunit/Runner/Exception/ClassDoesNotExistException.php', - 'PHPUnit\\Runner\\ClassDoesNotImplementExtensionInterfaceException' => '/phpunit/Runner/Exception/ClassDoesNotImplementExtensionInterfaceException.php', + 'PHPUnit\\Runner\\ClassDoesNotExtendTestCaseException' => '/phpunit/Runner/Exception/ClassDoesNotExtendTestCaseException.php', 'PHPUnit\\Runner\\ClassIsAbstractException' => '/phpunit/Runner/Exception/ClassIsAbstractException.php', 'PHPUnit\\Runner\\CodeCoverage' => '/phpunit/Runner/CodeCoverage.php', 'PHPUnit\\Runner\\DirectoryCannotBeCreatedException' => '/phpunit/Runner/Exception/DirectoryCannotBeCreatedException.php', + 'PHPUnit\\Runner\\ErrorException' => '/phpunit/Runner/Exception/ErrorException.php', + 'PHPUnit\\Runner\\ErrorHandler' => '/phpunit/Runner/ErrorHandler.php', 'PHPUnit\\Runner\\Exception' => '/phpunit/Runner/Exception/Exception.php', 'PHPUnit\\Runner\\Extension\\Extension' => '/phpunit/Runner/Extension/Extension.php', 'PHPUnit\\Runner\\Extension\\ExtensionBootstrapper' => '/phpunit/Runner/Extension/ExtensionBootstrapper.php', @@ -975,6 +1039,12 @@ spl_autoload_register( 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => '/phpunit/Runner/Filter/GroupFilterIterator.php', 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => '/phpunit/Runner/Filter/IncludeGroupFilterIterator.php', 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => '/phpunit/Runner/Filter/NameFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\TestIdFilterIterator' => '/phpunit/Runner/Filter/TestIdFilterIterator.php', + 'PHPUnit\\Runner\\GarbageCollection\\ExecutionFinishedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/ExecutionFinishedSubscriber.php', + 'PHPUnit\\Runner\\GarbageCollection\\ExecutionStartedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/ExecutionStartedSubscriber.php', + 'PHPUnit\\Runner\\GarbageCollection\\GarbageCollectionHandler' => '/phpunit/Runner/GarbageCollection/GarbageCollectionHandler.php', + 'PHPUnit\\Runner\\GarbageCollection\\Subscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/Subscriber.php', + 'PHPUnit\\Runner\\GarbageCollection\\TestFinishedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/TestFinishedSubscriber.php', 'PHPUnit\\Runner\\InvalidOrderException' => '/phpunit/Runner/Exception/InvalidOrderException.php', 'PHPUnit\\Runner\\InvalidPhptFileException' => '/phpunit/Runner/Exception/InvalidPhptFileException.php', 'PHPUnit\\Runner\\NoIgnoredEventException' => '/phpunit/Runner/Exception/NoIgnoredEventException.php', @@ -1021,6 +1091,7 @@ spl_autoload_register( 'PHPUnit\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugNotAvailableException' => '/php-code-coverage/Exception/XdebugNotAvailableException.php', 'PHPUnit\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugNotEnabledException' => '/php-code-coverage/Exception/XdebugNotEnabledException.php', 'PHPUnit\\SebastianBergmann\\CodeCoverage\\Exception' => '/php-code-coverage/Exception/Exception.php', + 'PHPUnit\\SebastianBergmann\\CodeCoverage\\FileCouldNotBeWrittenException' => '/php-code-coverage/Exception/FileCouldNotBeWrittenException.php', 'PHPUnit\\SebastianBergmann\\CodeCoverage\\Filter' => '/php-code-coverage/Filter.php', 'PHPUnit\\SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => '/php-code-coverage/Exception/InvalidArgumentException.php', 'PHPUnit\\SebastianBergmann\\CodeCoverage\\NoCodeCoverageDriverAvailableException' => '/php-code-coverage/Exception/NoCodeCoverageDriverAvailableException.php', @@ -1206,6 +1277,7 @@ spl_autoload_register( 'PHPUnit\\TestRunner\\TestResult\\Collector' => '/phpunit/Runner/TestResult/Collector.php', 'PHPUnit\\TestRunner\\TestResult\\ExecutionStartedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/ExecutionStartedSubscriber.php', 'PHPUnit\\TestRunner\\TestResult\\Facade' => '/phpunit/Runner/TestResult/Facade.php', + 'PHPUnit\\TestRunner\\TestResult\\Issues\\Issue' => '/phpunit/Runner/TestResult/Issue.php', 'PHPUnit\\TestRunner\\TestResult\\PassedTests' => '/phpunit/Runner/TestResult/PassedTests.php', 'PHPUnit\\TestRunner\\TestResult\\Subscriber' => '/phpunit/Runner/TestResult/Subscriber/Subscriber.php', 'PHPUnit\\TestRunner\\TestResult\\TestConsideredRiskySubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestConsideredRiskySubscriber.php', @@ -1280,6 +1352,7 @@ spl_autoload_register( 'PHPUnit\\TextUI\\Configuration\\IniSettingCollectionIterator' => '/phpunit/TextUI/Configuration/Value/IniSettingCollectionIterator.php', 'PHPUnit\\TextUI\\Configuration\\LoggingNotConfiguredException' => '/phpunit/TextUI/Configuration/Exception/LoggingNotConfiguredException.php', 'PHPUnit\\TextUI\\Configuration\\Merger' => '/phpunit/TextUI/Configuration/Merger.php', + 'PHPUnit\\TextUI\\Configuration\\NoBaselineException' => '/phpunit/TextUI/Configuration/Exception/NoBaselineException.php', 'PHPUnit\\TextUI\\Configuration\\NoBootstrapException' => '/phpunit/TextUI/Configuration/Exception/NoBootstrapException.php', 'PHPUnit\\TextUI\\Configuration\\NoCacheDirectoryException' => '/phpunit/TextUI/Configuration/Exception/NoCacheDirectoryException.php', 'PHPUnit\\TextUI\\Configuration\\NoCliArgumentException' => '/phpunit/TextUI/Configuration/Exception/NoCliArgumentException.php', @@ -1291,6 +1364,9 @@ spl_autoload_register( 'PHPUnit\\TextUI\\Configuration\\Php' => '/phpunit/TextUI/Configuration/Value/Php.php', 'PHPUnit\\TextUI\\Configuration\\PhpHandler' => '/phpunit/TextUI/Configuration/PhpHandler.php', 'PHPUnit\\TextUI\\Configuration\\Registry' => '/phpunit/TextUI/Configuration/Registry.php', + 'PHPUnit\\TextUI\\Configuration\\Source' => '/phpunit/TextUI/Configuration/Value/Source.php', + 'PHPUnit\\TextUI\\Configuration\\SourceFilter' => '/phpunit/TextUI/Configuration/SourceFilter.php', + 'PHPUnit\\TextUI\\Configuration\\SourceMapper' => '/phpunit/TextUI/Configuration/SourceMapper.php', 'PHPUnit\\TextUI\\Configuration\\TestDirectory' => '/phpunit/TextUI/Configuration/Value/TestDirectory.php', 'PHPUnit\\TextUI\\Configuration\\TestDirectoryCollection' => '/phpunit/TextUI/Configuration/Value/TestDirectoryCollection.php', 'PHPUnit\\TextUI\\Configuration\\TestDirectoryCollectionIterator' => '/phpunit/TextUI/Configuration/Value/TestDirectoryCollectionIterator.php', @@ -1304,9 +1380,11 @@ spl_autoload_register( 'PHPUnit\\TextUI\\Configuration\\Variable' => '/phpunit/TextUI/Configuration/Value/Variable.php', 'PHPUnit\\TextUI\\Configuration\\VariableCollection' => '/phpunit/TextUI/Configuration/Value/VariableCollection.php', 'PHPUnit\\TextUI\\Configuration\\VariableCollectionIterator' => '/phpunit/TextUI/Configuration/Value/VariableCollectionIterator.php', + 'PHPUnit\\TextUI\\DirectoryDoesNotExistException' => '/phpunit/TextUI/Exception/DirectoryDoesNotExistException.php', 'PHPUnit\\TextUI\\Exception' => '/phpunit/TextUI/Exception/Exception.php', 'PHPUnit\\TextUI\\ExtensionsNotConfiguredException' => '/phpunit/TextUI/Exception/ExtensionsNotConfiguredException.php', 'PHPUnit\\TextUI\\Help' => '/phpunit/TextUI/Help.php', + 'PHPUnit\\TextUI\\InvalidSocketException' => '/phpunit/TextUI/Exception/InvalidSocketException.php', 'PHPUnit\\TextUI\\Output\\DefaultPrinter' => '/phpunit/TextUI/Output/Printer/DefaultPrinter.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\BeforeTestClassMethodErroredSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/BeforeTestClassMethodErroredSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\ProgressPrinter' => '/phpunit/TextUI/Output/Default/ProgressPrinter/ProgressPrinter.php', @@ -1317,10 +1395,10 @@ spl_autoload_register( 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestFinishedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestFinishedSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestMarkedIncompleteSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestMarkedIncompleteSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestPreparedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestPreparedSubscriber.php', - 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestPrintedUnexpectedOutputSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestPrintedUnexpectedOutputSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestRunnerExecutionStartedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestRunnerExecutionStartedSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestSkippedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestSkippedSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredDeprecationSubscriber.php', + 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredErrorSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredErrorSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredNoticeSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredNoticeSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpDeprecationSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpNoticeSubscriber.php', @@ -1329,6 +1407,7 @@ spl_autoload_register( 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitWarningSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredWarningSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ResultPrinter' => '/phpunit/TextUI/Output/Default/ResultPrinter.php', + 'PHPUnit\\TextUI\\Output\\Default\\UnexpectedOutputPrinter' => '/phpunit/TextUI/Output/Default/UnexpectedOutputPrinter.php', 'PHPUnit\\TextUI\\Output\\Facade' => '/phpunit/TextUI/Output/Facade.php', 'PHPUnit\\TextUI\\Output\\NullPrinter' => '/phpunit/TextUI/Output/Printer/NullPrinter.php', 'PHPUnit\\TextUI\\Output\\Printer' => '/phpunit/TextUI/Output/Printer/Printer.php', @@ -1341,6 +1420,7 @@ spl_autoload_register( 'PHPUnit\\TextUI\\TestFileNotFoundException' => '/phpunit/TextUI/Exception/TestFileNotFoundException.php', 'PHPUnit\\TextUI\\TestRunner' => '/phpunit/TextUI/TestRunner.php', 'PHPUnit\\TextUI\\TestSuiteFilterProcessor' => '/phpunit/TextUI/TestSuiteFilterProcessor.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\CannotFindSchemaException' => '/phpunit/TextUI/Configuration/Exception/CannotFindSchemaException.php', 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\CodeCoverage' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/CodeCoverage.php', 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Clover' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Clover.php', 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Cobertura' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Cobertura.php', @@ -1359,6 +1439,7 @@ spl_autoload_register( 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageXmlToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageXmlToReport.php', 'PHPUnit\\TextUI\\XmlConfiguration\\DefaultConfiguration' => '/phpunit/TextUI/Configuration/Xml/DefaultConfiguration.php', 'PHPUnit\\TextUI\\XmlConfiguration\\Exception' => '/phpunit/TextUI/Configuration/Xml/Exception.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\FailedSchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/FailedSchemaDetectionResult.php', 'PHPUnit\\TextUI\\XmlConfiguration\\Generator' => '/phpunit/TextUI/Configuration/Xml/Generator.php', 'PHPUnit\\TextUI\\XmlConfiguration\\Groups' => '/phpunit/TextUI/Configuration/Xml/Groups.php', 'PHPUnit\\TextUI\\XmlConfiguration\\IntroduceCacheDirectoryAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCacheDirectoryAttribute.php', @@ -1378,8 +1459,9 @@ spl_autoload_register( 'PHPUnit\\TextUI\\XmlConfiguration\\Migrator' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrator.php', 'PHPUnit\\TextUI\\XmlConfiguration\\MoveAttributesFromFilterWhitelistToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromFilterWhitelistToCoverage.php', 'PHPUnit\\TextUI\\XmlConfiguration\\MoveAttributesFromRootToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromRootToCoverage.php', - 'PHPUnit\\TextUI\\XmlConfiguration\\MoveWhitelistDirectoriesToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistDirectoriesToCoverage.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\MoveCoverageDirectoriesToSource' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveCoverageDirectoriesToSource.php', 'PHPUnit\\TextUI\\XmlConfiguration\\MoveWhitelistExcludesToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistExcludesToCoverage.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\MoveWhitelistIncludesToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistIncludesToCoverage.php', 'PHPUnit\\TextUI\\XmlConfiguration\\PHPUnit' => '/phpunit/TextUI/Configuration/Xml/PHPUnit.php', 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute.php', 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveBeStrictAboutTodoAnnotatedTestsAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutTodoAnnotatedTestsAttribute.php', @@ -1400,8 +1482,15 @@ spl_autoload_register( 'PHPUnit\\TextUI\\XmlConfiguration\\RenameBackupStaticAttributesAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBackupStaticAttributesAttribute.php', 'PHPUnit\\TextUI\\XmlConfiguration\\RenameBeStrictAboutCoversAnnotationAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBeStrictAboutCoversAnnotationAttribute.php', 'PHPUnit\\TextUI\\XmlConfiguration\\RenameForceCoversAnnotationAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameForceCoversAnnotationAttribute.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetectionResult.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaDetector' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetector.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaFinder' => '/phpunit/TextUI/Configuration/Xml/SchemaFinder.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\SnapshotNodeList' => '/phpunit/TextUI/Configuration/Xml/Migration/SnapshotNodeList.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\SuccessfulSchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SuccessfulSchemaDetectionResult.php', 'PHPUnit\\TextUI\\XmlConfiguration\\TestSuiteMapper' => '/phpunit/TextUI/Configuration/Xml/TestSuiteMapper.php', 'PHPUnit\\TextUI\\XmlConfiguration\\UpdateSchemaLocation' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/UpdateSchemaLocation.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\ValidationResult' => '/phpunit/TextUI/Configuration/Xml/Validator/ValidationResult.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\Validator' => '/phpunit/TextUI/Configuration/Xml/Validator/Validator.php', 'PHPUnit\\TheSeer\\Tokenizer\\Exception' => '/theseer-tokenizer/Exception.php', 'PHPUnit\\TheSeer\\Tokenizer\\NamespaceUri' => '/theseer-tokenizer/NamespaceUri.php', 'PHPUnit\\TheSeer\\Tokenizer\\NamespaceUriException' => '/theseer-tokenizer/NamespaceUriException.php', @@ -1412,19 +1501,16 @@ spl_autoload_register( 'PHPUnit\\TheSeer\\Tokenizer\\XMLSerializer' => '/theseer-tokenizer/XMLSerializer.php', 'PHPUnit\\Util\\Cloner' => '/phpunit/Util/Cloner.php', 'PHPUnit\\Util\\Color' => '/phpunit/Util/Color.php', - 'PHPUnit\\Util\\DirectoryDoesNotExistException' => '/phpunit/Util/Exception/DirectoryDoesNotExistException.php', - 'PHPUnit\\Util\\ErrorHandler' => '/phpunit/Util/ErrorHandler.php', 'PHPUnit\\Util\\Exception' => '/phpunit/Util/Exception/Exception.php', 'PHPUnit\\Util\\ExcludeList' => '/phpunit/Util/ExcludeList.php', + 'PHPUnit\\Util\\Exporter' => '/phpunit/Util/Exporter.php', 'PHPUnit\\Util\\Filesystem' => '/phpunit/Util/Filesystem.php', 'PHPUnit\\Util\\Filter' => '/phpunit/Util/Filter.php', 'PHPUnit\\Util\\GlobalState' => '/phpunit/Util/GlobalState.php', 'PHPUnit\\Util\\InvalidDirectoryException' => '/phpunit/Util/Exception/InvalidDirectoryException.php', 'PHPUnit\\Util\\InvalidJsonException' => '/phpunit/Util/Exception/InvalidJsonException.php', - 'PHPUnit\\Util\\InvalidSocketException' => '/phpunit/Util/Exception/InvalidSocketException.php', 'PHPUnit\\Util\\InvalidVersionOperatorException' => '/phpunit/Util/Exception/InvalidVersionOperatorException.php', 'PHPUnit\\Util\\Json' => '/phpunit/Util/Json.php', - 'PHPUnit\\Util\\NoTestCaseObjectOnCallStackException' => '/phpunit/Util/Exception/NoTestCaseObjectOnCallStackException.php', 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => '/phpunit/Util/PHP/AbstractPhpProcess.php', 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => '/phpunit/Util/PHP/DefaultPhpProcess.php', 'PHPUnit\\Util\\PHP\\PhpProcessException' => '/phpunit/Util/Exception/PhpProcessException.php', @@ -1433,22 +1519,13 @@ spl_autoload_register( 'PHPUnit\\Util\\Test' => '/phpunit/Util/Test.php', 'PHPUnit\\Util\\ThrowableToStringMapper' => '/phpunit/Util/ThrowableToStringMapper.php', 'PHPUnit\\Util\\VersionComparisonOperator' => '/phpunit/Util/VersionComparisonOperator.php', - 'PHPUnit\\Util\\Xml' => '/phpunit/Util/Xml.php', - 'PHPUnit\\Util\\Xml\\Exception' => '/phpunit/Util/Xml/Exception.php', - 'PHPUnit\\Util\\Xml\\FailedSchemaDetectionResult' => '/phpunit/Util/Xml/FailedSchemaDetectionResult.php', + 'PHPUnit\\Util\\Xml' => '/phpunit/Util/Xml/Xml.php', 'PHPUnit\\Util\\Xml\\Loader' => '/phpunit/Util/Xml/Loader.php', - 'PHPUnit\\Util\\Xml\\SchemaDetectionResult' => '/phpunit/Util/Xml/SchemaDetectionResult.php', - 'PHPUnit\\Util\\Xml\\SchemaDetector' => '/phpunit/Util/Xml/SchemaDetector.php', - 'PHPUnit\\Util\\Xml\\SchemaFinder' => '/phpunit/Util/Xml/SchemaFinder.php', - 'PHPUnit\\Util\\Xml\\SnapshotNodeList' => '/phpunit/Util/Xml/SnapshotNodeList.php', - 'PHPUnit\\Util\\Xml\\SuccessfulSchemaDetectionResult' => '/phpunit/Util/Xml/SuccessfulSchemaDetectionResult.php', - 'PHPUnit\\Util\\Xml\\ValidationResult' => '/phpunit/Util/Xml/ValidationResult.php', - 'PHPUnit\\Util\\Xml\\Validator' => '/phpunit/Util/Xml/Validator.php', 'PHPUnit\\Util\\Xml\\XmlException' => '/phpunit/Util/Exception/XmlException.php']; } if (isset($classes[$class])) { - require_once 'phar://phpunit-10.0.16.phar' . $classes[$class]; + require_once 'phar://phpunit-10.5.8.phar' . $classes[$class]; } }, true, @@ -1487,6 +1564,7 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Event\\Code\\ClassMethod' => '/phpunit/Event/Value/ClassMethod.php', 'PHPUnit\\Event\\Code\\ComparisonFailure' => '/phpunit/Event/Value/ComparisonFailure.php', 'PHPUnit\\Event\\Code\\ComparisonFailureBuilder' => '/phpunit/Event/Value/ComparisonFailureBuilder.php', + 'PHPUnit\\Event\\Code\\NoTestCaseObjectOnCallStackException' => '/phpunit/Event/Exception/NoTestCaseObjectOnCallStackException.php', 'PHPUnit\\Event\\Code\\Phpt' => '/phpunit/Event/Value/Test/Phpt.php', 'PHPUnit\\Event\\Code\\Test' => '/phpunit/Event/Value/Test/Test.php', 'PHPUnit\\Event\\Code\\TestCollection' => '/phpunit/Event/Value/Test/TestCollection.php', @@ -1524,10 +1602,14 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Event\\Subscriber' => '/phpunit/Event/Subscriber.php', 'PHPUnit\\Event\\SubscriberTypeAlreadyRegisteredException' => '/phpunit/Event/Exception/SubscriberTypeAlreadyRegisteredException.php', 'PHPUnit\\Event\\Telemetry\\Duration' => '/phpunit/Event/Value/Telemetry/Duration.php', + 'PHPUnit\\Event\\Telemetry\\GarbageCollectorStatus' => '/phpunit/Event/Value/Telemetry/GarbageCollectorStatus.php', + 'PHPUnit\\Event\\Telemetry\\GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/GarbageCollectorStatusProvider.php', 'PHPUnit\\Event\\Telemetry\\HRTime' => '/phpunit/Event/Value/Telemetry/HRTime.php', 'PHPUnit\\Event\\Telemetry\\Info' => '/phpunit/Event/Value/Telemetry/Info.php', 'PHPUnit\\Event\\Telemetry\\MemoryMeter' => '/phpunit/Event/Value/Telemetry/MemoryMeter.php', 'PHPUnit\\Event\\Telemetry\\MemoryUsage' => '/phpunit/Event/Value/Telemetry/MemoryUsage.php', + 'PHPUnit\\Event\\Telemetry\\Php81GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/Php81GarbageCollectorStatusProvider.php', + 'PHPUnit\\Event\\Telemetry\\Php83GarbageCollectorStatusProvider' => '/phpunit/Event/Value/Telemetry/Php83GarbageCollectorStatusProvider.php', 'PHPUnit\\Event\\Telemetry\\Snapshot' => '/phpunit/Event/Value/Telemetry/Snapshot.php', 'PHPUnit\\Event\\Telemetry\\StopWatch' => '/phpunit/Event/Value/Telemetry/StopWatch.php', 'PHPUnit\\Event\\Telemetry\\System' => '/phpunit/Event/Value/Telemetry/System.php', @@ -1549,6 +1631,8 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Event\\TestRunner\\DeprecationTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/DeprecationTriggeredSubscriber.php', 'PHPUnit\\Event\\TestRunner\\EventFacadeSealed' => '/phpunit/Event/Events/TestRunner/EventFacadeSealed.php', 'PHPUnit\\Event\\TestRunner\\EventFacadeSealedSubscriber' => '/phpunit/Event/Events/TestRunner/EventFacadeSealedSubscriber.php', + 'PHPUnit\\Event\\TestRunner\\ExecutionAborted' => '/phpunit/Event/Events/TestRunner/ExecutionAborted.php', + 'PHPUnit\\Event\\TestRunner\\ExecutionAbortedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionAbortedSubscriber.php', 'PHPUnit\\Event\\TestRunner\\ExecutionFinished' => '/phpunit/Event/Events/TestRunner/ExecutionFinished.php', 'PHPUnit\\Event\\TestRunner\\ExecutionFinishedSubscriber' => '/phpunit/Event/Events/TestRunner/ExecutionFinishedSubscriber.php', 'PHPUnit\\Event\\TestRunner\\ExecutionStarted' => '/phpunit/Event/Events/TestRunner/ExecutionStarted.php', @@ -1559,6 +1643,12 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Event\\TestRunner\\ExtensionLoadedFromPharSubscriber' => '/phpunit/Event/Events/TestRunner/ExtensionLoadedFromPharSubscriber.php', 'PHPUnit\\Event\\TestRunner\\Finished' => '/phpunit/Event/Events/TestRunner/Finished.php', 'PHPUnit\\Event\\TestRunner\\FinishedSubscriber' => '/phpunit/Event/Events/TestRunner/FinishedSubscriber.php', + 'PHPUnit\\Event\\TestRunner\\GarbageCollectionDisabled' => '/phpunit/Event/Events/TestRunner/GarbageCollectionDisabled.php', + 'PHPUnit\\Event\\TestRunner\\GarbageCollectionDisabledSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionDisabledSubscriber.php', + 'PHPUnit\\Event\\TestRunner\\GarbageCollectionEnabled' => '/phpunit/Event/Events/TestRunner/GarbageCollectionEnabled.php', + 'PHPUnit\\Event\\TestRunner\\GarbageCollectionEnabledSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionEnabledSubscriber.php', + 'PHPUnit\\Event\\TestRunner\\GarbageCollectionTriggered' => '/phpunit/Event/Events/TestRunner/GarbageCollectionTriggered.php', + 'PHPUnit\\Event\\TestRunner\\GarbageCollectionTriggeredSubscriber' => '/phpunit/Event/Events/TestRunner/GarbageCollectionTriggeredSubscriber.php', 'PHPUnit\\Event\\TestRunner\\Started' => '/phpunit/Event/Events/TestRunner/Started.php', 'PHPUnit\\Event\\TestRunner\\StartedSubscriber' => '/phpunit/Event/Events/TestRunner/StartedSubscriber.php', 'PHPUnit\\Event\\TestRunner\\WarningTriggered' => '/phpunit/Event/Events/TestRunner/WarningTriggered.php', @@ -1606,6 +1696,10 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Event\\Test\\ComparatorRegisteredSubscriber' => '/phpunit/Event/Events/Test/ComparatorRegisteredSubscriber.php', 'PHPUnit\\Event\\Test\\ConsideredRisky' => '/phpunit/Event/Events/Test/Issue/ConsideredRisky.php', 'PHPUnit\\Event\\Test\\ConsideredRiskySubscriber' => '/phpunit/Event/Events/Test/Issue/ConsideredRiskySubscriber.php', + 'PHPUnit\\Event\\Test\\DataProviderMethodCalled' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalled.php', + 'PHPUnit\\Event\\Test\\DataProviderMethodCalledSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalledSubscriber.php', + 'PHPUnit\\Event\\Test\\DataProviderMethodFinished' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinished.php', + 'PHPUnit\\Event\\Test\\DataProviderMethodFinishedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinishedSubscriber.php', 'PHPUnit\\Event\\Test\\DeprecationTriggered' => '/phpunit/Event/Events/Test/Issue/DeprecationTriggered.php', 'PHPUnit\\Event\\Test\\DeprecationTriggeredSubscriber' => '/phpunit/Event/Events/Test/Issue/DeprecationTriggeredSubscriber.php', 'PHPUnit\\Event\\Test\\ErrorTriggered' => '/phpunit/Event/Events/Test/Issue/ErrorTriggered.php', @@ -1655,6 +1749,8 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Event\\Test\\PreConditionCalledSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PreConditionCalledSubscriber.php', 'PHPUnit\\Event\\Test\\PreConditionFinished' => '/phpunit/Event/Events/Test/HookMethod/PreConditionFinished.php', 'PHPUnit\\Event\\Test\\PreConditionFinishedSubscriber' => '/phpunit/Event/Events/Test/HookMethod/PreConditionFinishedSubscriber.php', + 'PHPUnit\\Event\\Test\\PreparationFailed' => '/phpunit/Event/Events/Test/Lifecycle/PreparationFailed.php', + 'PHPUnit\\Event\\Test\\PreparationFailedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparationFailedSubscriber.php', 'PHPUnit\\Event\\Test\\PreparationStarted' => '/phpunit/Event/Events/Test/Lifecycle/PreparationStarted.php', 'PHPUnit\\Event\\Test\\PreparationStartedSubscriber' => '/phpunit/Event/Events/Test/Lifecycle/PreparationStartedSubscriber.php', 'PHPUnit\\Event\\Test\\Prepared' => '/phpunit/Event/Events/Test/Lifecycle/Prepared.php', @@ -1706,6 +1802,10 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Framework\\Attributes\\ExcludeGlobalVariableFromBackup' => '/phpunit/Framework/Attributes/ExcludeGlobalVariableFromBackup.php', 'PHPUnit\\Framework\\Attributes\\ExcludeStaticPropertyFromBackup' => '/phpunit/Framework/Attributes/ExcludeStaticPropertyFromBackup.php', 'PHPUnit\\Framework\\Attributes\\Group' => '/phpunit/Framework/Attributes/Group.php', + 'PHPUnit\\Framework\\Attributes\\IgnoreClassForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreClassForCodeCoverage.php', + 'PHPUnit\\Framework\\Attributes\\IgnoreDeprecations' => '/phpunit/Framework/Attributes/IgnoreDeprecations.php', + 'PHPUnit\\Framework\\Attributes\\IgnoreFunctionForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreFunctionForCodeCoverage.php', + 'PHPUnit\\Framework\\Attributes\\IgnoreMethodForCodeCoverage' => '/phpunit/Framework/Attributes/IgnoreMethodForCodeCoverage.php', 'PHPUnit\\Framework\\Attributes\\Large' => '/phpunit/Framework/Attributes/Large.php', 'PHPUnit\\Framework\\Attributes\\Medium' => '/phpunit/Framework/Attributes/Medium.php', 'PHPUnit\\Framework\\Attributes\\PostCondition' => '/phpunit/Framework/Attributes/PostCondition.php', @@ -1730,6 +1830,7 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Framework\\Attributes\\Ticket' => '/phpunit/Framework/Attributes/Ticket.php', 'PHPUnit\\Framework\\Attributes\\UsesClass' => '/phpunit/Framework/Attributes/UsesClass.php', 'PHPUnit\\Framework\\Attributes\\UsesFunction' => '/phpunit/Framework/Attributes/UsesFunction.php', + 'PHPUnit\\Framework\\Attributes\\WithoutErrorHandler' => '/phpunit/Framework/Attributes/WithoutErrorHandler.php', 'PHPUnit\\Framework\\CodeCoverageException' => '/phpunit/Framework/Exception/CodeCoverageException.php', 'PHPUnit\\Framework\\ComparisonMethodDoesNotAcceptParameterTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotAcceptParameterTypeException.php', 'PHPUnit\\Framework\\ComparisonMethodDoesNotDeclareBoolReturnTypeException' => '/phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareBoolReturnTypeException.php', @@ -1773,7 +1874,8 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Framework\\Constraint\\LogicalNot' => '/phpunit/Framework/Constraint/Operator/LogicalNot.php', 'PHPUnit\\Framework\\Constraint\\LogicalOr' => '/phpunit/Framework/Constraint/Operator/LogicalOr.php', 'PHPUnit\\Framework\\Constraint\\LogicalXor' => '/phpunit/Framework/Constraint/Operator/LogicalXor.php', - 'PHPUnit\\Framework\\Constraint\\ObjectEquals' => '/phpunit/Framework/Constraint/ObjectEquals.php', + 'PHPUnit\\Framework\\Constraint\\ObjectEquals' => '/phpunit/Framework/Constraint/Object/ObjectEquals.php', + 'PHPUnit\\Framework\\Constraint\\ObjectHasProperty' => '/phpunit/Framework/Constraint/Object/ObjectHasProperty.php', 'PHPUnit\\Framework\\Constraint\\Operator' => '/phpunit/Framework/Constraint/Operator/Operator.php', 'PHPUnit\\Framework\\Constraint\\RegularExpression' => '/phpunit/Framework/Constraint/String/RegularExpression.php', 'PHPUnit\\Framework\\Constraint\\SameSize' => '/phpunit/Framework/Constraint/Cardinality/SameSize.php', @@ -1789,7 +1891,6 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Framework\\Constraint\\UnaryOperator' => '/phpunit/Framework/Constraint/Operator/UnaryOperator.php', 'PHPUnit\\Framework\\DataProviderTestSuite' => '/phpunit/Framework/DataProviderTestSuite.php', 'PHPUnit\\Framework\\EmptyStringException' => '/phpunit/Framework/Exception/EmptyStringException.php', - 'PHPUnit\\Framework\\Error' => '/phpunit/Framework/Exception/Error.php', 'PHPUnit\\Framework\\Exception' => '/phpunit/Framework/Exception/Exception.php', 'PHPUnit\\Framework\\ExecutionOrderDependency' => '/phpunit/Framework/ExecutionOrderDependency.php', 'PHPUnit\\Framework\\ExpectationFailedException' => '/phpunit/Framework/Exception/ExpectationFailedException.php', @@ -1800,77 +1901,83 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Framework\\InvalidCoversTargetException' => '/phpunit/Framework/Exception/InvalidCoversTargetException.php', 'PHPUnit\\Framework\\InvalidDataProviderException' => '/phpunit/Framework/Exception/InvalidDataProviderException.php', 'PHPUnit\\Framework\\InvalidDependencyException' => '/phpunit/Framework/Exception/InvalidDependencyException.php', - 'PHPUnit\\Framework\\MockObject\\Api' => '/phpunit/Framework/MockObject/Api/Api.php', 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => '/phpunit/Framework/MockObject/Exception/BadMethodCallException.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => '/phpunit/Framework/MockObject/Builder/Identity.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => '/phpunit/Framework/MockObject/Builder/InvocationMocker.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationStubber' => '/phpunit/Framework/MockObject/Builder/InvocationStubber.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => '/phpunit/Framework/MockObject/Builder/MethodNameMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => '/phpunit/Framework/MockObject/Builder/ParametersMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => '/phpunit/Framework/MockObject/Builder/Stub.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => '/phpunit/Framework/MockObject/Runtime/Builder/Identity.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => '/phpunit/Framework/MockObject/Runtime/Builder/InvocationMocker.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationStubber' => '/phpunit/Framework/MockObject/Runtime/Builder/InvocationStubber.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => '/phpunit/Framework/MockObject/Runtime/Builder/MethodNameMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => '/phpunit/Framework/MockObject/Runtime/Builder/ParametersMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => '/phpunit/Framework/MockObject/Runtime/Builder/Stub.php', 'PHPUnit\\Framework\\MockObject\\CannotUseAddMethodsException' => '/phpunit/Framework/MockObject/Exception/CannotUseAddMethodsException.php', 'PHPUnit\\Framework\\MockObject\\CannotUseOnlyMethodsException' => '/phpunit/Framework/MockObject/Exception/CannotUseOnlyMethodsException.php', - 'PHPUnit\\Framework\\MockObject\\ClassAlreadyExistsException' => '/phpunit/Framework/MockObject/Exception/ClassAlreadyExistsException.php', - 'PHPUnit\\Framework\\MockObject\\ClassIsEnumerationException' => '/phpunit/Framework/MockObject/Exception/ClassIsEnumerationException.php', - 'PHPUnit\\Framework\\MockObject\\ClassIsFinalException' => '/phpunit/Framework/MockObject/Exception/ClassIsFinalException.php', - 'PHPUnit\\Framework\\MockObject\\ClassIsReadonlyException' => '/phpunit/Framework/MockObject/Exception/ClassIsReadonlyException.php', 'PHPUnit\\Framework\\MockObject\\ConfigurableMethod' => '/phpunit/Framework/MockObject/ConfigurableMethod.php', - 'PHPUnit\\Framework\\MockObject\\ConfigurableMethodsAlreadyInitializedException' => '/phpunit/Framework/MockObject/Exception/ConfigurableMethodsAlreadyInitializedException.php', - 'PHPUnit\\Framework\\MockObject\\DuplicateMethodException' => '/phpunit/Framework/MockObject/Exception/DuplicateMethodException.php', + 'PHPUnit\\Framework\\MockObject\\DoubledCloneMethod' => '/phpunit/Framework/MockObject/Runtime/Api/DoubledCloneMethod.php', 'PHPUnit\\Framework\\MockObject\\Exception' => '/phpunit/Framework/MockObject/Exception/Exception.php', - 'PHPUnit\\Framework\\MockObject\\Generator' => '/phpunit/Framework/MockObject/Generator.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\ClassAlreadyExistsException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassAlreadyExistsException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsEnumerationException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsEnumerationException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsFinalException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsFinalException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\ClassIsReadonlyException' => '/phpunit/Framework/MockObject/Generator/Exception/ClassIsReadonlyException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\DuplicateMethodException' => '/phpunit/Framework/MockObject/Generator/Exception/DuplicateMethodException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\Exception' => '/phpunit/Framework/MockObject/Generator/Exception/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\Generator' => '/phpunit/Framework/MockObject/Generator/Generator.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\InvalidMethodNameException' => '/phpunit/Framework/MockObject/Generator/Exception/InvalidMethodNameException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\MockClass' => '/phpunit/Framework/MockObject/Generator/MockClass.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\MockMethod' => '/phpunit/Framework/MockObject/Generator/MockMethod.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\MockMethodSet' => '/phpunit/Framework/MockObject/Generator/MockMethodSet.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\MockTrait' => '/phpunit/Framework/MockObject/Generator/MockTrait.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\MockType' => '/phpunit/Framework/MockObject/Generator/MockType.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\OriginalConstructorInvocationRequiredException' => '/phpunit/Framework/MockObject/Generator/Exception/OriginalConstructorInvocationRequiredException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\ReflectionException' => '/phpunit/Framework/MockObject/Generator/Exception/ReflectionException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\RuntimeException' => '/phpunit/Framework/MockObject/Generator/Exception/RuntimeException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\SoapExtensionNotAvailableException' => '/phpunit/Framework/MockObject/Generator/Exception/SoapExtensionNotAvailableException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\TemplateLoader' => '/phpunit/Framework/MockObject/Generator/TemplateLoader.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownClassException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownClassException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownTraitException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownTraitException.php', + 'PHPUnit\\Framework\\MockObject\\Generator\\UnknownTypeException' => '/phpunit/Framework/MockObject/Generator/Exception/UnknownTypeException.php', 'PHPUnit\\Framework\\MockObject\\IncompatibleReturnValueException' => '/phpunit/Framework/MockObject/Exception/IncompatibleReturnValueException.php', - 'PHPUnit\\Framework\\MockObject\\InvalidMethodNameException' => '/phpunit/Framework/MockObject/Exception/InvalidMethodNameException.php', - 'PHPUnit\\Framework\\MockObject\\Invocation' => '/phpunit/Framework/MockObject/Invocation.php', - 'PHPUnit\\Framework\\MockObject\\InvocationHandler' => '/phpunit/Framework/MockObject/InvocationHandler.php', + 'PHPUnit\\Framework\\MockObject\\Invocation' => '/phpunit/Framework/MockObject/Runtime/Invocation.php', + 'PHPUnit\\Framework\\MockObject\\InvocationHandler' => '/phpunit/Framework/MockObject/Runtime/InvocationHandler.php', 'PHPUnit\\Framework\\MockObject\\MatchBuilderNotFoundException' => '/phpunit/Framework/MockObject/Exception/MatchBuilderNotFoundException.php', - 'PHPUnit\\Framework\\MockObject\\Matcher' => '/phpunit/Framework/MockObject/Matcher.php', + 'PHPUnit\\Framework\\MockObject\\Matcher' => '/phpunit/Framework/MockObject/Runtime/Matcher.php', 'PHPUnit\\Framework\\MockObject\\MatcherAlreadyRegisteredException' => '/phpunit/Framework/MockObject/Exception/MatcherAlreadyRegisteredException.php', - 'PHPUnit\\Framework\\MockObject\\Method' => '/phpunit/Framework/MockObject/Api/Method.php', + 'PHPUnit\\Framework\\MockObject\\Method' => '/phpunit/Framework/MockObject/Runtime/Api/Method.php', 'PHPUnit\\Framework\\MockObject\\MethodCannotBeConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodCannotBeConfiguredException.php', 'PHPUnit\\Framework\\MockObject\\MethodNameAlreadyConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodNameAlreadyConfiguredException.php', - 'PHPUnit\\Framework\\MockObject\\MethodNameConstraint' => '/phpunit/Framework/MockObject/MethodNameConstraint.php', + 'PHPUnit\\Framework\\MockObject\\MethodNameConstraint' => '/phpunit/Framework/MockObject/Runtime/MethodNameConstraint.php', 'PHPUnit\\Framework\\MockObject\\MethodNameNotConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodNameNotConfiguredException.php', 'PHPUnit\\Framework\\MockObject\\MethodParametersAlreadyConfiguredException' => '/phpunit/Framework/MockObject/Exception/MethodParametersAlreadyConfiguredException.php', 'PHPUnit\\Framework\\MockObject\\MockBuilder' => '/phpunit/Framework/MockObject/MockBuilder.php', - 'PHPUnit\\Framework\\MockObject\\MockClass' => '/phpunit/Framework/MockObject/MockClass.php', - 'PHPUnit\\Framework\\MockObject\\MockMethod' => '/phpunit/Framework/MockObject/MockMethod.php', - 'PHPUnit\\Framework\\MockObject\\MockMethodSet' => '/phpunit/Framework/MockObject/MockMethodSet.php', - 'PHPUnit\\Framework\\MockObject\\MockObject' => '/phpunit/Framework/MockObject/MockObject.php', - 'PHPUnit\\Framework\\MockObject\\MockTrait' => '/phpunit/Framework/MockObject/MockTrait.php', - 'PHPUnit\\Framework\\MockObject\\MockType' => '/phpunit/Framework/MockObject/MockType.php', - 'PHPUnit\\Framework\\MockObject\\MockedCloneMethod' => '/phpunit/Framework/MockObject/Api/MockedCloneMethod.php', - 'PHPUnit\\Framework\\MockObject\\OriginalConstructorInvocationRequiredException' => '/phpunit/Framework/MockObject/Exception/OriginalConstructorInvocationRequiredException.php', + 'PHPUnit\\Framework\\MockObject\\MockObject' => '/phpunit/Framework/MockObject/Runtime/Interface/MockObject.php', + 'PHPUnit\\Framework\\MockObject\\MockObjectApi' => '/phpunit/Framework/MockObject/Runtime/Api/MockObjectApi.php', + 'PHPUnit\\Framework\\MockObject\\MockObjectInternal' => '/phpunit/Framework/MockObject/Runtime/Interface/MockObjectInternal.php', + 'PHPUnit\\Framework\\MockObject\\NeverReturningMethodException' => '/phpunit/Framework/MockObject/Exception/NeverReturningMethodException.php', + 'PHPUnit\\Framework\\MockObject\\ProxiedCloneMethod' => '/phpunit/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php', 'PHPUnit\\Framework\\MockObject\\ReflectionException' => '/phpunit/Framework/MockObject/Exception/ReflectionException.php', + 'PHPUnit\\Framework\\MockObject\\ReturnValueGenerator' => '/phpunit/Framework/MockObject/Runtime/ReturnValueGenerator.php', 'PHPUnit\\Framework\\MockObject\\ReturnValueNotConfiguredException' => '/phpunit/Framework/MockObject/Exception/ReturnValueNotConfiguredException.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\AnyInvokedCount' => '/phpunit/Framework/MockObject/Rule/AnyInvokedCount.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\AnyParameters' => '/phpunit/Framework/MockObject/Rule/AnyParameters.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\InvocationOrder' => '/phpunit/Framework/MockObject/Rule/InvocationOrder.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastCount' => '/phpunit/Framework/MockObject/Rule/InvokedAtLeastCount.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastOnce' => '/phpunit/Framework/MockObject/Rule/InvokedAtLeastOnce.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtMostCount' => '/phpunit/Framework/MockObject/Rule/InvokedAtMostCount.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedCount' => '/phpunit/Framework/MockObject/Rule/InvokedCount.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\MethodName' => '/phpunit/Framework/MockObject/Rule/MethodName.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\Parameters' => '/phpunit/Framework/MockObject/Rule/Parameters.php', - 'PHPUnit\\Framework\\MockObject\\Rule\\ParametersRule' => '/phpunit/Framework/MockObject/Rule/ParametersRule.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\AnyInvokedCount' => '/phpunit/Framework/MockObject/Runtime/Rule/AnyInvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\AnyParameters' => '/phpunit/Framework/MockObject/Runtime/Rule/AnyParameters.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvocationOrder' => '/phpunit/Framework/MockObject/Runtime/Rule/InvocationOrder.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastOnce' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastOnce.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtMostCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedAtMostCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedCount' => '/phpunit/Framework/MockObject/Runtime/Rule/InvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\MethodName' => '/phpunit/Framework/MockObject/Runtime/Rule/MethodName.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\Parameters' => '/phpunit/Framework/MockObject/Runtime/Rule/Parameters.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\ParametersRule' => '/phpunit/Framework/MockObject/Runtime/Rule/ParametersRule.php', 'PHPUnit\\Framework\\MockObject\\RuntimeException' => '/phpunit/Framework/MockObject/Exception/RuntimeException.php', - 'PHPUnit\\Framework\\MockObject\\SoapExtensionNotAvailableException' => '/phpunit/Framework/MockObject/Exception/SoapExtensionNotAvailableException.php', - 'PHPUnit\\Framework\\MockObject\\Stub' => '/phpunit/Framework/MockObject/Stub.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => '/phpunit/Framework/MockObject/Stub/ConsecutiveCalls.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => '/phpunit/Framework/MockObject/Stub/Exception.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => '/phpunit/Framework/MockObject/Stub/ReturnArgument.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => '/phpunit/Framework/MockObject/Stub/ReturnCallback.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => '/phpunit/Framework/MockObject/Stub/ReturnReference.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => '/phpunit/Framework/MockObject/Stub/ReturnSelf.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => '/phpunit/Framework/MockObject/Stub/ReturnStub.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => '/phpunit/Framework/MockObject/Stub/ReturnValueMap.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\Stub' => '/phpunit/Framework/MockObject/Stub/Stub.php', - 'PHPUnit\\Framework\\MockObject\\TemplateLoader' => '/phpunit/Framework/MockObject/TemplateLoader.php', - 'PHPUnit\\Framework\\MockObject\\UnknownClassException' => '/phpunit/Framework/MockObject/Exception/UnknownClassException.php', - 'PHPUnit\\Framework\\MockObject\\UnknownTraitException' => '/phpunit/Framework/MockObject/Exception/UnknownTraitException.php', - 'PHPUnit\\Framework\\MockObject\\UnknownTypeException' => '/phpunit/Framework/MockObject/Exception/UnknownTypeException.php', - 'PHPUnit\\Framework\\MockObject\\UnmockedCloneMethod' => '/phpunit/Framework/MockObject/Api/UnmockedCloneMethod.php', - 'PHPUnit\\Framework\\MockObject\\Verifiable' => '/phpunit/Framework/MockObject/Verifiable.php', + 'PHPUnit\\Framework\\MockObject\\Stub' => '/phpunit/Framework/MockObject/Runtime/Interface/Stub.php', + 'PHPUnit\\Framework\\MockObject\\StubApi' => '/phpunit/Framework/MockObject/Runtime/Api/StubApi.php', + 'PHPUnit\\Framework\\MockObject\\StubInternal' => '/phpunit/Framework/MockObject/Runtime/Interface/StubInternal.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => '/phpunit/Framework/MockObject/Runtime/Stub/ConsecutiveCalls.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => '/phpunit/Framework/MockObject/Runtime/Stub/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnArgument.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnCallback.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnReference.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnSelf.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnStub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => '/phpunit/Framework/MockObject/Runtime/Stub/ReturnValueMap.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\Stub' => '/phpunit/Framework/MockObject/Runtime/Stub/Stub.php', 'PHPUnit\\Framework\\NoChildTestSuiteException' => '/phpunit/Framework/Exception/NoChildTestSuiteException.php', 'PHPUnit\\Framework\\PhptAssertionFailedError' => '/phpunit/Framework/Exception/PhptAssertionFailedError.php', 'PHPUnit\\Framework\\ProcessIsolationException' => '/phpunit/Framework/Exception/ProcessIsolationException.php', @@ -1903,7 +2010,6 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Framework\\TestStatus\\Warning' => '/phpunit/Framework/TestStatus/Warning.php', 'PHPUnit\\Framework\\TestSuite' => '/phpunit/Framework/TestSuite.php', 'PHPUnit\\Framework\\TestSuiteIterator' => '/phpunit/Framework/TestSuiteIterator.php', - 'PHPUnit\\Framework\\UnknownClassException' => '/phpunit/Framework/Exception/UnknownClassException.php', 'PHPUnit\\Framework\\UnknownClassOrInterfaceException' => '/phpunit/Framework/Exception/UnknownClassOrInterfaceException.php', 'PHPUnit\\Framework\\UnknownTypeException' => '/phpunit/Framework/Exception/UnknownTypeException.php', 'PHPUnit\\Logging\\EventLogger' => '/phpunit/Logging/EventLogger.php', @@ -1914,6 +2020,8 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Logging\\JUnit\\TestFailedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestFailedSubscriber.php', 'PHPUnit\\Logging\\JUnit\\TestFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestFinishedSubscriber.php', 'PHPUnit\\Logging\\JUnit\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestMarkedIncompleteSubscriber.php', + 'PHPUnit\\Logging\\JUnit\\TestPreparationFailedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparationFailedSubscriber.php', + 'PHPUnit\\Logging\\JUnit\\TestPreparationStartedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparationStartedSubscriber.php', 'PHPUnit\\Logging\\JUnit\\TestPreparedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestPreparedSubscriber.php', 'PHPUnit\\Logging\\JUnit\\TestRunnerExecutionFinishedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestRunnerExecutionFinishedSubscriber.php', 'PHPUnit\\Logging\\JUnit\\TestSkippedSubscriber' => '/phpunit/Logging/JUnit/Subscriber/TestSkippedSubscriber.php', @@ -1934,26 +2042,28 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Logging\\TestDox\\HtmlRenderer' => '/phpunit/Logging/TestDox/HtmlRenderer.php', 'PHPUnit\\Logging\\TestDox\\NamePrettifier' => '/phpunit/Logging/TestDox/NamePrettifier.php', 'PHPUnit\\Logging\\TestDox\\PlainTextRenderer' => '/phpunit/Logging/TestDox/PlainTextRenderer.php', - 'PHPUnit\\Logging\\TestDox\\Subscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/Subscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestConsideredRiskySubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestConsideredRiskySubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestCreatedMockObjectForAbstractClassSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedMockObjectForAbstractClassSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestCreatedMockObjectForTraitSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedMockObjectForTraitSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestCreatedMockObjectFromWsdlSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedMockObjectFromWsdlSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestCreatedMockObjectSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedMockObjectSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestCreatedPartialMockObjectSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedPartialMockObjectSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestCreatedTestProxySubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedTestProxySubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestCreatedTestStubSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedTestStubSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestErroredSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestErroredSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestFailedSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestFailedSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestFinishedSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestFinishedSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestMarkedIncompleteSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestPassedSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestPassedSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestPreparedSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestPreparedSubscriber.php', - 'PHPUnit\\Logging\\TestDox\\TestResult' => '/phpunit/Logging/TestDox/TestMethod/TestResult.php', - 'PHPUnit\\Logging\\TestDox\\TestResultCollection' => '/phpunit/Logging/TestDox/TestMethod/TestResultCollection.php', - 'PHPUnit\\Logging\\TestDox\\TestResultCollectionIterator' => '/phpunit/Logging/TestDox/TestMethod/TestResultCollectionIterator.php', - 'PHPUnit\\Logging\\TestDox\\TestResultCollector' => '/phpunit/Logging/TestDox/TestMethod/TestResultCollector.php', - 'PHPUnit\\Logging\\TestDox\\TestSkippedSubscriber' => '/phpunit/Logging/TestDox/TestMethod/Subscriber/TestSkippedSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\Subscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/Subscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestConsideredRiskySubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestConsideredRiskySubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestErroredSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestErroredSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestFailedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestFailedSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestFinishedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestFinishedSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestMarkedIncompleteSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestMarkedIncompleteSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestPassedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestPassedSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestPreparedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestPreparedSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestResult' => '/phpunit/Logging/TestDox/TestResult/TestResult.php', + 'PHPUnit\\Logging\\TestDox\\TestResultCollection' => '/phpunit/Logging/TestDox/TestResult/TestResultCollection.php', + 'PHPUnit\\Logging\\TestDox\\TestResultCollectionIterator' => '/phpunit/Logging/TestDox/TestResult/TestResultCollectionIterator.php', + 'PHPUnit\\Logging\\TestDox\\TestResultCollector' => '/phpunit/Logging/TestDox/TestResult/TestResultCollector.php', + 'PHPUnit\\Logging\\TestDox\\TestSkippedSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestSkippedSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredNoticeSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredNoticeSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitDeprecationSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitErrorSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.php', + 'PHPUnit\\Logging\\TestDox\\TestTriggeredWarningSubscriber' => '/phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredWarningSubscriber.php', 'PHPUnit\\Metadata\\After' => '/phpunit/Metadata/After.php', 'PHPUnit\\Metadata\\AfterClass' => '/phpunit/Metadata/AfterClass.php', 'PHPUnit\\Metadata\\Annotation\\Parser\\DocBlock' => '/phpunit/Metadata/Parser/Annotation/DocBlock.php', @@ -1982,6 +2092,10 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Metadata\\ExcludeGlobalVariableFromBackup' => '/phpunit/Metadata/ExcludeGlobalVariableFromBackup.php', 'PHPUnit\\Metadata\\ExcludeStaticPropertyFromBackup' => '/phpunit/Metadata/ExcludeStaticPropertyFromBackup.php', 'PHPUnit\\Metadata\\Group' => '/phpunit/Metadata/Group.php', + 'PHPUnit\\Metadata\\IgnoreClassForCodeCoverage' => '/phpunit/Metadata/IgnoreClassForCodeCoverage.php', + 'PHPUnit\\Metadata\\IgnoreDeprecations' => '/phpunit/Metadata/IgnoreDeprecations.php', + 'PHPUnit\\Metadata\\IgnoreFunctionForCodeCoverage' => '/phpunit/Metadata/IgnoreFunctionForCodeCoverage.php', + 'PHPUnit\\Metadata\\IgnoreMethodForCodeCoverage' => '/phpunit/Metadata/IgnoreMethodForCodeCoverage.php', 'PHPUnit\\Metadata\\InvalidVersionRequirementException' => '/phpunit/Metadata/Exception/InvalidVersionRequirementException.php', 'PHPUnit\\Metadata\\Metadata' => '/phpunit/Metadata/Metadata.php', 'PHPUnit\\Metadata\\MetadataCollection' => '/phpunit/Metadata/MetadataCollection.php', @@ -2018,6 +2132,7 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Metadata\\Version\\ComparisonRequirement' => '/phpunit/Metadata/Version/ComparisonRequirement.php', 'PHPUnit\\Metadata\\Version\\ConstraintRequirement' => '/phpunit/Metadata/Version/ConstraintRequirement.php', 'PHPUnit\\Metadata\\Version\\Requirement' => '/phpunit/Metadata/Version/Requirement.php', + 'PHPUnit\\Metadata\\WithoutErrorHandler' => '/phpunit/Metadata/WithoutErrorHandler.php', 'PHPUnit\\PharIo\\Manifest\\Application' => '/phar-io-manifest/values/Application.php', 'PHPUnit\\PharIo\\Manifest\\ApplicationName' => '/phar-io-manifest/values/ApplicationName.php', 'PHPUnit\\PharIo\\Manifest\\Author' => '/phar-io-manifest/values/Author.php', @@ -2119,24 +2234,22 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\PhpParser\\Internal\\DiffElem' => '/nikic-php-parser/PhpParser/Internal/DiffElem.php', 'PHPUnit\\PhpParser\\Internal\\Differ' => '/nikic-php-parser/PhpParser/Internal/Differ.php', 'PHPUnit\\PhpParser\\Internal\\PrintableNewAnonClassNode' => '/nikic-php-parser/PhpParser/Internal/PrintableNewAnonClassNode.php', + 'PHPUnit\\PhpParser\\Internal\\TokenPolyfill' => '/nikic-php-parser/PhpParser/Internal/TokenPolyfill.php', 'PHPUnit\\PhpParser\\Internal\\TokenStream' => '/nikic-php-parser/PhpParser/Internal/TokenStream.php', 'PHPUnit\\PhpParser\\JsonDecoder' => '/nikic-php-parser/PhpParser/JsonDecoder.php', 'PHPUnit\\PhpParser\\Lexer' => '/nikic-php-parser/PhpParser/Lexer.php', 'PHPUnit\\PhpParser\\Lexer\\Emulative' => '/nikic-php-parser/PhpParser/Lexer/Emulative.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\AttributeEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php', - 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\CoaleseEqualTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/CoaleseEqualTokenEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\EnumTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\ExplicitOctalEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php', - 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\FlexibleDocStringEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/FlexibleDocStringEmulator.php', - 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\FnTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/FnTokenEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\KeywordEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\MatchTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\NullsafeTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php', - 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\NumericLiteralSeparatorEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/NumericLiteralSeparatorEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyFunctionTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyTokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\ReverseEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php', 'PHPUnit\\PhpParser\\Lexer\\TokenEmulator\\TokenEmulator' => '/nikic-php-parser/PhpParser/Lexer/TokenEmulator/TokenEmulator.php', + 'PHPUnit\\PhpParser\\Modifiers' => '/nikic-php-parser/PhpParser/Modifiers.php', 'PHPUnit\\PhpParser\\NameContext' => '/nikic-php-parser/PhpParser/NameContext.php', 'PHPUnit\\PhpParser\\Node' => '/nikic-php-parser/PhpParser/Node.php', 'PHPUnit\\PhpParser\\NodeAbstract' => '/nikic-php-parser/PhpParser/NodeAbstract.php', @@ -2147,19 +2260,22 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\PhpParser\\NodeVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor.php', 'PHPUnit\\PhpParser\\NodeVisitorAbstract' => '/nikic-php-parser/PhpParser/NodeVisitorAbstract.php', 'PHPUnit\\PhpParser\\NodeVisitor\\CloningVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/CloningVisitor.php', + 'PHPUnit\\PhpParser\\NodeVisitor\\CommentAnnotatingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/CommentAnnotatingVisitor.php', 'PHPUnit\\PhpParser\\NodeVisitor\\FindingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/FindingVisitor.php', 'PHPUnit\\PhpParser\\NodeVisitor\\FirstFindingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/FirstFindingVisitor.php', 'PHPUnit\\PhpParser\\NodeVisitor\\NameResolver' => '/nikic-php-parser/PhpParser/NodeVisitor/NameResolver.php', 'PHPUnit\\PhpParser\\NodeVisitor\\NodeConnectingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/NodeConnectingVisitor.php', 'PHPUnit\\PhpParser\\NodeVisitor\\ParentConnectingVisitor' => '/nikic-php-parser/PhpParser/NodeVisitor/ParentConnectingVisitor.php', 'PHPUnit\\PhpParser\\Node\\Arg' => '/nikic-php-parser/PhpParser/Node/Arg.php', + 'PHPUnit\\PhpParser\\Node\\ArrayItem' => '/nikic-php-parser/PhpParser/Node/ArrayItem.php', 'PHPUnit\\PhpParser\\Node\\Attribute' => '/nikic-php-parser/PhpParser/Node/Attribute.php', 'PHPUnit\\PhpParser\\Node\\AttributeGroup' => '/nikic-php-parser/PhpParser/Node/AttributeGroup.php', + 'PHPUnit\\PhpParser\\Node\\ClosureUse' => '/nikic-php-parser/PhpParser/Node/ClosureUse.php', 'PHPUnit\\PhpParser\\Node\\ComplexType' => '/nikic-php-parser/PhpParser/Node/ComplexType.php', 'PHPUnit\\PhpParser\\Node\\Const_' => '/nikic-php-parser/PhpParser/Node/Const_.php', + 'PHPUnit\\PhpParser\\Node\\DeclareItem' => '/nikic-php-parser/PhpParser/Node/DeclareItem.php', 'PHPUnit\\PhpParser\\Node\\Expr' => '/nikic-php-parser/PhpParser/Node/Expr.php', 'PHPUnit\\PhpParser\\Node\\Expr\\ArrayDimFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ArrayDimFetch.php', - 'PHPUnit\\PhpParser\\Node\\Expr\\ArrayItem' => '/nikic-php-parser/PhpParser/Node/Expr/ArrayItem.php', 'PHPUnit\\PhpParser\\Node\\Expr\\Array_' => '/nikic-php-parser/PhpParser/Node/Expr/Array_.php', 'PHPUnit\\PhpParser\\Node\\Expr\\ArrowFunction' => '/nikic-php-parser/PhpParser/Node/Expr/ArrowFunction.php', 'PHPUnit\\PhpParser\\Node\\Expr\\Assign' => '/nikic-php-parser/PhpParser/Node/Expr/Assign.php', @@ -2220,7 +2336,6 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\PhpParser\\Node\\Expr\\ClassConstFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ClassConstFetch.php', 'PHPUnit\\PhpParser\\Node\\Expr\\Clone_' => '/nikic-php-parser/PhpParser/Node/Expr/Clone_.php', 'PHPUnit\\PhpParser\\Node\\Expr\\Closure' => '/nikic-php-parser/PhpParser/Node/Expr/Closure.php', - 'PHPUnit\\PhpParser\\Node\\Expr\\ClosureUse' => '/nikic-php-parser/PhpParser/Node/Expr/ClosureUse.php', 'PHPUnit\\PhpParser\\Node\\Expr\\ConstFetch' => '/nikic-php-parser/PhpParser/Node/Expr/ConstFetch.php', 'PHPUnit\\PhpParser\\Node\\Expr\\Empty_' => '/nikic-php-parser/PhpParser/Node/Expr/Empty_.php', 'PHPUnit\\PhpParser\\Node\\Expr\\Error' => '/nikic-php-parser/PhpParser/Node/Expr/Error.php', @@ -2255,6 +2370,7 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\PhpParser\\Node\\Expr\\Yield_' => '/nikic-php-parser/PhpParser/Node/Expr/Yield_.php', 'PHPUnit\\PhpParser\\Node\\FunctionLike' => '/nikic-php-parser/PhpParser/Node/FunctionLike.php', 'PHPUnit\\PhpParser\\Node\\Identifier' => '/nikic-php-parser/PhpParser/Node/Identifier.php', + 'PHPUnit\\PhpParser\\Node\\InterpolatedStringPart' => '/nikic-php-parser/PhpParser/Node/InterpolatedStringPart.php', 'PHPUnit\\PhpParser\\Node\\IntersectionType' => '/nikic-php-parser/PhpParser/Node/IntersectionType.php', 'PHPUnit\\PhpParser\\Node\\MatchArm' => '/nikic-php-parser/PhpParser/Node/MatchArm.php', 'PHPUnit\\PhpParser\\Node\\Name' => '/nikic-php-parser/PhpParser/Node/Name.php', @@ -2262,11 +2378,11 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\PhpParser\\Node\\Name\\Relative' => '/nikic-php-parser/PhpParser/Node/Name/Relative.php', 'PHPUnit\\PhpParser\\Node\\NullableType' => '/nikic-php-parser/PhpParser/Node/NullableType.php', 'PHPUnit\\PhpParser\\Node\\Param' => '/nikic-php-parser/PhpParser/Node/Param.php', + 'PHPUnit\\PhpParser\\Node\\PropertyItem' => '/nikic-php-parser/PhpParser/Node/PropertyItem.php', 'PHPUnit\\PhpParser\\Node\\Scalar' => '/nikic-php-parser/PhpParser/Node/Scalar.php', - 'PHPUnit\\PhpParser\\Node\\Scalar\\DNumber' => '/nikic-php-parser/PhpParser/Node/Scalar/DNumber.php', - 'PHPUnit\\PhpParser\\Node\\Scalar\\Encapsed' => '/nikic-php-parser/PhpParser/Node/Scalar/Encapsed.php', - 'PHPUnit\\PhpParser\\Node\\Scalar\\EncapsedStringPart' => '/nikic-php-parser/PhpParser/Node/Scalar/EncapsedStringPart.php', - 'PHPUnit\\PhpParser\\Node\\Scalar\\LNumber' => '/nikic-php-parser/PhpParser/Node/Scalar/LNumber.php', + 'PHPUnit\\PhpParser\\Node\\Scalar\\Float_' => '/nikic-php-parser/PhpParser/Node/Scalar/Float_.php', + 'PHPUnit\\PhpParser\\Node\\Scalar\\Int_' => '/nikic-php-parser/PhpParser/Node/Scalar/Int_.php', + 'PHPUnit\\PhpParser\\Node\\Scalar\\InterpolatedString' => '/nikic-php-parser/PhpParser/Node/Scalar/InterpolatedString.php', 'PHPUnit\\PhpParser\\Node\\Scalar\\MagicConst' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst.php', 'PHPUnit\\PhpParser\\Node\\Scalar\\MagicConst\\Class_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Class_.php', 'PHPUnit\\PhpParser\\Node\\Scalar\\MagicConst\\Dir' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Dir.php', @@ -2277,7 +2393,9 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\PhpParser\\Node\\Scalar\\MagicConst\\Namespace_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Namespace_.php', 'PHPUnit\\PhpParser\\Node\\Scalar\\MagicConst\\Trait_' => '/nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Trait_.php', 'PHPUnit\\PhpParser\\Node\\Scalar\\String_' => '/nikic-php-parser/PhpParser/Node/Scalar/String_.php', + 'PHPUnit\\PhpParser\\Node\\StaticVar' => '/nikic-php-parser/PhpParser/Node/StaticVar.php', 'PHPUnit\\PhpParser\\Node\\Stmt' => '/nikic-php-parser/PhpParser/Node/Stmt.php', + 'PHPUnit\\PhpParser\\Node\\Stmt\\Block' => '/nikic-php-parser/PhpParser/Node/Stmt/Block.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Break_' => '/nikic-php-parser/PhpParser/Node/Stmt/Break_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Case_' => '/nikic-php-parser/PhpParser/Node/Stmt/Case_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Catch_' => '/nikic-php-parser/PhpParser/Node/Stmt/Catch_.php', @@ -2287,7 +2405,6 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\PhpParser\\Node\\Stmt\\Class_' => '/nikic-php-parser/PhpParser/Node/Stmt/Class_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Const_' => '/nikic-php-parser/PhpParser/Node/Stmt/Const_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Continue_' => '/nikic-php-parser/PhpParser/Node/Stmt/Continue_.php', - 'PHPUnit\\PhpParser\\Node\\Stmt\\DeclareDeclare' => '/nikic-php-parser/PhpParser/Node/Stmt/DeclareDeclare.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Declare_' => '/nikic-php-parser/PhpParser/Node/Stmt/Declare_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Do_' => '/nikic-php-parser/PhpParser/Node/Stmt/Do_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Echo_' => '/nikic-php-parser/PhpParser/Node/Stmt/Echo_.php', @@ -2311,12 +2428,9 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\PhpParser\\Node\\Stmt\\Namespace_' => '/nikic-php-parser/PhpParser/Node/Stmt/Namespace_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Nop' => '/nikic-php-parser/PhpParser/Node/Stmt/Nop.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Property' => '/nikic-php-parser/PhpParser/Node/Stmt/Property.php', - 'PHPUnit\\PhpParser\\Node\\Stmt\\PropertyProperty' => '/nikic-php-parser/PhpParser/Node/Stmt/PropertyProperty.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Return_' => '/nikic-php-parser/PhpParser/Node/Stmt/Return_.php', - 'PHPUnit\\PhpParser\\Node\\Stmt\\StaticVar' => '/nikic-php-parser/PhpParser/Node/Stmt/StaticVar.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Static_' => '/nikic-php-parser/PhpParser/Node/Stmt/Static_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Switch_' => '/nikic-php-parser/PhpParser/Node/Stmt/Switch_.php', - 'PHPUnit\\PhpParser\\Node\\Stmt\\Throw_' => '/nikic-php-parser/PhpParser/Node/Stmt/Throw_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\TraitUse' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUse.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\TraitUseAdaptation' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Alias' => '/nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php', @@ -2324,28 +2438,44 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\PhpParser\\Node\\Stmt\\Trait_' => '/nikic-php-parser/PhpParser/Node/Stmt/Trait_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\TryCatch' => '/nikic-php-parser/PhpParser/Node/Stmt/TryCatch.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Unset_' => '/nikic-php-parser/PhpParser/Node/Stmt/Unset_.php', - 'PHPUnit\\PhpParser\\Node\\Stmt\\UseUse' => '/nikic-php-parser/PhpParser/Node/Stmt/UseUse.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\Use_' => '/nikic-php-parser/PhpParser/Node/Stmt/Use_.php', 'PHPUnit\\PhpParser\\Node\\Stmt\\While_' => '/nikic-php-parser/PhpParser/Node/Stmt/While_.php', 'PHPUnit\\PhpParser\\Node\\UnionType' => '/nikic-php-parser/PhpParser/Node/UnionType.php', + 'PHPUnit\\PhpParser\\Node\\UseItem' => '/nikic-php-parser/PhpParser/Node/UseItem.php', 'PHPUnit\\PhpParser\\Node\\VarLikeIdentifier' => '/nikic-php-parser/PhpParser/Node/VarLikeIdentifier.php', 'PHPUnit\\PhpParser\\Node\\VariadicPlaceholder' => '/nikic-php-parser/PhpParser/Node/VariadicPlaceholder.php', 'PHPUnit\\PhpParser\\Parser' => '/nikic-php-parser/PhpParser/Parser.php', 'PHPUnit\\PhpParser\\ParserAbstract' => '/nikic-php-parser/PhpParser/ParserAbstract.php', 'PHPUnit\\PhpParser\\ParserFactory' => '/nikic-php-parser/PhpParser/ParserFactory.php', - 'PHPUnit\\PhpParser\\Parser\\Multiple' => '/nikic-php-parser/PhpParser/Parser/Multiple.php', - 'PHPUnit\\PhpParser\\Parser\\Php5' => '/nikic-php-parser/PhpParser/Parser/Php5.php', 'PHPUnit\\PhpParser\\Parser\\Php7' => '/nikic-php-parser/PhpParser/Parser/Php7.php', - 'PHPUnit\\PhpParser\\Parser\\Tokens' => '/nikic-php-parser/PhpParser/Parser/Tokens.php', + 'PHPUnit\\PhpParser\\Parser\\Php8' => '/nikic-php-parser/PhpParser/Parser/Php8.php', + 'PHPUnit\\PhpParser\\PhpVersion' => '/nikic-php-parser/PhpParser/PhpVersion.php', + 'PHPUnit\\PhpParser\\PrettyPrinter' => '/nikic-php-parser/PhpParser/PrettyPrinter.php', 'PHPUnit\\PhpParser\\PrettyPrinterAbstract' => '/nikic-php-parser/PhpParser/PrettyPrinterAbstract.php', 'PHPUnit\\PhpParser\\PrettyPrinter\\Standard' => '/nikic-php-parser/PhpParser/PrettyPrinter/Standard.php', + 'PHPUnit\\PhpParser\\Token' => '/nikic-php-parser/PhpParser/Token.php', + 'PHPUnit\\Runner\\Baseline\\Baseline' => '/phpunit/Runner/Baseline/Baseline.php', + 'PHPUnit\\Runner\\Baseline\\CannotLoadBaselineException' => '/phpunit/Runner/Baseline/Exception/CannotLoadBaselineException.php', + 'PHPUnit\\Runner\\Baseline\\FileDoesNotHaveLineException' => '/phpunit/Runner/Baseline/Exception/FileDoesNotHaveLineException.php', + 'PHPUnit\\Runner\\Baseline\\Generator' => '/phpunit/Runner/Baseline/Generator.php', + 'PHPUnit\\Runner\\Baseline\\Issue' => '/phpunit/Runner/Baseline/Issue.php', + 'PHPUnit\\Runner\\Baseline\\Reader' => '/phpunit/Runner/Baseline/Reader.php', + 'PHPUnit\\Runner\\Baseline\\RelativePathCalculator' => '/phpunit/Runner/Baseline/RelativePathCalculator.php', + 'PHPUnit\\Runner\\Baseline\\Subscriber' => '/phpunit/Runner/Baseline/Subscriber/Subscriber.php', + 'PHPUnit\\Runner\\Baseline\\TestTriggeredDeprecationSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredDeprecationSubscriber.php', + 'PHPUnit\\Runner\\Baseline\\TestTriggeredNoticeSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredNoticeSubscriber.php', + 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpDeprecationSubscriber.php', + 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpNoticeSubscriber.php', + 'PHPUnit\\Runner\\Baseline\\TestTriggeredPhpWarningSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredPhpWarningSubscriber.php', + 'PHPUnit\\Runner\\Baseline\\TestTriggeredWarningSubscriber' => '/phpunit/Runner/Baseline/Subscriber/TestTriggeredWarningSubscriber.php', + 'PHPUnit\\Runner\\Baseline\\Writer' => '/phpunit/Runner/Baseline/Writer.php', 'PHPUnit\\Runner\\ClassCannotBeFoundException' => '/phpunit/Runner/Exception/ClassCannotBeFoundException.php', - 'PHPUnit\\Runner\\ClassCannotBeInstantiatedException' => '/phpunit/Runner/Exception/ClassCannotBeInstantiatedException.php', - 'PHPUnit\\Runner\\ClassDoesNotExistException' => '/phpunit/Runner/Exception/ClassDoesNotExistException.php', - 'PHPUnit\\Runner\\ClassDoesNotImplementExtensionInterfaceException' => '/phpunit/Runner/Exception/ClassDoesNotImplementExtensionInterfaceException.php', + 'PHPUnit\\Runner\\ClassDoesNotExtendTestCaseException' => '/phpunit/Runner/Exception/ClassDoesNotExtendTestCaseException.php', 'PHPUnit\\Runner\\ClassIsAbstractException' => '/phpunit/Runner/Exception/ClassIsAbstractException.php', 'PHPUnit\\Runner\\CodeCoverage' => '/phpunit/Runner/CodeCoverage.php', 'PHPUnit\\Runner\\DirectoryCannotBeCreatedException' => '/phpunit/Runner/Exception/DirectoryCannotBeCreatedException.php', + 'PHPUnit\\Runner\\ErrorException' => '/phpunit/Runner/Exception/ErrorException.php', + 'PHPUnit\\Runner\\ErrorHandler' => '/phpunit/Runner/ErrorHandler.php', 'PHPUnit\\Runner\\Exception' => '/phpunit/Runner/Exception/Exception.php', 'PHPUnit\\Runner\\Extension\\Extension' => '/phpunit/Runner/Extension/Extension.php', 'PHPUnit\\Runner\\Extension\\ExtensionBootstrapper' => '/phpunit/Runner/Extension/ExtensionBootstrapper.php', @@ -2358,6 +2488,12 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => '/phpunit/Runner/Filter/GroupFilterIterator.php', 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => '/phpunit/Runner/Filter/IncludeGroupFilterIterator.php', 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => '/phpunit/Runner/Filter/NameFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\TestIdFilterIterator' => '/phpunit/Runner/Filter/TestIdFilterIterator.php', + 'PHPUnit\\Runner\\GarbageCollection\\ExecutionFinishedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/ExecutionFinishedSubscriber.php', + 'PHPUnit\\Runner\\GarbageCollection\\ExecutionStartedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/ExecutionStartedSubscriber.php', + 'PHPUnit\\Runner\\GarbageCollection\\GarbageCollectionHandler' => '/phpunit/Runner/GarbageCollection/GarbageCollectionHandler.php', + 'PHPUnit\\Runner\\GarbageCollection\\Subscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/Subscriber.php', + 'PHPUnit\\Runner\\GarbageCollection\\TestFinishedSubscriber' => '/phpunit/Runner/GarbageCollection/Subscriber/TestFinishedSubscriber.php', 'PHPUnit\\Runner\\InvalidOrderException' => '/phpunit/Runner/Exception/InvalidOrderException.php', 'PHPUnit\\Runner\\InvalidPhptFileException' => '/phpunit/Runner/Exception/InvalidPhptFileException.php', 'PHPUnit\\Runner\\NoIgnoredEventException' => '/phpunit/Runner/Exception/NoIgnoredEventException.php', @@ -2404,6 +2540,7 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugNotAvailableException' => '/php-code-coverage/Exception/XdebugNotAvailableException.php', 'PHPUnit\\SebastianBergmann\\CodeCoverage\\Driver\\XdebugNotEnabledException' => '/php-code-coverage/Exception/XdebugNotEnabledException.php', 'PHPUnit\\SebastianBergmann\\CodeCoverage\\Exception' => '/php-code-coverage/Exception/Exception.php', + 'PHPUnit\\SebastianBergmann\\CodeCoverage\\FileCouldNotBeWrittenException' => '/php-code-coverage/Exception/FileCouldNotBeWrittenException.php', 'PHPUnit\\SebastianBergmann\\CodeCoverage\\Filter' => '/php-code-coverage/Filter.php', 'PHPUnit\\SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => '/php-code-coverage/Exception/InvalidArgumentException.php', 'PHPUnit\\SebastianBergmann\\CodeCoverage\\NoCodeCoverageDriverAvailableException' => '/php-code-coverage/Exception/NoCodeCoverageDriverAvailableException.php', @@ -2589,6 +2726,7 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\TestRunner\\TestResult\\Collector' => '/phpunit/Runner/TestResult/Collector.php', 'PHPUnit\\TestRunner\\TestResult\\ExecutionStartedSubscriber' => '/phpunit/Runner/TestResult/Subscriber/ExecutionStartedSubscriber.php', 'PHPUnit\\TestRunner\\TestResult\\Facade' => '/phpunit/Runner/TestResult/Facade.php', + 'PHPUnit\\TestRunner\\TestResult\\Issues\\Issue' => '/phpunit/Runner/TestResult/Issue.php', 'PHPUnit\\TestRunner\\TestResult\\PassedTests' => '/phpunit/Runner/TestResult/PassedTests.php', 'PHPUnit\\TestRunner\\TestResult\\Subscriber' => '/phpunit/Runner/TestResult/Subscriber/Subscriber.php', 'PHPUnit\\TestRunner\\TestResult\\TestConsideredRiskySubscriber' => '/phpunit/Runner/TestResult/Subscriber/TestConsideredRiskySubscriber.php', @@ -2663,6 +2801,7 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\TextUI\\Configuration\\IniSettingCollectionIterator' => '/phpunit/TextUI/Configuration/Value/IniSettingCollectionIterator.php', 'PHPUnit\\TextUI\\Configuration\\LoggingNotConfiguredException' => '/phpunit/TextUI/Configuration/Exception/LoggingNotConfiguredException.php', 'PHPUnit\\TextUI\\Configuration\\Merger' => '/phpunit/TextUI/Configuration/Merger.php', + 'PHPUnit\\TextUI\\Configuration\\NoBaselineException' => '/phpunit/TextUI/Configuration/Exception/NoBaselineException.php', 'PHPUnit\\TextUI\\Configuration\\NoBootstrapException' => '/phpunit/TextUI/Configuration/Exception/NoBootstrapException.php', 'PHPUnit\\TextUI\\Configuration\\NoCacheDirectoryException' => '/phpunit/TextUI/Configuration/Exception/NoCacheDirectoryException.php', 'PHPUnit\\TextUI\\Configuration\\NoCliArgumentException' => '/phpunit/TextUI/Configuration/Exception/NoCliArgumentException.php', @@ -2674,6 +2813,9 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\TextUI\\Configuration\\Php' => '/phpunit/TextUI/Configuration/Value/Php.php', 'PHPUnit\\TextUI\\Configuration\\PhpHandler' => '/phpunit/TextUI/Configuration/PhpHandler.php', 'PHPUnit\\TextUI\\Configuration\\Registry' => '/phpunit/TextUI/Configuration/Registry.php', + 'PHPUnit\\TextUI\\Configuration\\Source' => '/phpunit/TextUI/Configuration/Value/Source.php', + 'PHPUnit\\TextUI\\Configuration\\SourceFilter' => '/phpunit/TextUI/Configuration/SourceFilter.php', + 'PHPUnit\\TextUI\\Configuration\\SourceMapper' => '/phpunit/TextUI/Configuration/SourceMapper.php', 'PHPUnit\\TextUI\\Configuration\\TestDirectory' => '/phpunit/TextUI/Configuration/Value/TestDirectory.php', 'PHPUnit\\TextUI\\Configuration\\TestDirectoryCollection' => '/phpunit/TextUI/Configuration/Value/TestDirectoryCollection.php', 'PHPUnit\\TextUI\\Configuration\\TestDirectoryCollectionIterator' => '/phpunit/TextUI/Configuration/Value/TestDirectoryCollectionIterator.php', @@ -2687,9 +2829,11 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\TextUI\\Configuration\\Variable' => '/phpunit/TextUI/Configuration/Value/Variable.php', 'PHPUnit\\TextUI\\Configuration\\VariableCollection' => '/phpunit/TextUI/Configuration/Value/VariableCollection.php', 'PHPUnit\\TextUI\\Configuration\\VariableCollectionIterator' => '/phpunit/TextUI/Configuration/Value/VariableCollectionIterator.php', + 'PHPUnit\\TextUI\\DirectoryDoesNotExistException' => '/phpunit/TextUI/Exception/DirectoryDoesNotExistException.php', 'PHPUnit\\TextUI\\Exception' => '/phpunit/TextUI/Exception/Exception.php', 'PHPUnit\\TextUI\\ExtensionsNotConfiguredException' => '/phpunit/TextUI/Exception/ExtensionsNotConfiguredException.php', 'PHPUnit\\TextUI\\Help' => '/phpunit/TextUI/Help.php', + 'PHPUnit\\TextUI\\InvalidSocketException' => '/phpunit/TextUI/Exception/InvalidSocketException.php', 'PHPUnit\\TextUI\\Output\\DefaultPrinter' => '/phpunit/TextUI/Output/Printer/DefaultPrinter.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\BeforeTestClassMethodErroredSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/BeforeTestClassMethodErroredSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\ProgressPrinter' => '/phpunit/TextUI/Output/Default/ProgressPrinter/ProgressPrinter.php', @@ -2700,10 +2844,10 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestFinishedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestFinishedSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestMarkedIncompleteSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestMarkedIncompleteSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestPreparedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestPreparedSubscriber.php', - 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestPrintedUnexpectedOutputSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestPrintedUnexpectedOutputSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestRunnerExecutionStartedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestRunnerExecutionStartedSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestSkippedSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestSkippedSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredDeprecationSubscriber.php', + 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredErrorSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredErrorSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredNoticeSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredNoticeSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpDeprecationSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpDeprecationSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpNoticeSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpNoticeSubscriber.php', @@ -2712,6 +2856,7 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredPhpunitWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitWarningSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ProgressPrinter\\TestTriggeredWarningSubscriber' => '/phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredWarningSubscriber.php', 'PHPUnit\\TextUI\\Output\\Default\\ResultPrinter' => '/phpunit/TextUI/Output/Default/ResultPrinter.php', + 'PHPUnit\\TextUI\\Output\\Default\\UnexpectedOutputPrinter' => '/phpunit/TextUI/Output/Default/UnexpectedOutputPrinter.php', 'PHPUnit\\TextUI\\Output\\Facade' => '/phpunit/TextUI/Output/Facade.php', 'PHPUnit\\TextUI\\Output\\NullPrinter' => '/phpunit/TextUI/Output/Printer/NullPrinter.php', 'PHPUnit\\TextUI\\Output\\Printer' => '/phpunit/TextUI/Output/Printer/Printer.php', @@ -2724,6 +2869,7 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\TextUI\\TestFileNotFoundException' => '/phpunit/TextUI/Exception/TestFileNotFoundException.php', 'PHPUnit\\TextUI\\TestRunner' => '/phpunit/TextUI/TestRunner.php', 'PHPUnit\\TextUI\\TestSuiteFilterProcessor' => '/phpunit/TextUI/TestSuiteFilterProcessor.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\CannotFindSchemaException' => '/phpunit/TextUI/Configuration/Exception/CannotFindSchemaException.php', 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\CodeCoverage' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/CodeCoverage.php', 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Clover' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Clover.php', 'PHPUnit\\TextUI\\XmlConfiguration\\CodeCoverage\\Report\\Cobertura' => '/phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Cobertura.php', @@ -2742,6 +2888,7 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\TextUI\\XmlConfiguration\\CoverageXmlToReport' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageXmlToReport.php', 'PHPUnit\\TextUI\\XmlConfiguration\\DefaultConfiguration' => '/phpunit/TextUI/Configuration/Xml/DefaultConfiguration.php', 'PHPUnit\\TextUI\\XmlConfiguration\\Exception' => '/phpunit/TextUI/Configuration/Xml/Exception.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\FailedSchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/FailedSchemaDetectionResult.php', 'PHPUnit\\TextUI\\XmlConfiguration\\Generator' => '/phpunit/TextUI/Configuration/Xml/Generator.php', 'PHPUnit\\TextUI\\XmlConfiguration\\Groups' => '/phpunit/TextUI/Configuration/Xml/Groups.php', 'PHPUnit\\TextUI\\XmlConfiguration\\IntroduceCacheDirectoryAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCacheDirectoryAttribute.php', @@ -2761,8 +2908,9 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\TextUI\\XmlConfiguration\\Migrator' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrator.php', 'PHPUnit\\TextUI\\XmlConfiguration\\MoveAttributesFromFilterWhitelistToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromFilterWhitelistToCoverage.php', 'PHPUnit\\TextUI\\XmlConfiguration\\MoveAttributesFromRootToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromRootToCoverage.php', - 'PHPUnit\\TextUI\\XmlConfiguration\\MoveWhitelistDirectoriesToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistDirectoriesToCoverage.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\MoveCoverageDirectoriesToSource' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveCoverageDirectoriesToSource.php', 'PHPUnit\\TextUI\\XmlConfiguration\\MoveWhitelistExcludesToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistExcludesToCoverage.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\MoveWhitelistIncludesToCoverage' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistIncludesToCoverage.php', 'PHPUnit\\TextUI\\XmlConfiguration\\PHPUnit' => '/phpunit/TextUI/Configuration/Xml/PHPUnit.php', 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute.php', 'PHPUnit\\TextUI\\XmlConfiguration\\RemoveBeStrictAboutTodoAnnotatedTestsAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutTodoAnnotatedTestsAttribute.php', @@ -2783,8 +2931,15 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\TextUI\\XmlConfiguration\\RenameBackupStaticAttributesAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBackupStaticAttributesAttribute.php', 'PHPUnit\\TextUI\\XmlConfiguration\\RenameBeStrictAboutCoversAnnotationAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBeStrictAboutCoversAnnotationAttribute.php', 'PHPUnit\\TextUI\\XmlConfiguration\\RenameForceCoversAnnotationAttribute' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameForceCoversAnnotationAttribute.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetectionResult.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaDetector' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetector.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\SchemaFinder' => '/phpunit/TextUI/Configuration/Xml/SchemaFinder.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\SnapshotNodeList' => '/phpunit/TextUI/Configuration/Xml/Migration/SnapshotNodeList.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\SuccessfulSchemaDetectionResult' => '/phpunit/TextUI/Configuration/Xml/SchemaDetector/SuccessfulSchemaDetectionResult.php', 'PHPUnit\\TextUI\\XmlConfiguration\\TestSuiteMapper' => '/phpunit/TextUI/Configuration/Xml/TestSuiteMapper.php', 'PHPUnit\\TextUI\\XmlConfiguration\\UpdateSchemaLocation' => '/phpunit/TextUI/Configuration/Xml/Migration/Migrations/UpdateSchemaLocation.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\ValidationResult' => '/phpunit/TextUI/Configuration/Xml/Validator/ValidationResult.php', + 'PHPUnit\\TextUI\\XmlConfiguration\\Validator' => '/phpunit/TextUI/Configuration/Xml/Validator/Validator.php', 'PHPUnit\\TheSeer\\Tokenizer\\Exception' => '/theseer-tokenizer/Exception.php', 'PHPUnit\\TheSeer\\Tokenizer\\NamespaceUri' => '/theseer-tokenizer/NamespaceUri.php', 'PHPUnit\\TheSeer\\Tokenizer\\NamespaceUriException' => '/theseer-tokenizer/NamespaceUriException.php', @@ -2795,19 +2950,16 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\TheSeer\\Tokenizer\\XMLSerializer' => '/theseer-tokenizer/XMLSerializer.php', 'PHPUnit\\Util\\Cloner' => '/phpunit/Util/Cloner.php', 'PHPUnit\\Util\\Color' => '/phpunit/Util/Color.php', - 'PHPUnit\\Util\\DirectoryDoesNotExistException' => '/phpunit/Util/Exception/DirectoryDoesNotExistException.php', - 'PHPUnit\\Util\\ErrorHandler' => '/phpunit/Util/ErrorHandler.php', 'PHPUnit\\Util\\Exception' => '/phpunit/Util/Exception/Exception.php', 'PHPUnit\\Util\\ExcludeList' => '/phpunit/Util/ExcludeList.php', + 'PHPUnit\\Util\\Exporter' => '/phpunit/Util/Exporter.php', 'PHPUnit\\Util\\Filesystem' => '/phpunit/Util/Filesystem.php', 'PHPUnit\\Util\\Filter' => '/phpunit/Util/Filter.php', 'PHPUnit\\Util\\GlobalState' => '/phpunit/Util/GlobalState.php', 'PHPUnit\\Util\\InvalidDirectoryException' => '/phpunit/Util/Exception/InvalidDirectoryException.php', 'PHPUnit\\Util\\InvalidJsonException' => '/phpunit/Util/Exception/InvalidJsonException.php', - 'PHPUnit\\Util\\InvalidSocketException' => '/phpunit/Util/Exception/InvalidSocketException.php', 'PHPUnit\\Util\\InvalidVersionOperatorException' => '/phpunit/Util/Exception/InvalidVersionOperatorException.php', 'PHPUnit\\Util\\Json' => '/phpunit/Util/Json.php', - 'PHPUnit\\Util\\NoTestCaseObjectOnCallStackException' => '/phpunit/Util/Exception/NoTestCaseObjectOnCallStackException.php', 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => '/phpunit/Util/PHP/AbstractPhpProcess.php', 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => '/phpunit/Util/PHP/DefaultPhpProcess.php', 'PHPUnit\\Util\\PHP\\PhpProcessException' => '/phpunit/Util/Exception/PhpProcessException.php', @@ -2816,24 +2968,21 @@ foreach (['PHPUnit\\DeepCopy\\DeepCopy' => '/myclabs-deep-copy/DeepCopy/DeepCopy 'PHPUnit\\Util\\Test' => '/phpunit/Util/Test.php', 'PHPUnit\\Util\\ThrowableToStringMapper' => '/phpunit/Util/ThrowableToStringMapper.php', 'PHPUnit\\Util\\VersionComparisonOperator' => '/phpunit/Util/VersionComparisonOperator.php', - 'PHPUnit\\Util\\Xml' => '/phpunit/Util/Xml.php', - 'PHPUnit\\Util\\Xml\\Exception' => '/phpunit/Util/Xml/Exception.php', - 'PHPUnit\\Util\\Xml\\FailedSchemaDetectionResult' => '/phpunit/Util/Xml/FailedSchemaDetectionResult.php', + 'PHPUnit\\Util\\Xml' => '/phpunit/Util/Xml/Xml.php', 'PHPUnit\\Util\\Xml\\Loader' => '/phpunit/Util/Xml/Loader.php', - 'PHPUnit\\Util\\Xml\\SchemaDetectionResult' => '/phpunit/Util/Xml/SchemaDetectionResult.php', - 'PHPUnit\\Util\\Xml\\SchemaDetector' => '/phpunit/Util/Xml/SchemaDetector.php', - 'PHPUnit\\Util\\Xml\\SchemaFinder' => '/phpunit/Util/Xml/SchemaFinder.php', - 'PHPUnit\\Util\\Xml\\SnapshotNodeList' => '/phpunit/Util/Xml/SnapshotNodeList.php', - 'PHPUnit\\Util\\Xml\\SuccessfulSchemaDetectionResult' => '/phpunit/Util/Xml/SuccessfulSchemaDetectionResult.php', - 'PHPUnit\\Util\\Xml\\ValidationResult' => '/phpunit/Util/Xml/ValidationResult.php', - 'PHPUnit\\Util\\Xml\\Validator' => '/phpunit/Util/Xml/Validator.php', 'PHPUnit\\Util\\Xml\\XmlException' => '/phpunit/Util/Exception/XmlException.php'] as $file) { - require_once 'phar://phpunit-10.0.16.phar' . $file; + require_once 'phar://phpunit-10.5.8.phar' . $file; } require __PHPUNIT_PHAR_ROOT__ . '/phpunit/Framework/Assert/Functions.php'; if ($execute) { + if (isset($printComposerLock)) { + print file_get_contents(__PHPUNIT_PHAR_ROOT__ . '/composer.lock'); + + exit; + } + if (isset($printManifest)) { print file_get_contents(__PHPUNIT_PHAR_ROOT__ . '/manifest.txt'); @@ -2852,114 +3001,1665 @@ if ($execute) { } __HALT_COMPILER(); ?> -yphpunit-10.0.16.phar manifest.txtdcW'myclabs-deep-copy/DeepCopy/DeepCopy.phpdLä7myclabs-deep-copy/DeepCopy/Exception/CloneException.phpd {ˤ:myclabs-deep-copy/DeepCopy/Exception/PropertyException.phpd3Gz5myclabs-deep-copy/DeepCopy/Filter/ChainableFilter.phpdTE Gmyclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php -d -DgLmyclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.phpd)$Bmyclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.phpd),myclabs-deep-copy/DeepCopy/Filter/Filter.phpdddM0myclabs-deep-copy/DeepCopy/Filter/KeepFilter.phpdYn3myclabs-deep-copy/DeepCopy/Filter/ReplaceFilter.phpd3myclabs-deep-copy/DeepCopy/Filter/SetNullFilter.phpd䊉Dmyclabs-deep-copy/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.phpdpr.myclabs-deep-copy/DeepCopy/Matcher/Matcher.phpd6myclabs-deep-copy/DeepCopy/Matcher/PropertyMatcher.phpd=Bv:myclabs-deep-copy/DeepCopy/Matcher/PropertyNameMatcher.phpdR:myclabs-deep-copy/DeepCopy/Matcher/PropertyTypeMatcher.php2d2ZQͤ:myclabs-deep-copy/DeepCopy/Reflection/ReflectionHelper.php5d5ىAmyclabs-deep-copy/DeepCopy/TypeFilter/Date/DateIntervalFilter.phpdƤ7myclabs-deep-copy/DeepCopy/TypeFilter/ReplaceFilter.phpdz;myclabs-deep-copy/DeepCopy/TypeFilter/ShallowCopyFilter.phpdؤ?myclabs-deep-copy/DeepCopy/TypeFilter/Spl/ArrayObjectFilter.phpd^Amyclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.phpdv|Gmyclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.phpdT+4myclabs-deep-copy/DeepCopy/TypeFilter/TypeFilter.phpdVD6myclabs-deep-copy/DeepCopy/TypeMatcher/TypeMatcher.phpdQBŤ(myclabs-deep-copy/DeepCopy/deep_copy.phpdrxmyclabs-deep-copy/LICENSE5d5ʭ˄nikic-php-parser/LICENSEd*&nikic-php-parser/PhpParser/Builder.phpd61nikic-php-parser/PhpParser/Builder/ClassConst.phpm dm z-nikic-php-parser/PhpParser/Builder/Class_.phpdc32nikic-php-parser/PhpParser/Builder/Declaration.phpdE7/nikic-php-parser/PhpParser/Builder/EnumCase.php^d^ueT,nikic-php-parser/PhpParser/Builder/Enum_.php d #3nikic-php-parser/PhpParser/Builder/FunctionLike.phpdZqe0nikic-php-parser/PhpParser/Builder/Function_.phpFdFux1nikic-php-parser/PhpParser/Builder/Interface_.php d -nikic-php-parser/PhpParser/Builder/Method.phpd}1nikic-php-parser/PhpParser/Builder/Namespace_.php:d:ˆp,nikic-php-parser/PhpParser/Builder/Param.php d ֤/nikic-php-parser/PhpParser/Builder/Property.php|d|O /nikic-php-parser/PhpParser/Builder/TraitUse.phpWdWL@9nikic-php-parser/PhpParser/Builder/TraitUseAdaptation.phpdUVx-nikic-php-parser/PhpParser/Builder/Trait_.phpdkj+nikic-php-parser/PhpParser/Builder/Use_.phpds-nikic-php-parser/PhpParser/BuilderFactory.php+d+޶-nikic-php-parser/PhpParser/BuilderHelpers.php$d$:@&nikic-php-parser/PhpParser/Comment.phpdA*nikic-php-parser/PhpParser/Comment/Doc.phpxdxp;nikic-php-parser/PhpParser/ConstExprEvaluationException.php_d_I 1nikic-php-parser/PhpParser/ConstExprEvaluator.phpl%dl%evQ$nikic-php-parser/PhpParser/Error.phpdQZ+nikic-php-parser/PhpParser/ErrorHandler.php/d/#\6nikic-php-parser/PhpParser/ErrorHandler/Collecting.phpd&Ȥ4nikic-php-parser/PhpParser/ErrorHandler/Throwing.phpdS}<0nikic-php-parser/PhpParser/Internal/DiffElem.php7d7$.nikic-php-parser/PhpParser/Internal/Differ.php-d-^Anikic-php-parser/PhpParser/Internal/PrintableNewAnonClassNode.php$d$'c3nikic-php-parser/PhpParser/Internal/TokenStream.php#d#f*nikic-php-parser/PhpParser/JsonDecoder.php d xg$nikic-php-parser/PhpParser/Lexer.phpyZdyZq⃤.nikic-php-parser/PhpParser/Lexer/Emulative.phpO#dO#ܲݤDnikic-php-parser/PhpParser/Lexer/TokenEmulator/AttributeEmulator.phpdrLnikic-php-parser/PhpParser/Lexer/TokenEmulator/CoaleseEqualTokenEmulator.php d *§oDnikic-php-parser/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.phpdLFHnikic-php-parser/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.phpd*#Lnikic-php-parser/PhpParser/Lexer/TokenEmulator/FlexibleDocStringEmulator.phpn dn 1Bnikic-php-parser/PhpParser/Lexer/TokenEmulator/FnTokenEmulator.phpdjBnikic-php-parser/PhpParser/Lexer/TokenEmulator/KeywordEmulator.phpd`atEnikic-php-parser/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.phpdc/Hnikic-php-parser/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.phpd:&ERnikic-php-parser/PhpParser/Lexer/TokenEmulator/NumericLiteralSeparatorEmulator.phpVdVPnikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.phpde!ćHnikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.phpLdL -`9JBnikic-php-parser/PhpParser/Lexer/TokenEmulator/ReverseEmulator.phpdI}@nikic-php-parser/PhpParser/Lexer/TokenEmulator/TokenEmulator.phpuduD4h*nikic-php-parser/PhpParser/NameContext.php%d%G-#nikic-php-parser/PhpParser/Node.phpdyݗ'nikic-php-parser/PhpParser/Node/Arg.php0d0q H-nikic-php-parser/PhpParser/Node/Attribute.phpHdHhqK2nikic-php-parser/PhpParser/Node/AttributeGroup.phpdB9/nikic-php-parser/PhpParser/Node/ComplexType.phpSdS(*nikic-php-parser/PhpParser/Node/Const_.phpdZ(nikic-php-parser/PhpParser/Node/Expr.phpdh傤6nikic-php-parser/PhpParser/Node/Expr/ArrayDimFetch.phpMdMIY2nikic-php-parser/PhpParser/Node/Expr/ArrayItem.phpxdx| 2/nikic-php-parser/PhpParser/Node/Expr/Array_.php8d8;p6nikic-php-parser/PhpParser/Node/Expr/ArrowFunction.php d w3/nikic-php-parser/PhpParser/Node/Expr/Assign.phpd1nikic-php-parser/PhpParser/Node/Expr/AssignOp.phpd,<nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseAnd.phpdu;nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseOr.phpd;<nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseXor.phpdlϚ:nikic-php-parser/PhpParser/Node/Expr/AssignOp/Coalesce.phpdq,8nikic-php-parser/PhpParser/Node/Expr/AssignOp/Concat.phpd5nikic-php-parser/PhpParser/Node/Expr/AssignOp/Div.phpdYP -7nikic-php-parser/PhpParser/Node/Expr/AssignOp/Minus.phpd隤5nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mod.phpd]10Y5nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mul.phpdπ/6nikic-php-parser/PhpParser/Node/Expr/AssignOp/Plus.phpd&|5nikic-php-parser/PhpParser/Node/Expr/AssignOp/Pow.phpdyV;nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftLeft.phpd<nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftRight.phpds*2nikic-php-parser/PhpParser/Node/Expr/AssignRef.phpHdHE`ob1nikic-php-parser/PhpParser/Node/Expr/BinaryOp.phpodo Ѥ<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.phpPdP6L6;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseOr.phpNdN_|<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseXor.phpPdP~Ƥ<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanAnd.phpQdQ5v;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanOr.phpOdOeӸ:nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Coalesce.phpMdMY 8nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Concat.phpHdH @q5nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Div.phpBdBi7nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Equal.phpGdGݙʤ9nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Greater.phpJdJ4ͤ@nikic-php-parser/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.phpYdY^ز;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Identical.phpPdP"<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalAnd.phpRdRi;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalOr.phpOdO@<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalXor.phpRdR4e7nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Minus.phpFdF$Lˤ5nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mod.phpBdBʤ5nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mul.phpBdB|:nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotEqual.phpMdM>nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotIdentical.phpVdVh< -6nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Plus.phpDdD' ,5nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Pow.phpCdC;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftLeft.phpOdOQ#<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftRight.phpQdQǤ9nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Smaller.phpJdJf@nikic-php-parser/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.phpYdY⍤;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Spaceship.phpPdPHƉ.3nikic-php-parser/PhpParser/Node/Expr/BitwiseNot.phpd~'3nikic-php-parser/PhpParser/Node/Expr/BooleanNot.phpdDC1nikic-php-parser/PhpParser/Node/Expr/CallLike.php&d&KS0-nikic-php-parser/PhpParser/Node/Expr/Cast.phpAdA:Vs4nikic-php-parser/PhpParser/Node/Expr/Cast/Array_.phpdI|3nikic-php-parser/PhpParser/Node/Expr/Cast/Bool_.phpd V]S4nikic-php-parser/PhpParser/Node/Expr/Cast/Double.phpd>,2nikic-php-parser/PhpParser/Node/Expr/Cast/Int_.phpdc5nikic-php-parser/PhpParser/Node/Expr/Cast/Object_.phpd5nikic-php-parser/PhpParser/Node/Expr/Cast/String_.phpd4nikic-php-parser/PhpParser/Node/Expr/Cast/Unset_.phpd1Ӥ8nikic-php-parser/PhpParser/Node/Expr/ClassConstFetch.phpd/nikic-php-parser/PhpParser/Node/Expr/Clone_.phpdW0nikic-php-parser/PhpParser/Node/Expr/Closure.php -d -U;3nikic-php-parser/PhpParser/Node/Expr/ClosureUse.phpdh3nikic-php-parser/PhpParser/Node/Expr/ConstFetch.phpd޶%/nikic-php-parser/PhpParser/Node/Expr/Empty_.phpd'.nikic-php-parser/PhpParser/Node/Expr/Error.phpda\6nikic-php-parser/PhpParser/Node/Expr/ErrorSuppress.phpdg.nikic-php-parser/PhpParser/Node/Expr/Eval_.phpd356.nikic-php-parser/PhpParser/Node/Expr/Exit_.phpd1nikic-php-parser/PhpParser/Node/Expr/FuncCall.php3d3%A1nikic-php-parser/PhpParser/Node/Expr/Include_.phpdi4nikic-php-parser/PhpParser/Node/Expr/Instanceof_.phpada< /nikic-php-parser/PhpParser/Node/Expr/Isset_.phpdI.nikic-php-parser/PhpParser/Node/Expr/List_.phpd/nikic-php-parser/PhpParser/Node/Expr/Match_.phpdW 3nikic-php-parser/PhpParser/Node/Expr/MethodCall.phpOdODWX-nikic-php-parser/PhpParser/Node/Expr/New_.phpdiĤ;nikic-php-parser/PhpParser/Node/Expr/NullsafeMethodCall.phpfdfɤ>nikic-php-parser/PhpParser/Node/Expr/NullsafePropertyFetch.phpd /N0nikic-php-parser/PhpParser/Node/Expr/PostDec.phpdw:0nikic-php-parser/PhpParser/Node/Expr/PostInc.phpdᦦ!/nikic-php-parser/PhpParser/Node/Expr/PreDec.phpdtg/nikic-php-parser/PhpParser/Node/Expr/PreInc.phpdYä/nikic-php-parser/PhpParser/Node/Expr/Print_.phpdnX6nikic-php-parser/PhpParser/Node/Expr/PropertyFetch.phpdɾ2nikic-php-parser/PhpParser/Node/Expr/ShellExec.phpdhy3nikic-php-parser/PhpParser/Node/Expr/StaticCall.phpede<nikic-php-parser/PhpParser/Node/Expr/StaticPropertyFetch.php&d&ܐ0nikic-php-parser/PhpParser/Node/Expr/Ternary.phpdQͤ/nikic-php-parser/PhpParser/Node/Expr/Throw_.phpd ?3nikic-php-parser/PhpParser/Node/Expr/UnaryMinus.phpdlA2nikic-php-parser/PhpParser/Node/Expr/UnaryPlus.phpde̤1nikic-php-parser/PhpParser/Node/Expr/Variable.phpdmJr2nikic-php-parser/PhpParser/Node/Expr/YieldFrom.phpdw8/nikic-php-parser/PhpParser/Node/Expr/Yield_.php\d\ 0nikic-php-parser/PhpParser/Node/FunctionLike.phpd4ͤ.nikic-php-parser/PhpParser/Node/Identifier.phpdJa4nikic-php-parser/PhpParser/Node/IntersectionType.phpdo,nikic-php-parser/PhpParser/Node/MatchArm.phpd+m6(nikic-php-parser/PhpParser/Node/Name.php d Q酯7nikic-php-parser/PhpParser/Node/Name/FullyQualified.phpd 1nikic-php-parser/PhpParser/Node/Name/Relative.phpdǛEf0nikic-php-parser/PhpParser/Node/NullableType.phpd6C)nikic-php-parser/PhpParser/Node/Param.phpbdbMߤ*nikic-php-parser/PhpParser/Node/Scalar.phpkdk,ߤ2nikic-php-parser/PhpParser/Node/Scalar/DNumber.phpdx3H:3nikic-php-parser/PhpParser/Node/Scalar/Encapsed.phpdRU=nikic-php-parser/PhpParser/Node/Scalar/EncapsedStringPart.phpd%2nikic-php-parser/PhpParser/Node/Scalar/LNumber.php d z5nikic-php-parser/PhpParser/Node/Scalar/MagicConst.phpcdc,xG<nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Class_.phpTdT㨘X9nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Dir.phpMdMal:nikic-php-parser/PhpParser/Node/Scalar/MagicConst/File.phpPdP#?nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Function_.php]d]HnY:nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Line.phpPdPM4<nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Method.phpVdVΤ@nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Namespace_.php`d`><nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Trait_.phpTdTd2nikic-php-parser/PhpParser/Node/Scalar/String_.phpqdqT$Q(nikic-php-parser/PhpParser/Node/Stmt.phpdv2//nikic-php-parser/PhpParser/Node/Stmt/Break_.phpd֤.nikic-php-parser/PhpParser/Node/Stmt/Case_.phpldlu/nikic-php-parser/PhpParser/Node/Stmt/Catch_.php|d|*V>3nikic-php-parser/PhpParser/Node/Stmt/ClassConst.phpdeX?ͤ2nikic-php-parser/PhpParser/Node/Stmt/ClassLike.php d 04nikic-php-parser/PhpParser/Node/Stmt/ClassMethod.phpdX/nikic-php-parser/PhpParser/Node/Stmt/Class_.phpudu_ļ/nikic-php-parser/PhpParser/Node/Stmt/Const_.phpd2nikic-php-parser/PhpParser/Node/Stmt/Continue_.phpd7nikic-php-parser/PhpParser/Node/Stmt/DeclareDeclare.phpdƀ1nikic-php-parser/PhpParser/Node/Stmt/Declare_.phpd.. -,nikic-php-parser/PhpParser/Node/Stmt/Do_.phpBdB -@.nikic-php-parser/PhpParser/Node/Stmt/Echo_.phpd͘Ƥ0nikic-php-parser/PhpParser/Node/Stmt/ElseIf_.phpIdIEä.nikic-php-parser/PhpParser/Node/Stmt/Else_.phpd|ä1nikic-php-parser/PhpParser/Node/Stmt/EnumCase.phpdjD.nikic-php-parser/PhpParser/Node/Stmt/Enum_.php=d=dA3nikic-php-parser/PhpParser/Node/Stmt/Expression.phpdRK1nikic-php-parser/PhpParser/Node/Stmt/Finally_.phpd1A-nikic-php-parser/PhpParser/Node/Stmt/For_.php>d>NQ1nikic-php-parser/PhpParser/Node/Stmt/Foreach_.phpodo92nikic-php-parser/PhpParser/Node/Stmt/Function_.php, -d, -nL0nikic-php-parser/PhpParser/Node/Stmt/Global_.phpd.nikic-php-parser/PhpParser/Node/Stmt/Goto_.phpdVyPn1nikic-php-parser/PhpParser/Node/Stmt/GroupUse.php -d -ߎ0|5nikic-php-parser/PhpParser/Node/Stmt/HaltCompiler.phpd];,nikic-php-parser/PhpParser/Node/Stmt/If_.php:d:u٤3nikic-php-parser/PhpParser/Node/Stmt/InlineHTML.phpd]3nikic-php-parser/PhpParser/Node/Stmt/Interface_.phpdL/Ǥ.nikic-php-parser/PhpParser/Node/Stmt/Label.phpdӤ3nikic-php-parser/PhpParser/Node/Stmt/Namespace_.phpd㹀,nikic-php-parser/PhpParser/Node/Stmt/Nop.php@d@G1nikic-php-parser/PhpParser/Node/Stmt/Property.phpO -dO -=9nikic-php-parser/PhpParser/Node/Stmt/PropertyProperty.phpd҉0nikic-php-parser/PhpParser/Node/Stmt/Return_.phpdͿ)e2nikic-php-parser/PhpParser/Node/Stmt/StaticVar.phpd0nikic-php-parser/PhpParser/Node/Stmt/Static_.phpd0nikic-php-parser/PhpParser/Node/Stmt/Switch_.php5d5FFY/nikic-php-parser/PhpParser/Node/Stmt/Throw_.phpd1nikic-php-parser/PhpParser/Node/Stmt/TraitUse.phpdg,;nikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation.phpda8Anikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.phpAdAdFnikic-php-parser/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.phpZdZP֤/nikic-php-parser/PhpParser/Node/Stmt/Trait_.phpd$v1nikic-php-parser/PhpParser/Node/Stmt/TryCatch.php$d$W/nikic-php-parser/PhpParser/Node/Stmt/Unset_.phpd=oB/nikic-php-parser/PhpParser/Node/Stmt/UseUse.phpdddb-nikic-php-parser/PhpParser/Node/Stmt/Use_.phpldl9=|/nikic-php-parser/PhpParser/Node/Stmt/While_.phpEdEա-nikic-php-parser/PhpParser/Node/UnionType.phpdԛ5nikic-php-parser/PhpParser/Node/VarLikeIdentifier.phpd&7nikic-php-parser/PhpParser/Node/VariadicPlaceholder.phpdP+nikic-php-parser/PhpParser/NodeAbstract.phpZdZ׻@)nikic-php-parser/PhpParser/NodeDumper.phpdddY l)nikic-php-parser/PhpParser/NodeFinder.php d ,nikic-php-parser/PhpParser/NodeTraverser.php]'d]'TG:Ƥ5nikic-php-parser/PhpParser/NodeTraverserInterface.php|d|Ś *nikic-php-parser/PhpParser/NodeVisitor.phpd39nikic-php-parser/PhpParser/NodeVisitor/CloningVisitor.phpd"WJ9nikic-php-parser/PhpParser/NodeVisitor/FindingVisitor.phpdB>nikic-php-parser/PhpParser/NodeVisitor/FirstFindingVisitor.phpdm4Ť7nikic-php-parser/PhpParser/NodeVisitor/NameResolver.phpq&dq&ǠG@nikic-php-parser/PhpParser/NodeVisitor/NodeConnectingVisitor.phpdu -äBnikic-php-parser/PhpParser/NodeVisitor/ParentConnectingVisitor.phpuduME2nikic-php-parser/PhpParser/NodeVisitorAbstract.phpd%nikic-php-parser/PhpParser/Parser.php}d}{.nikic-php-parser/PhpParser/Parser/Multiple.phpdsF)7*nikic-php-parser/PhpParser/Parser/Php5.php+d+N׊*nikic-php-parser/PhpParser/Parser/Php7.phpOdOȅ,nikic-php-parser/PhpParser/Parser/Tokens.php&d&<-nikic-php-parser/PhpParser/ParserAbstract.phpTdT'[,nikic-php-parser/PhpParser/ParserFactory.phpd -~&5nikic-php-parser/PhpParser/PrettyPrinter/Standard.phpd'4nikic-php-parser/PhpParser/PrettyPrinterAbstract.phpdܤobject-enumerator/LICENSEdfobject-reflector/LICENSEdR6phar-io-manifest/LICENSE`d`p+phar-io-manifest/ManifestDocumentMapper.phpd:#phar-io-manifest/ManifestLoader.phpd.-a'phar-io-manifest/ManifestSerializer.phpdrp:phar-io-manifest/exceptions/ElementCollectionException.phpd I)phar-io-manifest/exceptions/Exception.phpd?phar-io-manifest/exceptions/InvalidApplicationNameException.phpd:@>5phar-io-manifest/exceptions/InvalidEmailException.phpd<3phar-io-manifest/exceptions/InvalidUrlException.phpd 9phar-io-manifest/exceptions/ManifestDocumentException.phpd!P4@phar-io-manifest/exceptions/ManifestDocumentLoadingException.phpHdHǃ?phar-io-manifest/exceptions/ManifestDocumentMapperException.phpd:9z8phar-io-manifest/exceptions/ManifestElementException.phpdA47phar-io-manifest/exceptions/ManifestLoaderException.phpdD>'phar-io-manifest/values/Application.phpdI$ۤ+phar-io-manifest/values/ApplicationName.php;d;D"phar-io-manifest/values/Author.phpdF,phar-io-manifest/values/AuthorCollection.phpdo4phar-io-manifest/values/AuthorCollectionIterator.php3d3џ,phar-io-manifest/values/BundledComponent.php@d@DP`6phar-io-manifest/values/BundledComponentCollection.php d ¾W6>phar-io-manifest/values/BundledComponentCollectionIterator.phpdVh0phar-io-manifest/values/CopyrightInformation.phpPdP ai!phar-io-manifest/values/Email.phpNdNZ&%phar-io-manifest/values/Extension.phpdq}#phar-io-manifest/values/Library.phpdO#phar-io-manifest/values/License.phpd&!o$phar-io-manifest/values/Manifest.php -d -=La3phar-io-manifest/values/PhpExtensionRequirement.phpd11phar-io-manifest/values/PhpVersionRequirement.phpdm?'phar-io-manifest/values/Requirement.phpdd1phar-io-manifest/values/RequirementCollection.phpdP9phar-io-manifest/values/RequirementCollectionIterator.phpjdjܭ: phar-io-manifest/values/Type.phpd=%phar-io-manifest/values/Url.phpd͚&phar-io-manifest/xml/AuthorElement.phprdr<0phar-io-manifest/xml/AuthorElementCollection.php,d,-'phar-io-manifest/xml/BundlesElement.phpSdSWN>)phar-io-manifest/xml/ComponentElement.phpydyݤ3phar-io-manifest/xml/ComponentElementCollection.php5d5(\(phar-io-manifest/xml/ContainsElement.phpndnf)phar-io-manifest/xml/CopyrightElement.phpd7*phar-io-manifest/xml/ElementCollection.phpd@ #phar-io-manifest/xml/ExtElement.php d y>-phar-io-manifest/xml/ExtElementCollection.php#d#E)phar-io-manifest/xml/ExtensionElement.php}d}0'phar-io-manifest/xml/LicenseElement.phpodo%:')phar-io-manifest/xml/ManifestDocument.php - d - 4(phar-io-manifest/xml/ManifestElement.php4d4#phar-io-manifest/xml/PhpElement.phpdB:5(phar-io-manifest/xml/RequiresElement.php$d$>!phar-io-version/BuildMetaData.phpdphar-io-version/LICENSE&d&Ҫ $phar-io-version/PreReleaseSuffix.phpd:phar-io-version/Version.phpdu#+phar-io-version/VersionConstraintParser.phpT dT Ф*phar-io-version/VersionConstraintValue.phpH -dH -F{~4!phar-io-version/VersionNumber.phpdO19phar-io-version/constraints/AbstractVersionConstraint.phpdxB9phar-io-version/constraints/AndVersionConstraintGroup.phpdY4phar-io-version/constraints/AnyVersionConstraint.phpRdR #6phar-io-version/constraints/ExactVersionConstraint.phpd!Ephar-io-version/constraints/GreaterThanOrEqualToVersionConstraint.phpdVU8phar-io-version/constraints/OrVersionConstraintGroup.phpdM%Fphar-io-version/constraints/SpecificMajorAndMinorVersionConstraint.phpdɍ>phar-io-version/constraints/SpecificMajorVersionConstraint.phpd`9q:1phar-io-version/constraints/VersionConstraint.phpdeDq(phar-io-version/exceptions/Exception.phpd$eb?phar-io-version/exceptions/InvalidPreReleaseSuffixException.phpdҵ6phar-io-version/exceptions/InvalidVersionException.phpd4/S7phar-io-version/exceptions/NoBuildMetaDataException.phpd]:phar-io-version/exceptions/NoPreReleaseSuffixException.phpdT4Dphar-io-version/exceptions/UnsupportedVersionConstraintException.phpd9"php-code-coverage/CodeCoverage.php;d;[ߤ4php-code-coverage/Data/ProcessedCodeCoverageData.php#d#QL.php-code-coverage/Data/RawCodeCoverageData.phpd Z7#php-code-coverage/Driver/Driver.php d cհ'php-code-coverage/Driver/PcovDriver.phpd=%php-code-coverage/Driver/Selector.php1d15)php-code-coverage/Driver/XdebugDriver.phpg dg ڤJphp-code-coverage/Exception/BranchAndPathCoverageNotSupportedException.phpd77Fphp-code-coverage/Exception/DeadCodeDetectionNotSupportedException.phpdCphp-code-coverage/Exception/DirectoryCouldNotBeCreatedException.phpd)php-code-coverage/Exception/Exception.php}d}z8php-code-coverage/Exception/InvalidArgumentException.phpdK.nFphp-code-coverage/Exception/NoCodeCoverageDriverAvailableException.php/d/6R]php-code-coverage/Exception/NoCodeCoverageDriverWithPathCoverageSupportAvailableException.phpada"A/php-code-coverage/Exception/ParserException.phpd,/Dphp-code-coverage/Exception/PathExistsButIsNotDirectoryException.phpd.29php-code-coverage/Exception/PcovNotAvailableException.phpadaj3php-code-coverage/Exception/ReflectionException.phpdk)?php-code-coverage/Exception/ReportAlreadyFinalizedException.php:d:d%6Iphp-code-coverage/Exception/StaticAnalysisCacheNotConfiguredException.phpd}6php-code-coverage/Exception/TestIdMissingException.phpd -Cphp-code-coverage/Exception/UnintentionallyCoveredCodeException.phpd}=php-code-coverage/Exception/WriteOperationFailedException.phpd(e;php-code-coverage/Exception/XdebugNotAvailableException.phpedeNG9php-code-coverage/Exception/XdebugNotEnabledException.phpxdx@_;,php-code-coverage/Exception/XmlException.phpdWܤphp-code-coverage/Filter.php d xˇphp-code-coverage/LICENSEd-~y֤'php-code-coverage/Node/AbstractNode.php%d%ּeΤ"php-code-coverage/Node/Builder.phpdT֤$php-code-coverage/Node/CrapIndex.phpd8\$php-code-coverage/Node/Directory.phpV$dV$\php-code-coverage/Node/File.phpIdI/#php-code-coverage/Node/Iterator.phpxdx8A)#php-code-coverage/Report/Clover.php'd'l4&php-code-coverage/Report/Cobertura.php(1d(1q#php-code-coverage/Report/Crap4j.phpdX+(php-code-coverage/Report/Html/Colors.phpdX`/php-code-coverage/Report/Html/CustomCssFile.php6d6"2bS(php-code-coverage/Report/Html/Facade.phpdpF*php-code-coverage/Report/Html/Renderer.php d G4php-code-coverage/Report/Html/Renderer/Dashboard.php{ d{ D54php-code-coverage/Report/Html/Renderer/Directory.php d (/php-code-coverage/Report/Html/Renderer/File.php&d&KCŤBphp-code-coverage/Report/Html/Renderer/Template/branches.html.distdh2+Fphp-code-coverage/Report/Html/Renderer/Template/coverage_bar.html.dist'd'O}Mphp-code-coverage/Report/Html/Renderer/Template/coverage_bar_branch.html.dist'd'O}Ephp-code-coverage/Report/Html/Renderer/Template/css/bootstrap.min.cssydyĤ>php-code-coverage/Report/Html/Renderer/Template/css/custom.cssdAphp-code-coverage/Report/Html/Renderer/Template/css/nv.d3.min.cssX%dX%0,@php-code-coverage/Report/Html/Renderer/Template/css/octicons.cssXdX'#=php-code-coverage/Report/Html/Renderer/Template/css/style.cssH -dH -Cphp-code-coverage/Report/Html/Renderer/Template/dashboard.html.distdDJphp-code-coverage/Report/Html/Renderer/Template/dashboard_branch.html.distdDCphp-code-coverage/Report/Html/Renderer/Template/directory.html.distdՆJphp-code-coverage/Report/Html/Renderer/Template/directory_branch.html.distdn2]Hphp-code-coverage/Report/Html/Renderer/Template/directory_item.html.distAdAdsOphp-code-coverage/Report/Html/Renderer/Template/directory_item_branch.html.dist;d;mۤ>php-code-coverage/Report/Html/Renderer/Template/file.html.distP dP j*Ephp-code-coverage/Report/Html/Renderer/Template/file_branch.html.dist d ㉞Cphp-code-coverage/Report/Html/Renderer/Template/file_item.html.distrdr/yJphp-code-coverage/Report/Html/Renderer/Template/file_item_branch.html.distldl-Cphp-code-coverage/Report/Html/Renderer/Template/icons/file-code.svg0d0QUUHphp-code-coverage/Report/Html/Renderer/Template/icons/file-directory.svgdZCphp-code-coverage/Report/Html/Renderer/Template/js/bootstrap.min.jscdc"#<php-code-coverage/Report/Html/Renderer/Template/js/d3.min.jsPdPhb:php-code-coverage/Report/Html/Renderer/Template/js/file.jsdb䆤@php-code-coverage/Report/Html/Renderer/Template/js/jquery.min.js@^d@^ ?php-code-coverage/Report/Html/Renderer/Template/js/nv.d3.min.jsRdRphp-code-coverage/Report/Html/Renderer/Template/line.html.distd{?php-code-coverage/Report/Html/Renderer/Template/lines.html.distededf Ephp-code-coverage/Report/Html/Renderer/Template/method_item.html.distdjפLphp-code-coverage/Report/Html/Renderer/Template/method_item_branch.html.distdyĎk?php-code-coverage/Report/Html/Renderer/Template/paths.html.distd*'ݤ php-code-coverage/Report/PHP.phpdg!php-code-coverage/Report/Text.php&d&ਤ'php-code-coverage/Report/Thresholds.phpSdS 1php-code-coverage/Report/Xml/BuildInformation.phpdzݤ)php-code-coverage/Report/Xml/Coverage.phpd׍d*php-code-coverage/Report/Xml/Directory.phpdAf'php-code-coverage/Report/Xml/Facade.php!d!t7 &%php-code-coverage/Report/Xml/File.phpd4E'php-code-coverage/Report/Xml/Method.phpDdDC#T%php-code-coverage/Report/Xml/Node.phpd(php-code-coverage/Report/Xml/Project.phpfdfPe'php-code-coverage/Report/Xml/Report.php d HC'php-code-coverage/Report/Xml/Source.phpsdsCaꀤ&php-code-coverage/Report/Xml/Tests.phpdd'php-code-coverage/Report/Xml/Totals.phpdAx%php-code-coverage/Report/Xml/Unit.phpdj0php-code-coverage/StaticAnalysis/CacheWarmer.php)d) ۤ8php-code-coverage/StaticAnalysis/CachingFileAnalyser.phpTdT{H;php-code-coverage/StaticAnalysis/CodeUnitFindingVisitor.phpR&dR&ĤBphp-code-coverage/StaticAnalysis/ExecutableLinesFindingVisitor.php;'d;'1php-code-coverage/StaticAnalysis/FileAnalyser.phpdJ?php-code-coverage/StaticAnalysis/IgnoredLinesFindingVisitor.php d \GԤ8php-code-coverage/StaticAnalysis/ParsingFileAnalyser.phpqdq4$php-code-coverage/TestSize/Known.phpXdXzK$php-code-coverage/TestSize/Large.phpd'r %php-code-coverage/TestSize/Medium.phpd{`$php-code-coverage/TestSize/Small.phpdŖ_'php-code-coverage/TestSize/TestSize.phpd8&php-code-coverage/TestSize/Unknown.phpidi%,(php-code-coverage/TestStatus/Failure.phphdhK8B&php-code-coverage/TestStatus/Known.phpd(php-code-coverage/TestStatus/Success.phphdhcp+php-code-coverage/TestStatus/TestStatus.phpd%!(php-code-coverage/TestStatus/Unknown.phpmdm[%php-code-coverage/Util/Filesystem.phpd%php-code-coverage/Util/Percentage.php^d^5?:php-code-coverage/Version.phpd$%php-file-iterator/ExcludeIterator.phpd'fphp-file-iterator/Facade.phpdc\mephp-file-iterator/Factory.php -d -gmphp-file-iterator/Iterator.php d Jphp-file-iterator/LICENSEd-~y֤php-invoker/Invoker.phpdc$php-invoker/exceptions/Exception.phprdrvvduDphp-invoker/exceptions/ProcessControlExtensionNotLoadedException.phpd +php-invoker/exceptions/TimeoutException.phpd.php-text-template/LICENSEd-~y֤php-text-template/Template.phpU dU %*php-text-template/exceptions/Exception.phpydyn9php-text-template/exceptions/InvalidArgumentException.phpdaM1php-text-template/exceptions/RuntimeException.phpdYm'php-timer/Duration.php d 2php-timer/LICENSEd$php-timer/ResourceUsageFormatter.phpd Hphp-timer/Timer.phpdQ>El"php-timer/exceptions/Exception.phpndniuۤ/php-timer/exceptions/NoActiveTimerException.phpdl٤Ephp-timer/exceptions/TimeSinceStartOfRequestNotAvailableException.phpd$b phpunit.xsd=d=|H1phpunit/Event/Dispatcher/CollectingDispatcher.phpd!0phpunit/Event/Dispatcher/DeferringDispatcher.phpdD-phpunit/Event/Dispatcher/DirectDispatcher.php d g'phpunit/Event/Dispatcher/Dispatcher.phpd8Ť3phpunit/Event/Dispatcher/SubscribableDispatcher.php&d&>Y,,phpunit/Event/Emitter/DispatchingEmitter.phpdddw!phpunit/Event/Emitter/Emitter.php!d!׸'-phpunit/Event/Events/Application/Finished.phpdp,7phpunit/Event/Events/Application/FinishedSubscriber.php7d7,~դ,phpunit/Event/Events/Application/Started.phpdW6phpunit/Event/Events/Application/StartedSubscriber.php5d5fphpunit/Event/Events/Event.php d w(phpunit/Event/Events/EventCollection.phpOdOak0phpunit/Event/Events/EventCollectionIterator.phpd`N7phpunit/Event/Events/Test/Assertion/AssertionFailed.phpd1ݤAphpunit/Event/Events/Test/Assertion/AssertionFailedSubscriber.php7d7haב:phpunit/Event/Events/Test/Assertion/AssertionSucceeded.phpdUUDphpunit/Event/Events/Test/Assertion/AssertionSucceededSubscriber.php=d=m2phpunit/Event/Events/Test/ComparatorRegistered.php d <phpunit/Event/Events/Test/ComparatorRegisteredSubscriber.phpAdA8VBphpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalled.phpmdm֤Lphpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalledSubscriber.phpKdKĶLDphpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinished.phpddd)Nphpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinishedSubscriber.phpOdO>phpunit/Event/Events/Test/HookMethod/AfterTestMethodCalled.phpdddHphpunit/Event/Events/Test/HookMethod/AfterTestMethodCalledSubscriber.phpCdCߊ@phpunit/Event/Events/Test/HookMethod/AfterTestMethodFinished.php[d[o΀Jphpunit/Event/Events/Test/HookMethod/AfterTestMethodFinishedSubscriber.phpGdGV)Dphpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalled.phpqdq,UNphpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalledSubscriber.phpOdOҘI Ephpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErrored.phpdOphpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErroredSubscriber.phpQdQFphpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinished.phphdhZPphpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinishedSubscriber.phpSdS/h?phpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalled.phpfdf![Iphpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalledSubscriber.phpEdEphpunit/Event/Events/Test/HookMethod/PostConditionFinished.php]d]Hphpunit/Event/Events/Test/HookMethod/PostConditionFinishedSubscriber.phpCdCkxŤ;phpunit/Event/Events/Test/HookMethod/PreConditionCalled.phpdddtդEphpunit/Event/Events/Test/HookMethod/PreConditionCalledSubscriber.php=d=T#=phpunit/Event/Events/Test/HookMethod/PreConditionFinished.php[d[ƄGphpunit/Event/Events/Test/HookMethod/PreConditionFinishedSubscriber.phpAdAm3phpunit/Event/Events/Test/Issue/ConsideredRisky.phpKdK =phpunit/Event/Events/Test/Issue/ConsideredRiskySubscriber.php7d7¤8phpunit/Event/Events/Test/Issue/DeprecationTriggered.phpdMǤBphpunit/Event/Events/Test/Issue/DeprecationTriggeredSubscriber.phpAdA8d2phpunit/Event/Events/Test/Issue/ErrorTriggered.phpd<phpunit/Event/Events/Test/Issue/ErrorTriggeredSubscriber.php5d53phpunit/Event/Events/Test/Issue/NoticeTriggered.phpdJJ¤=phpunit/Event/Events/Test/Issue/NoticeTriggeredSubscriber.php7d7xp;phpunit/Event/Events/Test/Issue/PhpDeprecationTriggered.phpdKEphpunit/Event/Events/Test/Issue/PhpDeprecationTriggeredSubscriber.phpGdGdS6phpunit/Event/Events/Test/Issue/PhpNoticeTriggered.phpd@phpunit/Event/Events/Test/Issue/PhpNoticeTriggeredSubscriber.php=d=L07phpunit/Event/Events/Test/Issue/PhpWarningTriggered.phpd -ZAphpunit/Event/Events/Test/Issue/PhpWarningTriggeredSubscriber.php?d?Xޤ?phpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggered.phpd$/Iphpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggeredSubscriber.phpOdOjt9phpunit/Event/Events/Test/Issue/PhpunitErrorTriggered.phpdqCphpunit/Event/Events/Test/Issue/PhpunitErrorTriggeredSubscriber.phpCdC;phpunit/Event/Events/Test/Issue/PhpunitWarningTriggered.phpdESޤEphpunit/Event/Events/Test/Issue/PhpunitWarningTriggeredSubscriber.phpGdGM4phpunit/Event/Events/Test/Issue/WarningTriggered.phpd>phpunit/Event/Events/Test/Issue/WarningTriggeredSubscriber.php9d9#A@0phpunit/Event/Events/Test/Lifecycle/Finished.php{d{ դ:phpunit/Event/Events/Test/Lifecycle/FinishedSubscriber.php)d)Qb:phpunit/Event/Events/Test/Lifecycle/PreparationStarted.phpuduX[`Dphpunit/Event/Events/Test/Lifecycle/PreparationStartedSubscriber.php=d=w 0phpunit/Event/Events/Test/Lifecycle/Prepared.php`d`ISϤ:phpunit/Event/Events/Test/Lifecycle/PreparedSubscriber.php)d)Ѥy-phpunit/Event/Events/Test/Outcome/Errored.phpdQa4$7phpunit/Event/Events/Test/Outcome/ErroredSubscriber.php'd' >,phpunit/Event/Events/Test/Outcome/Failed.phpdE*%6phpunit/Event/Events/Test/Outcome/FailedSubscriber.php%d%ǩ6phpunit/Event/Events/Test/Outcome/MarkedIncomplete.phpdHԤ@phpunit/Event/Events/Test/Outcome/MarkedIncompleteSubscriber.php9d96Ф,phpunit/Event/Events/Test/Outcome/Passed.php\d\6phpunit/Event/Events/Test/Outcome/PassedSubscriber.php%d%pE-phpunit/Event/Events/Test/Outcome/Skipped.phpdoKȏ7phpunit/Event/Events/Test/Outcome/SkippedSubscriber.php'd'%I5phpunit/Event/Events/Test/PrintedUnexpectedOutput.phpdOg?phpunit/Event/Events/Test/PrintedUnexpectedOutputSubscriber.phpGdG`ɐ:phpunit/Event/Events/Test/TestDouble/MockObjectCreated.phpd{͵Dphpunit/Event/Events/Test/TestDouble/MockObjectCreatedSubscriber.php;d;h{6Jphpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreated.phpdҽTphpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreatedSubscriber.php[d[ -vUphpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreated.phpXdXr_phpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreatedSubscriber.phpqdq/uBphpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreated.phpd> Lphpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreatedSubscriber.phpKdK#TBphpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreated.php -d -ȌkLphpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreatedSubscriber.phpKdKIAphpunit/Event/Events/Test/TestDouble/PartialMockObjectCreated.php=d=sUKphpunit/Event/Events/Test/TestDouble/PartialMockObjectCreatedSubscriber.phpIdI2!9phpunit/Event/Events/Test/TestDouble/TestProxyCreated.phpdͤCphpunit/Event/Events/Test/TestDouble/TestProxyCreatedSubscriber.php9d9K8phpunit/Event/Events/Test/TestDouble/TestStubCreated.phpdsʤBphpunit/Event/Events/Test/TestDouble/TestStubCreatedSubscriber.php7d7d#Sphpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreated.phpTdT̪ ]phpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreatedSubscriber.phpmdmKѕ=5phpunit/Event/Events/TestRunner/BootstrapFinished.phpidi?phpunit/Event/Events/TestRunner/BootstrapFinishedSubscriber.phpGdGaݤ.phpunit/Event/Events/TestRunner/Configured.php}d}u8phpunit/Event/Events/TestRunner/ConfiguredSubscriber.php9d9դ8phpunit/Event/Events/TestRunner/DeprecationTriggered.phptdtӤzBphpunit/Event/Events/TestRunner/DeprecationTriggeredSubscriber.phpMdMd5phpunit/Event/Events/TestRunner/EventFacadeSealed.phpd{J?phpunit/Event/Events/TestRunner/EventFacadeSealedSubscriber.phpGdG{ 5phpunit/Event/Events/TestRunner/ExecutionFinished.phpdБW?phpunit/Event/Events/TestRunner/ExecutionFinishedSubscriber.phpGdGH4phpunit/Event/Events/TestRunner/ExecutionStarted.phpdcic>phpunit/Event/Events/TestRunner/ExecutionStartedSubscriber.phpEdES9phpunit/Event/Events/TestRunner/ExtensionBootstrapped.phpydy%קCphpunit/Event/Events/TestRunner/ExtensionBootstrappedSubscriber.phpOdOpɞ2;phpunit/Event/Events/TestRunner/ExtensionLoadedFromPhar.phpd䟉Ephpunit/Event/Events/TestRunner/ExtensionLoadedFromPharSubscriber.phpSdSR^1,phpunit/Event/Events/TestRunner/Finished.php{d{zǡ6phpunit/Event/Events/TestRunner/FinishedSubscriber.php5d5̤+phpunit/Event/Events/TestRunner/Started.phpydy5phpunit/Event/Events/TestRunner/StartedSubscriber.php3d3 4phpunit/Event/Events/TestRunner/WarningTriggered.phpldl.Cv>phpunit/Event/Events/TestRunner/WarningTriggeredSubscriber.phpEdE8K+phpunit/Event/Events/TestSuite/Filtered.phpdo5phpunit/Event/Events/TestSuite/FilteredSubscriber.php3d3|+phpunit/Event/Events/TestSuite/Finished.phpdM`xd5phpunit/Event/Events/TestSuite/FinishedSubscriber.php3d3զ)phpunit/Event/Events/TestSuite/Loaded.phpdX(\*3phpunit/Event/Events/TestSuite/LoadedSubscriber.php/d/^7*phpunit/Event/Events/TestSuite/Skipped.phpd4phpunit/Event/Events/TestSuite/SkippedSubscriber.php1d1D!)phpunit/Event/Events/TestSuite/Sorted.php'd'j 3phpunit/Event/Events/TestSuite/SortedSubscriber.php/d/ Ȥ*phpunit/Event/Events/TestSuite/Started.phpdl4phpunit/Event/Events/TestSuite/StartedSubscriber.php1d1i5k9phpunit/Event/Exception/EventAlreadyAssignedException.php d 0ɤ8phpunit/Event/Exception/EventFacadeIsSealedException.php -d -J ؤ%phpunit/Event/Exception/Exception.phpLdLgx4phpunit/Event/Exception/InvalidArgumentException.phpd䀤1phpunit/Event/Exception/InvalidEventException.phpdE>6phpunit/Event/Exception/InvalidSubscriberException.phpdSg$phpunit/Event/Exception/MapError.phpdRGphpunit/Event/Exception/MoreThanOneDataSetFromDataProviderException.php0d0R=8phpunit/Event/Exception/NoComparisonFailureException.phpd{k>phpunit/Event/Exception/NoDataSetFromDataProviderException.php'd'@~8phpunit/Event/Exception/NoPreviousThrowableException.php -d -~,phpunit/Event/Exception/RuntimeException.phpdLDphpunit/Event/Exception/SubscriberTypeAlreadyRegisteredException.phpdįK1phpunit/Event/Exception/UnknownEventException.phpd}5phpunit/Event/Exception/UnknownEventTypeException.phpd/<6phpunit/Event/Exception/UnknownSubscriberException.phpd ˤ:phpunit/Event/Exception/UnknownSubscriberTypeException.php d &'*phpunit/Event/Facade.phpdAvphpunit/Event/Subscriber.phpddlkphpunit/Event/Tracer.phpdr7phpunit/Event/TypeMap.php d #phpunit/Event/Value/ClassMethod.phpdB)phpunit/Event/Value/ComparisonFailure.phpdk;0phpunit/Event/Value/ComparisonFailureBuilder.phpdvZ/phpunit/Event/Value/Runtime/OperatingSystem.phpdgA! #phpunit/Event/Value/Runtime/PHP.php d P'phpunit/Event/Value/Runtime/PHPUnit.phpodo3'phpunit/Event/Value/Runtime/Runtime.phpdk?J*phpunit/Event/Value/Telemetry/Duration.php d /(phpunit/Event/Value/Telemetry/HRTime.php d Fɤ&phpunit/Event/Value/Telemetry/Info.php -d --phpunit/Event/Value/Telemetry/MemoryMeter.php6d6-phpunit/Event/Value/Telemetry/MemoryUsage.phpgdg-*phpunit/Event/Value/Telemetry/Snapshot.php)d)\q+phpunit/Event/Value/Telemetry/StopWatch.phpd7\;(phpunit/Event/Value/Telemetry/System.phpd#3phpunit/Event/Value/Telemetry/SystemMemoryMeter.php~d~q`e1phpunit/Event/Value/Telemetry/SystemStopWatch.phpd H};phpunit/Event/Value/Telemetry/SystemStopWatchWithOffset.php8d8D !phpunit/Event/Value/Test/Phpt.phpRdR߭L!phpunit/Event/Value/Test/Test.phpd]+phpunit/Event/Value/Test/TestCollection.php1d1J3T3phpunit/Event/Value/Test/TestCollectionIterator.phpdbx:phpunit/Event/Value/Test/TestData/DataFromDataProvider.phpKdK?m<phpunit/Event/Value/Test/TestData/DataFromTestDependency.phpd.phpunit/Event/Value/Test/TestData/TestData.phpdn~8phpunit/Event/Value/Test/TestData/TestDataCollection.php -d -*^@phpunit/Event/Value/Test/TestData/TestDataCollectionIterator.phpdA$phpunit/Event/Value/Test/TestDox.php d Kyx+phpunit/Event/Value/Test/TestDoxBuilder.phpdU'phpunit/Event/Value/Test/TestMethod.php d bpy.phpunit/Event/Value/Test/TestMethodBuilder.phpd +phpunit/Event/Value/TestSuite/TestSuite.phpd2phpunit/Event/Value/TestSuite/TestSuiteBuilder.phpN dN v7phpunit/Event/Value/TestSuite/TestSuiteForTestClass.phpdN&Hphpunit/Event/Value/TestSuite/TestSuiteForTestMethodWithDataProvider.phpTdTTN3phpunit/Event/Value/TestSuite/TestSuiteWithName.phpd4d !phpunit/Event/Value/Throwable.php_ d_  (phpunit/Event/Value/ThrowableBuilder.phpdabphpunit/Exception.phpLdLߊphpunit/Framework/Assert.php{d{u[;&phpunit/Framework/Assert/Functions.phpTdT99H&phpunit/Framework/Attributes/After.phpd~jL¤+phpunit/Framework/Attributes/AfterClass.phpd׎.phpunit/Framework/Attributes/BackupGlobals.phpdmEO7phpunit/Framework/Attributes/BackupStaticProperties.phpdh'phpunit/Framework/Attributes/Before.phpd;,phpunit/Framework/Attributes/BeforeClass.phpd\3phpunit/Framework/Attributes/CodeCoverageIgnore.php#d#/@',phpunit/Framework/Attributes/CoversClass.phpdCb/phpunit/Framework/Attributes/CoversFunction.phpdΐX.phpunit/Framework/Attributes/CoversNothing.phpd&ޏ-phpunit/Framework/Attributes/DataProvider.phpdM5phpunit/Framework/Attributes/DataProviderExternal.phpdh5(phpunit/Framework/Attributes/Depends.phpdO0phpunit/Framework/Attributes/DependsExternal.phpd -p>phpunit/Framework/Attributes/DependsExternalUsingDeepClone.phpdWgAphpunit/Framework/Attributes/DependsExternalUsingShallowClone.php d //phpunit/Framework/Attributes/DependsOnClass.phpd4=phpunit/Framework/Attributes/DependsOnClassUsingDeepClone.phpd'@phpunit/Framework/Attributes/DependsOnClassUsingShallowClone.phpd}E6phpunit/Framework/Attributes/DependsUsingDeepClone.phpdrˌ9phpunit/Framework/Attributes/DependsUsingShallowClone.phpd& 9phpunit/Framework/Attributes/DoesNotPerformAssertions.php)d)J.~@phpunit/Framework/Attributes/ExcludeGlobalVariableFromBackup.phpdL༤@phpunit/Framework/Attributes/ExcludeStaticPropertyFromBackup.php2d2&phpunit/Framework/Attributes/Group.phpdio&phpunit/Framework/Attributes/Large.phpd"mn'phpunit/Framework/Attributes/Medium.phpd'2.phpunit/Framework/Attributes/PostCondition.phpdK-phpunit/Framework/Attributes/PreCondition.phpdؕ@4phpunit/Framework/Attributes/PreserveGlobalState.phpdM|1phpunit/Framework/Attributes/RequiresFunction.phpdd/phpunit/Framework/Attributes/RequiresMethod.phpdG -8phpunit/Framework/Attributes/RequiresOperatingSystem.phpd>phpunit/Framework/Attributes/RequiresOperatingSystemFamily.phpd-",phpunit/Framework/Attributes/RequiresPhp.phpdn5phpunit/Framework/Attributes/RequiresPhpExtension.phpvdve(a0phpunit/Framework/Attributes/RequiresPhpunit.phpdIt0phpunit/Framework/Attributes/RequiresSetting.phpdLP:phpunit/Framework/Attributes/RunClassInSeparateProcess.phpd:5phpunit/Framework/Attributes/RunInSeparateProcess.php d <phpunit/Framework/Attributes/RunTestsInSeparateProcesses.phpdĪ&phpunit/Framework/Attributes/Small.phpdw~%phpunit/Framework/Attributes/Test.phpd#(phpunit/Framework/Attributes/TestDox.phpd{)phpunit/Framework/Attributes/TestWith.phpd[4-phpunit/Framework/Attributes/TestWithJson.phpdrzC'phpunit/Framework/Attributes/Ticket.phpd 2*phpunit/Framework/Attributes/UsesClass.phpdVF-phpunit/Framework/Attributes/UsesFunction.phpdN5ﻤ0phpunit/Framework/Constraint/Boolean/IsFalse.phpbdbBVu/phpunit/Framework/Constraint/Boolean/IsTrue.php_d_)phpunit/Framework/Constraint/Callback.phpd.@-2phpunit/Framework/Constraint/Cardinality/Count.php d ^.8phpunit/Framework/Constraint/Cardinality/GreaterThan.phpda4phpunit/Framework/Constraint/Cardinality/IsEmpty.php_d_yGϤ5phpunit/Framework/Constraint/Cardinality/LessThan.phpdߤo,5phpunit/Framework/Constraint/Cardinality/SameSize.phpd+phpunit/Framework/Constraint/Constraint.phpmdm}1phpunit/Framework/Constraint/Equality/IsEqual.php! d! xc`?phpunit/Framework/Constraint/Equality/IsEqualCanonicalizing.phpO -dO -x=phpunit/Framework/Constraint/Equality/IsEqualIgnoringCase.phpM -dM -}7:phpunit/Framework/Constraint/Equality/IsEqualWithDelta.php d MZf4phpunit/Framework/Constraint/Exception/Exception.phpvdvz8phpunit/Framework/Constraint/Exception/ExceptionCode.phpd?]Gphpunit/Framework/Constraint/Exception/ExceptionMessageIsOrContains.phpd_Sphpunit/Framework/Constraint/Exception/ExceptionMessageMatchesRegularExpression.php<d<K;phpunit/Framework/Constraint/Filesystem/DirectoryExists.phpdyy6phpunit/Framework/Constraint/Filesystem/FileExists.phpdC 6phpunit/Framework/Constraint/Filesystem/IsReadable.phpdȅ]6phpunit/Framework/Constraint/Filesystem/IsWritable.phpd +phpunit/Framework/Constraint/IsAnything.phpd{Ϝ,phpunit/Framework/Constraint/IsIdentical.php d 72,phpunit/Framework/Constraint/JsonMatches.php d '4|.phpunit/Framework/Constraint/Math/IsFinite.php|d|G˴w0phpunit/Framework/Constraint/Math/IsInfinite.phpd3ߡ+phpunit/Framework/Constraint/Math/IsNan.phppdpZMw-phpunit/Framework/Constraint/ObjectEquals.phpodo, 8phpunit/Framework/Constraint/Operator/BinaryOperator.php] d]  4phpunit/Framework/Constraint/Operator/LogicalAnd.php]d]F4phpunit/Framework/Constraint/Operator/LogicalNot.php d  33phpunit/Framework/Constraint/Operator/LogicalOr.phpAdA(K4phpunit/Framework/Constraint/Operator/LogicalXor.phpd2phpunit/Framework/Constraint/Operator/Operator.php,d,{7phpunit/Framework/Constraint/Operator/UnaryOperator.phpd.{-.phpunit/Framework/Constraint/String/IsJson.phpd(9phpunit/Framework/Constraint/String/RegularExpression.php`d`m6phpunit/Framework/Constraint/String/StringContains.php -d -E6phpunit/Framework/Constraint/String/StringEndsWith.phpdrmMphpunit/Framework/Constraint/String/StringEqualsStringIgnoringLineEndings.php:d:IlFphpunit/Framework/Constraint/String/StringMatchesFormatDescription.php d m}t8phpunit/Framework/Constraint/String/StringStartsWith.phpdi.Qդ8phpunit/Framework/Constraint/Traversable/ArrayHasKey.phptdt~ҳ33phpunit/Framework/Constraint/Traversable/IsList.phpxdxv @phpunit/Framework/Constraint/Traversable/TraversableContains.php<d<YGEphpunit/Framework/Constraint/Traversable/TraversableContainsEqual.php)d)%Iphpunit/Framework/Constraint/Traversable/TraversableContainsIdentical.phpdyDphpunit/Framework/Constraint/Traversable/TraversableContainsOnly.phpTdTW?2phpunit/Framework/Constraint/Type/IsInstanceOf.phpdX,phpunit/Framework/Constraint/Type/IsNull.php^d^Vɭ,phpunit/Framework/Constraint/Type/IsType.phpd8]+phpunit/Framework/DataProviderTestSuite.php1d1V14phpunit/Framework/Exception/AssertionFailedError.phpd5phpunit/Framework/Exception/CodeCoverageException.phpd[4phpunit/Framework/Exception/EmptyStringException.phpd!%phpunit/Framework/Exception/Error.phpdj1)phpunit/Framework/Exception/Exception.php d ٤:phpunit/Framework/Exception/ExpectationFailedException.phpdA>phpunit/Framework/Exception/GeneratorNotSupportedException.phpd(d9phpunit/Framework/Exception/Incomplete/IncompleteTest.phpd,+>phpunit/Framework/Exception/Incomplete/IncompleteTestError.phpdםܤ8phpunit/Framework/Exception/InvalidArgumentException.phpd:(<phpunit/Framework/Exception/InvalidCoversTargetException.phpdo苤<phpunit/Framework/Exception/InvalidDataProviderException.phpd.ڜɤ:phpunit/Framework/Exception/InvalidDependencyException.phpd}9phpunit/Framework/Exception/NoChildTestSuiteException.phpdP$Nphpunit/Framework/Exception/ObjectEquals/ActualValueIsNotAnObjectException.phpAdA<ؤ`phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotAcceptParameterTypeException.phpd@bphpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareBoolReturnTypeException.phpdPigphpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareExactlyOneParameterException.phpdFaphpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareParameterTypeException.phpdENRphpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotExistException.phpdui8phpunit/Framework/Exception/PhptAssertionFailedError.php2d2_9phpunit/Framework/Exception/ProcessIsolationException.phpdH:3phpunit/Framework/Exception/Skipped/SkippedTest.phpdS.=phpunit/Framework/Exception/Skipped/SkippedTestSuiteError.phpdxCphpunit/Framework/Exception/Skipped/SkippedWithMessageException.phpdz$5phpunit/Framework/Exception/UnknownClassException.phprdrk(ؤ@phpunit/Framework/Exception/UnknownClassOrInterfaceException.phpdӤ4phpunit/Framework/Exception/UnknownTypeException.phpndn(j.phpunit/Framework/ExecutionOrderDependency.phpdX>2&(phpunit/Framework/MockObject/Api/Api.php d =8Q_+phpunit/Framework/MockObject/Api/Method.php d G(6phpunit/Framework/MockObject/Api/MockedCloneMethod.php1d1>BѤ8phpunit/Framework/MockObject/Api/UnmockedCloneMethod.phpNdN/1phpunit/Framework/MockObject/Builder/Identity.php[d[$X3{9phpunit/Framework/MockObject/Builder/InvocationMocker.phpkdk߰:phpunit/Framework/MockObject/Builder/InvocationStubber.phpdeU8phpunit/Framework/MockObject/Builder/MethodNameMatch.phpd:'8phpunit/Framework/MockObject/Builder/ParametersMatch.phpNdNx)-phpunit/Framework/MockObject/Builder/Stub.phpd(3phpunit/Framework/MockObject/ConfigurableMethod.phpbdbAphpunit/Framework/MockObject/Exception/BadMethodCallException.phpdΫXGphpunit/Framework/MockObject/Exception/CannotUseAddMethodsException.php5d5{Hphpunit/Framework/MockObject/Exception/CannotUseOnlyMethodsException.phpEdEFphpunit/Framework/MockObject/Exception/ClassAlreadyExistsException.phpdFphpunit/Framework/MockObject/Exception/ClassIsEnumerationException.phpdN@phpunit/Framework/MockObject/Exception/ClassIsFinalException.phpd()Cphpunit/Framework/MockObject/Exception/ClassIsReadonlyException.phpdOuXYphpunit/Framework/MockObject/Exception/ConfigurableMethodsAlreadyInitializedException.php d ɅWCphpunit/Framework/MockObject/Exception/DuplicateMethodException.phpdy4phpunit/Framework/MockObject/Exception/Exception.phpdB'Kphpunit/Framework/MockObject/Exception/IncompatibleReturnValueException.phpydy|/Ephpunit/Framework/MockObject/Exception/InvalidMethodNameException.phpd ܤHphpunit/Framework/MockObject/Exception/MatchBuilderNotFoundException.phpdLphpunit/Framework/MockObject/Exception/MatcherAlreadyRegisteredException.phpdz'Lphpunit/Framework/MockObject/Exception/MethodCannotBeConfiguredException.phpd}QOphpunit/Framework/MockObject/Exception/MethodNameAlreadyConfiguredException.phpdӁƤKphpunit/Framework/MockObject/Exception/MethodNameNotConfiguredException.php~d~x1)Uphpunit/Framework/MockObject/Exception/MethodParametersAlreadyConfiguredException.phpd rYphpunit/Framework/MockObject/Exception/OriginalConstructorInvocationRequiredException.phpdک>phpunit/Framework/MockObject/Exception/ReflectionException.phpd.ؔLphpunit/Framework/MockObject/Exception/ReturnValueNotConfiguredException.php0d0F;phpunit/Framework/MockObject/Exception/RuntimeException.phpd_|Mphpunit/Framework/MockObject/Exception/SoapExtensionNotAvailableException.phpdz@phpunit/Framework/MockObject/Exception/UnknownClassException.phpd5uW@phpunit/Framework/MockObject/Exception/UnknownTraitException.phpdq¥?phpunit/Framework/MockObject/Exception/UnknownTypeException.phpd~*phpunit/Framework/MockObject/Generator.php7}d7}Djr6phpunit/Framework/MockObject/Generator/deprecation.tpl;d;O5s7phpunit/Framework/MockObject/Generator/intersection.tplLdL-X7phpunit/Framework/MockObject/Generator/mocked_class.tpldwZ8phpunit/Framework/MockObject/Generator/mocked_method.tplFdFKFphpunit/Framework/MockObject/Generator/mocked_method_never_or_void.tpldp?phpunit/Framework/MockObject/Generator/mocked_static_method.tpld 4R9phpunit/Framework/MockObject/Generator/proxied_method.tpl}d}@ėGphpunit/Framework/MockObject/Generator/proxied_method_never_or_void.tplvdvT6phpunit/Framework/MockObject/Generator/trait_class.tplQdQ<Ȥ5phpunit/Framework/MockObject/Generator/wsdl_class.tpld6phpunit/Framework/MockObject/Generator/wsdl_method.tpl<d<i+phpunit/Framework/MockObject/Invocation.php!d!u2phpunit/Framework/MockObject/InvocationHandler.phpdjkפ(phpunit/Framework/MockObject/Matcher.phpsdsߤ5phpunit/Framework/MockObject/MethodNameConstraint.phpdʦ,phpunit/Framework/MockObject/MockBuilder.php&d&*phpunit/Framework/MockObject/MockClass.phpd_ޭ+phpunit/Framework/MockObject/MockMethod.php"d"y.phpunit/Framework/MockObject/MockMethodSet.php]d].ۤ+phpunit/Framework/MockObject/MockObject.phpdPߤ*phpunit/Framework/MockObject/MockTrait.phpd~;0)phpunit/Framework/MockObject/MockType.phpdFFt5phpunit/Framework/MockObject/Rule/AnyInvokedCount.phpd33phpunit/Framework/MockObject/Rule/AnyParameters.phpd~'5phpunit/Framework/MockObject/Rule/InvocationOrder.phpdh9phpunit/Framework/MockObject/Rule/InvokedAtLeastCount.phpdF88phpunit/Framework/MockObject/Rule/InvokedAtLeastOnce.phpd 8phpunit/Framework/MockObject/Rule/InvokedAtMostCount.phpd.P2phpunit/Framework/MockObject/Rule/InvokedCount.phpd쯑0phpunit/Framework/MockObject/Rule/MethodName.phpdf-Ф0phpunit/Framework/MockObject/Rule/Parameters.php|d|4phpunit/Framework/MockObject/Rule/ParametersRule.phpcdc?(%phpunit/Framework/MockObject/Stub.phpdŎ6phpunit/Framework/MockObject/Stub/ConsecutiveCalls.phpda/phpunit/Framework/MockObject/Stub/Exception.php<d<bT@F4phpunit/Framework/MockObject/Stub/ReturnArgument.phpd4p4phpunit/Framework/MockObject/Stub/ReturnCallback.phpdP J5phpunit/Framework/MockObject/Stub/ReturnReference.phpdŤ0phpunit/Framework/MockObject/Stub/ReturnSelf.php:d:s0phpunit/Framework/MockObject/Stub/ReturnStub.phpdx4phpunit/Framework/MockObject/Stub/ReturnValueMap.phpd.*phpunit/Framework/MockObject/Stub/Stub.phpdi/phpunit/Framework/MockObject/TemplateLoader.phpd[`+phpunit/Framework/MockObject/Verifiable.phpd̐ s!phpunit/Framework/Reorderable.phpd˯$phpunit/Framework/SelfDescribing.php -d -sphpunit/Framework/Test.phpdǺ!phpunit/Framework/TestBuilder.php%d%)rphpunit/Framework/TestCase.phpdQ -h phpunit/Framework/TestRunner.php5d5):$phpunit/Framework/TestSize/Known.phpd)T Ф$phpunit/Framework/TestSize/Large.php/d/N`i%phpunit/Framework/TestSize/Medium.php2d2b{$phpunit/Framework/TestSize/Small.php#d#24'phpunit/Framework/TestSize/TestSize.php5d5ˮ&phpunit/Framework/TestSize/Unknown.phpdg,phpunit/Framework/TestStatus/Deprecation.phpdȸ&phpunit/Framework/TestStatus/Error.phpdۑ(phpunit/Framework/TestStatus/Failure.phpdp!]+phpunit/Framework/TestStatus/Incomplete.phpdC&phpunit/Framework/TestStatus/Known.phpzdz->f'phpunit/Framework/TestStatus/Notice.phpd'S(&phpunit/Framework/TestStatus/Risky.phpdVw(phpunit/Framework/TestStatus/Skipped.phpd4̤(phpunit/Framework/TestStatus/Success.phpdڍ]8+phpunit/Framework/TestStatus/TestStatus.phpndnb(phpunit/Framework/TestStatus/Unknown.php d 7W(phpunit/Framework/TestStatus/Warning.phpdYphpunit/Framework/TestSuite.phpJdJ&'phpunit/Framework/TestSuiteIterator.php3d3.Kphpunit/Logging/EventLogger.phpd-|phpunit/Logging/Exception.phpd%٤(phpunit/Logging/JUnit/JunitXmlLogger.php.d.RT^ͤ/phpunit/Logging/JUnit/Subscriber/Subscriber.phpdyJ;:phpunit/Logging/JUnit/Subscriber/TestErroredSubscriber.phpzdzP_ˤ9phpunit/Logging/JUnit/Subscriber/TestFailedSubscriber.phptdtr);phpunit/Logging/JUnit/Subscriber/TestFinishedSubscriber.phpd Cphpunit/Logging/JUnit/Subscriber/TestMarkedIncompleteSubscriber.phpdP;phpunit/Logging/JUnit/Subscriber/TestPreparedSubscriber.phpd:wJphpunit/Logging/JUnit/Subscriber/TestRunnerExecutionFinishedSubscriber.phpdĤ:phpunit/Logging/JUnit/Subscriber/TestSkippedSubscriber.phpzdzY@phpunit/Logging/JUnit/Subscriber/TestSuiteFinishedSubscriber.phpdVG?phpunit/Logging/JUnit/Subscriber/TestSuiteStartedSubscriber.phpd?2phpunit/Logging/TeamCity/Subscriber/Subscriber.phpdGEphpunit/Logging/TeamCity/Subscriber/TestConsideredRiskySubscriber.php?d?s&U=phpunit/Logging/TeamCity/Subscriber/TestErroredSubscriber.phpdФ<phpunit/Logging/TeamCity/Subscriber/TestFailedSubscriber.php d U>phpunit/Logging/TeamCity/Subscriber/TestFinishedSubscriber.phpdi&iFphpunit/Logging/TeamCity/Subscriber/TestMarkedIncompleteSubscriber.phpEdE >phpunit/Logging/TeamCity/Subscriber/TestPreparedSubscriber.phpd Mphpunit/Logging/TeamCity/Subscriber/TestRunnerExecutionFinishedSubscriber.phpd,=phpunit/Logging/TeamCity/Subscriber/TestSkippedSubscriber.phpdmF֤Cphpunit/Logging/TeamCity/Subscriber/TestSuiteFinishedSubscriber.phpdxBphpunit/Logging/TeamCity/Subscriber/TestSuiteStartedSubscriber.phpd}G9+phpunit/Logging/TeamCity/TeamCityLogger.php>%d>% ϧ(phpunit/Logging/TestDox/HtmlRenderer.php d lE*phpunit/Logging/TestDox/NamePrettifier.phpd:lPh-phpunit/Logging/TestDox/PlainTextRenderer.phpede <phpunit/Logging/TestDox/TestMethod/Subscriber/Subscriber.phpd'ĤOphpunit/Logging/TestDox/TestMethod/Subscriber/TestConsideredRiskySubscriber.phpdAaphpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedMockObjectForAbstractClassSubscriber.php8d8G驤Yphpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedMockObjectForTraitSubscriber.phpdR< Yphpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedMockObjectFromWsdlSubscriber.phpdQphpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedMockObjectSubscriber.phpdԤXphpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedPartialMockObjectSubscriber.php d 2Pphpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedTestProxySubscriber.phpdOphpunit/Logging/TestDox/TestMethod/Subscriber/TestCreatedTestStubSubscriber.phpdaGphpunit/Logging/TestDox/TestMethod/Subscriber/TestErroredSubscriber.phpd;m Fphpunit/Logging/TestDox/TestMethod/Subscriber/TestFailedSubscriber.phpdF,Hphpunit/Logging/TestDox/TestMethod/Subscriber/TestFinishedSubscriber.phpdPGPphpunit/Logging/TestDox/TestMethod/Subscriber/TestMarkedIncompleteSubscriber.phpd {Fphpunit/Logging/TestDox/TestMethod/Subscriber/TestPassedSubscriber.phpd)#Hphpunit/Logging/TestDox/TestMethod/Subscriber/TestPreparedSubscriber.phpd.Gphpunit/Logging/TestDox/TestMethod/Subscriber/TestSkippedSubscriber.phpd<Ӥ1phpunit/Logging/TestDox/TestMethod/TestResult.phpd%+8;phpunit/Logging/TestDox/TestMethod/TestResultCollection.phpdCphpunit/Logging/TestDox/TestMethod/TestResultCollectionIterator.phpdx:phpunit/Logging/TestDox/TestMethod/TestResultCollector.phpdnvWphpunit/Metadata/After.php$d$Е1Τphpunit/Metadata/AfterClass.php.d.LR%phpunit/Metadata/Api/CodeCoverage.phpd%phpunit/Metadata/Api/DataProvider.phpd2%phpunit/Metadata/Api/Dependencies.php d  eɤphpunit/Metadata/Api/Groups.php9 d9 z/[C$phpunit/Metadata/Api/HookMethods.php} d} K5¤%phpunit/Metadata/Api/Requirements.phpd>c8"phpunit/Metadata/BackupGlobals.php:d:€k+phpunit/Metadata/BackupStaticProperties.phpLdL& phpunit/Metadata/Before.php&d& phpunit/Metadata/BeforeClass.php0d0Aphpunit/Metadata/Covers.php,d,Q phpunit/Metadata/CoversClass.phpd3'phpunit/Metadata/CoversDefaultClass.phpd"#phpunit/Metadata/CoversFunction.php>d>^$"phpunit/Metadata/CoversNothing.php4d4~Zc!phpunit/Metadata/DataProvider.phpdj#phpunit/Metadata/DependsOnClass.phpadadˤ$phpunit/Metadata/DependsOnMethod.php!d! -phpunit/Metadata/DoesNotPerformAssertions.phpJdJ8 \'Tphpunit/Metadata/Exception/AnnotationsAreNotSupportedForInternalClassesException.php:d:,Ȥ(phpunit/Metadata/Exception/Exception.phpOdOwAphpunit/Metadata/Exception/InvalidVersionRequirementException.phpdPR<phpunit/Metadata/Exception/NoVersionRequirementException.phpd?+睤2phpunit/Metadata/Exception/ReflectionException.phpdn4phpunit/Metadata/ExcludeGlobalVariableFromBackup.phpdg"4phpunit/Metadata/ExcludeStaticPropertyFromBackup.phpdʁg?phpunit/Metadata/Group.php<d<@7;phpunit/Metadata/Metadata.php.Jd.J.6J'phpunit/Metadata/MetadataCollection.php(d(0R/phpunit/Metadata/MetadataCollectionIterator.phpd2I/phpunit/Metadata/Parser/Annotation/DocBlock.phpP"dP"nV/phpunit/Metadata/Parser/Annotation/Registry.php d ],phpunit/Metadata/Parser/AnnotationParser.php~Cd~C^+phpunit/Metadata/Parser/AttributeParser.phpPdP )phpunit/Metadata/Parser/CachingParser.php -d -e"phpunit/Metadata/Parser/Parser.phpdOv'phpunit/Metadata/Parser/ParserChain.phpd -nY$phpunit/Metadata/Parser/Registry.phpbdb)D"phpunit/Metadata/PostCondition.php4d46..!phpunit/Metadata/PreCondition.php2d2.(phpunit/Metadata/PreserveGlobalState.phpFdF8%phpunit/Metadata/RequiresFunction.phpddd`B#phpunit/Metadata/RequiresMethod.phpdR,phpunit/Metadata/RequiresOperatingSystem.phpdM+A2phpunit/Metadata/RequiresOperatingSystemFamily.phpd'r phpunit/Metadata/RequiresPhp.phpd-Y)phpunit/Metadata/RequiresPhpExtension.phpdEW'$phpunit/Metadata/RequiresPhpunit.phpd!9a$phpunit/Metadata/RequiresSetting.phpdAm.phpunit/Metadata/RunClassInSeparateProcess.phpLdLwT)phpunit/Metadata/RunInSeparateProcess.phpBdBiZ0phpunit/Metadata/RunTestsInSeparateProcesses.phpPdPtphpunit/Metadata/Test.php"d"phpunit/Metadata/TestDox.php"d"phpunit/Metadata/TestWith.php!d!phpunit/Metadata/Uses.php(d(פphpunit/Metadata/UsesClass.phpd7*Ⱥ%phpunit/Metadata/UsesDefaultClass.phpd/7X!phpunit/Metadata/UsesFunction.php7d7(؟֤2phpunit/Metadata/Version/ComparisonRequirement.phphdh52phpunit/Metadata/Version/ConstraintRequirement.phpdw㳤(phpunit/Metadata/Version/Requirement.phpda p_phpunit/Runner/CodeCoverage.php0d0E8phpunit/Runner/Exception/ClassCannotBeFoundException.phpdc?phpunit/Runner/Exception/ClassCannotBeInstantiatedException.php$d$K7phpunit/Runner/Exception/ClassDoesNotExistException.phpdJ5@Mphpunit/Runner/Exception/ClassDoesNotImplementExtensionInterfaceException.phpdΤ5phpunit/Runner/Exception/ClassIsAbstractException.phpdp7o>phpunit/Runner/Exception/DirectoryCannotBeCreatedException.phpd:Vr&phpunit/Runner/Exception/Exception.phpdnHA6phpunit/Runner/Exception/FileDoesNotExistException.phpdg K2phpunit/Runner/Exception/InvalidOrderException.phpd8Kڤ5phpunit/Runner/Exception/InvalidPhptFileException.phpdzA>4phpunit/Runner/Exception/NoIgnoredEventException.phpd3Uǚ;phpunit/Runner/Exception/ParameterDoesNotExistException.phpd]wQDphpunit/Runner/Exception/PhptExternalFileCannotBeLoadedException.phpdj0phpunit/Runner/Exception/ReflectionException.phpd^ss<phpunit/Runner/Exception/UnsupportedPhptSectionException.phpd &phpunit/Runner/Extension/Extension.phpdVZ2phpunit/Runner/Extension/ExtensionBootstrapper.phpd֓~#phpunit/Runner/Extension/Facade.phpdW;0phpunit/Runner/Extension/ParameterCollection.phpdnZ[c'phpunit/Runner/Extension/PharLoader.php d 4phpunit/Runner/Filter/ExcludeGroupFilterIterator.phpldlH}H!phpunit/Runner/Filter/Factory.phpds-phpunit/Runner/Filter/GroupFilterIterator.phpd)դ4phpunit/Runner/Filter/IncludeGroupFilterIterator.phpkdkSw,phpunit/Runner/Filter/NameFilterIterator.php d phpunit/Runner/PhptTestCase.phpUdU1phpunit/Runner/ResultCache/DefaultResultCache.php d X-.phpunit/Runner/ResultCache/NullResultCache.phpdS*phpunit/Runner/ResultCache/ResultCache.phpd3Gb1phpunit/Runner/ResultCache/ResultCacheHandler.phpdXY4phpunit/Runner/ResultCache/Subscriber/Subscriber.phpdM#Gphpunit/Runner/ResultCache/Subscriber/TestConsideredRiskySubscriber.phpd$k?phpunit/Runner/ResultCache/Subscriber/TestErroredSubscriber.phpd4}Fr>phpunit/Runner/ResultCache/Subscriber/TestFailedSubscriber.phpd )@phpunit/Runner/ResultCache/Subscriber/TestFinishedSubscriber.phpUdUVHphpunit/Runner/ResultCache/Subscriber/TestMarkedIncompleteSubscriber.phpd.6@phpunit/Runner/ResultCache/Subscriber/TestPreparedSubscriber.phpdΤ?phpunit/Runner/ResultCache/Subscriber/TestSkippedSubscriber.phpOdODÇEphpunit/Runner/ResultCache/Subscriber/TestSuiteFinishedSubscriber.phpdߤDphpunit/Runner/ResultCache/Subscriber/TestSuiteStartedSubscriber.phpd0DĤ'phpunit/Runner/TestResult/Collector.php8<d8< L1 $phpunit/Runner/TestResult/Facade.php -d -G.=)phpunit/Runner/TestResult/PassedTests.php d |Ophpunit/Runner/TestResult/Subscriber/BeforeTestClassMethodErroredSubscriber.php.d.$|;Cphpunit/Runner/TestResult/Subscriber/ExecutionStartedSubscriber.php$d$ޙ63phpunit/Runner/TestResult/Subscriber/Subscriber.phpd񡠒Fphpunit/Runner/TestResult/Subscriber/TestConsideredRiskySubscriber.phpd}9r4>phpunit/Runner/TestResult/Subscriber/TestErroredSubscriber.phpdܤ=phpunit/Runner/TestResult/Subscriber/TestFailedSubscriber.phpd?%+?phpunit/Runner/TestResult/Subscriber/TestFinishedSubscriber.phpdۤGphpunit/Runner/TestResult/Subscriber/TestMarkedIncompleteSubscriber.phpdlH?phpunit/Runner/TestResult/Subscriber/TestPreparedSubscriber.phpd<¤Qphpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredDeprecationSubscriber.phpdYMphpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredWarningSubscriber.phpdx>phpunit/Runner/TestResult/Subscriber/TestSkippedSubscriber.phpdADphpunit/Runner/TestResult/Subscriber/TestSuiteFinishedSubscriber.phpSdS*Cphpunit/Runner/TestResult/Subscriber/TestSuiteSkippedSubscriber.phpdFCphpunit/Runner/TestResult/Subscriber/TestSuiteStartedSubscriber.phpd bZKphpunit/Runner/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.phpdsXcEphpunit/Runner/TestResult/Subscriber/TestTriggeredErrorSubscriber.phpd{9Fphpunit/Runner/TestResult/Subscriber/TestTriggeredNoticeSubscriber.phpdߋ%Nphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.phpdeLOԤIphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.phpd dJphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.phpdèMRphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php0d0gﰤLphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.php d T5Nphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.phpdDnGphpunit/Runner/TestResult/Subscriber/TestTriggeredWarningSubscriber.phpdɤ(phpunit/Runner/TestResult/TestResult.phpGdG$L"phpunit/Runner/TestSuiteLoader.php d } -"phpunit/Runner/TestSuiteSorter.php%d% 1phpunit/Runner/Version.phpds_Cphpunit/TextUI/Application.php=d=g"phpunit/TextUI/Command/Command.phpdO㍤9phpunit/TextUI/Command/Commands/AtLeastVersionCommand.phpdTؼ@phpunit/TextUI/Command/Commands/GenerateConfigurationCommand.phpdor5phpunit/TextUI/Command/Commands/ListGroupsCommand.phpdpz9phpunit/TextUI/Command/Commands/ListTestSuitesCommand.phpdKn:phpunit/TextUI/Command/Commands/ListTestsAsTextCommand.phpdE>9phpunit/TextUI/Command/Commands/ListTestsAsXmlCommand.phpd ?phpunit/TextUI/Command/Commands/MigrateConfigurationCommand.phpd3phpunit/TextUI/Command/Commands/ShowHelpCommand.php/d/>>#6phpunit/TextUI/Command/Commands/ShowVersionCommand.phpSdS7phpunit/TextUI/Command/Commands/VersionCheckCommand.phpdZ@phpunit/TextUI/Command/Commands/WarmCodeCoverageCacheCommand.phpz dz *!phpunit/TextUI/Command/Result.phpcdc{(phpunit/TextUI/Configuration/Builder.phpdG,phpunit/TextUI/Configuration/Cli/Builder.phpQdQ^Z2phpunit/TextUI/Configuration/Cli/Configuration.phpzdz.phpunit/TextUI/Configuration/Cli/Exception.phpd%zE?phpunit/TextUI/Configuration/Cli/XmlConfigurationFileFinder.phpd p;phpunit/TextUI/Configuration/CodeCoverageFilterRegistry.phpda.phpunit/TextUI/Configuration/Configuration.phpd@ޤSphpunit/TextUI/Configuration/Exception/CodeCoverageReportNotConfiguredException.php$d$Nphpunit/TextUI/Configuration/Exception/ConfigurationCannotBeBuiltException.phpdZ$&4phpunit/TextUI/Configuration/Exception/Exception.phpdGphpunit/TextUI/Configuration/Exception/FilterNotConfiguredException.phpdgGLphpunit/TextUI/Configuration/Exception/IncludePathNotConfiguredException.phpdxHphpunit/TextUI/Configuration/Exception/LoggingNotConfiguredException.phpdY%?phpunit/TextUI/Configuration/Exception/NoBootstrapException.phpd`lƤDphpunit/TextUI/Configuration/Exception/NoCacheDirectoryException.phpdCAphpunit/TextUI/Configuration/Exception/NoCliArgumentException.phpd|J?RGphpunit/TextUI/Configuration/Exception/NoConfigurationFileException.phpdMLphpunit/TextUI/Configuration/Exception/NoCoverageCacheDirectoryException.phpd;Cphpunit/TextUI/Configuration/Exception/NoCustomCssFileException.phpdʑ0Fphpunit/TextUI/Configuration/Exception/NoDefaultTestSuiteException.phpd Lphpunit/TextUI/Configuration/Exception/NoPharExtensionDirectoryException.phpd)R'phpunit/TextUI/Configuration/Merger.phpxdx ٤+phpunit/TextUI/Configuration/PhpHandler.php\d\y)phpunit/TextUI/Configuration/Registry.php d - 3z1phpunit/TextUI/Configuration/TestSuiteBuilder.php -d -/bt/phpunit/TextUI/Configuration/Value/Constant.php8d8bt9phpunit/TextUI/Configuration/Value/ConstantCollection.phpdW6bAphpunit/TextUI/Configuration/Value/ConstantCollectionIterator.phpdg]0phpunit/TextUI/Configuration/Value/Directory.phpd3F:phpunit/TextUI/Configuration/Value/DirectoryCollection.php d ?aBphpunit/TextUI/Configuration/Value/DirectoryCollectionIterator.phpdہW9phpunit/TextUI/Configuration/Value/ExtensionBootstrap.phpdr[Cphpunit/TextUI/Configuration/Value/ExtensionBootstrapCollection.phpdѤKphpunit/TextUI/Configuration/Value/ExtensionBootstrapCollectionIterator.phpd( V+phpunit/TextUI/Configuration/Value/File.phpd**5phpunit/TextUI/Configuration/Value/FileCollection.phpd'P=phpunit/TextUI/Configuration/Value/FileCollectionIterator.phpndnj6phpunit/TextUI/Configuration/Value/FilterDirectory.phpd~@phpunit/TextUI/Configuration/Value/FilterDirectoryCollection.phpDdDJHphpunit/TextUI/Configuration/Value/FilterDirectoryCollectionIterator.phpd񭥤,phpunit/TextUI/Configuration/Value/Group.phpdkפ6phpunit/TextUI/Configuration/Value/GroupCollection.php8d8+Bm>phpunit/TextUI/Configuration/Value/GroupCollectionIterator.phpydywX1phpunit/TextUI/Configuration/Value/IniSetting.php1d1;phpunit/TextUI/Configuration/Value/IniSettingCollection.phpd^Cphpunit/TextUI/Configuration/Value/IniSettingCollectionIterator.phpd8Ф*phpunit/TextUI/Configuration/Value/Php.phpYdY畉4phpunit/TextUI/Configuration/Value/TestDirectory.phpd Ф>phpunit/TextUI/Configuration/Value/TestDirectoryCollection.php-d-zȤFphpunit/TextUI/Configuration/Value/TestDirectoryCollectionIterator.phpda>k/phpunit/TextUI/Configuration/Value/TestFile.phpd)tФ9phpunit/TextUI/Configuration/Value/TestFileCollection.phpdAphpunit/TextUI/Configuration/Value/TestFileCollectionIterator.phpdp0phpunit/TextUI/Configuration/Value/TestSuite.phpd(j:phpunit/TextUI/Configuration/Value/TestSuiteCollection.phpdPBphpunit/TextUI/Configuration/Value/TestSuiteCollectionIterator.phpd;E/phpunit/TextUI/Configuration/Value/Variable.phpd@9phpunit/TextUI/Configuration/Value/VariableCollection.phpdїAphpunit/TextUI/Configuration/Value/VariableCollectionIterator.phpdՑ>phpunit/TextUI/Configuration/Xml/CodeCoverage/CodeCoverage.phpd?phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Clover.phpdƣˠBphpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Cobertura.phpd5?phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Crap4j.phppdp^=phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Html.php -d -CD<phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Php.phpdCC|=phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Text.php}d}<phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Xml.phpd:H-2phpunit/TextUI/Configuration/Xml/Configuration.phpB -dB -^L9phpunit/TextUI/Configuration/Xml/DefaultConfiguration.php -d -J%.phpunit/TextUI/Configuration/Xml/Exception.phpdN5+.phpunit/TextUI/Configuration/Xml/Generator.phpd,<"+phpunit/TextUI/Configuration/Xml/Groups.phpddd8=Ӥ@phpunit/TextUI/Configuration/Xml/LoadedFromFileConfiguration.php7d7O 7+phpunit/TextUI/Configuration/Xml/Loader.php^vd^vNp2phpunit/TextUI/Configuration/Xml/Logging/Junit.phpdФ4phpunit/TextUI/Configuration/Xml/Logging/Logging.php -d -#5phpunit/TextUI/Configuration/Xml/Logging/TeamCity.phpdϦ9phpunit/TextUI/Configuration/Xml/Logging/TestDox/Html.phpdB*$9phpunit/TextUI/Configuration/Xml/Logging/TestDox/Text.phpd?phpunit/TextUI/Configuration/Xml/Migration/MigrationBuilder.php6d6vWcHphpunit/TextUI/Configuration/Xml/Migration/MigrationBuilderException.phpdUWĝAphpunit/TextUI/Configuration/Xml/Migration/MigrationException.phpd\ZIphpunit/TextUI/Configuration/Xml/Migration/Migrations/ConvertLogTypes.phpdhoePphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCloverToReport.phpXdXijPphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCrap4jToReport.phpd$i'Nphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageHtmlToReport.phpdՄjMphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoveragePhpToReport.phpFdF^ӤNphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageTextToReport.phpdV_Mphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageXmlToReport.phpKdK_ Zphpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCacheDirectoryAttribute.php\d\Rphpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCoverageElement.phpdUNphpunit/TextUI/Configuration/Xml/Migration/Migrations/LogToReportMigration.phpdUCphpunit/TextUI/Configuration/Xml/Migration/Migrations/Migration.phpd'ephpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromFilterWhitelistToCoverage.phpdU%5Zphpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromRootToCoverage.phpd"O\phpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistDirectoriesToCoverage.phpd†踤Yphpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistExcludesToCoverage.phpdsphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute.phpd yhphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutTodoAnnotatedTestsAttribute.phpmdmXphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheResultFileAttribute.php=d=ۨǤTphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheTokensAttribute.php1d1T9`phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveConversionToExceptionsAttributes.php d fphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementCacheDirectoryAttribute.phpdmphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementProcessUncoveredFilesAttribute.phpd[ Kphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveEmptyFilter.php{d{KIphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveListeners.php'd'nHphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLogTypes.phpodo3Ophpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLoggingElements.php)d).Vphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveNoInteractionAttribute.php7d7⼿Qphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemovePrinterAttributes.phpd}Tphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestDoxGroupsElement.php6d6DYphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestSuiteLoaderAttributes.phpdsUPphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveVerboseAttribute.php%d%J_phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBackupStaticAttributesAttribute.php$d$CȤfphpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBeStrictAboutCoversAnnotationAttribute.phpNdNb^phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameForceCoversAnnotationAttribute.php"d" Nphpunit/TextUI/Configuration/Xml/Migration/Migrations/UpdateSchemaLocation.phpd 7phpunit/TextUI/Configuration/Xml/Migration/Migrator.phpdd=,phpunit/TextUI/Configuration/Xml/PHPUnit.php?5d?5G=[4phpunit/TextUI/Configuration/Xml/TestSuiteMapper.phpdy&phpunit/TextUI/Exception/Exception.phpdD{i=phpunit/TextUI/Exception/ExtensionsNotConfiguredException.phpd3f.0phpunit/TextUI/Exception/ReflectionException.phpdJuv-phpunit/TextUI/Exception/RuntimeException.phpd ;phpunit/TextUI/Exception/TestDirectoryNotFoundException.phpdnL6phpunit/TextUI/Exception/TestFileNotFoundException.phpd?lphpunit/TextUI/Help.php1/d1/[PAphpunit/TextUI/Output/Default/ProgressPrinter/ProgressPrinter.phpa#da#$cphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/BeforeTestClassMethodErroredSubscriber.phpFdFC8%Gphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/Subscriber.php;d;Ȥ^phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpWarningSubscriber.phpdafphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.phpAdAsbphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredPhpunitWarningSubscriber.php)d).E[phpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/TestTriggeredWarningSubscriber.phpdʹ/phpunit/TextUI/Output/Default/ResultPrinter.php>d>60 phpunit/TextUI/Output/Facade.phpdXk0phpunit/TextUI/Output/Printer/DefaultPrinter.php -d -Dݹr-phpunit/TextUI/Output/Printer/NullPrinter.php4d4F /)phpunit/TextUI/Output/Printer/Printer.phpdG(phpunit/TextUI/Output/SummaryPrinter.phpjdj /phpunit/TextUI/Output/TestDox/ResultPrinter.php($d($zD*phpunit/TextUI/ShellExitCodeCalculator.phpdL̤phpunit/TextUI/TestRunner.phpd:+phpunit/TextUI/TestSuiteFilterProcessor.phpdjphpunit/Util/Cloner.phpdU+phpunit/Util/Color.php4d4K.phpunit/Util/ErrorHandler.phpdn!'9phpunit/Util/Exception/DirectoryDoesNotExistException.phpd=$phpunit/Util/Exception/Exception.phpd94phpunit/Util/Exception/InvalidDirectoryException.phpdN/phpunit/Util/Exception/InvalidJsonException.phpd)s1phpunit/Util/Exception/InvalidSocketException.phpddf:phpunit/Util/Exception/InvalidVersionOperatorException.phpdw?phpunit/Util/Exception/NoTestCaseObjectOnCallStackException.phpxdxi.phpunit/Util/Exception/PhpProcessException.phpdXt-'phpunit/Util/Exception/XmlException.phpd;phpunit/Util/ExcludeList.phpdVӓphpunit/Util/Filesystem.phppdpssphpunit/Util/Filter.php d #8Фphpunit/Util/GlobalState.phpidi{wphpunit/Util/Json.php -d -'phpunit/Util/PHP/AbstractPhpProcess.php !d !&phpunit/Util/PHP/DefaultPhpProcess.phpd+phpunit/Util/PHP/Template/TestCaseClass.tpl d .S,phpunit/Util/PHP/Template/TestCaseMethod.tpl d 2.Ť*phpunit/Util/PHP/Template/PhptTestCase.tpld`J&phpunit/Util/PHP/WindowsPhpProcess.phpdSphpunit/Util/Reflection.php3d3gMYphpunit/Util/Test.phpd߉(phpunit/Util/ThrowableToStringMapper.phpdS *phpunit/Util/VersionComparisonOperator.php3d3:Uphpunit/Util/Xml.phpd.phpunit/Util/Xml/Exception.phpdӤ0phpunit/Util/Xml/FailedSchemaDetectionResult.phpd#Sphpunit/Util/Xml/Loader.php d JC*phpunit/Util/Xml/SchemaDetectionResult.phpd38u#phpunit/Util/Xml/SchemaDetector.php7d7 ^}!phpunit/Util/Xml/SchemaFinder.phpd)%phpunit/Util/Xml/SnapshotNodeList.phpXdXm)sebastian-comparator/ObjectComparator.php -d -rXƤ+sebastian-comparator/ResourceComparator.phpIdIN')sebastian-comparator/ScalarComparator.php d D~&3sebastian-comparator/SplObjectStorageComparator.phpd'sebastian-comparator/TypeComparator.phpd-sebastian-comparator/exceptions/Exception.phpvdvEᵤ4sebastian-comparator/exceptions/RuntimeException.phpdV'#sebastian-complexity/Calculator.php d hg.sebastian-complexity/Complexity/Complexity.phpd'8sebastian-complexity/Complexity/ComplexityCollection.phpd2@sebastian-complexity/Complexity/ComplexityCollectionIterator.phpd=+ma,sebastian-complexity/Exception/Exception.phpvdv73sebastian-complexity/Exception/RuntimeException.phpdCdWsebastian-complexity/LICENSEdP@٤=sebastian-complexity/Visitor/ComplexityCalculatingVisitor.php d ڤGsebastian-complexity/Visitor/CyclomaticComplexityCalculatingVisitor.phpdx!esebastian-diff/Chunk.phpdsebastian-diff/Diff.php`d`&sebastian-diff/Differ.phpdה3sebastian-diff/Exception/ConfigurationException.php!d!&sebastian-diff/Exception/Exception.phpjdj05sebastian-diff/Exception/InvalidArgumentException.phpdqsebastian-diff/LICENSEdTsebastian-diff/Line.phpdǺ5sebastian-diff/LongestCommonSubsequenceCalculator.phpd}e7zDsebastian-diff/MemoryEfficientLongestCommonSubsequenceCalculator.phpdåf14sebastian-diff/Output/AbstractChunkOutputBuilder.phpds/sebastian-diff/Output/DiffOnlyOutputBuilder.phpydy"4sebastian-diff/Output/DiffOutputBuilderInterface.phpdV8sebastian-diff/Output/StrictUnifiedDiffOutputBuilder.phpU(dU(ߢ"2sebastian-diff/Output/UnifiedDiffOutputBuilder.phpdɅ|sebastian-diff/Parser.php\ d\ S1pBsebastian-diff/TimeEfficientLongestCommonSubsequenceCalculator.phpd5,!sebastian-environment/Console.phpdP1Ťsebastian-environment/LICENSEdWj!sebastian-environment/Runtime.php)d)@sebastian-exporter/Exporter.php#d#~ksebastian-exporter/LICENSEdT'sebastian-global-state/CodeExporter.phph dh :}&sebastian-global-state/ExcludeList.php d :$sebastian-global-state/LICENSEd$#sebastian-global-state/Restorer.php d 0|#sebastian-global-state/Snapshot.php,'d,' /sebastian-global-state/exceptions/Exception.phpydyJ6sebastian-global-state/exceptions/RuntimeException.phpd;#sebastian-lines-of-code/Counter.php d d/sebastian-lines-of-code/Exception/Exception.phpzdz aV>sebastian-lines-of-code/Exception/IllogicalValuesException.phpdG<sebastian-lines-of-code/Exception/NegativeValueException.phpd -ڤ6sebastian-lines-of-code/Exception/RuntimeException.phpdKsebastian-lines-of-code/LICENSEdP@٤/sebastian-lines-of-code/LineCountingVisitor.phpzdzV:p'sebastian-lines-of-code/LinesOfCode.php d *sebastian-object-enumerator/Enumerator.phpd_.sebastian-object-reflector/ObjectReflector.phpd9m 'sebastian-recursion-context/Context.phpd!#sebastian-recursion-context/LICENSEdTsebastian-type/LICENSEd sebastian-type/Parameter.phpd~]#sebastian-type/ReflectionMapper.phpd 8sebastian-type/TypeName.phpdh&sebastian-type/exception/Exception.phpjdjbᮧ-sebastian-type/exception/RuntimeException.phpd%$sebastian-type/type/CallableType.phpdĊP!sebastian-type/type/FalseType.phpbdb_&)sebastian-type/type/GenericObjectType.php d c(sebastian-type/type/IntersectionType.php -d -¤$sebastian-type/type/IterableType.phpd3դ!sebastian-type/type/MixedType.php'd'o!sebastian-type/type/NeverType.phpdFҹ sebastian-type/type/NullType.php"d"9$F"sebastian-type/type/ObjectType.php%d%"sebastian-type/type/SimpleType.php,d,0"sebastian-type/type/StaticType.phpd", sebastian-type/type/TrueType.php]d]<iפsebastian-type/type/Type.phpdR!sebastian-type/type/UnionType.php* d* AA#sebastian-type/type/UnknownType.phpdǤ sebastian-type/type/VoidType.phpdsebastian-version/LICENSEdVosebastian-version/Version.phpd.7theseer-tokenizer/Exception.phpndn'Ǥtheseer-tokenizer/LICENSEdR ("theseer-tokenizer/NamespaceUri.phpHdH=C+theseer-tokenizer/NamespaceUriException.phpydy'Hetheseer-tokenizer/Token.phpd4%theseer-tokenizer/TokenCollection.php -d -a.theseer-tokenizer/TokenCollectionException.php|d|`g-theseer-tokenizer/Tokenizer.php -d -zl#theseer-tokenizer/XMLSerializer.phpdg; .phpstorm.meta.phpdOphpunit/phpunit: 10.0.16 +phpunit-10.5.8.phar composer.lockqeq2v manifest.txtetW'myclabs-deep-copy/DeepCopy/DeepCopy.phpeLä7myclabs-deep-copy/DeepCopy/Exception/CloneException.phpe {ˤ:myclabs-deep-copy/DeepCopy/Exception/PropertyException.phpe3Gz5myclabs-deep-copy/DeepCopy/Filter/ChainableFilter.phpeTE Gmyclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php +e +DgLmyclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.phpe)$Bmyclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.phpe),myclabs-deep-copy/DeepCopy/Filter/Filter.phpdedM0myclabs-deep-copy/DeepCopy/Filter/KeepFilter.phpeYn3myclabs-deep-copy/DeepCopy/Filter/ReplaceFilter.phpe3myclabs-deep-copy/DeepCopy/Filter/SetNullFilter.phpe䊉Dmyclabs-deep-copy/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.phpepr.myclabs-deep-copy/DeepCopy/Matcher/Matcher.phpe6myclabs-deep-copy/DeepCopy/Matcher/PropertyMatcher.phpe=Bv:myclabs-deep-copy/DeepCopy/Matcher/PropertyNameMatcher.phpeR:myclabs-deep-copy/DeepCopy/Matcher/PropertyTypeMatcher.php2e2ZQͤ:myclabs-deep-copy/DeepCopy/Reflection/ReflectionHelper.php5e5ىAmyclabs-deep-copy/DeepCopy/TypeFilter/Date/DateIntervalFilter.phpeƤ7myclabs-deep-copy/DeepCopy/TypeFilter/ReplaceFilter.phpez;myclabs-deep-copy/DeepCopy/TypeFilter/ShallowCopyFilter.phpeؤ?myclabs-deep-copy/DeepCopy/TypeFilter/Spl/ArrayObjectFilter.phpe^Amyclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.phpev|Gmyclabs-deep-copy/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.phpeT+4myclabs-deep-copy/DeepCopy/TypeFilter/TypeFilter.phpeVD6myclabs-deep-copy/DeepCopy/TypeMatcher/TypeMatcher.phpeQBŤ(myclabs-deep-copy/DeepCopy/deep_copy.phperxmyclabs-deep-copy/LICENSE5e5ʭ˄nikic-php-parser/LICENSEe*&nikic-php-parser/PhpParser/Builder.phpe61nikic-php-parser/PhpParser/Builder/ClassConst.phpei a-nikic-php-parser/PhpParser/Builder/Class_.phpReR.ٜΤ2nikic-php-parser/PhpParser/Builder/Declaration.phpe ]/nikic-php-parser/PhpParser/Builder/EnumCase.phpe@E,nikic-php-parser/PhpParser/Builder/Enum_.php e y3nikic-php-parser/PhpParser/Builder/FunctionLike.php.e.0nikic-php-parser/PhpParser/Builder/Function_.phpxex V1nikic-php-parser/PhpParser/Builder/Interface_.phpS +eS +]-nikic-php-parser/PhpParser/Builder/Method.phpeQ]1nikic-php-parser/PhpParser/Builder/Namespace_.phpbeb#㽃,nikic-php-parser/PhpParser/Builder/Param.php+e+ŵyˤ/nikic-php-parser/PhpParser/Builder/Property.phpe+Ҥ/nikic-php-parser/PhpParser/Builder/TraitUse.phpeo9nikic-php-parser/PhpParser/Builder/TraitUseAdaptation.phpeu1-nikic-php-parser/PhpParser/Builder/Trait_.php# e# QDK+nikic-php-parser/PhpParser/Builder/Use_.phpeڙ)-nikic-php-parser/PhpParser/BuilderFactory.php(e(v9-nikic-php-parser/PhpParser/BuilderHelpers.php$e$m&nikic-php-parser/PhpParser/Comment.phpeӥ?w*nikic-php-parser/PhpParser/Comment/Doc.phpxexp;nikic-php-parser/PhpParser/ConstExprEvaluationException.phpyey('1nikic-php-parser/PhpParser/ConstExprEvaluator.php &e &;n$nikic-php-parser/PhpParser/Error.phpeb+nikic-php-parser/PhpParser/ErrorHandler.php6e6ȓ6nikic-php-parser/PhpParser/ErrorHandler/Collecting.phpe-94nikic-php-parser/PhpParser/ErrorHandler/Throwing.phpeT`0nikic-php-parser/PhpParser/Internal/DiffElem.phpe@.nikic-php-parser/PhpParser/Internal/Differ.phpeW=Anikic-php-parser/PhpParser/Internal/PrintableNewAnonClassNode.php] +e] +fѤ5nikic-php-parser/PhpParser/Internal/TokenPolyfill.php$e$㸫_3nikic-php-parser/PhpParser/Internal/TokenStream.php!e!**nikic-php-parser/PhpParser/JsonDecoder.php e _*?$nikic-php-parser/PhpParser/Lexer.php.e.1.nikic-php-parser/PhpParser/Lexer/Emulative.phpK eK LDnikic-php-parser/PhpParser/Lexer/TokenEmulator/AttributeEmulator.phpeUP&Dnikic-php-parser/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.phpet Hnikic-php-parser/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.phpeK`Bnikic-php-parser/PhpParser/Lexer/TokenEmulator/KeywordEmulator.phpeN֤Enikic-php-parser/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.phpe\Hnikic-php-parser/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php/e/3Pnikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.phpey}Hnikic-php-parser/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php`e`oBnikic-php-parser/PhpParser/Lexer/TokenEmulator/ReverseEmulator.phpeb@nikic-php-parser/PhpParser/Lexer/TokenEmulator/TokenEmulator.phpPeP?*(nikic-php-parser/PhpParser/Modifiers.phpe~*nikic-php-parser/PhpParser/NameContext.php~&e~&"Aդ#nikic-php-parser/PhpParser/Node.phpe]'nikic-php-parser/PhpParser/Node/Arg.phpe{3-nikic-php-parser/PhpParser/Node/ArrayItem.phpeU -nikic-php-parser/PhpParser/Node/Attribute.phpVeV|)2nikic-php-parser/PhpParser/Node/AttributeGroup.phpeYh.nikic-php-parser/PhpParser/Node/ClosureUse.phpe^ s/nikic-php-parser/PhpParser/Node/ComplexType.phpSeS(*nikic-php-parser/PhpParser/Node/Const_.phpeD/nikic-php-parser/PhpParser/Node/DeclareItem.phpe.5(nikic-php-parser/PhpParser/Node/Expr.phpeh傤6nikic-php-parser/PhpParser/Node/Expr/ArrayDimFetch.phpQeQ 2nikic-php-parser/PhpParser/Node/Expr/ArrayItem.php\e\%դ/nikic-php-parser/PhpParser/Node/Expr/Array_.phphehf6nikic-php-parser/PhpParser/Node/Expr/ArrowFunction.php4 +e4 +T@G/nikic-php-parser/PhpParser/Node/Expr/Assign.php!e!d1nikic-php-parser/PhpParser/Node/Expr/AssignOp.phpek;V<nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseAnd.phpeu;nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseOr.phpe;<nikic-php-parser/PhpParser/Node/Expr/AssignOp/BitwiseXor.phpelϚ:nikic-php-parser/PhpParser/Node/Expr/AssignOp/Coalesce.phpeq,8nikic-php-parser/PhpParser/Node/Expr/AssignOp/Concat.phpe5nikic-php-parser/PhpParser/Node/Expr/AssignOp/Div.phpeYP +7nikic-php-parser/PhpParser/Node/Expr/AssignOp/Minus.phpe隤5nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mod.phpe]10Y5nikic-php-parser/PhpParser/Node/Expr/AssignOp/Mul.phpeπ/6nikic-php-parser/PhpParser/Node/Expr/AssignOp/Plus.phpe&|5nikic-php-parser/PhpParser/Node/Expr/AssignOp/Pow.phpeyV;nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftLeft.phpe<nikic-php-parser/PhpParser/Node/Expr/AssignOp/ShiftRight.phpes*2nikic-php-parser/PhpParser/Node/Expr/AssignRef.phpReRB1nikic-php-parser/PhpParser/Node/Expr/BinaryOp.php^e^~[<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.phpPeP6L6;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseOr.phpNeN_|<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BitwiseXor.phpPeP~Ƥ<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanAnd.phpQeQ5v;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/BooleanOr.phpOeOeӸ:nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Coalesce.phpMeMY 8nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Concat.phpHeH @q5nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Div.phpBeBi7nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Equal.phpGeGݙʤ9nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Greater.phpJeJ4ͤ@nikic-php-parser/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.phpYeY^ز;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Identical.phpPeP"<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalAnd.phpReRi;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalOr.phpOeO@<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/LogicalXor.phpReR4e7nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Minus.phpFeF$Lˤ5nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mod.phpBeBʤ5nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Mul.phpBeB|:nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotEqual.phpMeM>nikic-php-parser/PhpParser/Node/Expr/BinaryOp/NotIdentical.phpVeVh< +6nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Plus.phpDeD' ,5nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Pow.phpCeC;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftLeft.phpOeOQ#<nikic-php-parser/PhpParser/Node/Expr/BinaryOp/ShiftRight.phpQeQǤ9nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Smaller.phpJeJf@nikic-php-parser/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.phpYeY⍤;nikic-php-parser/PhpParser/Node/Expr/BinaryOp/Spaceship.phpPePHƉ.3nikic-php-parser/PhpParser/Node/Expr/BitwiseNot.phpek3nikic-php-parser/PhpParser/Node/Expr/BooleanNot.phpe-ڷ1nikic-php-parser/PhpParser/Node/Expr/CallLike.phpecH-nikic-php-parser/PhpParser/Node/Expr/Cast.phpNeNb4nikic-php-parser/PhpParser/Node/Expr/Cast/Array_.phpeI|3nikic-php-parser/PhpParser/Node/Expr/Cast/Bool_.phpe V]S4nikic-php-parser/PhpParser/Node/Expr/Cast/Double.phpeEfG2nikic-php-parser/PhpParser/Node/Expr/Cast/Int_.phpec5nikic-php-parser/PhpParser/Node/Expr/Cast/Object_.phpe5nikic-php-parser/PhpParser/Node/Expr/Cast/String_.phpe4nikic-php-parser/PhpParser/Node/Expr/Cast/Unset_.phpe1Ӥ8nikic-php-parser/PhpParser/Node/Expr/ClassConstFetch.php e UH/nikic-php-parser/PhpParser/Node/Expr/Clone_.phpe0nikic-php-parser/PhpParser/Node/Expr/Closure.php\ e\ .3nikic-php-parser/PhpParser/Node/Expr/ClosureUse.php]e].Eʮ3nikic-php-parser/PhpParser/Node/Expr/ConstFetch.phpeFe0դ/nikic-php-parser/PhpParser/Node/Expr/Empty_.phpeb.nikic-php-parser/PhpParser/Node/Expr/Error.phpe&6nikic-php-parser/PhpParser/Node/Expr/ErrorSuppress.phpeJ.nikic-php-parser/PhpParser/Node/Expr/Eval_.phpe..nikic-php-parser/PhpParser/Node/Expr/Exit_.phpe(vT1nikic-php-parser/PhpParser/Node/Expr/FuncCall.php e KÑ1nikic-php-parser/PhpParser/Node/Expr/Include_.phpe 4nikic-php-parser/PhpParser/Node/Expr/Instanceof_.phpe9/nikic-php-parser/PhpParser/Node/Expr/Isset_.phpe==s.nikic-php-parser/PhpParser/Node/Expr/List_.phpe+/nikic-php-parser/PhpParser/Node/Expr/Match_.php1e1 D3nikic-php-parser/PhpParser/Node/Expr/MethodCall.php<e<A-nikic-php-parser/PhpParser/Node/Expr/New_.phpeۤ;nikic-php-parser/PhpParser/Node/Expr/NullsafeMethodCall.phpSeS?Y>nikic-php-parser/PhpParser/Node/Expr/NullsafePropertyFetch.phpe0nikic-php-parser/PhpParser/Node/Expr/PostDec.phpe"J;0nikic-php-parser/PhpParser/Node/Expr/PostInc.phpeN /nikic-php-parser/PhpParser/Node/Expr/PreDec.phpe( i/nikic-php-parser/PhpParser/Node/Expr/PreInc.phpe֤/nikic-php-parser/PhpParser/Node/Expr/Print_.phpeC6nikic-php-parser/PhpParser/Node/Expr/PropertyFetch.phpe.2nikic-php-parser/PhpParser/Node/Expr/ShellExec.php>e>ц3nikic-php-parser/PhpParser/Node/Expr/StaticCall.phpGeGRZmr<nikic-php-parser/PhpParser/Node/Expr/StaticPropertyFetch.php)e)}P0nikic-php-parser/PhpParser/Node/Expr/Ternary.phpexڟ/nikic-php-parser/PhpParser/Node/Expr/Throw_.phpe3nikic-php-parser/PhpParser/Node/Expr/UnaryMinus.phpe&2nikic-php-parser/PhpParser/Node/Expr/UnaryPlus.phpeP1nikic-php-parser/PhpParser/Node/Expr/Variable.phpecޤ2nikic-php-parser/PhpParser/Node/Expr/YieldFrom.phpe>Q/nikic-php-parser/PhpParser/Node/Expr/Yield_.phpiei㬤0nikic-php-parser/PhpParser/Node/FunctionLike.phpeS.nikic-php-parser/PhpParser/Node/Identifier.php&e&km:nikic-php-parser/PhpParser/Node/InterpolatedStringPart.phpmem^#4nikic-php-parser/PhpParser/Node/IntersectionType.phpeL,nikic-php-parser/PhpParser/Node/MatchArm.phpe=[(nikic-php-parser/PhpParser/Node/Name.php e YӴ7nikic-php-parser/PhpParser/Node/Name/FullyQualified.phpe 1nikic-php-parser/PhpParser/Node/Name/Relative.phpeǛEf0nikic-php-parser/PhpParser/Node/NullableType.phpe4%)nikic-php-parser/PhpParser/Node/Param.phpD +eD +0nikic-php-parser/PhpParser/Node/PropertyItem.phpSeSE *nikic-php-parser/PhpParser/Node/Scalar.phpkek,ߤ2nikic-php-parser/PhpParser/Node/Scalar/DNumber.phpVeV73nikic-php-parser/PhpParser/Node/Scalar/Encapsed.phpbeb"=nikic-php-parser/PhpParser/Node/Scalar/EncapsedStringPart.phpiei)r1nikic-php-parser/PhpParser/Node/Scalar/Float_.php[e[)M(/nikic-php-parser/PhpParser/Node/Scalar/Int_.php e =nikic-php-parser/PhpParser/Node/Scalar/InterpolatedString.phpeK#2nikic-php-parser/PhpParser/Node/Scalar/LNumber.phpTeT35nikic-php-parser/PhpParser/Node/Scalar/MagicConst.phprer}<nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Class_.phpTeT㨘X9nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Dir.phpMeMal:nikic-php-parser/PhpParser/Node/Scalar/MagicConst/File.phpPeP#?nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Function_.php]e]HnY:nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Line.phpPePM4<nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Method.phpVeVΤ@nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Namespace_.php`e`><nikic-php-parser/PhpParser/Node/Scalar/MagicConst/Trait_.phpTeTd2nikic-php-parser/PhpParser/Node/Scalar/String_.phpe-nikic-php-parser/PhpParser/Node/StaticVar.phpe 1(nikic-php-parser/PhpParser/Node/Stmt.phpev2/.nikic-php-parser/PhpParser/Node/Stmt/Block.phpe/nikic-php-parser/PhpParser/Node/Stmt/Break_.phpe(⤌.nikic-php-parser/PhpParser/Node/Stmt/Case_.phpez/nikic-php-parser/PhpParser/Node/Stmt/Catch_.phpoeo綳3nikic-php-parser/PhpParser/Node/Stmt/ClassConst.phpMeM֤2nikic-php-parser/PhpParser/Node/Stmt/ClassLike.php e BF4nikic-php-parser/PhpParser/Node/Stmt/ClassMethod.phpes됤/nikic-php-parser/PhpParser/Node/Stmt/Class_.php e *[/nikic-php-parser/PhpParser/Node/Stmt/Const_.phpe]l2nikic-php-parser/PhpParser/Node/Stmt/Continue_.phpeϋKɤ7nikic-php-parser/PhpParser/Node/Stmt/DeclareDeclare.php^e^T_1nikic-php-parser/PhpParser/Node/Stmt/Declare_.phpei>,nikic-php-parser/PhpParser/Node/Stmt/Do_.phpNeN".nikic-php-parser/PhpParser/Node/Stmt/Echo_.phpeh=0nikic-php-parser/PhpParser/Node/Stmt/ElseIf_.phpUeU_դ.nikic-php-parser/PhpParser/Node/Stmt/Else_.phper1nikic-php-parser/PhpParser/Node/Stmt/EnumCase.phpe]Ɇ.nikic-php-parser/PhpParser/Node/Stmt/Enum_.phpDeD%U3nikic-php-parser/PhpParser/Node/Stmt/Expression.phpe-`U1nikic-php-parser/PhpParser/Node/Stmt/Finally_.phpef f-nikic-php-parser/PhpParser/Node/Stmt/For_.phpe`ߤ1nikic-php-parser/PhpParser/Node/Stmt/Foreach_.phpea2nikic-php-parser/PhpParser/Node/Stmt/Function_.php +e +VŤ0nikic-php-parser/PhpParser/Node/Stmt/Global_.phpe~.nikic-php-parser/PhpParser/Node/Stmt/Goto_.phpe l<1nikic-php-parser/PhpParser/Node/Stmt/GroupUse.phpPeP#5nikic-php-parser/PhpParser/Node/Stmt/HaltCompiler.phpeĬ,nikic-php-parser/PhpParser/Node/Stmt/If_.phpe~3nikic-php-parser/PhpParser/Node/Stmt/InlineHTML.phpeݤ3nikic-php-parser/PhpParser/Node/Stmt/Interface_.phpHeH.nikic-php-parser/PhpParser/Node/Stmt/Label.phpe떤3nikic-php-parser/PhpParser/Node/Stmt/Namespace_.phpenikic-php-parser/PhpParser/NodeVisitor/FirstFindingVisitor.phpek7nikic-php-parser/PhpParser/NodeVisitor/NameResolver.php&e&[r@nikic-php-parser/PhpParser/NodeVisitor/NodeConnectingVisitor.phpe)ߤBnikic-php-parser/PhpParser/NodeVisitor/ParentConnectingVisitor.php{e{52nikic-php-parser/PhpParser/NodeVisitorAbstract.phpeU _%nikic-php-parser/PhpParser/Parser.phpe.*nikic-php-parser/PhpParser/Parser/Php7.phpeIeeIؤ*nikic-php-parser/PhpParser/Parser/Php8.phpKeK0-nikic-php-parser/PhpParser/ParserAbstract.phpe"ƒv,nikic-php-parser/PhpParser/ParserFactory.phpe3)nikic-php-parser/PhpParser/PhpVersion.phpeR,nikic-php-parser/PhpParser/PrettyPrinter.phpe3W+5nikic-php-parser/PhpParser/PrettyPrinter/Standard.phpe`c{4nikic-php-parser/PhpParser/PrettyPrinterAbstract.phpe,dȤ$nikic-php-parser/PhpParser/Token.phpeK[3nikic-php-parser/PhpParser/compatibility_tokens.phpieiMiѤobject-enumerator/LICENSEefobject-reflector/LICENSEeR6phar-io-manifest/LICENSE`e`p+phar-io-manifest/ManifestDocumentMapper.phpe:#phar-io-manifest/ManifestLoader.phpe.-a'phar-io-manifest/ManifestSerializer.phperp:phar-io-manifest/exceptions/ElementCollectionException.phpe I)phar-io-manifest/exceptions/Exception.phpe?phar-io-manifest/exceptions/InvalidApplicationNameException.phpe:@>5phar-io-manifest/exceptions/InvalidEmailException.phpe<3phar-io-manifest/exceptions/InvalidUrlException.phpe 9phar-io-manifest/exceptions/ManifestDocumentException.phpe!P4@phar-io-manifest/exceptions/ManifestDocumentLoadingException.phpHeHǃ?phar-io-manifest/exceptions/ManifestDocumentMapperException.phpe:9z8phar-io-manifest/exceptions/ManifestElementException.phpeA47phar-io-manifest/exceptions/ManifestLoaderException.phpeD>'phar-io-manifest/values/Application.phpeI$ۤ+phar-io-manifest/values/ApplicationName.php;e;D"phar-io-manifest/values/Author.phpeF,phar-io-manifest/values/AuthorCollection.phpeo4phar-io-manifest/values/AuthorCollectionIterator.php3e3џ,phar-io-manifest/values/BundledComponent.php@e@DP`6phar-io-manifest/values/BundledComponentCollection.php e ¾W6>phar-io-manifest/values/BundledComponentCollectionIterator.phpeVh0phar-io-manifest/values/CopyrightInformation.phpPeP ai!phar-io-manifest/values/Email.phpNeNZ&%phar-io-manifest/values/Extension.phpeq}#phar-io-manifest/values/Library.phpeO#phar-io-manifest/values/License.phpe&!o$phar-io-manifest/values/Manifest.php +e +=La3phar-io-manifest/values/PhpExtensionRequirement.phpe11phar-io-manifest/values/PhpVersionRequirement.phpem?'phar-io-manifest/values/Requirement.phped1phar-io-manifest/values/RequirementCollection.phpeP9phar-io-manifest/values/RequirementCollectionIterator.phpjejܭ: phar-io-manifest/values/Type.phpe=%phar-io-manifest/values/Url.phpe͚&phar-io-manifest/xml/AuthorElement.phprer<0phar-io-manifest/xml/AuthorElementCollection.php,e,-'phar-io-manifest/xml/BundlesElement.phpSeSWN>)phar-io-manifest/xml/ComponentElement.phpyeyݤ3phar-io-manifest/xml/ComponentElementCollection.php5e5(\(phar-io-manifest/xml/ContainsElement.phpnenf)phar-io-manifest/xml/CopyrightElement.phpe7*phar-io-manifest/xml/ElementCollection.phpe@ #phar-io-manifest/xml/ExtElement.php e y>-phar-io-manifest/xml/ExtElementCollection.php#e#E)phar-io-manifest/xml/ExtensionElement.php}e}0'phar-io-manifest/xml/LicenseElement.phpoeo%:')phar-io-manifest/xml/ManifestDocument.php + e + 4(phar-io-manifest/xml/ManifestElement.php4e4#phar-io-manifest/xml/PhpElement.phpeB:5(phar-io-manifest/xml/RequiresElement.php$e$>!phar-io-version/BuildMetaData.phpephar-io-version/LICENSE&e&Ҫ $phar-io-version/PreReleaseSuffix.phpe:phar-io-version/Version.phpeu#+phar-io-version/VersionConstraintParser.phpT eT Ф*phar-io-version/VersionConstraintValue.phpH +eH +F{~4!phar-io-version/VersionNumber.phpeO19phar-io-version/constraints/AbstractVersionConstraint.phpexB9phar-io-version/constraints/AndVersionConstraintGroup.phpeY4phar-io-version/constraints/AnyVersionConstraint.phpReR #6phar-io-version/constraints/ExactVersionConstraint.phpe!Ephar-io-version/constraints/GreaterThanOrEqualToVersionConstraint.phpeVU8phar-io-version/constraints/OrVersionConstraintGroup.phpeM%Fphar-io-version/constraints/SpecificMajorAndMinorVersionConstraint.phpeɍ>phar-io-version/constraints/SpecificMajorVersionConstraint.phpe`9q:1phar-io-version/constraints/VersionConstraint.phpeeDq(phar-io-version/exceptions/Exception.phpe$eb?phar-io-version/exceptions/InvalidPreReleaseSuffixException.phpeҵ6phar-io-version/exceptions/InvalidVersionException.phpe4/S7phar-io-version/exceptions/NoBuildMetaDataException.phpe]:phar-io-version/exceptions/NoPreReleaseSuffixException.phpeT4Dphar-io-version/exceptions/UnsupportedVersionConstraintException.phpe9"php-code-coverage/CodeCoverage.phpAeAc4php-code-coverage/Data/ProcessedCodeCoverageData.php\'e\'.php-code-coverage/Data/RawCodeCoverageData.php#e#&#php-code-coverage/Driver/Driver.php e cհ'php-code-coverage/Driver/PcovDriver.phpe=%php-code-coverage/Driver/Selector.php1e15)php-code-coverage/Driver/XdebugDriver.php e …3jJphp-code-coverage/Exception/BranchAndPathCoverageNotSupportedException.phpe77Fphp-code-coverage/Exception/DeadCodeDetectionNotSupportedException.phpeCphp-code-coverage/Exception/DirectoryCouldNotBeCreatedException.phpe)php-code-coverage/Exception/Exception.php}e}z>php-code-coverage/Exception/FileCouldNotBeWrittenException.phper8php-code-coverage/Exception/InvalidArgumentException.phpeK.nFphp-code-coverage/Exception/NoCodeCoverageDriverAvailableException.php/e/6R]php-code-coverage/Exception/NoCodeCoverageDriverWithPathCoverageSupportAvailableException.phpaea"A/php-code-coverage/Exception/ParserException.phpe,/Dphp-code-coverage/Exception/PathExistsButIsNotDirectoryException.phpe.29php-code-coverage/Exception/PcovNotAvailableException.phpaeaj3php-code-coverage/Exception/ReflectionException.phpek)?php-code-coverage/Exception/ReportAlreadyFinalizedException.php:e:d%6Iphp-code-coverage/Exception/StaticAnalysisCacheNotConfiguredException.phpe}6php-code-coverage/Exception/TestIdMissingException.phpe +Cphp-code-coverage/Exception/UnintentionallyCoveredCodeException.phpe}=php-code-coverage/Exception/WriteOperationFailedException.phpe(e;php-code-coverage/Exception/XdebugNotAvailableException.phpeeeNG9php-code-coverage/Exception/XdebugNotEnabledException.phpxex@_;,php-code-coverage/Exception/XmlException.phpeWܤphp-code-coverage/Filter.phpc ec Z,php-code-coverage/LICENSEe-~y֤'php-code-coverage/Node/AbstractNode.php5e5Ğ"php-code-coverage/Node/Builder.phpOeOi$php-code-coverage/Node/CrapIndex.phpe8\$php-code-coverage/Node/Directory.phpF$eF$äphp-code-coverage/Node/File.php[We[WL¤#php-code-coverage/Node/Iterator.phpxex8A)#php-code-coverage/Report/Clover.php6(e6(&php-code-coverage/Report/Cobertura.php?1e?1W0#php-code-coverage/Report/Crap4j.php)e)wҤ(php-code-coverage/Report/Html/Colors.phpeX`/php-code-coverage/Report/Html/CustomCssFile.php6e6"2bS(php-code-coverage/Report/Html/Facade.phpe&'*php-code-coverage/Report/Html/Renderer.php e G4php-code-coverage/Report/Html/Renderer/Dashboard.php!e!/Ѥ4php-code-coverage/Report/Html/Renderer/Directory.php5e5V/g/php-code-coverage/Report/Html/Renderer/File.php܊e܊kBphp-code-coverage/Report/Html/Renderer/Template/branches.html.disteh2+Fphp-code-coverage/Report/Html/Renderer/Template/coverage_bar.html.dist'e'O}Mphp-code-coverage/Report/Html/Renderer/Template/coverage_bar_branch.html.dist'e'O}Ephp-code-coverage/Report/Html/Renderer/Template/css/bootstrap.min.cssyeyĤ>php-code-coverage/Report/Html/Renderer/Template/css/custom.csseAphp-code-coverage/Report/Html/Renderer/Template/css/nv.d3.min.cssX%eX%0,@php-code-coverage/Report/Html/Renderer/Template/css/octicons.cssXeX'#=php-code-coverage/Report/Html/Renderer/Template/css/style.cssH +eH +BѺCphp-code-coverage/Report/Html/Renderer/Template/dashboard.html.disteDJphp-code-coverage/Report/Html/Renderer/Template/dashboard_branch.html.disteDCphp-code-coverage/Report/Html/Renderer/Template/directory.html.disteՆJphp-code-coverage/Report/Html/Renderer/Template/directory_branch.html.disten2]Hphp-code-coverage/Report/Html/Renderer/Template/directory_item.html.distAeAdsOphp-code-coverage/Report/Html/Renderer/Template/directory_item_branch.html.dist;e;mۤ>php-code-coverage/Report/Html/Renderer/Template/file.html.distP eP j*Ephp-code-coverage/Report/Html/Renderer/Template/file_branch.html.dist e ㉞Cphp-code-coverage/Report/Html/Renderer/Template/file_item.html.distrer/yJphp-code-coverage/Report/Html/Renderer/Template/file_item_branch.html.distlel-Cphp-code-coverage/Report/Html/Renderer/Template/icons/file-code.svg0e0QUUHphp-code-coverage/Report/Html/Renderer/Template/icons/file-directory.svgeZCphp-code-coverage/Report/Html/Renderer/Template/js/bootstrap.min.jscec"#<php-code-coverage/Report/Html/Renderer/Template/js/d3.min.jsPePhb:php-code-coverage/Report/Html/Renderer/Template/js/file.jseb䆤@php-code-coverage/Report/Html/Renderer/Template/js/jquery.min.js@^e@^ ?php-code-coverage/Report/Html/Renderer/Template/js/nv.d3.min.jsReRphp-code-coverage/Report/Html/Renderer/Template/line.html.diste{?php-code-coverage/Report/Html/Renderer/Template/lines.html.disteeedf Ephp-code-coverage/Report/Html/Renderer/Template/method_item.html.distejפLphp-code-coverage/Report/Html/Renderer/Template/method_item_branch.html.disteyĎk?php-code-coverage/Report/Html/Renderer/Template/paths.html.diste*'ݤ php-code-coverage/Report/PHP.phpe<[!php-code-coverage/Report/Text.php&e&ਤ'php-code-coverage/Report/Thresholds.phpSeS 1php-code-coverage/Report/Xml/BuildInformation.phpezݤ)php-code-coverage/Report/Xml/Coverage.phpe׍d*php-code-coverage/Report/Xml/Directory.phpeAf'php-code-coverage/Report/Xml/Facade.php!e!t7 &%php-code-coverage/Report/Xml/File.phpe4E'php-code-coverage/Report/Xml/Method.phpDeDC#T%php-code-coverage/Report/Xml/Node.phpe(php-code-coverage/Report/Xml/Project.phpfefPe'php-code-coverage/Report/Xml/Report.php e HC'php-code-coverage/Report/Xml/Source.phpsesCaꀤ&php-code-coverage/Report/Xml/Tests.phpelXΤ'php-code-coverage/Report/Xml/Totals.phpeAx%php-code-coverage/Report/Xml/Unit.phpej0php-code-coverage/StaticAnalysis/CacheWarmer.php`e`_%פ8php-code-coverage/StaticAnalysis/CachingFileAnalyser.phpet;php-code-coverage/StaticAnalysis/CodeUnitFindingVisitor.php%e%&`Bphp-code-coverage/StaticAnalysis/ExecutableLinesFindingVisitor.php,e,p(1php-code-coverage/StaticAnalysis/FileAnalyser.phpe5?php-code-coverage/StaticAnalysis/IgnoredLinesFindingVisitor.php e \GԤ8php-code-coverage/StaticAnalysis/ParsingFileAnalyser.phpeBah$php-code-coverage/TestSize/Known.phpXeXzK$php-code-coverage/TestSize/Large.phpe'r %php-code-coverage/TestSize/Medium.phpe{`$php-code-coverage/TestSize/Small.phpeŖ_'php-code-coverage/TestSize/TestSize.phpe8&php-code-coverage/TestSize/Unknown.phpiei%,(php-code-coverage/TestStatus/Failure.phphehK8B&php-code-coverage/TestStatus/Known.phpe(php-code-coverage/TestStatus/Success.phphehcp+php-code-coverage/TestStatus/TestStatus.phpe%!(php-code-coverage/TestStatus/Unknown.phpmem[%php-code-coverage/Util/Filesystem.phpe%php-code-coverage/Util/Percentage.php^e^5?:php-code-coverage/Version.phpe#ؤ%php-file-iterator/ExcludeIterator.php.e.&php-file-iterator/Facade.phpelphp-file-iterator/Factory.php +e +>AqOphp-file-iterator/Iterator.php e Jphp-file-iterator/LICENSEe-~y֤php-invoker/Invoker.phpec$php-invoker/exceptions/Exception.phprervvduDphp-invoker/exceptions/ProcessControlExtensionNotLoadedException.phpe +php-invoker/exceptions/TimeoutException.phpe.php-text-template/LICENSEe-~y֤php-text-template/Template.phpV eV *`4*php-text-template/exceptions/Exception.phpyeyn9php-text-template/exceptions/InvalidArgumentException.phpeaM1php-text-template/exceptions/RuntimeException.phpeYm'php-timer/Duration.php e 2php-timer/LICENSEe$php-timer/ResourceUsageFormatter.phpe Hphp-timer/Timer.phpeQ>El"php-timer/exceptions/Exception.phpneniuۤ/php-timer/exceptions/NoActiveTimerException.phpel٤Ephp-timer/exceptions/TimeSinceStartOfRequestNotAvailableException.phpe$b phpunit.xsdGFeGF1&`1phpunit/Event/Dispatcher/CollectingDispatcher.phpe!0phpunit/Event/Dispatcher/DeferringDispatcher.php:e:&u-phpunit/Event/Dispatcher/DirectDispatcher.phpY eY s'phpunit/Event/Dispatcher/Dispatcher.phpe8Ť3phpunit/Event/Dispatcher/SubscribableDispatcher.phpePl{K,phpunit/Event/Emitter/DispatchingEmitter.phprerd!phpunit/Event/Emitter/Emitter.phpT*eT*%?-phpunit/Event/Events/Application/Finished.phpep,7phpunit/Event/Events/Application/FinishedSubscriber.php7e7,~դ,phpunit/Event/Events/Application/Started.phpeW6phpunit/Event/Events/Application/StartedSubscriber.php5e5fphpunit/Event/Events/Event.php e w(phpunit/Event/Events/EventCollection.phpOeOak0phpunit/Event/Events/EventCollectionIterator.phpe`N7phpunit/Event/Events/Test/Assertion/AssertionFailed.phpe>LAphpunit/Event/Events/Test/Assertion/AssertionFailedSubscriber.phpIeIkc:phpunit/Event/Events/Test/Assertion/AssertionSucceeded.phpe@Dphpunit/Event/Events/Test/Assertion/AssertionSucceededSubscriber.phpOeO)Rդ2phpunit/Event/Events/Test/ComparatorRegistered.php e <phpunit/Event/Events/Test/ComparatorRegisteredSubscriber.phpAeA8VBphpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalled.phpmem֤Lphpunit/Event/Events/Test/HookMethod/AfterLastTestMethodCalledSubscriber.phpKeKĶLDphpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinished.phpded)Nphpunit/Event/Events/Test/HookMethod/AfterLastTestMethodFinishedSubscriber.phpOeO>phpunit/Event/Events/Test/HookMethod/AfterTestMethodCalled.phpdedHphpunit/Event/Events/Test/HookMethod/AfterTestMethodCalledSubscriber.phpCeCߊ@phpunit/Event/Events/Test/HookMethod/AfterTestMethodFinished.php[e[o΀Jphpunit/Event/Events/Test/HookMethod/AfterTestMethodFinishedSubscriber.phpGeGV)Dphpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalled.phpqeq,UNphpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodCalledSubscriber.phpOeOҘI Ephpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErrored.phpeOphpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodErroredSubscriber.phpQeQFphpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinished.phphehZPphpunit/Event/Events/Test/HookMethod/BeforeFirstTestMethodFinishedSubscriber.phpSeS/h?phpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalled.phpfef![Iphpunit/Event/Events/Test/HookMethod/BeforeTestMethodCalledSubscriber.phpEeEphpunit/Event/Events/Test/HookMethod/PostConditionFinished.php]e]Hphpunit/Event/Events/Test/HookMethod/PostConditionFinishedSubscriber.phpCeCkxŤ;phpunit/Event/Events/Test/HookMethod/PreConditionCalled.phpdedtդEphpunit/Event/Events/Test/HookMethod/PreConditionCalledSubscriber.php=e=T#=phpunit/Event/Events/Test/HookMethod/PreConditionFinished.php[e[ƄGphpunit/Event/Events/Test/HookMethod/PreConditionFinishedSubscriber.phpAeAm3phpunit/Event/Events/Test/Issue/ConsideredRisky.phpe=phpunit/Event/Events/Test/Issue/ConsideredRiskySubscriber.php7e7¤8phpunit/Event/Events/Test/Issue/DeprecationTriggered.php" e"  Bphpunit/Event/Events/Test/Issue/DeprecationTriggeredSubscriber.phpAeA8d2phpunit/Event/Events/Test/Issue/ErrorTriggered.php~ e~ <phpunit/Event/Events/Test/Issue/ErrorTriggeredSubscriber.php5e53phpunit/Event/Events/Test/Issue/NoticeTriggered.php +e +4$=phpunit/Event/Events/Test/Issue/NoticeTriggeredSubscriber.php7e7xp;phpunit/Event/Events/Test/Issue/PhpDeprecationTriggered.php) e) IgbEphpunit/Event/Events/Test/Issue/PhpDeprecationTriggeredSubscriber.phpGeGdS6phpunit/Event/Events/Test/Issue/PhpNoticeTriggered.php e AS@phpunit/Event/Events/Test/Issue/PhpNoticeTriggeredSubscriber.php=e=L07phpunit/Event/Events/Test/Issue/PhpWarningTriggered.php e vAphpunit/Event/Events/Test/Issue/PhpWarningTriggeredSubscriber.php?e?Xޤ?phpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggered.phpheh#ѤIphpunit/Event/Events/Test/Issue/PhpunitDeprecationTriggeredSubscriber.phpOeOjt9phpunit/Event/Events/Test/Issue/PhpunitErrorTriggered.phpueupjCphpunit/Event/Events/Test/Issue/PhpunitErrorTriggeredSubscriber.phpCeC;phpunit/Event/Events/Test/Issue/PhpunitWarningTriggered.php`e`@@ŤEphpunit/Event/Events/Test/Issue/PhpunitWarningTriggeredSubscriber.phpGeGM4phpunit/Event/Events/Test/Issue/WarningTriggered.php +e +ݤ>phpunit/Event/Events/Test/Issue/WarningTriggeredSubscriber.php9e9#A@@phpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalled.php2e2%|Jphpunit/Event/Events/Test/Lifecycle/DataProviderMethodCalledSubscriber.phpIeIQNBphpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinished.php,e,Lphpunit/Event/Events/Test/Lifecycle/DataProviderMethodFinishedSubscriber.phpMeMN0phpunit/Event/Events/Test/Lifecycle/Finished.php{e{ դ:phpunit/Event/Events/Test/Lifecycle/FinishedSubscriber.php)e)Qb9phpunit/Event/Events/Test/Lifecycle/PreparationFailed.phpsesx\Cphpunit/Event/Events/Test/Lifecycle/PreparationFailedSubscriber.php;e;W:phpunit/Event/Events/Test/Lifecycle/PreparationStarted.phpueuX[`Dphpunit/Event/Events/Test/Lifecycle/PreparationStartedSubscriber.php=e=w 0phpunit/Event/Events/Test/Lifecycle/Prepared.php`e`ISϤ:phpunit/Event/Events/Test/Lifecycle/PreparedSubscriber.php)e)Ѥy-phpunit/Event/Events/Test/Outcome/Errored.phpes7phpunit/Event/Events/Test/Outcome/ErroredSubscriber.php'e' >,phpunit/Event/Events/Test/Outcome/Failed.phpe6phpunit/Event/Events/Test/Outcome/FailedSubscriber.php%e%ǩ6phpunit/Event/Events/Test/Outcome/MarkedIncomplete.phpe6;@phpunit/Event/Events/Test/Outcome/MarkedIncompleteSubscriber.php9e96Ф,phpunit/Event/Events/Test/Outcome/Passed.php\e\6phpunit/Event/Events/Test/Outcome/PassedSubscriber.php%e%pE-phpunit/Event/Events/Test/Outcome/Skipped.phpeoKȏ7phpunit/Event/Events/Test/Outcome/SkippedSubscriber.php'e'%I5phpunit/Event/Events/Test/PrintedUnexpectedOutput.phpeOg?phpunit/Event/Events/Test/PrintedUnexpectedOutputSubscriber.phpGeG`ɐ:phpunit/Event/Events/Test/TestDouble/MockObjectCreated.phpe{͵Dphpunit/Event/Events/Test/TestDouble/MockObjectCreatedSubscriber.php;e;h{6Jphpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreated.phpeҽTphpunit/Event/Events/Test/TestDouble/MockObjectForAbstractClassCreatedSubscriber.php[e[ +vUphpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreated.phpXeXr_phpunit/Event/Events/Test/TestDouble/MockObjectForIntersectionOfInterfacesCreatedSubscriber.phpqeq/uBphpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreated.phpe> Lphpunit/Event/Events/Test/TestDouble/MockObjectForTraitCreatedSubscriber.phpKeK#TBphpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreated.php +e +ȌkLphpunit/Event/Events/Test/TestDouble/MockObjectFromWsdlCreatedSubscriber.phpKeKIAphpunit/Event/Events/Test/TestDouble/PartialMockObjectCreated.php=e=sUKphpunit/Event/Events/Test/TestDouble/PartialMockObjectCreatedSubscriber.phpIeI2!9phpunit/Event/Events/Test/TestDouble/TestProxyCreated.phpeͤCphpunit/Event/Events/Test/TestDouble/TestProxyCreatedSubscriber.php9e9K8phpunit/Event/Events/Test/TestDouble/TestStubCreated.phpesʤBphpunit/Event/Events/Test/TestDouble/TestStubCreatedSubscriber.php7e7d#Sphpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreated.phpTeT̪ ]phpunit/Event/Events/Test/TestDouble/TestStubForIntersectionOfInterfacesCreatedSubscriber.phpmemKѕ=5phpunit/Event/Events/TestRunner/BootstrapFinished.phpiei?phpunit/Event/Events/TestRunner/BootstrapFinishedSubscriber.phpGeGaݤ.phpunit/Event/Events/TestRunner/Configured.php}e}u8phpunit/Event/Events/TestRunner/ConfiguredSubscriber.php9e9դ8phpunit/Event/Events/TestRunner/DeprecationTriggered.phptetӤzBphpunit/Event/Events/TestRunner/DeprecationTriggeredSubscriber.phpMeMd5phpunit/Event/Events/TestRunner/EventFacadeSealed.phpe{J?phpunit/Event/Events/TestRunner/EventFacadeSealedSubscriber.phpGeG{ 4phpunit/Event/Events/TestRunner/ExecutionAborted.phpeȃx>phpunit/Event/Events/TestRunner/ExecutionAbortedSubscriber.phpEeE W5phpunit/Event/Events/TestRunner/ExecutionFinished.phpeБW?phpunit/Event/Events/TestRunner/ExecutionFinishedSubscriber.phpGeGH4phpunit/Event/Events/TestRunner/ExecutionStarted.phpecic>phpunit/Event/Events/TestRunner/ExecutionStartedSubscriber.phpEeES9phpunit/Event/Events/TestRunner/ExtensionBootstrapped.phpyey%קCphpunit/Event/Events/TestRunner/ExtensionBootstrappedSubscriber.phpOeOpɞ2;phpunit/Event/Events/TestRunner/ExtensionLoadedFromPhar.phpe䟉Ephpunit/Event/Events/TestRunner/ExtensionLoadedFromPharSubscriber.phpSeSR^1,phpunit/Event/Events/TestRunner/Finished.php{e{zǡ6phpunit/Event/Events/TestRunner/FinishedSubscriber.php5e5̤=phpunit/Event/Events/TestRunner/GarbageCollectionDisabled.phpe\$Gphpunit/Event/Events/TestRunner/GarbageCollectionDisabledSubscriber.phpWeWJj<phpunit/Event/Events/TestRunner/GarbageCollectionEnabled.phpeFphpunit/Event/Events/TestRunner/GarbageCollectionEnabledSubscriber.phpUeU77>phpunit/Event/Events/TestRunner/GarbageCollectionTriggered.phpe2ɤHphpunit/Event/Events/TestRunner/GarbageCollectionTriggeredSubscriber.phpYeY &ݤ+phpunit/Event/Events/TestRunner/Started.phpyey5phpunit/Event/Events/TestRunner/StartedSubscriber.php3e3 4phpunit/Event/Events/TestRunner/WarningTriggered.phplel.Cv>phpunit/Event/Events/TestRunner/WarningTriggeredSubscriber.phpEeE8K+phpunit/Event/Events/TestSuite/Filtered.phpeo5phpunit/Event/Events/TestSuite/FilteredSubscriber.php3e3|+phpunit/Event/Events/TestSuite/Finished.phpeĤt5phpunit/Event/Events/TestSuite/FinishedSubscriber.php3e3զ)phpunit/Event/Events/TestSuite/Loaded.phpeX(\*3phpunit/Event/Events/TestSuite/LoadedSubscriber.php/e/^7*phpunit/Event/Events/TestSuite/Skipped.phpep%4phpunit/Event/Events/TestSuite/SkippedSubscriber.php1e1D!)phpunit/Event/Events/TestSuite/Sorted.php'e'j 3phpunit/Event/Events/TestSuite/SortedSubscriber.php/e/ Ȥ*phpunit/Event/Events/TestSuite/Started.phpeз1٤4phpunit/Event/Events/TestSuite/StartedSubscriber.php1e1i5k9phpunit/Event/Exception/EventAlreadyAssignedException.php e 0ɤ8phpunit/Event/Exception/EventFacadeIsSealedException.php +e +J ؤ%phpunit/Event/Exception/Exception.phpLeLgx4phpunit/Event/Exception/InvalidArgumentException.phpe䀤1phpunit/Event/Exception/InvalidEventException.phpeE>6phpunit/Event/Exception/InvalidSubscriberException.phpeSg$phpunit/Event/Exception/MapError.phpeRGphpunit/Event/Exception/MoreThanOneDataSetFromDataProviderException.php0e0R=8phpunit/Event/Exception/NoComparisonFailureException.phpe{k>phpunit/Event/Exception/NoDataSetFromDataProviderException.php'e'@~8phpunit/Event/Exception/NoPreviousThrowableException.php +e +~@phpunit/Event/Exception/NoTestCaseObjectOnCallStackException.phpe,phpunit/Event/Exception/RuntimeException.phpeLDphpunit/Event/Exception/SubscriberTypeAlreadyRegisteredException.phpeįK1phpunit/Event/Exception/UnknownEventException.phpe}5phpunit/Event/Exception/UnknownEventTypeException.phpe/<6phpunit/Event/Exception/UnknownSubscriberException.phpe ˤ:phpunit/Event/Exception/UnknownSubscriberTypeException.php e &'*phpunit/Event/Facade.php"e")phpunit/Event/Subscriber.phpedlkphpunit/Event/Tracer.phper7phpunit/Event/TypeMap.php5e5pF'#phpunit/Event/Value/ClassMethod.phpeB)phpunit/Event/Value/ComparisonFailure.phpek;0phpunit/Event/Value/ComparisonFailureBuilder.phpevZ/phpunit/Event/Value/Runtime/OperatingSystem.phpegA! #phpunit/Event/Value/Runtime/PHP.php e P'phpunit/Event/Value/Runtime/PHPUnit.phpoeo3'phpunit/Event/Value/Runtime/Runtime.phpek?J*phpunit/Event/Value/Telemetry/Duration.php e *t8phpunit/Event/Value/Telemetry/GarbageCollectorStatus.phpWeW;ä@phpunit/Event/Value/Telemetry/GarbageCollectorStatusProvider.phpeN (phpunit/Event/Value/Telemetry/HRTime.php e Fɤ&phpunit/Event/Value/Telemetry/Info.php +e +gHh!-phpunit/Event/Value/Telemetry/MemoryMeter.php:e:XH-phpunit/Event/Value/Telemetry/MemoryUsage.phpgeg-Ephpunit/Event/Value/Telemetry/Php81GarbageCollectorStatusProvider.phpjej9Ephpunit/Event/Value/Telemetry/Php83GarbageCollectorStatusProvider.phper*phpunit/Event/Value/Telemetry/Snapshot.phpe +.+phpunit/Event/Value/Telemetry/StopWatch.phpeF4S(phpunit/Event/Value/Telemetry/System.php<e<fK3phpunit/Event/Value/Telemetry/SystemMemoryMeter.php~e~q`e1phpunit/Event/Value/Telemetry/SystemStopWatch.phpe H};phpunit/Event/Value/Telemetry/SystemStopWatchWithOffset.phpReR +]qC!phpunit/Event/Value/Test/Phpt.php`e`B!phpunit/Event/Value/Test/Test.phpei +phpunit/Event/Value/Test/TestCollection.php1e1J3T3phpunit/Event/Value/Test/TestCollectionIterator.phpebx:phpunit/Event/Value/Test/TestData/DataFromDataProvider.php e bJ<phpunit/Event/Value/Test/TestData/DataFromTestDependency.phpe.phpunit/Event/Value/Test/TestData/TestData.phpen~8phpunit/Event/Value/Test/TestData/TestDataCollection.php +e +*^@phpunit/Event/Value/Test/TestData/TestDataCollectionIterator.phpeA$phpunit/Event/Value/Test/TestDox.php e Kyx+phpunit/Event/Value/Test/TestDoxBuilder.phpeU'phpunit/Event/Value/Test/TestMethod.phpe O.phpunit/Event/Value/Test/TestMethodBuilder.php e LJT+phpunit/Event/Value/TestSuite/TestSuite.phpe2phpunit/Event/Value/TestSuite/TestSuiteBuilder.php e {7phpunit/Event/Value/TestSuite/TestSuiteForTestClass.phpeN&Hphpunit/Event/Value/TestSuite/TestSuiteForTestMethodWithDataProvider.phpeФ3phpunit/Event/Value/TestSuite/TestSuiteWithName.phpe4d !phpunit/Event/Value/Throwable.php_ e_  (phpunit/Event/Value/ThrowableBuilder.php e _phpunit/Exception.phpLeLߊphpunit/Framework/Assert.phpe;i&phpunit/Framework/Assert/Functions.php,\e,\¬&phpunit/Framework/Attributes/After.phpe~jL¤+phpunit/Framework/Attributes/AfterClass.phpe׎.phpunit/Framework/Attributes/BackupGlobals.phpemEO7phpunit/Framework/Attributes/BackupStaticProperties.phpeh'phpunit/Framework/Attributes/Before.phpe;,phpunit/Framework/Attributes/BeforeClass.phpe\3phpunit/Framework/Attributes/CodeCoverageIgnore.phpnenpw,phpunit/Framework/Attributes/CoversClass.phpeCb/phpunit/Framework/Attributes/CoversFunction.phpeΐX.phpunit/Framework/Attributes/CoversNothing.phpe&ޏ-phpunit/Framework/Attributes/DataProvider.phpeM5phpunit/Framework/Attributes/DataProviderExternal.phpeh5(phpunit/Framework/Attributes/Depends.phpeO0phpunit/Framework/Attributes/DependsExternal.phpe +p>phpunit/Framework/Attributes/DependsExternalUsingDeepClone.phpeWgAphpunit/Framework/Attributes/DependsExternalUsingShallowClone.php e //phpunit/Framework/Attributes/DependsOnClass.phpe4=phpunit/Framework/Attributes/DependsOnClassUsingDeepClone.phpe'@phpunit/Framework/Attributes/DependsOnClassUsingShallowClone.phpe}E6phpunit/Framework/Attributes/DependsUsingDeepClone.phperˌ9phpunit/Framework/Attributes/DependsUsingShallowClone.phpe& 9phpunit/Framework/Attributes/DoesNotPerformAssertions.php)e)J.~@phpunit/Framework/Attributes/ExcludeGlobalVariableFromBackup.phpeL༤@phpunit/Framework/Attributes/ExcludeStaticPropertyFromBackup.php2e2&phpunit/Framework/Attributes/Group.phpeio;phpunit/Framework/Attributes/IgnoreClassForCodeCoverage.phpe3phpunit/Framework/Attributes/IgnoreDeprecations.php#e#]e>phpunit/Framework/Attributes/IgnoreFunctionForCodeCoverage.phped6`<phpunit/Framework/Attributes/IgnoreMethodForCodeCoverage.phpPePQ&phpunit/Framework/Attributes/Large.phpe"mn'phpunit/Framework/Attributes/Medium.phpe'2.phpunit/Framework/Attributes/PostCondition.phpeK-phpunit/Framework/Attributes/PreCondition.phpeؕ@4phpunit/Framework/Attributes/PreserveGlobalState.phpeM|1phpunit/Framework/Attributes/RequiresFunction.phped/phpunit/Framework/Attributes/RequiresMethod.phpeG +8phpunit/Framework/Attributes/RequiresOperatingSystem.phpe>phpunit/Framework/Attributes/RequiresOperatingSystemFamily.phpe-",phpunit/Framework/Attributes/RequiresPhp.phpen5phpunit/Framework/Attributes/RequiresPhpExtension.phpveve(a0phpunit/Framework/Attributes/RequiresPhpunit.phpeIt0phpunit/Framework/Attributes/RequiresSetting.phpeLP:phpunit/Framework/Attributes/RunClassInSeparateProcess.phpe:5phpunit/Framework/Attributes/RunInSeparateProcess.php e <phpunit/Framework/Attributes/RunTestsInSeparateProcesses.phpeĪ&phpunit/Framework/Attributes/Small.phpew~%phpunit/Framework/Attributes/Test.phpe#(phpunit/Framework/Attributes/TestDox.phpe{)phpunit/Framework/Attributes/TestWith.phpe[4-phpunit/Framework/Attributes/TestWithJson.phperzC'phpunit/Framework/Attributes/Ticket.phpe 2*phpunit/Framework/Attributes/UsesClass.phpeVF-phpunit/Framework/Attributes/UsesFunction.phpeN5ﻤ4phpunit/Framework/Attributes/WithoutErrorHandler.php +e +0phpunit/Framework/Constraint/Boolean/IsFalse.phpbebBVu/phpunit/Framework/Constraint/Boolean/IsTrue.php_e_)phpunit/Framework/Constraint/Callback.phpe.@-2phpunit/Framework/Constraint/Cardinality/Count.php e ^.8phpunit/Framework/Constraint/Cardinality/GreaterThan.phpVeVl=O4phpunit/Framework/Constraint/Cardinality/IsEmpty.phpded+R-5phpunit/Framework/Constraint/Cardinality/LessThan.phpPePդ5phpunit/Framework/Constraint/Cardinality/SameSize.phpeBs+phpunit/Framework/Constraint/Constraint.php e vߤ1phpunit/Framework/Constraint/Equality/IsEqual.php_ e_ ?phpunit/Framework/Constraint/Equality/IsEqualCanonicalizing.php +e +Ф=phpunit/Framework/Constraint/Equality/IsEqualIgnoringCase.php +e +F:phpunit/Framework/Constraint/Equality/IsEqualWithDelta.php e \̤4phpunit/Framework/Constraint/Exception/Exception.phpvevz8phpunit/Framework/Constraint/Exception/ExceptionCode.phpeMGphpunit/Framework/Constraint/Exception/ExceptionMessageIsOrContains.phpeSphpunit/Framework/Constraint/Exception/ExceptionMessageMatchesRegularExpression.phpNeNiK;phpunit/Framework/Constraint/Filesystem/DirectoryExists.phpeyy6phpunit/Framework/Constraint/Filesystem/FileExists.phpeC 6phpunit/Framework/Constraint/Filesystem/IsReadable.phpeȅ]6phpunit/Framework/Constraint/Filesystem/IsWritable.phpe +phpunit/Framework/Constraint/IsAnything.phpe{Ϝ,phpunit/Framework/Constraint/IsIdentical.phpe^j,phpunit/Framework/Constraint/JsonMatches.php e '4|.phpunit/Framework/Constraint/Math/IsFinite.php|e|G˴w0phpunit/Framework/Constraint/Math/IsInfinite.phpe3ߡ+phpunit/Framework/Constraint/Math/IsNan.phppepZMw4phpunit/Framework/Constraint/Object/ObjectEquals.phptet{`9phpunit/Framework/Constraint/Object/ObjectHasProperty.phpef8phpunit/Framework/Constraint/Operator/BinaryOperator.php] e]  4phpunit/Framework/Constraint/Operator/LogicalAnd.php]e]F4phpunit/Framework/Constraint/Operator/LogicalNot.phpK eK 3phpunit/Framework/Constraint/Operator/LogicalOr.phpAeA(K4phpunit/Framework/Constraint/Operator/LogicalXor.phpe2phpunit/Framework/Constraint/Operator/Operator.php,e,{7phpunit/Framework/Constraint/Operator/UnaryOperator.phpe.{-.phpunit/Framework/Constraint/String/IsJson.php4 e4 [ڤ9phpunit/Framework/Constraint/String/RegularExpression.php`e`m6phpunit/Framework/Constraint/String/StringContains.phpVeV2[6phpunit/Framework/Constraint/String/StringEndsWith.phpermMphpunit/Framework/Constraint/String/StringEqualsStringIgnoringLineEndings.php:e:IlFphpunit/Framework/Constraint/String/StringMatchesFormatDescription.php e m}t8phpunit/Framework/Constraint/String/StringStartsWith.phpei.Qդ8phpunit/Framework/Constraint/Traversable/ArrayHasKey.phpeL괤3phpunit/Framework/Constraint/Traversable/IsList.phpZeZ\)F@phpunit/Framework/Constraint/Traversable/TraversableContains.phpehEphpunit/Framework/Constraint/Traversable/TraversableContainsEqual.php)e)%Iphpunit/Framework/Constraint/Traversable/TraversableContainsIdentical.phpeyDphpunit/Framework/Constraint/Traversable/TraversableContainsOnly.phpTeTW?2phpunit/Framework/Constraint/Type/IsInstanceOf.phpeVm",phpunit/Framework/Constraint/Type/IsNull.php^e^Vɭ,phpunit/Framework/Constraint/Type/IsType.phpe!ޕ+phpunit/Framework/DataProviderTestSuite.phpeUa4phpunit/Framework/Exception/AssertionFailedError.phpe5phpunit/Framework/Exception/CodeCoverageException.phpe[4phpunit/Framework/Exception/EmptyStringException.phpe!)phpunit/Framework/Exception/Exception.phpeR*,:phpunit/Framework/Exception/ExpectationFailedException.phpeA>phpunit/Framework/Exception/GeneratorNotSupportedException.phpe(d9phpunit/Framework/Exception/Incomplete/IncompleteTest.phpe,+>phpunit/Framework/Exception/Incomplete/IncompleteTestError.phpeםܤ8phpunit/Framework/Exception/InvalidArgumentException.phpe:(<phpunit/Framework/Exception/InvalidCoversTargetException.phpeo苤<phpunit/Framework/Exception/InvalidDataProviderException.phpe.ڜɤ:phpunit/Framework/Exception/InvalidDependencyException.phpe}9phpunit/Framework/Exception/NoChildTestSuiteException.phpeP$Nphpunit/Framework/Exception/ObjectEquals/ActualValueIsNotAnObjectException.phpAeA<ؤ`phpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotAcceptParameterTypeException.phpe@bphpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareBoolReturnTypeException.phpePigphpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareExactlyOneParameterException.phpeFaphpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotDeclareParameterTypeException.phpeENRphpunit/Framework/Exception/ObjectEquals/ComparisonMethodDoesNotExistException.phpeui8phpunit/Framework/Exception/PhptAssertionFailedError.php2e2_9phpunit/Framework/Exception/ProcessIsolationException.phpeH:3phpunit/Framework/Exception/Skipped/SkippedTest.phpeS.=phpunit/Framework/Exception/Skipped/SkippedTestSuiteError.phpexCphpunit/Framework/Exception/Skipped/SkippedWithMessageException.phpez$@phpunit/Framework/Exception/UnknownClassOrInterfaceException.phpeӤ4phpunit/Framework/Exception/UnknownTypeException.phpnen(j.phpunit/Framework/ExecutionOrderDependency.phpeX>2&3phpunit/Framework/MockObject/ConfigurableMethod.phpeVkRAphpunit/Framework/MockObject/Exception/BadMethodCallException.phpeΫXGphpunit/Framework/MockObject/Exception/CannotUseAddMethodsException.php5e5{Hphpunit/Framework/MockObject/Exception/CannotUseOnlyMethodsException.phpe/(4phpunit/Framework/MockObject/Exception/Exception.phpeB'Kphpunit/Framework/MockObject/Exception/IncompatibleReturnValueException.phpyey|/Hphpunit/Framework/MockObject/Exception/MatchBuilderNotFoundException.phpeLphpunit/Framework/MockObject/Exception/MatcherAlreadyRegisteredException.phpez'Lphpunit/Framework/MockObject/Exception/MethodCannotBeConfiguredException.phpe}QOphpunit/Framework/MockObject/Exception/MethodNameAlreadyConfiguredException.phpeӁƤKphpunit/Framework/MockObject/Exception/MethodNameNotConfiguredException.php~e~x1)Uphpunit/Framework/MockObject/Exception/MethodParametersAlreadyConfiguredException.phpe rHphpunit/Framework/MockObject/Exception/NeverReturningMethodException.phpmem+">phpunit/Framework/MockObject/Exception/ReflectionException.phpe.ؔLphpunit/Framework/MockObject/Exception/ReturnValueNotConfiguredException.php<e<Qo;phpunit/Framework/MockObject/Exception/RuntimeException.phpe_|Pphpunit/Framework/MockObject/Generator/Exception/ClassAlreadyExistsException.phpeϠPphpunit/Framework/MockObject/Generator/Exception/ClassIsEnumerationException.phpeYJphpunit/Framework/MockObject/Generator/Exception/ClassIsFinalException.phpeQMphpunit/Framework/MockObject/Generator/Exception/ClassIsReadonlyException.phpeYMphpunit/Framework/MockObject/Generator/Exception/DuplicateMethodException.phpe.٤>phpunit/Framework/MockObject/Generator/Exception/Exception.phpeOphpunit/Framework/MockObject/Generator/Exception/InvalidMethodNameException.phpelDcphpunit/Framework/MockObject/Generator/Exception/OriginalConstructorInvocationRequiredException.phpeDKƤHphpunit/Framework/MockObject/Generator/Exception/ReflectionException.phpeq3Ephpunit/Framework/MockObject/Generator/Exception/RuntimeException.phpe}ʻWphpunit/Framework/MockObject/Generator/Exception/SoapExtensionNotAvailableException.phpen5Jphpunit/Framework/MockObject/Generator/Exception/UnknownClassException.phpeZMJphpunit/Framework/MockObject/Generator/Exception/UnknownTraitException.php +e +9ѤIphpunit/Framework/MockObject/Generator/Exception/UnknownTypeException.phpe#J4phpunit/Framework/MockObject/Generator/Generator.php^~e^~Yw'4phpunit/Framework/MockObject/Generator/MockClass.phpdedN|5phpunit/Framework/MockObject/Generator/MockMethod.php)e)i8phpunit/Framework/MockObject/Generator/MockMethodSet.phpqeqR4phpunit/Framework/MockObject/Generator/MockTrait.phpe:3phpunit/Framework/MockObject/Generator/MockType.phpedp[9phpunit/Framework/MockObject/Generator/TemplateLoader.phpeqWp@phpunit/Framework/MockObject/Generator/templates/deprecation.tpl;e;O5sCphpunit/Framework/MockObject/Generator/templates/doubled_method.tpl8e8)դJphpunit/Framework/MockObject/Generator/templates/doubled_static_method.tple 4RAphpunit/Framework/MockObject/Generator/templates/intersection.tplLeL-XCphpunit/Framework/MockObject/Generator/templates/proxied_method.tple Fphpunit/Framework/MockObject/Generator/templates/test_double_class.tplfef' @phpunit/Framework/MockObject/Generator/templates/trait_class.tplQeQ<Ȥ?phpunit/Framework/MockObject/Generator/templates/wsdl_class.tple@phpunit/Framework/MockObject/Generator/templates/wsdl_method.tpl<e<i,phpunit/Framework/MockObject/MockBuilder.phpp/ep/ ?phpunit/Framework/MockObject/Runtime/Api/DoubledCloneMethod.php2e2.I3phpunit/Framework/MockObject/Runtime/Api/Method.php e G(:phpunit/Framework/MockObject/Runtime/Api/MockObjectApi.php}e} +?phpunit/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.phpMeMf4phpunit/Framework/MockObject/Runtime/Api/StubApi.php5e59phpunit/Framework/MockObject/Runtime/Builder/Identity.php[e[$X3{Aphpunit/Framework/MockObject/Runtime/Builder/InvocationMocker.php#e#rBphpunit/Framework/MockObject/Runtime/Builder/InvocationStubber.phpeeU@phpunit/Framework/MockObject/Runtime/Builder/MethodNameMatch.phpe:'@phpunit/Framework/MockObject/Runtime/Builder/ParametersMatch.phpNeNx)5phpunit/Framework/MockObject/Runtime/Builder/Stub.phpe(=phpunit/Framework/MockObject/Runtime/Interface/MockObject.phpetEphpunit/Framework/MockObject/Runtime/Interface/MockObjectInternal.phpe c7phpunit/Framework/MockObject/Runtime/Interface/Stub.phpeliH?phpunit/Framework/MockObject/Runtime/Interface/StubInternal.phpded٤3phpunit/Framework/MockObject/Runtime/Invocation.phpe.pOA:phpunit/Framework/MockObject/Runtime/InvocationHandler.phpe0phpunit/Framework/MockObject/Runtime/Matcher.phpe=phpunit/Framework/MockObject/Runtime/MethodNameConstraint.phpeӶ=phpunit/Framework/MockObject/Runtime/ReturnValueGenerator.phpkek=phpunit/Framework/MockObject/Runtime/Rule/AnyInvokedCount.phpe3;phpunit/Framework/MockObject/Runtime/Rule/AnyParameters.phpeU=phpunit/Framework/MockObject/Runtime/Rule/InvocationOrder.phpeH NAphpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastCount.phpeiԤ@phpunit/Framework/MockObject/Runtime/Rule/InvokedAtLeastOnce.phpe @phpunit/Framework/MockObject/Runtime/Rule/InvokedAtMostCount.phpeN:phpunit/Framework/MockObject/Runtime/Rule/InvokedCount.phpZ eZ 8phpunit/Framework/MockObject/Runtime/Rule/MethodName.phpeʆ8phpunit/Framework/MockObject/Runtime/Rule/Parameters.php9e9ڳj<phpunit/Framework/MockObject/Runtime/Rule/ParametersRule.phpel^L>phpunit/Framework/MockObject/Runtime/Stub/ConsecutiveCalls.phpe7phpunit/Framework/MockObject/Runtime/Stub/Exception.php;e; Ҥ<phpunit/Framework/MockObject/Runtime/Stub/ReturnArgument.php4e4`<phpunit/Framework/MockObject/Runtime/Stub/ReturnCallback.phpieit=phpunit/Framework/MockObject/Runtime/Stub/ReturnReference.phpeuߔ8phpunit/Framework/MockObject/Runtime/Stub/ReturnSelf.phpeר ݤ8phpunit/Framework/MockObject/Runtime/Stub/ReturnStub.phpe`[<phpunit/Framework/MockObject/Runtime/Stub/ReturnValueMap.phpeʤ2phpunit/Framework/MockObject/Runtime/Stub/Stub.phpzez!phpunit/Framework/Reorderable.phpe˯$phpunit/Framework/SelfDescribing.php +e +sphpunit/Framework/Test.phpeǺ!phpunit/Framework/TestBuilder.php%e%݇Ӥphpunit/Framework/TestCase.phpSeS+ߤ phpunit/Framework/TestRunner.php68e68wHʤ$phpunit/Framework/TestSize/Known.phpe)T Ф$phpunit/Framework/TestSize/Large.php/e/N`i%phpunit/Framework/TestSize/Medium.php2e2b{$phpunit/Framework/TestSize/Small.php#e#24'phpunit/Framework/TestSize/TestSize.php5e5ˮ&phpunit/Framework/TestSize/Unknown.phpeg,phpunit/Framework/TestStatus/Deprecation.phpev&phpunit/Framework/TestStatus/Error.phpe'qH(phpunit/Framework/TestStatus/Failure.phpe:+phpunit/Framework/TestStatus/Incomplete.phpe&phpunit/Framework/TestStatus/Known.phpjej7'phpunit/Framework/TestStatus/Notice.phpe!D炤&phpunit/Framework/TestStatus/Risky.phpep(phpunit/Framework/TestStatus/Skipped.phpex(phpunit/Framework/TestStatus/Success.phpeAg+phpunit/Framework/TestStatus/TestStatus.php^e^UF(phpunit/Framework/TestStatus/Unknown.phpeV(phpunit/Framework/TestStatus/Warning.phpeqZiphpunit/Framework/TestSuite.php1De1DԤ'phpunit/Framework/TestSuiteIterator.php3e3.Kphpunit/Logging/EventLogger.phpeytphpunit/Logging/Exception.phpe%٤(phpunit/Logging/JUnit/JunitXmlLogger.phpE/eE/)%/phpunit/Logging/JUnit/Subscriber/Subscriber.phpeyJ;:phpunit/Logging/JUnit/Subscriber/TestErroredSubscriber.php e 9phpunit/Logging/JUnit/Subscriber/TestFailedSubscriber.phpeZ;phpunit/Logging/JUnit/Subscriber/TestFinishedSubscriber.phpeA0pCphpunit/Logging/JUnit/Subscriber/TestMarkedIncompleteSubscriber.php?e?"3ǤDphpunit/Logging/JUnit/Subscriber/TestPreparationFailedSubscriber.php?e?1eEphpunit/Logging/JUnit/Subscriber/TestPreparationStartedSubscriber.phpKeK pܤ;phpunit/Logging/JUnit/Subscriber/TestPreparedSubscriber.php e oˤJphpunit/Logging/JUnit/Subscriber/TestRunnerExecutionFinishedSubscriber.phpeĤ:phpunit/Logging/JUnit/Subscriber/TestSkippedSubscriber.php e @phpunit/Logging/JUnit/Subscriber/TestSuiteFinishedSubscriber.phpeVG?phpunit/Logging/JUnit/Subscriber/TestSuiteStartedSubscriber.phpe?2phpunit/Logging/TeamCity/Subscriber/Subscriber.phpeGEphpunit/Logging/TeamCity/Subscriber/TestConsideredRiskySubscriber.php?e?s&U=phpunit/Logging/TeamCity/Subscriber/TestErroredSubscriber.phpeФ<phpunit/Logging/TeamCity/Subscriber/TestFailedSubscriber.php e U>phpunit/Logging/TeamCity/Subscriber/TestFinishedSubscriber.phpei&iFphpunit/Logging/TeamCity/Subscriber/TestMarkedIncompleteSubscriber.phpEeE >phpunit/Logging/TeamCity/Subscriber/TestPreparedSubscriber.phpe Mphpunit/Logging/TeamCity/Subscriber/TestRunnerExecutionFinishedSubscriber.phpe,=phpunit/Logging/TeamCity/Subscriber/TestSkippedSubscriber.phpemF֤Cphpunit/Logging/TeamCity/Subscriber/TestSuiteFinishedSubscriber.phpexBphpunit/Logging/TeamCity/Subscriber/TestSuiteStartedSubscriber.phpe}G9+phpunit/Logging/TeamCity/TeamCityLogger.php$e$yj(phpunit/Logging/TestDox/HtmlRenderer.php e lE*phpunit/Logging/TestDox/NamePrettifier.php!e!;Y-phpunit/Logging/TestDox/PlainTextRenderer.phpe<phpunit/Logging/TestDox/TestResult/Subscriber/Subscriber.phpe'ĤOphpunit/Logging/TestDox/TestResult/Subscriber/TestConsideredRiskySubscriber.phpeAGphpunit/Logging/TestDox/TestResult/Subscriber/TestErroredSubscriber.phpe;m Fphpunit/Logging/TestDox/TestResult/Subscriber/TestFailedSubscriber.phpeF,Hphpunit/Logging/TestDox/TestResult/Subscriber/TestFinishedSubscriber.phpePGPphpunit/Logging/TestDox/TestResult/Subscriber/TestMarkedIncompleteSubscriber.phpe {Fphpunit/Logging/TestDox/TestResult/Subscriber/TestPassedSubscriber.phpe)#Hphpunit/Logging/TestDox/TestResult/Subscriber/TestPreparedSubscriber.phpe.Gphpunit/Logging/TestDox/TestResult/Subscriber/TestSkippedSubscriber.phpe<ӤTphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.phpeo!Ophpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredNoticeSubscriber.phpeZWphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.php e uRphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.phpe$ ɤSphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.phpe_a[phpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php$e$𛭤Uphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.phpeWphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.php e -.Pphpunit/Logging/TestDox/TestResult/Subscriber/TestTriggeredWarningSubscriber.phpeB1phpunit/Logging/TestDox/TestResult/TestResult.phpefE.{;phpunit/Logging/TestDox/TestResult/TestResultCollection.phpeCphpunit/Logging/TestDox/TestResult/TestResultCollectionIterator.phpex:phpunit/Logging/TestDox/TestResult/TestResultCollector.php&e&/phpunit/Metadata/After.php]e]}p֤phpunit/Metadata/AfterClass.phplel{ۤ%phpunit/Metadata/Api/CodeCoverage.php$e$B& %phpunit/Metadata/Api/DataProvider.phpM!eM!p%phpunit/Metadata/Api/Dependencies.php e  eɤphpunit/Metadata/Api/Groups.php9 e9 z/[C$phpunit/Metadata/Api/HookMethods.phpu eu ` %phpunit/Metadata/Api/Requirements.phpe>c8"phpunit/Metadata/BackupGlobals.phpep<媤+phpunit/Metadata/BackupStaticProperties.phpe̤phpunit/Metadata/Before.php`e`X phpunit/Metadata/BeforeClass.phpoeokphpunit/Metadata/Covers.php+e+][ phpunit/Metadata/CoversClass.php@e@'phpunit/Metadata/CoversDefaultClass.phpXeX[~#phpunit/Metadata/CoversFunction.phpKeK Qä"phpunit/Metadata/CoversNothing.phpueu\`!phpunit/Metadata/DataProvider.phpe*'#phpunit/Metadata/DependsOnClass.phpe{9Y$phpunit/Metadata/DependsOnMethod.phpel,ؤ-phpunit/Metadata/DoesNotPerformAssertions.phpeaTphpunit/Metadata/Exception/AnnotationsAreNotSupportedForInternalClassesException.php:e:,Ȥ(phpunit/Metadata/Exception/Exception.phpOeOwAphpunit/Metadata/Exception/InvalidVersionRequirementException.phpePR<phpunit/Metadata/Exception/NoVersionRequirementException.phpe?+睤2phpunit/Metadata/Exception/ReflectionException.phpen4phpunit/Metadata/ExcludeGlobalVariableFromBackup.phpeU4phpunit/Metadata/ExcludeStaticPropertyFromBackup.phpephpunit/Metadata/Group.php=e=U/phpunit/Metadata/IgnoreClassForCodeCoverage.phpek'phpunit/Metadata/IgnoreDeprecations.phpe0Hi2phpunit/Metadata/IgnoreFunctionForCodeCoverage.phpeyA3s0phpunit/Metadata/IgnoreMethodForCodeCoverage.phpeV:;Bphpunit/Metadata/Metadata.php[e[J'phpunit/Metadata/MetadataCollection.php<.e<.7/phpunit/Metadata/MetadataCollectionIterator.phpe2I/phpunit/Metadata/Parser/Annotation/DocBlock.phpP"eP"nV/phpunit/Metadata/Parser/Annotation/Registry.php e ],phpunit/Metadata/Parser/AnnotationParser.phpaDeaDկ+phpunit/Metadata/Parser/AttributeParser.phpWeWt)phpunit/Metadata/Parser/CachingParser.phpePy~"phpunit/Metadata/Parser/Parser.phpeOv'phpunit/Metadata/Parser/ParserChain.phpe +nY$phpunit/Metadata/Parser/Registry.phpMeM2e"phpunit/Metadata/PostCondition.phpueuX !phpunit/Metadata/PreCondition.phprer\AI<(phpunit/Metadata/PreserveGlobalState.phpe%phpunit/Metadata/RequiresFunction.phpsesh#phpunit/Metadata/RequiresMethod.phpeФ,phpunit/Metadata/RequiresOperatingSystem.phpe/2phpunit/Metadata/RequiresOperatingSystemFamily.phpe.E phpunit/Metadata/RequiresPhp.php%e% E)phpunit/Metadata/RequiresPhpExtension.phpe{k:$phpunit/Metadata/RequiresPhpunit.php1e1$phpunit/Metadata/RequiresSetting.phpez{ڤ.phpunit/Metadata/RunClassInSeparateProcess.phpe9)phpunit/Metadata/RunInSeparateProcess.phpe&0phpunit/Metadata/RunTestsInSeparateProcesses.phpeez(phpunit/Metadata/Test.phpZeZ.ophpunit/Metadata/TestDox.php e (phpunit/Metadata/TestWith.phpeL:phpunit/Metadata/Uses.php%e%Fphpunit/Metadata/UsesClass.php:e:rY%phpunit/Metadata/UsesDefaultClass.phpReR"!!phpunit/Metadata/UsesFunction.phpBeBqɤ2phpunit/Metadata/Version/ComparisonRequirement.phpheh52phpunit/Metadata/Version/ConstraintRequirement.phpew㳤(phpunit/Metadata/Version/Requirement.phpea p_(phpunit/Metadata/WithoutErrorHandler.phpe#+@$phpunit/Runner/Baseline/Baseline.phpeAphpunit/Runner/Baseline/Exception/CannotLoadBaselineException.phpe\8Bphpunit/Runner/Baseline/Exception/FileDoesNotHaveLineException.phpeM%phpunit/Runner/Baseline/Generator.php e *Y!phpunit/Runner/Baseline/Issue.php e 95¤"phpunit/Runner/Baseline/Reader.phpn en G2phpunit/Runner/Baseline/RelativePathCalculator.php +e +1phpunit/Runner/Baseline/Subscriber/Subscriber.phpe>>kIphpunit/Runner/Baseline/Subscriber/TestTriggeredDeprecationSubscriber.phpeP53Dphpunit/Runner/Baseline/Subscriber/TestTriggeredNoticeSubscriber.phpnen6=Lphpunit/Runner/Baseline/Subscriber/TestTriggeredPhpDeprecationSubscriber.phpeO դGphpunit/Runner/Baseline/Subscriber/TestTriggeredPhpNoticeSubscriber.php}e}KPHphpunit/Runner/Baseline/Subscriber/TestTriggeredPhpWarningSubscriber.phpeD-lEphpunit/Runner/Baseline/Subscriber/TestTriggeredWarningSubscriber.phpsesk2"phpunit/Runner/Baseline/Writer.phpe-,phpunit/Runner/CodeCoverage.phpt2et2}phpunit/Runner/ErrorHandler.phppep.~j8phpunit/Runner/Exception/ClassCannotBeFoundException.phpec@phpunit/Runner/Exception/ClassDoesNotExtendTestCaseException.phpen5phpunit/Runner/Exception/ClassIsAbstractException.phpep7o>phpunit/Runner/Exception/DirectoryCannotBeCreatedException.phpe:Vr+phpunit/Runner/Exception/ErrorException.phpee"&phpunit/Runner/Exception/Exception.phpenHA6phpunit/Runner/Exception/FileDoesNotExistException.phpeg K2phpunit/Runner/Exception/InvalidOrderException.phpe8Kڤ5phpunit/Runner/Exception/InvalidPhptFileException.phpezA>4phpunit/Runner/Exception/NoIgnoredEventException.phpe3Uǚ;phpunit/Runner/Exception/ParameterDoesNotExistException.phpe]wQDphpunit/Runner/Exception/PhptExternalFileCannotBeLoadedException.phpej0phpunit/Runner/Exception/ReflectionException.phpe^ss<phpunit/Runner/Exception/UnsupportedPhptSectionException.phpe &phpunit/Runner/Extension/Extension.phpeVZ2phpunit/Runner/Extension/ExtensionBootstrapper.php[ e[ Zq3#phpunit/Runner/Extension/Facade.php +e +TŃ0phpunit/Runner/Extension/ParameterCollection.phpenZ[c'phpunit/Runner/Extension/PharLoader.phpeD 4phpunit/Runner/Filter/ExcludeGroupFilterIterator.phplelH}H!phpunit/Runner/Filter/Factory.phpeX/-phpunit/Runner/Filter/GroupFilterIterator.php9e9.&?4phpunit/Runner/Filter/IncludeGroupFilterIterator.phpkekSw,phpunit/Runner/Filter/NameFilterIterator.php e uc.phpunit/Runner/Filter/TestIdFilterIterator.phpe/=phpunit/Runner/GarbageCollection/GarbageCollectionHandler.phpetKphpunit/Runner/GarbageCollection/Subscriber/ExecutionFinishedSubscriber.phpeRJphpunit/Runner/GarbageCollection/Subscriber/ExecutionStartedSubscriber.phpe+0:phpunit/Runner/GarbageCollection/Subscriber/Subscriber.php"e"eFphpunit/Runner/GarbageCollection/Subscriber/TestFinishedSubscriber.php[e[Hphpunit/Runner/PhptTestCase.phpZUeZU`-Ϥ1phpunit/Runner/ResultCache/DefaultResultCache.php e X-.phpunit/Runner/ResultCache/NullResultCache.phpeS*phpunit/Runner/ResultCache/ResultCache.phpe3Gb1phpunit/Runner/ResultCache/ResultCacheHandler.phpe4phpunit/Runner/ResultCache/Subscriber/Subscriber.phpeM#Gphpunit/Runner/ResultCache/Subscriber/TestConsideredRiskySubscriber.phpe$k?phpunit/Runner/ResultCache/Subscriber/TestErroredSubscriber.phpe4}Fr>phpunit/Runner/ResultCache/Subscriber/TestFailedSubscriber.phpe )@phpunit/Runner/ResultCache/Subscriber/TestFinishedSubscriber.phpUeUVHphpunit/Runner/ResultCache/Subscriber/TestMarkedIncompleteSubscriber.phpe.6@phpunit/Runner/ResultCache/Subscriber/TestPreparedSubscriber.phpeΤ?phpunit/Runner/ResultCache/Subscriber/TestSkippedSubscriber.phpOeODÇEphpunit/Runner/ResultCache/Subscriber/TestSuiteFinishedSubscriber.phpeߤDphpunit/Runner/ResultCache/Subscriber/TestSuiteStartedSubscriber.phpe0DĤ'phpunit/Runner/TestResult/Collector.php!Ie!I$phpunit/Runner/TestResult/Facade.php e X#phpunit/Runner/TestResult/Issue.php e ysh)phpunit/Runner/TestResult/PassedTests.php$ e$ kWOphpunit/Runner/TestResult/Subscriber/BeforeTestClassMethodErroredSubscriber.php.e.$|;Cphpunit/Runner/TestResult/Subscriber/ExecutionStartedSubscriber.php$e$ޙ63phpunit/Runner/TestResult/Subscriber/Subscriber.phpe񡠒Fphpunit/Runner/TestResult/Subscriber/TestConsideredRiskySubscriber.phpe}9r4>phpunit/Runner/TestResult/Subscriber/TestErroredSubscriber.phpeܤ=phpunit/Runner/TestResult/Subscriber/TestFailedSubscriber.phpe?%+?phpunit/Runner/TestResult/Subscriber/TestFinishedSubscriber.phpeۤGphpunit/Runner/TestResult/Subscriber/TestMarkedIncompleteSubscriber.phpelH?phpunit/Runner/TestResult/Subscriber/TestPreparedSubscriber.phpe<¤Qphpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredDeprecationSubscriber.phpeYMphpunit/Runner/TestResult/Subscriber/TestRunnerTriggeredWarningSubscriber.phpex>phpunit/Runner/TestResult/Subscriber/TestSkippedSubscriber.phpeADphpunit/Runner/TestResult/Subscriber/TestSuiteFinishedSubscriber.phpeCphpunit/Runner/TestResult/Subscriber/TestSuiteSkippedSubscriber.phpeFCphpunit/Runner/TestResult/Subscriber/TestSuiteStartedSubscriber.phpe bZKphpunit/Runner/TestResult/Subscriber/TestTriggeredDeprecationSubscriber.phpesXcEphpunit/Runner/TestResult/Subscriber/TestTriggeredErrorSubscriber.phpe{9Fphpunit/Runner/TestResult/Subscriber/TestTriggeredNoticeSubscriber.phpeߋ%Nphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpDeprecationSubscriber.phpeeLOԤIphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpNoticeSubscriber.phpe dJphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpWarningSubscriber.phpeèMRphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitDeprecationSubscriber.php0e0gﰤLphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitErrorSubscriber.php e T5Nphpunit/Runner/TestResult/Subscriber/TestTriggeredPhpunitWarningSubscriber.phpeDnGphpunit/Runner/TestResult/Subscriber/TestTriggeredWarningSubscriber.phpeɤ(phpunit/Runner/TestResult/TestResult.php<e<&u;"phpunit/Runner/TestSuiteLoader.phpe[ +uФ"phpunit/Runner/TestSuiteSorter.phpR%eR%phpunit/Runner/Version.phpesphpunit/TextUI/Application.phpOeOx"phpunit/TextUI/Command/Command.phpeO㍤9phpunit/TextUI/Command/Commands/AtLeastVersionCommand.phpeTؼ@phpunit/TextUI/Command/Commands/GenerateConfigurationCommand.phpeor5phpunit/TextUI/Command/Commands/ListGroupsCommand.phpe,e9phpunit/TextUI/Command/Commands/ListTestSuitesCommand.phpeKn:phpunit/TextUI/Command/Commands/ListTestsAsTextCommand.phpeE>9phpunit/TextUI/Command/Commands/ListTestsAsXmlCommand.phpe >?phpunit/TextUI/Command/Commands/MigrateConfigurationCommand.phpe+3phpunit/TextUI/Command/Commands/ShowHelpCommand.php/e/>>#6phpunit/TextUI/Command/Commands/ShowVersionCommand.phpSeS7phpunit/TextUI/Command/Commands/VersionCheckCommand.phpe"Ƥ@phpunit/TextUI/Command/Commands/WarmCodeCoverageCacheCommand.php e )!phpunit/TextUI/Command/Result.phpcec{(phpunit/TextUI/Configuration/Builder.phpe4a(,phpunit/TextUI/Configuration/Cli/Builder.phpfZefZv2phpunit/TextUI/Configuration/Cli/Configuration.phpe#c.phpunit/TextUI/Configuration/Cli/Exception.phpe%zE?phpunit/TextUI/Configuration/Cli/XmlConfigurationFileFinder.phpe`L;phpunit/TextUI/Configuration/CodeCoverageFilterRegistry.phpe .phpunit/TextUI/Configuration/Configuration.php~e~a]8Dphpunit/TextUI/Configuration/Exception/CannotFindSchemaException.php&e&ؔ}Sphpunit/TextUI/Configuration/Exception/CodeCoverageReportNotConfiguredException.php$e$Nphpunit/TextUI/Configuration/Exception/ConfigurationCannotBeBuiltException.phpeZ$&4phpunit/TextUI/Configuration/Exception/Exception.phpeGphpunit/TextUI/Configuration/Exception/FilterNotConfiguredException.phpegGLphpunit/TextUI/Configuration/Exception/IncludePathNotConfiguredException.phpexHphpunit/TextUI/Configuration/Exception/LoggingNotConfiguredException.phpeY%>phpunit/TextUI/Configuration/Exception/NoBaselineException.phpeP!:?phpunit/TextUI/Configuration/Exception/NoBootstrapException.phpe`lƤDphpunit/TextUI/Configuration/Exception/NoCacheDirectoryException.phpeCAphpunit/TextUI/Configuration/Exception/NoCliArgumentException.phpe|J?RGphpunit/TextUI/Configuration/Exception/NoConfigurationFileException.phpeMLphpunit/TextUI/Configuration/Exception/NoCoverageCacheDirectoryException.phpe;Cphpunit/TextUI/Configuration/Exception/NoCustomCssFileException.phpeʑ0Fphpunit/TextUI/Configuration/Exception/NoDefaultTestSuiteException.phpe Lphpunit/TextUI/Configuration/Exception/NoPharExtensionDirectoryException.phpe)R'phpunit/TextUI/Configuration/Merger.phped.s}+phpunit/TextUI/Configuration/PhpHandler.php\e\y)phpunit/TextUI/Configuration/Registry.phpK eK /B-phpunit/TextUI/Configuration/SourceFilter.phpe^:ؤ-phpunit/TextUI/Configuration/SourceMapper.php e ff1phpunit/TextUI/Configuration/TestSuiteBuilder.phpe ă/phpunit/TextUI/Configuration/Value/Constant.php>e>o<9phpunit/TextUI/Configuration/Value/ConstantCollection.phpeW6bAphpunit/TextUI/Configuration/Value/ConstantCollectionIterator.phpeg]0phpunit/TextUI/Configuration/Value/Directory.phpe3F:phpunit/TextUI/Configuration/Value/DirectoryCollection.php e ?aBphpunit/TextUI/Configuration/Value/DirectoryCollectionIterator.phpeہW9phpunit/TextUI/Configuration/Value/ExtensionBootstrap.phper[Cphpunit/TextUI/Configuration/Value/ExtensionBootstrapCollection.phpeѤKphpunit/TextUI/Configuration/Value/ExtensionBootstrapCollectionIterator.phpe( V+phpunit/TextUI/Configuration/Value/File.php/e/w5phpunit/TextUI/Configuration/Value/FileCollection.phpe'P=phpunit/TextUI/Configuration/Value/FileCollectionIterator.phpnenj6phpunit/TextUI/Configuration/Value/FilterDirectory.phpepS@phpunit/TextUI/Configuration/Value/FilterDirectoryCollection.phpDeDJHphpunit/TextUI/Configuration/Value/FilterDirectoryCollectionIterator.phpe񭥤,phpunit/TextUI/Configuration/Value/Group.phpekפ6phpunit/TextUI/Configuration/Value/GroupCollection.php8e8+Bm>phpunit/TextUI/Configuration/Value/GroupCollectionIterator.phpyeywX1phpunit/TextUI/Configuration/Value/IniSetting.php1e1;phpunit/TextUI/Configuration/Value/IniSettingCollection.phpe^Cphpunit/TextUI/Configuration/Value/IniSettingCollectionIterator.phpe8Ф*phpunit/TextUI/Configuration/Value/Php.phpYeY畉-phpunit/TextUI/Configuration/Value/Source.phpe-Ȥ4phpunit/TextUI/Configuration/Value/TestDirectory.phpeF >phpunit/TextUI/Configuration/Value/TestDirectoryCollection.php-e-zȤFphpunit/TextUI/Configuration/Value/TestDirectoryCollectionIterator.phpea>k/phpunit/TextUI/Configuration/Value/TestFile.phpe)tФ9phpunit/TextUI/Configuration/Value/TestFileCollection.phpeAphpunit/TextUI/Configuration/Value/TestFileCollectionIterator.phpep0phpunit/TextUI/Configuration/Value/TestSuite.phpe䣉:phpunit/TextUI/Configuration/Value/TestSuiteCollection.phpePBphpunit/TextUI/Configuration/Value/TestSuiteCollectionIterator.phpe;E/phpunit/TextUI/Configuration/Value/Variable.phpe@9phpunit/TextUI/Configuration/Value/VariableCollection.phpeїAphpunit/TextUI/Configuration/Value/VariableCollectionIterator.phpeՑ>phpunit/TextUI/Configuration/Xml/CodeCoverage/CodeCoverage.phpe?phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Clover.phpeƣˠBphpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Cobertura.phpe5?phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Crap4j.phppep^=phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Html.php +e +CD<phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Php.phpeCC|=phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Text.php}e}<phpunit/TextUI/Configuration/Xml/CodeCoverage/Report/Xml.phpe:H-2phpunit/TextUI/Configuration/Xml/Configuration.php e lE<9phpunit/TextUI/Configuration/Xml/DefaultConfiguration.php e uԤ.phpunit/TextUI/Configuration/Xml/Exception.phpeN5+.phpunit/TextUI/Configuration/Xml/Generator.phpeX]!+phpunit/TextUI/Configuration/Xml/Groups.phpded8=Ӥ@phpunit/TextUI/Configuration/Xml/LoadedFromFileConfiguration.phpe-[+phpunit/TextUI/Configuration/Xml/Loader.phpσeσ`Ӥ2phpunit/TextUI/Configuration/Xml/Logging/Junit.phpeФ4phpunit/TextUI/Configuration/Xml/Logging/Logging.php +e +#5phpunit/TextUI/Configuration/Xml/Logging/TeamCity.phpeϦ9phpunit/TextUI/Configuration/Xml/Logging/TestDox/Html.phpeB*$9phpunit/TextUI/Configuration/Xml/Logging/TestDox/Text.phpe?phpunit/TextUI/Configuration/Xml/Migration/MigrationBuilder.php` e` HHHphpunit/TextUI/Configuration/Xml/Migration/MigrationBuilderException.phpeUWĝAphpunit/TextUI/Configuration/Xml/Migration/MigrationException.phpe\ZIphpunit/TextUI/Configuration/Xml/Migration/Migrations/ConvertLogTypes.phpehoePphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCloverToReport.phpXeXijPphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageCrap4jToReport.phpe$i'Nphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageHtmlToReport.phpeՄjMphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoveragePhpToReport.phpFeF^ӤNphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageTextToReport.phpeV_Mphpunit/TextUI/Configuration/Xml/Migration/Migrations/CoverageXmlToReport.phpKeK_ Zphpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCacheDirectoryAttribute.php\e\Rphpunit/TextUI/Configuration/Xml/Migration/Migrations/IntroduceCoverageElement.phpeUNphpunit/TextUI/Configuration/Xml/Migration/Migrations/LogToReportMigration.phpeUCphpunit/TextUI/Configuration/Xml/Migration/Migrations/Migration.phpe'ephpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromFilterWhitelistToCoverage.phpeU%5Zphpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveAttributesFromRootToCoverage.phpe"OYphpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveCoverageDirectoriesToSource.phpWeWyzYphpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistExcludesToCoverage.phpe +Yphpunit/TextUI/Configuration/Xml/Migration/Migrations/MoveWhitelistIncludesToCoverage.phpe8;sphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute.phpe yhphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveBeStrictAboutTodoAnnotatedTestsAttribute.phpmemXphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheResultFileAttribute.php=e=ۨǤTphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCacheTokensAttribute.php1e1T9`phpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveConversionToExceptionsAttributes.php e fphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementCacheDirectoryAttribute.phpemphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveCoverageElementProcessUncoveredFilesAttribute.phpe[ Kphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveEmptyFilter.php{e{KIphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveListeners.php'e'nHphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLogTypes.phpieiOphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveLoggingElements.php)e).Vphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveNoInteractionAttribute.php7e7⼿Qphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemovePrinterAttributes.phpe}Tphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestDoxGroupsElement.php6e6DYphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveTestSuiteLoaderAttributes.phpesUPphpunit/TextUI/Configuration/Xml/Migration/Migrations/RemoveVerboseAttribute.php%e%J_phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBackupStaticAttributesAttribute.php$e$CȤfphpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameBeStrictAboutCoversAnnotationAttribute.phpNeNb^phpunit/TextUI/Configuration/Xml/Migration/Migrations/RenameForceCoversAnnotationAttribute.php"e" Nphpunit/TextUI/Configuration/Xml/Migration/Migrations/UpdateSchemaLocation.phpe 7phpunit/TextUI/Configuration/Xml/Migration/Migrator.php:e:zk?phpunit/TextUI/Configuration/Xml/Migration/SnapshotNodeList.phpgegi,phpunit/TextUI/Configuration/Xml/PHPUnit.php;e;,K6Ophpunit/TextUI/Configuration/Xml/SchemaDetector/FailedSchemaDetectionResult.phpe,F6¤Iphpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetectionResult.php.e.͋*ӤBphpunit/TextUI/Configuration/Xml/SchemaDetector/SchemaDetector.phpeR~Sphpunit/TextUI/Configuration/Xml/SchemaDetector/SuccessfulSchemaDetectionResult.php,e,k1phpunit/TextUI/Configuration/Xml/SchemaFinder.phpeVNˤ4phpunit/TextUI/Configuration/Xml/TestSuiteMapper.phpebH?phpunit/TextUI/Configuration/Xml/Validator/ValidationResult.phpe]8phpunit/TextUI/Configuration/Xml/Validator/Validator.php1e1EŤ;phpunit/TextUI/Exception/DirectoryDoesNotExistException.phpe-ʤ&phpunit/TextUI/Exception/Exception.phpeD{i=phpunit/TextUI/Exception/ExtensionsNotConfiguredException.phpe3f.3phpunit/TextUI/Exception/InvalidSocketException.phpe0phpunit/TextUI/Exception/ReflectionException.phpeJuv-phpunit/TextUI/Exception/RuntimeException.phpe ;phpunit/TextUI/Exception/TestDirectoryNotFoundException.phpenL6phpunit/TextUI/Exception/TestFileNotFoundException.phpe?lphpunit/TextUI/Help.phpn2en2)ȤAphpunit/TextUI/Output/Default/ProgressPrinter/ProgressPrinter.phpx0ex06vcphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/BeforeTestClassMethodErroredSubscriber.phpFeFC8%Gphpunit/TextUI/Output/Default/ProgressPrinter/Subscriber/Subscriber.php;e;e> *sebastian-comparator/NumericComparator.phpe]>m)sebastian-comparator/ObjectComparator.php +e +rXƤ+sebastian-comparator/ResourceComparator.phpIeIN')sebastian-comparator/ScalarComparator.php e D~&3sebastian-comparator/SplObjectStorageComparator.phpe'sebastian-comparator/TypeComparator.phpe-sebastian-comparator/exceptions/Exception.phpvevEᵤ4sebastian-comparator/exceptions/RuntimeException.phpeV'#sebastian-complexity/Calculator.phpe(͂.sebastian-complexity/Complexity/Complexity.php2e2 +U[8sebastian-complexity/Complexity/ComplexityCollection.php +e +ʼz@sebastian-complexity/Complexity/ComplexityCollectionIterator.phpe]Y,sebastian-complexity/Exception/Exception.phpvev73sebastian-complexity/Exception/RuntimeException.phpeCdWsebastian-complexity/LICENSEeP@٤=sebastian-complexity/Visitor/ComplexityCalculatingVisitor.php e Gsebastian-complexity/Visitor/CyclomaticComplexityCalculatingVisitor.phpeܽsebastian-diff/Chunk.php e sebastian-diff/Diff.phpWeWXsebastian-diff/Differ.phpeה3sebastian-diff/Exception/ConfigurationException.php!e!&sebastian-diff/Exception/Exception.phpjej05sebastian-diff/Exception/InvalidArgumentException.phpeqsebastian-diff/LICENSEeTsebastian-diff/Line.phpemg5sebastian-diff/LongestCommonSubsequenceCalculator.phpe}e7zDsebastian-diff/MemoryEfficientLongestCommonSubsequenceCalculator.phpy ey [DQ4sebastian-diff/Output/AbstractChunkOutputBuilder.phpes/sebastian-diff/Output/DiffOnlyOutputBuilder.phpyey"4sebastian-diff/Output/DiffOutputBuilderInterface.phpeV8sebastian-diff/Output/StrictUnifiedDiffOutputBuilder.phpU(eU(ߢ"2sebastian-diff/Output/UnifiedDiffOutputBuilder.phpeɅ|sebastian-diff/Parser.php e cGBsebastian-diff/TimeEfficientLongestCommonSubsequenceCalculator.php. e. N!sebastian-environment/Console.phpeP1Ťsebastian-environment/LICENSEeWj!sebastian-environment/Runtime.phpeB^sebastian-exporter/Exporter.php"e"5sebastian-exporter/LICENSEeT'sebastian-global-state/CodeExporter.phph eh :}&sebastian-global-state/ExcludeList.php e :$sebastian-global-state/LICENSEe$#sebastian-global-state/Restorer.php2 e2 Rɤ#sebastian-global-state/Snapshot.php&e&r/sebastian-global-state/exceptions/Exception.phpyeyJ6sebastian-global-state/exceptions/RuntimeException.phpe;#sebastian-lines-of-code/Counter.phpeD/sebastian-lines-of-code/Exception/Exception.phpzez aV>sebastian-lines-of-code/Exception/IllogicalValuesException.phpeG<sebastian-lines-of-code/Exception/NegativeValueException.phpe +ڤ6sebastian-lines-of-code/Exception/RuntimeException.phpeKsebastian-lines-of-code/LICENSEeP@٤/sebastian-lines-of-code/LineCountingVisitor.phpe ^'sebastian-lines-of-code/LinesOfCode.php e (EФ*sebastian-object-enumerator/Enumerator.phpe_.sebastian-object-reflector/ObjectReflector.phpe9m 'sebastian-recursion-context/Context.phpe!#sebastian-recursion-context/LICENSEeTsebastian-type/LICENSEe sebastian-type/Parameter.phpe~]#sebastian-type/ReflectionMapper.phpe 8sebastian-type/TypeName.phpeh&sebastian-type/exception/Exception.phpjejbᮧ-sebastian-type/exception/RuntimeException.phpe%$sebastian-type/type/CallableType.phpeĊP!sebastian-type/type/FalseType.phpbeb_&)sebastian-type/type/GenericObjectType.php e c(sebastian-type/type/IntersectionType.php +e +¤$sebastian-type/type/IterableType.phpe3դ!sebastian-type/type/MixedType.php'e'o!sebastian-type/type/NeverType.phpeFҹ sebastian-type/type/NullType.php"e"9$F"sebastian-type/type/ObjectType.php%e%"sebastian-type/type/SimpleType.php,e,0"sebastian-type/type/StaticType.phpe", sebastian-type/type/TrueType.php]e]<iפsebastian-type/type/Type.phpeR!sebastian-type/type/UnionType.php* e* AA#sebastian-type/type/UnknownType.phpeǤ sebastian-type/type/VoidType.phpesebastian-version/LICENSEeVosebastian-version/Version.phpe.7theseer-tokenizer/Exception.phpnen'Ǥtheseer-tokenizer/LICENSEeR ("theseer-tokenizer/NamespaceUri.phpHeH=C+theseer-tokenizer/NamespaceUriException.phpyey'Hetheseer-tokenizer/Token.phpe4%theseer-tokenizer/TokenCollection.php +e +a.theseer-tokenizer/TokenCollectionException.php|e|`g-theseer-tokenizer/Tokenizer.php! e! X(֤#theseer-tokenizer/XMLSerializer.phpeg; .phpstorm.meta.phpeɒs{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "e06728e5442edec84af96f94a889b4a7", + "packages": [ + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.0.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4a21235f7e56e713259a6f76bf4b5ea08502b9dc", + "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.0" + }, + "time": "2024-01-07T17:17:35+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "10.1.11", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "78c3b7625965c2513ee96569a4dbb62601784145" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/78c3b7625965c2513ee96569a4dbb62601784145", + "reference": "78c3b7625965c2513ee96569a4dbb62601784145", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-text-template": "^3.0", + "sebastian/code-unit-reverse-lookup": "^3.0", + "sebastian/complexity": "^3.0", + "sebastian/environment": "^6.0", + "sebastian/lines-of-code": "^2.0", + "sebastian/version": "^4.0", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.11" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T15:38:30+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T06:24:48+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:56:09+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T14:07:24+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:57:52+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:15+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:59:15+00:00" + }, + { + "name": "sebastian/comparator", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-14T13:18:12+00:00" + }, + { + "name": "sebastian/complexity", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "68ff824baeae169ec9f2137158ee529584553799" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:37:17+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/fbf413a49e54f6b9b17e12d900ac7f6101591b7f", + "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-22T10:55:06+00:00" + }, + { + "name": "sebastian/environment", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951", + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-04-11T05:39:26+00:00" + }, + { + "name": "sebastian/exporter", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc", + "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-09-24T13:22:09+00:00" + }, + { + "name": "sebastian/global-state", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-07-19T07:19:23+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:38:20+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:08:32+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:06:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:05:40+00:00" + }, + { + "name": "sebastian/type", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:10:45+00:00" + }, + { + "name": "sebastian/version", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-07T11:34:05+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.2" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2023-11-20T00:12:19+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": ">=8.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*" + }, + "platform-dev": [], + "platform-overrides": { + "php": "8.1.0" + }, + "plugin-api-version": "2.6.0" +} +phpunit/phpunit: 10.5.8 myclabs/deep-copy: 1.11.1 -nikic/php-parser: v4.15.4 +nikic/php-parser: v5.0.0 phar-io/manifest: 2.0.3 phar-io/version: 3.2.1 -phpunit/php-code-coverage: 10.0.2 -phpunit/php-file-iterator: 4.0.1 +phpunit/php-code-coverage: 10.1.11 +phpunit/php-file-iterator: 4.1.0 phpunit/php-invoker: 4.0.0 -phpunit/php-text-template: 3.0.0 +phpunit/php-text-template: 3.0.1 phpunit/php-timer: 6.0.0 sebastian/cli-parser: 2.0.0 sebastian/code-unit: 2.0.0 sebastian/code-unit-reverse-lookup: 3.0.0 -sebastian/comparator: 5.0.0 -sebastian/complexity: 3.0.0 -sebastian/diff: 5.0.0 -sebastian/environment: 6.0.0 -sebastian/exporter: 5.0.0 -sebastian/global-state: 6.0.0 -sebastian/lines-of-code: 2.0.0 +sebastian/comparator: 5.0.1 +sebastian/complexity: 3.2.0 +sebastian/diff: 5.1.0 +sebastian/environment: 6.0.1 +sebastian/exporter: 5.1.1 +sebastian/global-state: 6.0.1 +sebastian/lines-of-code: 2.0.2 sebastian/object-enumerator: 5.0.0 sebastian/object-reflector: 3.0.0 sebastian/recursion-context: 5.0.0 sebastian/type: 4.0.0 sebastian/version: 4.0.1 -theseer/tokenizer: 1.2.1 +theseer/tokenizer: 1.2.2 */ + protected array $attributes = []; + /** @var list */ + protected array $constants = []; + /** @var list */ + protected array $attributeGroups = []; + /** @var Identifier|Node\Name|Node\ComplexType|null */ + protected ?Node $type = null; /** * Creates a class constant builder * - * @param string|Identifier $name Name + * @param string|Identifier $name Name * @param Node\Expr|bool|null|int|float|string|array $value Value */ public function __construct($name, $value) @@ -3922,7 +5627,7 @@ class ClassConst implements PhpParser\Builder /** * Add another constant to const group * - * @param string|Identifier $name Name + * @param string|Identifier $name Name * @param Node\Expr|bool|null|int|float|string|array $value Value * * @return $this The builder instance (for fluid interface) @@ -3939,7 +5644,7 @@ class ClassConst implements PhpParser\Builder */ public function makePublic() { - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PUBLIC); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC); return $this; } /** @@ -3949,7 +5654,7 @@ class ClassConst implements PhpParser\Builder */ public function makeProtected() { - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PROTECTED); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED); return $this; } /** @@ -3959,7 +5664,7 @@ class ClassConst implements PhpParser\Builder */ public function makePrivate() { - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PRIVATE); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE); return $this; } /** @@ -3969,7 +5674,7 @@ class ClassConst implements PhpParser\Builder */ public function makeFinal() { - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_FINAL); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::FINAL); return $this; } /** @@ -3996,6 +5701,18 @@ class ClassConst implements PhpParser\Builder $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute); return $this; } + /** + * Sets the constant type. + * + * @param string|Node\Name|Identifier|Node\ComplexType $type + * + * @return $this + */ + public function setType($type) + { + $this->type = BuilderHelpers::normalizeType($type); + return $this; + } /** * Returns the built class node. * @@ -4003,7 +5720,7 @@ class ClassConst implements PhpParser\Builder */ public function getNode() : PhpParser\Node { - return new Stmt\ClassConst($this->constants, $this->flags, $this->attributes, $this->attributeGroups); + return new Stmt\ClassConst($this->constants, $this->flags, $this->attributes, $this->attributeGroups, $this->type); } } */ + protected array $implements = []; + protected int $flags = 0; + /** @var list */ + protected array $uses = []; + /** @var list */ + protected array $constants = []; + /** @var list */ + protected array $properties = []; + /** @var list */ + protected array $methods = []; + /** @var list */ + protected array $attributeGroups = []; /** * Creates a class builder. * @@ -4070,7 +5793,7 @@ class Class_ extends Declaration */ public function makeAbstract() { - $this->flags = BuilderHelpers::addClassModifier($this->flags, Stmt\Class_::MODIFIER_ABSTRACT); + $this->flags = BuilderHelpers::addClassModifier($this->flags, Modifiers::ABSTRACT); return $this; } /** @@ -4080,12 +5803,17 @@ class Class_ extends Declaration */ public function makeFinal() { - $this->flags = BuilderHelpers::addClassModifier($this->flags, Stmt\Class_::MODIFIER_FINAL); + $this->flags = BuilderHelpers::addClassModifier($this->flags, Modifiers::FINAL); return $this; } + /** + * Makes the class readonly. + * + * @return $this The builder instance (for fluid interface) + */ public function makeReadonly() { - $this->flags = BuilderHelpers::addClassModifier($this->flags, Stmt\Class_::MODIFIER_READONLY); + $this->flags = BuilderHelpers::addClassModifier($this->flags, Modifiers::READONLY); return $this; } /** @@ -4098,12 +5826,17 @@ class Class_ extends Declaration public function addStmt($stmt) { $stmt = BuilderHelpers::normalizeNode($stmt); - $targets = [Stmt\TraitUse::class => &$this->uses, Stmt\ClassConst::class => &$this->constants, Stmt\Property::class => &$this->properties, Stmt\ClassMethod::class => &$this->methods]; - $class = \get_class($stmt); - if (!isset($targets[$class])) { + if ($stmt instanceof Stmt\Property) { + $this->properties[] = $stmt; + } elseif ($stmt instanceof Stmt\ClassMethod) { + $this->methods[] = $stmt; + } elseif ($stmt instanceof Stmt\TraitUse) { + $this->uses[] = $stmt; + } elseif ($stmt instanceof Stmt\ClassConst) { + $this->constants[] = $stmt; + } else { throw new \LogicException(\sprintf('Unexpected node of type "%s"', $stmt->getType())); } - $targets[$class][] = $stmt; return $this; } /** @@ -4137,12 +5870,20 @@ use PHPUnit\PhpParser; use PHPUnit\PhpParser\BuilderHelpers; abstract class Declaration implements PhpParser\Builder { - protected $attributes = []; + /** @var array */ + protected array $attributes = []; + /** + * Adds a statement. + * + * @param PhpParser\Node\Stmt|PhpParser\Builder $stmt The statement to add + * + * @return $this The builder instance (for fluid interface) + */ public abstract function addStmt($stmt); /** * Adds multiple statements. * - * @param array $stmts The statements to add + * @param (PhpParser\Node\Stmt|PhpParser\Builder)[] $stmts The statements to add * * @return $this The builder instance (for fluid interface) */ @@ -4178,15 +5919,18 @@ use PHPUnit\PhpParser\Node\Identifier; use PHPUnit\PhpParser\Node\Stmt; class EnumCase implements PhpParser\Builder { + /** @var Identifier|string */ protected $name; - protected $value = null; - protected $attributes = []; - /** @var Node\AttributeGroup[] */ - protected $attributeGroups = []; + /** @var ?Node\Expr */ + protected ?Node\Expr $value = null; + /** @var array */ + protected array $attributes = []; + /** @var list */ + protected array $attributeGroups = []; /** * Creates an enum case builder. * - * @param string|Identifier $name Name + * @param string|Identifier $name Name */ public function __construct($name) { @@ -4251,15 +5995,20 @@ use PHPUnit\PhpParser\Node\Name; use PHPUnit\PhpParser\Node\Stmt; class Enum_ extends Declaration { - protected $name; - protected $scalarType = null; - protected $implements = []; - protected $uses = []; - protected $enumCases = []; - protected $constants = []; - protected $methods = []; - /** @var Node\AttributeGroup[] */ - protected $attributeGroups = []; + protected string $name; + protected ?Identifier $scalarType = null; + /** @var list */ + protected array $implements = []; + /** @var list */ + protected array $uses = []; + /** @var list */ + protected array $enumCases = []; + /** @var list */ + protected array $constants = []; + /** @var list */ + protected array $methods = []; + /** @var list */ + protected array $attributeGroups = []; /** * Creates an enum builder. * @@ -4272,7 +6021,7 @@ class Enum_ extends Declaration /** * Sets the scalar type. * - * @param string|Identifier $type + * @param string|Identifier $scalarType * * @return $this */ @@ -4305,12 +6054,17 @@ class Enum_ extends Declaration public function addStmt($stmt) { $stmt = BuilderHelpers::normalizeNode($stmt); - $targets = [Stmt\TraitUse::class => &$this->uses, Stmt\EnumCase::class => &$this->enumCases, Stmt\ClassConst::class => &$this->constants, Stmt\ClassMethod::class => &$this->methods]; - $class = \get_class($stmt); - if (!isset($targets[$class])) { + if ($stmt instanceof Stmt\EnumCase) { + $this->enumCases[] = $stmt; + } elseif ($stmt instanceof Stmt\ClassMethod) { + $this->methods[] = $stmt; + } elseif ($stmt instanceof Stmt\TraitUse) { + $this->uses[] = $stmt; + } elseif ($stmt instanceof Stmt\ClassConst) { + $this->constants[] = $stmt; + } else { throw new \LogicException(\sprintf('Unexpected node of type "%s"', $stmt->getType())); } - $targets[$class][] = $stmt; return $this; } /** @@ -4344,10 +6098,11 @@ use PHPUnit\PhpParser\BuilderHelpers; use PHPUnit\PhpParser\Node; abstract class FunctionLike extends Declaration { - protected $returnByRef = \false; - protected $params = []; - /** @var string|Node\Name|Node\NullableType|null */ - protected $returnType = null; + protected bool $returnByRef = \false; + /** @var Node\Param[] */ + protected array $params = []; + /** @var Node\Identifier|Node\Name|Node\ComplexType|null */ + protected ?Node $returnType = null; /** * Make the function return by reference. * @@ -4377,7 +6132,7 @@ abstract class FunctionLike extends Declaration /** * Adds multiple parameters. * - * @param array $params The parameters to add + * @param (Node\Param|Param)[] $params The parameters to add * * @return $this The builder instance (for fluid interface) */ @@ -4412,10 +6167,11 @@ use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\Node\Stmt; class Function_ extends FunctionLike { - protected $name; - protected $stmts = []; - /** @var Node\AttributeGroup[] */ - protected $attributeGroups = []; + protected string $name; + /** @var list */ + protected array $stmts = []; + /** @var list */ + protected array $attributeGroups = []; /** * Creates a function builder. * @@ -4471,12 +6227,15 @@ use PHPUnit\PhpParser\Node\Name; use PHPUnit\PhpParser\Node\Stmt; class Interface_ extends Declaration { - protected $name; - protected $extends = []; - protected $constants = []; - protected $methods = []; - /** @var Node\AttributeGroup[] */ - protected $attributeGroups = []; + protected string $name; + /** @var list */ + protected array $extends = []; + /** @var list */ + protected array $constants = []; + /** @var list */ + protected array $methods = []; + /** @var list */ + protected array $attributeGroups = []; /** * Creates an interface builder. * @@ -4550,16 +6309,17 @@ namespace PHPUnit\PhpParser\Builder; use PHPUnit\PhpParser; use PHPUnit\PhpParser\BuilderHelpers; +use PHPUnit\PhpParser\Modifiers; use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\Node\Stmt; class Method extends FunctionLike { - protected $name; - protected $flags = 0; - /** @var array|null */ - protected $stmts = []; - /** @var Node\AttributeGroup[] */ - protected $attributeGroups = []; + protected string $name; + protected int $flags = 0; + /** @var list|null */ + protected ?array $stmts = []; + /** @var list */ + protected array $attributeGroups = []; /** * Creates a method builder. * @@ -4576,7 +6336,7 @@ class Method extends FunctionLike */ public function makePublic() { - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PUBLIC); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC); return $this; } /** @@ -4586,7 +6346,7 @@ class Method extends FunctionLike */ public function makeProtected() { - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PROTECTED); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED); return $this; } /** @@ -4596,7 +6356,7 @@ class Method extends FunctionLike */ public function makePrivate() { - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PRIVATE); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE); return $this; } /** @@ -4606,7 +6366,7 @@ class Method extends FunctionLike */ public function makeStatic() { - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_STATIC); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::STATIC); return $this; } /** @@ -4619,7 +6379,7 @@ class Method extends FunctionLike if (!empty($this->stmts)) { throw new \LogicException('Cannot make method with statements abstract'); } - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_ABSTRACT); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::ABSTRACT); $this->stmts = null; // abstract methods don't have statements return $this; @@ -4631,7 +6391,7 @@ class Method extends FunctionLike */ public function makeFinal() { - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_FINAL); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::FINAL); return $this; } /** @@ -4682,8 +6442,9 @@ use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\Node\Stmt; class Namespace_ extends Declaration { - private $name; - private $stmts = []; + private ?Node\Name $name; + /** @var Stmt[] */ + private array $stmts = []; /** * Creates a namespace builder. * @@ -4722,17 +6483,19 @@ namespace PHPUnit\PhpParser\Builder; use PHPUnit\PhpParser; use PHPUnit\PhpParser\BuilderHelpers; +use PHPUnit\PhpParser\Modifiers; use PHPUnit\PhpParser\Node; class Param implements PhpParser\Builder { - protected $name; - protected $default = null; - /** @var Node\Identifier|Node\Name|Node\NullableType|null */ - protected $type = null; - protected $byRef = \false; - protected $variadic = \false; - /** @var Node\AttributeGroup[] */ - protected $attributeGroups = []; + protected string $name; + protected ?Node\Expr $default = null; + /** @var Node\Identifier|Node\Name|Node\ComplexType|null */ + protected ?Node $type = null; + protected bool $byRef = \false; + protected int $flags = 0; + protected bool $variadic = \false; + /** @var list */ + protected array $attributeGroups = []; /** * Creates a parameter builder. * @@ -4770,36 +6533,63 @@ class Param implements PhpParser\Builder return $this; } /** - * Sets type for the parameter. + * Make the parameter accept the value by reference. * - * @param string|Node\Name|Node\Identifier|Node\ComplexType $type Parameter type + * @return $this The builder instance (for fluid interface) + */ + public function makeByRef() + { + $this->byRef = \true; + return $this; + } + /** + * Make the parameter variadic * * @return $this The builder instance (for fluid interface) + */ + public function makeVariadic() + { + $this->variadic = \true; + return $this; + } + /** + * Makes the (promoted) parameter public. * - * @deprecated Use setType() instead + * @return $this The builder instance (for fluid interface) */ - public function setTypeHint($type) + public function makePublic() { - return $this->setType($type); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC); + return $this; } /** - * Make the parameter accept the value by reference. + * Makes the (promoted) parameter protected. * * @return $this The builder instance (for fluid interface) */ - public function makeByRef() + public function makeProtected() { - $this->byRef = \true; + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED); return $this; } /** - * Make the parameter variadic + * Makes the (promoted) parameter private. * * @return $this The builder instance (for fluid interface) */ - public function makeVariadic() + public function makePrivate() { - $this->variadic = \true; + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE); + return $this; + } + /** + * Makes the (promoted) parameter readonly. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeReadonly() + { + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::READONLY); return $this; } /** @@ -4821,7 +6611,7 @@ class Param implements PhpParser\Builder */ public function getNode() : Node { - return new Node\Param(new Node\Expr\Variable($this->name), $this->default, $this->type, $this->byRef, $this->variadic, [], 0, $this->attributeGroups); + return new Node\Param(new Node\Expr\Variable($this->name), $this->default, $this->type, $this->byRef, $this->variadic, [], $this->flags, $this->attributeGroups); } } */ + protected array $attributes = []; + /** @var null|Identifier|Name|ComplexType */ + protected ?Node $type = null; + /** @var list */ + protected array $attributeGroups = []; /** * Creates a property builder. * @@ -4862,7 +6654,7 @@ class Property implements PhpParser\Builder */ public function makePublic() { - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PUBLIC); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC); return $this; } /** @@ -4872,7 +6664,7 @@ class Property implements PhpParser\Builder */ public function makeProtected() { - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PROTECTED); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED); return $this; } /** @@ -4882,7 +6674,7 @@ class Property implements PhpParser\Builder */ public function makePrivate() { - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PRIVATE); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE); return $this; } /** @@ -4892,7 +6684,7 @@ class Property implements PhpParser\Builder */ public function makeStatic() { - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_STATIC); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::STATIC); return $this; } /** @@ -4902,7 +6694,7 @@ class Property implements PhpParser\Builder */ public function makeReadonly() { - $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_READONLY); + $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::READONLY); return $this; } /** @@ -4960,7 +6752,7 @@ class Property implements PhpParser\Builder */ public function getNode() : PhpParser\Node { - return new Stmt\Property($this->flags !== 0 ? $this->flags : Stmt\Class_::MODIFIER_PUBLIC, [new Stmt\PropertyProperty($this->name, $this->default)], $this->attributes, $this->type, $this->attributeGroups); + return new Stmt\Property($this->flags !== 0 ? $this->flags : Modifiers::PUBLIC, [new Node\PropertyItem($this->name, $this->default)], $this->attributes, $this->type, $this->attributeGroups); } } type !== self::TYPE_ALIAS) { throw new \LogicException('Cannot set alias for not alias adaptation buider'); } - $this->alias = $alias; + $this->alias = BuilderHelpers::normalizeIdentifier($alias); return $this; } /** - * Sets adaptated method public. + * Sets adapted method public. * * @return $this The builder instance (for fluid interface) */ public function makePublic() { - $this->setModifier(Stmt\Class_::MODIFIER_PUBLIC); + $this->setModifier(Modifiers::PUBLIC); return $this; } /** - * Sets adaptated method protected. + * Sets adapted method protected. * * @return $this The builder instance (for fluid interface) */ public function makeProtected() { - $this->setModifier(Stmt\Class_::MODIFIER_PROTECTED); + $this->setModifier(Modifiers::PROTECTED); return $this; } /** - * Sets adaptated method private. + * Sets adapted method private. * * @return $this The builder instance (for fluid interface) */ public function makePrivate() { - $this->setModifier(Stmt\Class_::MODIFIER_PRIVATE); + $this->setModifier(Modifiers::PRIVATE); return $this; } /** @@ -5129,7 +6924,7 @@ class TraitUseAdaptation implements Builder } return $this; } - protected function setModifier(int $modifier) + protected function setModifier(int $modifier) : void { if ($this->type === self::TYPE_UNDEFINED) { $this->type = self::TYPE_ALIAS; @@ -5171,12 +6966,17 @@ use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\Node\Stmt; class Trait_ extends Declaration { - protected $name; - protected $uses = []; - protected $properties = []; - protected $methods = []; - /** @var Node\AttributeGroup[] */ - protected $attributeGroups = []; + protected string $name; + /** @var list */ + protected array $uses = []; + /** @var list */ + protected array $constants = []; + /** @var list */ + protected array $properties = []; + /** @var list */ + protected array $methods = []; + /** @var list */ + protected array $attributeGroups = []; /** * Creates an interface builder. * @@ -5202,6 +7002,8 @@ class Trait_ extends Declaration $this->methods[] = $stmt; } elseif ($stmt instanceof Stmt\TraitUse) { $this->uses[] = $stmt; + } elseif ($stmt instanceof Stmt\ClassConst) { + $this->constants[] = $stmt; } else { throw new \LogicException(\sprintf('Unexpected node of type "%s"', $stmt->getType())); } @@ -5226,7 +7028,7 @@ class Trait_ extends Declaration */ public function getNode() : PhpParser\Node { - return new Stmt\Trait_($this->name, ['stmts' => \array_merge($this->uses, $this->properties, $this->methods), 'attrGroups' => $this->attributeGroups], $this->attributes); + return new Stmt\Trait_($this->name, ['stmts' => \array_merge($this->uses, $this->constants, $this->properties, $this->methods), 'attrGroups' => $this->attributeGroups], $this->attributes); } } name, $this->alias)], $this->type); + return new Stmt\Use_([new Node\UseItem($this->name, $this->alias)], $this->type); } } */ public function args(array $args) : array { @@ -5536,9 +7333,7 @@ class BuilderFactory * Creates a function call node. * * @param string|Name|Expr $name Function name - * @param array $args Function arguments - * - * @return Expr\FuncCall + * @param array $args Function arguments */ public function funcCall($name, array $args = []) : Expr\FuncCall { @@ -5547,11 +7342,9 @@ class BuilderFactory /** * Creates a method call node. * - * @param Expr $var Variable the method is called on + * @param Expr $var Variable the method is called on * @param string|Identifier|Expr $name Method name - * @param array $args Method arguments - * - * @return Expr\MethodCall + * @param array $args Method arguments */ public function methodCall(Expr $var, $name, array $args = []) : Expr\MethodCall { @@ -5560,11 +7353,9 @@ class BuilderFactory /** * Creates a static method call node. * - * @param string|Name|Expr $class Class name - * @param string|Identifier|Expr $name Method name - * @param array $args Method arguments - * - * @return Expr\StaticCall + * @param string|Name|Expr $class Class name + * @param string|Identifier|Expr $name Method name + * @param array $args Method arguments */ public function staticCall($class, $name, array $args = []) : Expr\StaticCall { @@ -5574,9 +7365,7 @@ class BuilderFactory * Creates an object creation node. * * @param string|Name|Expr $class Class name - * @param array $args Constructor arguments - * - * @return Expr\New_ + * @param array $args Constructor arguments */ public function new($class, array $args = []) : Expr\New_ { @@ -5586,8 +7375,6 @@ class BuilderFactory * Creates a constant fetch node. * * @param string|Name $name Constant name - * - * @return Expr\ConstFetch */ public function constFetch($name) : Expr\ConstFetch { @@ -5596,10 +7383,8 @@ class BuilderFactory /** * Creates a property fetch node. * - * @param Expr $var Variable holding object + * @param Expr $var Variable holding object * @param string|Identifier|Expr $name Property name - * - * @return Expr\PropertyFetch */ public function propertyFetch(Expr $var, $name) : Expr\PropertyFetch { @@ -5608,21 +7393,17 @@ class BuilderFactory /** * Creates a class constant fetch node. * - * @param string|Name|Expr $class Class name - * @param string|Identifier $name Constant name - * - * @return Expr\ClassConstFetch + * @param string|Name|Expr $class Class name + * @param string|Identifier|Expr $name Constant name */ public function classConstFetch($class, $name) : Expr\ClassConstFetch { - return new Expr\ClassConstFetch(BuilderHelpers::normalizeNameOrExpr($class), BuilderHelpers::normalizeIdentifier($name)); + return new Expr\ClassConstFetch(BuilderHelpers::normalizeNameOrExpr($class), BuilderHelpers::normalizeIdentifierOrExpr($name)); } /** * Creates nested Concat nodes from a list of expressions. * * @param Expr|string ...$exprs Expressions or literal strings - * - * @return Concat */ public function concat(...$exprs) : Concat { @@ -5638,7 +7419,6 @@ class BuilderFactory } /** * @param string|Expr $expr - * @return Expr */ private function normalizeStringExpr($expr) : Expr { @@ -5840,10 +7620,10 @@ final class BuilderHelpers return new Expr\ConstFetch(new Name($value ? 'true' : 'false')); } if (\is_int($value)) { - return new Scalar\LNumber($value); + return new Scalar\Int_($value); } if (\is_float($value)) { - return new Scalar\DNumber($value); + return new Scalar\Float_($value); } if (\is_string($value)) { return new Scalar\String_($value); @@ -5854,10 +7634,10 @@ final class BuilderHelpers foreach ($value as $itemKey => $itemValue) { // for consecutive, numeric keys don't generate keys if (null !== $lastKey && ++$lastKey === $itemKey) { - $items[] = new Expr\ArrayItem(self::normalizeValue($itemValue)); + $items[] = new Node\ArrayItem(self::normalizeValue($itemValue)); } else { $lastKey = null; - $items[] = new Expr\ArrayItem(self::normalizeValue($itemValue), self::normalizeValue($itemKey)); + $items[] = new Node\ArrayItem(self::normalizeValue($itemValue), self::normalizeValue($itemKey)); } } return new Expr\Array_($items); @@ -5902,13 +7682,13 @@ final class BuilderHelpers * Adds a modifier and returns new modifier bitmask. * * @param int $modifiers Existing modifiers - * @param int $modifier Modifier to set + * @param int $modifier Modifier to set * * @return int New modifiers */ public static function addModifier(int $modifiers, int $modifier) : int { - Stmt\Class_::verifyModifier($modifiers, $modifier); + Modifiers::verifyModifier($modifiers, $modifier); return $modifiers | $modifier; } /** @@ -5917,7 +7697,7 @@ final class BuilderHelpers */ public static function addClassModifier(int $existingModifiers, int $modifierToSet) : int { - Stmt\Class_::verifyClassModifier($existingModifiers, $modifierToSet); + Modifiers::verifyClassModifier($existingModifiers, $modifierToSet); return $existingModifiers | $modifierToSet; } } @@ -5928,20 +7708,20 @@ namespace PHPUnit\PhpParser; class Comment implements \JsonSerializable { - protected $text; - protected $startLine; - protected $startFilePos; - protected $startTokenPos; - protected $endLine; - protected $endFilePos; - protected $endTokenPos; + protected string $text; + protected int $startLine; + protected int $startFilePos; + protected int $startTokenPos; + protected int $endLine; + protected int $endFilePos; + protected int $endTokenPos; /** * Constructs a comment node. * - * @param string $text Comment text (including comment delimiters like /*) - * @param int $startLine Line number the comment started on - * @param int $startFilePos File offset the comment started on - * @param int $startTokenPos Token offset the comment started on + * @param string $text Comment text (including comment delimiters like /*) + * @param int $startLine Line number the comment started on + * @param int $startFilePos File offset the comment started on + * @param int $startTokenPos Token offset the comment started on */ public function __construct(string $text, int $startLine = -1, int $startFilePos = -1, int $startTokenPos = -1, int $endLine = -1, int $endFilePos = -1, int $endTokenPos = -1) { @@ -6016,39 +7796,6 @@ class Comment implements \JsonSerializable { return $this->endTokenPos; } - /** - * Gets the line number the comment started on. - * - * @deprecated Use getStartLine() instead - * - * @return int Line number - */ - public function getLine() : int - { - return $this->startLine; - } - /** - * Gets the file offset the comment started on. - * - * @deprecated Use getStartFilePos() instead - * - * @return int File offset - */ - public function getFilePos() : int - { - return $this->startFilePos; - } - /** - * Gets the token offset the comment started on. - * - * @deprecated Use getStartTokenPos() instead - * - * @return int Token offset - */ - public function getTokenPos() : int - { - return $this->startTokenPos; - } /** * Gets the comment text. * @@ -6063,19 +7810,20 @@ class Comment implements \JsonSerializable * * "Reformatted" here means that we try to clean up the whitespace at the * starts of the lines. This is necessary because we receive the comments - * without trailing whitespace on the first line, but with trailing whitespace + * without leading whitespace on the first line, but with leading whitespace * on all subsequent lines. * - * @return mixed|string + * Additionally, this normalizes CRLF newlines to LF newlines. */ - public function getReformattedText() + public function getReformattedText() : string { - $text = \trim($this->text); + $text = \str_replace("\r\n", "\n", $this->text); $newlinePos = \strpos($text, "\n"); if (\false === $newlinePos) { // Single line comments don't need further processing return $text; - } elseif (\preg_match('((*BSR_ANYCRLF)(*ANYCRLF)^.*(?:\\R\\s+\\*.*)+$)', $text)) { + } + if (\preg_match('(^.*(?:\\n\\s+\\*.*)+$)', $text)) { // Multi line comment of the type // // /* @@ -6084,8 +7832,9 @@ class Comment implements \JsonSerializable // */ // // is handled by replacing the whitespace sequences before the * by a single space - return \preg_replace('(^\\s+\\*)m', ' *', $this->text); - } elseif (\preg_match('(^/\\*\\*?\\s*[\\r\\n])', $text) && \preg_match('(\\n(\\s*)\\*/$)', $text, $matches)) { + return \preg_replace('(^\\s+\\*)m', ' *', $text); + } + if (\preg_match('(^/\\*\\*?\\s*\\n)', $text) && \preg_match('(\\n(\\s*)\\*/$)', $text, $matches)) { // Multi line comment of the type // // /* @@ -6097,7 +7846,8 @@ class Comment implements \JsonSerializable // */ on all lines. So if the last line is " */", then " " is removed at the // start of all lines. return \preg_replace('(^' . \preg_quote($matches[1]) . ')m', '', $text); - } elseif (\preg_match('(^/\\*\\*?\\s*(?!\\s))', $text, $matches)) { + } + if (\preg_match('(^/\\*\\*?\\s*(?!\\s))', $text, $matches)) { // Multi line comment of the type // // /* Some text. @@ -6125,7 +7875,7 @@ class Comment implements \JsonSerializable private function getShortestWhitespacePrefixLen(string $str) : int { $lines = \explode("\n", $str); - $shortestPrefixLen = \INF; + $shortestPrefixLen = \PHP_INT_MAX; foreach ($lines as $line) { \preg_match('(^\\s*)', $line, $matches); $prefixLen = \strlen($matches[0]); @@ -6136,8 +7886,7 @@ class Comment implements \JsonSerializable return $shortestPrefixLen; } /** - * @return array - * @psalm-return array{nodeType:string, text:mixed, line:mixed, filePos:mixed} + * @return array{nodeType:string, text:mixed, line:mixed, filePos:mixed} */ public function jsonSerialize() : array { @@ -6166,6 +7915,7 @@ class Doc extends \PHPUnit\PhpParser\Comment } fallbackEvaluator = $fallbackEvaluator ?? function (Expr $expr) { throw new ConstExprEvaluationException("Expression of type {$expr->getType()} cannot be evaluated"); @@ -6268,9 +8020,10 @@ class ConstExprEvaluator { return $this->evaluate($expr); } + /** @return mixed */ private function evaluate(Expr $expr) { - if ($expr instanceof Scalar\LNumber || $expr instanceof Scalar\DNumber || $expr instanceof Scalar\String_) { + if ($expr instanceof Scalar\Int_ || $expr instanceof Scalar\Float_ || $expr instanceof Scalar\String_) { return $expr->value; } if ($expr instanceof Expr\Array_) { @@ -6303,7 +8056,7 @@ class ConstExprEvaluator } return ($this->fallbackEvaluator)($expr); } - private function evaluateArray(Expr\Array_ $expr) + private function evaluateArray(Expr\Array_ $expr) : array { $array = []; foreach ($expr->items as $item) { @@ -6317,6 +8070,7 @@ class ConstExprEvaluator } return $array; } + /** @return mixed */ private function evaluateTernary(Expr\Ternary $expr) { if (null === $expr->if) { @@ -6324,6 +8078,7 @@ class ConstExprEvaluator } return $this->evaluate($expr->cond) ? $this->evaluate($expr->if) : $this->evaluate($expr->else); } + /** @return mixed */ private function evaluateBinaryOp(Expr\BinaryOp $expr) { if ($expr instanceof Expr\BinaryOp\Coalesce && $expr->left instanceof Expr\ArrayDimFetch) { @@ -6392,6 +8147,7 @@ class ConstExprEvaluator } throw new \Exception('Should not happen'); } + /** @return mixed */ private function evaluateConstFetch(Expr\ConstFetch $expr) { $name = $expr->name->toLowerString(); @@ -6413,23 +8169,19 @@ namespace PHPUnit\PhpParser; class Error extends \RuntimeException { - protected $rawMessage; - protected $attributes; + protected string $rawMessage; + /** @var array */ + protected array $attributes; /** * Creates an Exception signifying a parse error. * - * @param string $message Error message - * @param array|int $attributes Attributes of node/token where error occurred - * (or start line of error -- deprecated) + * @param string $message Error message + * @param array $attributes Attributes of node/token where error occurred */ - public function __construct(string $message, $attributes = []) + public function __construct(string $message, array $attributes = []) { $this->rawMessage = $message; - if (\is_array($attributes)) { - $this->attributes = $attributes; - } else { - $this->attributes = ['startLine' => $attributes]; - } + $this->attributes = $attributes; $this->updateMessage(); } /** @@ -6462,7 +8214,7 @@ class Error extends \RuntimeException /** * Gets the attributes of the node/token the error occurred at. * - * @return array + * @return array */ public function getAttributes() : array { @@ -6471,9 +8223,9 @@ class Error extends \RuntimeException /** * Sets the attributes of the node/token the error occurred at. * - * @param array $attributes + * @param array $attributes */ - public function setAttributes(array $attributes) + public function setAttributes(array $attributes) : void { $this->attributes = $attributes; $this->updateMessage(); @@ -6483,7 +8235,7 @@ class Error extends \RuntimeException * * @param string $message Error message */ - public function setRawMessage(string $message) + public function setRawMessage(string $message) : void { $this->rawMessage = $message; $this->updateMessage(); @@ -6493,7 +8245,7 @@ class Error extends \RuntimeException * * @param int $line Error start line */ - public function setStartLine(int $line) + public function setStartLine(int $line) : void { $this->attributes['startLine'] = $line; $this->updateMessage(); @@ -6502,8 +8254,6 @@ class Error extends \RuntimeException * Returns whether the error has start and end column information. * * For column information enable the startFilePos and endFilePos in the lexer options. - * - * @return bool */ public function hasColumnInfo() : bool { @@ -6513,7 +8263,6 @@ class Error extends \RuntimeException * Gets the start column (1-based) into the line where the error started. * * @param string $code Source code of the file - * @return int */ public function getStartColumn(string $code) : int { @@ -6526,7 +8275,6 @@ class Error extends \RuntimeException * Gets the end column (1-based) into the line where the error ended. * * @param string $code Source code of the file - * @return int */ public function getEndColumn(string $code) : int { @@ -6550,7 +8298,7 @@ class Error extends \RuntimeException * Converts a file offset into a column. * * @param string $code Source code that $pos indexes into - * @param int $pos 0-based position in $code + * @param int $pos 0-based position in $code * * @return int 1-based column (relative to start of line) */ @@ -6568,7 +8316,7 @@ class Error extends \RuntimeException /** * Updates the exception message after a change to rawMessage or rawLine. */ - protected function updateMessage() + protected function updateMessage() : void { $this->message = $this->rawMessage; if (-1 === $this->getStartLine()) { @@ -6590,7 +8338,7 @@ interface ErrorHandler * * @param Error $error The error that needs to be handled */ - public function handleError(Error $error); + public function handleError(Error $error) : void; } errors[] = $error; } @@ -6623,8 +8371,6 @@ class Collecting implements ErrorHandler } /** * Check whether there are any errors. - * - * @return bool */ public function hasErrors() : bool { @@ -6633,7 +8379,7 @@ class Collecting implements ErrorHandler /** * Reset/clear collected errors. */ - public function clearErrors() + public function clearErrors() : void { $this->errors = []; } @@ -6652,7 +8398,7 @@ use PHPUnit\PhpParser\ErrorHandler; */ class Throwing implements ErrorHandler { - public function handleError(Error $error) + public function handleError(Error $error) : void { throw $error; } @@ -6667,16 +8413,21 @@ namespace PHPUnit\PhpParser\Internal; */ class DiffElem { - const TYPE_KEEP = 0; - const TYPE_REMOVE = 1; - const TYPE_ADD = 2; - const TYPE_REPLACE = 3; + public const TYPE_KEEP = 0; + public const TYPE_REMOVE = 1; + public const TYPE_ADD = 2; + public const TYPE_REPLACE = 3; /** @var int One of the TYPE_* constants */ - public $type; + public int $type; /** @var mixed Is null for add operations */ public $old; /** @var mixed Is null for remove operations */ public $new; + /** + * @param int $type One of the TYPE_* constants + * @param mixed $old Is null for add operations + * @param mixed $new Is null for remove operations + */ public function __construct(int $type, $old, $new) { $this->type = $type; @@ -6695,15 +8446,17 @@ namespace PHPUnit\PhpParser\Internal; * Myers, Eugene W. "An O (ND) difference algorithm and its variations." * Algorithmica 1.1 (1986): 251-266. * + * @template T * @internal */ class Differ { + /** @var callable(T, T): bool */ private $isEqual; /** * Create differ over the given equality relation. * - * @param callable $isEqual Equality relation with signature function($a, $b) : bool + * @param callable(T, T): bool $isEqual Equality relation */ public function __construct(callable $isEqual) { @@ -6712,13 +8465,15 @@ class Differ /** * Calculate diff (edit script) from $old to $new. * - * @param array $old Original array - * @param array $new New array + * @param T[] $old Original array + * @param T[] $new New array * * @return DiffElem[] Diff (edit script) */ - public function diff(array $old, array $new) + public function diff(array $old, array $new) : array { + $old = \array_values($old); + $new = \array_values($new); list($trace, $x, $y) = $this->calculateTrace($old, $new); return $this->extractDiff($trace, $x, $y, $old, $new); } @@ -6728,19 +8483,24 @@ class Differ * If a sequence of remove operations is followed by the same number of add operations, these * will be coalesced into replace operations. * - * @param array $old Original array - * @param array $new New array + * @param T[] $old Original array + * @param T[] $new New array * * @return DiffElem[] Diff (edit script), including replace operations */ - public function diffWithReplacements(array $old, array $new) + public function diffWithReplacements(array $old, array $new) : array { return $this->coalesceReplacements($this->diff($old, $new)); } - private function calculateTrace(array $a, array $b) + /** + * @param T[] $old + * @param T[] $new + * @return array{array>, int, int} + */ + private function calculateTrace(array $old, array $new) : array { - $n = \count($a); - $m = \count($b); + $n = \count($old); + $m = \count($new); $max = $n + $m; $v = [1 => 0]; $trace = []; @@ -6753,7 +8513,7 @@ class Differ $x = $v[$k - 1] + 1; } $y = $x - $k; - while ($x < $n && $y < $m && ($this->isEqual)($a[$x], $b[$y])) { + while ($x < $n && $y < $m && ($this->isEqual)($old[$x], $new[$y])) { $x++; $y++; } @@ -6765,7 +8525,13 @@ class Differ } throw new \Exception('Should not happen'); } - private function extractDiff(array $trace, int $x, int $y, array $a, array $b) + /** + * @param array> $trace + * @param T[] $old + * @param T[] $new + * @return DiffElem[] + */ + private function extractDiff(array $trace, int $x, int $y, array $old, array $new) : array { $result = []; for ($d = \count($trace) - 1; $d >= 0; $d--) { @@ -6779,7 +8545,7 @@ class Differ $prevX = $v[$prevK]; $prevY = $prevX - $prevK; while ($x > $prevX && $y > $prevY) { - $result[] = new DiffElem(DiffElem::TYPE_KEEP, $a[$x - 1], $b[$y - 1]); + $result[] = new DiffElem(DiffElem::TYPE_KEEP, $old[$x - 1], $new[$y - 1]); $x--; $y--; } @@ -6787,11 +8553,11 @@ class Differ break; } while ($x > $prevX) { - $result[] = new DiffElem(DiffElem::TYPE_REMOVE, $a[$x - 1], null); + $result[] = new DiffElem(DiffElem::TYPE_REMOVE, $old[$x - 1], null); $x--; } while ($y > $prevY) { - $result[] = new DiffElem(DiffElem::TYPE_ADD, null, $b[$y - 1]); + $result[] = new DiffElem(DiffElem::TYPE_ADD, null, $new[$y - 1]); $y--; } } @@ -6803,7 +8569,7 @@ class Differ * @param DiffElem[] $diff * @return DiffElem[] */ - private function coalesceReplacements(array $diff) + private function coalesceReplacements(array $diff) : array { $newDiff = []; $c = \count($diff); @@ -6856,31 +8622,42 @@ use PHPUnit\PhpParser\Node\Expr; class PrintableNewAnonClassNode extends Expr { /** @var Node\AttributeGroup[] PHP attribute groups */ - public $attrGroups; - /** @var Node\Arg[] Arguments */ - public $args; + public array $attrGroups; + /** @var int Modifiers */ + public int $flags; + /** @var (Node\Arg|Node\VariadicPlaceholder)[] Arguments */ + public array $args; /** @var null|Node\Name Name of extended class */ - public $extends; + public ?Node\Name $extends; /** @var Node\Name[] Names of implemented interfaces */ - public $implements; + public array $implements; /** @var Node\Stmt[] Statements */ - public $stmts; - public function __construct(array $attrGroups, array $args, Node\Name $extends = null, array $implements, array $stmts, array $attributes) + public array $stmts; + /** + * @param Node\AttributeGroup[] $attrGroups PHP attribute groups + * @param (Node\Arg|Node\VariadicPlaceholder)[] $args Arguments + * @param Node\Name|null $extends Name of extended class + * @param Node\Name[] $implements Names of implemented interfaces + * @param Node\Stmt[] $stmts Statements + * @param array $attributes Attributes + */ + public function __construct(array $attrGroups, int $flags, array $args, ?Node\Name $extends, array $implements, array $stmts, array $attributes) { parent::__construct($attributes); $this->attrGroups = $attrGroups; + $this->flags = $flags; $this->args = $args; $this->extends = $extends; $this->implements = $implements; $this->stmts = $stmts; } - public static function fromNewNode(Expr\New_ $newNode) + public static function fromNewNode(Expr\New_ $newNode) : self { $class = $newNode->class; \assert($class instanceof Node\Stmt\Class_); // We don't assert that $class->name is null here, to allow consumers to assign unique names // to anonymous classes for their own purposes. We simplify ignore the name here. - return new self($class->attrGroups, $newNode->args, $class->extends, $class->implements, $class->stmts, $newNode->getAttributes()); + return new self($class->attrGroups, $class->flags, $newNode->args, $class->extends, $class->implements, $class->stmts, $newNode->getAttributes()); } public function getType() : string { @@ -6888,7 +8665,215 @@ class PrintableNewAnonClassNode extends Expr } public function getSubNodeNames() : array { - return ['attrGroups', 'args', 'extends', 'implements', 'stmts']; + return ['attrGroups', 'flags', 'args', 'extends', 'implements', 'stmts']; + } +} += 80000) { + class TokenPolyfill extends \PhpToken + { + } + return; +} +/** + * This is a polyfill for the PhpToken class introduced in PHP 8.0. We do not actually polyfill + * PhpToken, because composer might end up picking a different polyfill implementation, which does + * not meet our requirements. + * + * @internal + */ +class TokenPolyfill +{ + /** @var int The ID of the token. Either a T_* constant of a character code < 256. */ + public int $id; + /** @var string The textual content of the token. */ + public string $text; + /** @var int The 1-based starting line of the token (or -1 if unknown). */ + public int $line; + /** @var int The 0-based starting position of the token (or -1 if unknown). */ + public int $pos; + /** @var array Tokens ignored by the PHP parser. */ + private const IGNORABLE_TOKENS = [\T_WHITESPACE => \true, \T_COMMENT => \true, \T_DOC_COMMENT => \true, \T_OPEN_TAG => \true]; + /** @var array Tokens that may be part of a T_NAME_* identifier. */ + private static array $identifierTokens; + /** + * Create a Token with the given ID and text, as well optional line and position information. + */ + public final function __construct(int $id, string $text, int $line = -1, int $pos = -1) + { + $this->id = $id; + $this->text = $text; + $this->line = $line; + $this->pos = $pos; + } + /** + * Get the name of the token. For single-char tokens this will be the token character. + * Otherwise it will be a T_* style name, or null if the token ID is unknown. + */ + public function getTokenName() : ?string + { + if ($this->id < 256) { + return \chr($this->id); + } + $name = \token_name($this->id); + return $name === 'UNKNOWN' ? null : $name; + } + /** + * Check whether the token is of the given kind. The kind may be either an integer that matches + * the token ID, a string that matches the token text, or an array of integers/strings. In the + * latter case, the function returns true if any of the kinds in the array match. + * + * @param int|string|(int|string)[] $kind + */ + public function is($kind) : bool + { + if (\is_int($kind)) { + return $this->id === $kind; + } + if (\is_string($kind)) { + return $this->text === $kind; + } + if (\is_array($kind)) { + foreach ($kind as $entry) { + if (\is_int($entry)) { + if ($this->id === $entry) { + return \true; + } + } elseif (\is_string($entry)) { + if ($this->text === $entry) { + return \true; + } + } else { + throw new \TypeError('Argument #1 ($kind) must only have elements of type string|int, ' . \gettype($entry) . ' given'); + } + } + return \false; + } + throw new \TypeError('Argument #1 ($kind) must be of type string|int|array, ' . \gettype($kind) . ' given'); + } + /** + * Check whether this token would be ignored by the PHP parser. Returns true for T_WHITESPACE, + * T_COMMENT, T_DOC_COMMENT and T_OPEN_TAG, and false for everything else. + */ + public function isIgnorable() : bool + { + return isset(self::IGNORABLE_TOKENS[$this->id]); + } + /** + * Return the textual content of the token. + */ + public function __toString() : string + { + return $this->text; + } + /** + * Tokenize the given source code and return an array of tokens. + * + * This performs certain canonicalizations to match the PHP 8.0 token format: + * * Bad characters are represented using T_BAD_CHARACTER rather than omitted. + * * T_COMMENT does not include trailing newlines, instead the newline is part of a following + * T_WHITESPACE token. + * * Namespaced names are represented using T_NAME_* tokens. + * + * @return static[] + */ + public static function tokenize(string $code, int $flags = 0) : array + { + self::init(); + $tokens = []; + $line = 1; + $pos = 0; + $origTokens = \token_get_all($code, $flags); + $numTokens = \count($origTokens); + for ($i = 0; $i < $numTokens; $i++) { + $token = $origTokens[$i]; + if (\is_string($token)) { + if (\strlen($token) === 2) { + // b" and B" are tokenized as single-char tokens, even though they aren't. + $tokens[] = new static(\ord('"'), $token, $line, $pos); + $pos += 2; + } else { + $tokens[] = new static(\ord($token), $token, $line, $pos); + $pos++; + } + } else { + $id = $token[0]; + $text = $token[1]; + // Emulate PHP 8.0 comment format, which does not include trailing whitespace anymore. + if ($id === \T_COMMENT && \substr($text, 0, 2) !== '/*' && \preg_match('/(\\r\\n|\\n|\\r)$/D', $text, $matches)) { + $trailingNewline = $matches[0]; + $text = \substr($text, 0, -\strlen($trailingNewline)); + $tokens[] = new static($id, $text, $line, $pos); + $pos += \strlen($text); + if ($i + 1 < $numTokens && $origTokens[$i + 1][0] === \T_WHITESPACE) { + // Move trailing newline into following T_WHITESPACE token, if it already exists. + $origTokens[$i + 1][1] = $trailingNewline . $origTokens[$i + 1][1]; + $origTokens[$i + 1][2]--; + } else { + // Otherwise, we need to create a new T_WHITESPACE token. + $tokens[] = new static(\T_WHITESPACE, $trailingNewline, $line, $pos); + $line++; + $pos += \strlen($trailingNewline); + } + continue; + } + // Emulate PHP 8.0 T_NAME_* tokens, by combining sequences of T_NS_SEPARATOR and + // T_STRING into a single token. + if ($id === \T_NS_SEPARATOR || isset(self::$identifierTokens[$id])) { + $newText = $text; + $lastWasSeparator = $id === \T_NS_SEPARATOR; + for ($j = $i + 1; $j < $numTokens; $j++) { + if ($lastWasSeparator) { + if (!isset(self::$identifierTokens[$origTokens[$j][0]])) { + break; + } + $lastWasSeparator = \false; + } else { + if ($origTokens[$j][0] !== \T_NS_SEPARATOR) { + break; + } + $lastWasSeparator = \true; + } + $newText .= $origTokens[$j][1]; + } + if ($lastWasSeparator) { + // Trailing separator is not part of the name. + $j--; + $newText = \substr($newText, 0, -1); + } + if ($j > $i + 1) { + if ($id === \T_NS_SEPARATOR) { + $id = \T_NAME_FULLY_QUALIFIED; + } elseif ($id === \T_NAMESPACE) { + $id = \T_NAME_RELATIVE; + } else { + $id = \T_NAME_QUALIFIED; + } + $tokens[] = new static($id, $newText, $line, $pos); + $pos += \strlen($newText); + $i = $j - 1; + continue; + } + } + $tokens[] = new static($id, $text, $line, $pos); + $line += \substr_count($text, "\n"); + $pos += \strlen($text); + } + } + return $tokens; + } + /** Initialize private static state needed by tokenize(). */ + private static function init() : void + { + if (isset(self::$identifierTokens)) { + return; + } + // Based on semi_reserved production. + self::$identifierTokens = \array_fill_keys([\T_STRING, \T_STATIC, \T_ABSTRACT, \T_FINAL, \T_PRIVATE, \T_PROTECTED, \T_PUBLIC, \T_READONLY, \T_INCLUDE, \T_INCLUDE_ONCE, \T_EVAL, \T_REQUIRE, \T_REQUIRE_ONCE, \T_LOGICAL_OR, \T_LOGICAL_XOR, \T_LOGICAL_AND, \T_INSTANCEOF, \T_NEW, \T_CLONE, \T_EXIT, \T_IF, \T_ELSEIF, \T_ELSE, \T_ENDIF, \T_ECHO, \T_DO, \T_WHILE, \T_ENDWHILE, \T_FOR, \T_ENDFOR, \T_FOREACH, \T_ENDFOREACH, \T_DECLARE, \T_ENDDECLARE, \T_AS, \T_TRY, \T_CATCH, \T_FINALLY, \T_THROW, \T_USE, \T_INSTEADOF, \T_GLOBAL, \T_VAR, \T_UNSET, \T_ISSET, \T_EMPTY, \T_CONTINUE, \T_GOTO, \T_FUNCTION, \T_CONST, \T_RETURN, \T_PRINT, \T_YIELD, \T_LIST, \T_SWITCH, \T_ENDSWITCH, \T_CASE, \T_DEFAULT, \T_BREAK, \T_ARRAY, \T_CALLABLE, \T_EXTENDS, \T_IMPLEMENTS, \T_NAMESPACE, \T_TRAIT, \T_INTERFACE, \T_CLASS, \T_CLASS_C, \T_TRAIT_C, \T_FUNC_C, \T_METHOD_C, \T_LINE, \T_FILE, \T_DIR, \T_NS_C, \T_HALT_COMPILER, \T_FN, \T_MATCH], \true); } } tokens; $pos--; for (; $pos >= 0; $pos--) { - $tokenType = $tokens[$pos][0]; - if ($tokenType === $expectedTokenType) { + $token = $tokens[$pos]; + if ($token->is($expectedTokenType)) { return \true; } - if ($tokenType !== \T_WHITESPACE && $tokenType !== \T_COMMENT && $tokenType !== \T_DOC_COMMENT) { + if (!$token->isIgnorable()) { break; } } @@ -6971,7 +8953,7 @@ class TokenStream * * During this check whitespace and comments are skipped. * - * @param int $pos Position after which the token should occur + * @param int $pos Position after which the token should occur * @param int|string $expectedTokenType Token to check for * * @return bool Whether the expected token was found @@ -6980,39 +8962,41 @@ class TokenStream { $tokens = $this->tokens; $pos++; - for (; $pos < \count($tokens); $pos++) { - $tokenType = $tokens[$pos][0]; - if ($tokenType === $expectedTokenType) { + for ($c = \count($tokens); $pos < $c; $pos++) { + $token = $tokens[$pos]; + if ($token->is($expectedTokenType)) { return \true; } - if ($tokenType !== \T_WHITESPACE && $tokenType !== \T_COMMENT && $tokenType !== \T_DOC_COMMENT) { + if (!$token->isIgnorable()) { break; } } return \false; } - public function skipLeft(int $pos, $skipTokenType) + /** @param int|string|(int|string)[] $skipTokenType */ + public function skipLeft(int $pos, $skipTokenType) : int { $tokens = $this->tokens; $pos = $this->skipLeftWhitespace($pos); if ($skipTokenType === \T_WHITESPACE) { return $pos; } - if ($tokens[$pos][0] !== $skipTokenType) { + if (!$tokens[$pos]->is($skipTokenType)) { // Shouldn't happen. The skip token MUST be there throw new \Exception('Encountered unexpected token'); } $pos--; return $this->skipLeftWhitespace($pos); } - public function skipRight(int $pos, $skipTokenType) + /** @param int|string|(int|string)[] $skipTokenType */ + public function skipRight(int $pos, $skipTokenType) : int { $tokens = $this->tokens; $pos = $this->skipRightWhitespace($pos); if ($skipTokenType === \T_WHITESPACE) { return $pos; } - if ($tokens[$pos][0] !== $skipTokenType) { + if (!$tokens[$pos]->is($skipTokenType)) { // Shouldn't happen. The skip token MUST be there throw new \Exception('Encountered unexpected token'); } @@ -7025,12 +9009,11 @@ class TokenStream * @param int $pos Token position * @return int Non-whitespace token position */ - public function skipLeftWhitespace(int $pos) + public function skipLeftWhitespace(int $pos) : int { $tokens = $this->tokens; for (; $pos >= 0; $pos--) { - $type = $tokens[$pos][0]; - if ($type !== \T_WHITESPACE && $type !== \T_COMMENT && $type !== \T_DOC_COMMENT) { + if (!$tokens[$pos]->isIgnorable()) { break; } } @@ -7042,23 +9025,22 @@ class TokenStream * @param int $pos Token position * @return int Non-whitespace token position */ - public function skipRightWhitespace(int $pos) + public function skipRightWhitespace(int $pos) : int { $tokens = $this->tokens; for ($count = \count($tokens); $pos < $count; $pos++) { - $type = $tokens[$pos][0]; - if ($type !== \T_WHITESPACE && $type !== \T_COMMENT && $type !== \T_DOC_COMMENT) { + if (!$tokens[$pos]->isIgnorable()) { break; } } return $pos; } - public function findRight(int $pos, $findTokenType) + /** @param int|string|(int|string)[] $findTokenType */ + public function findRight(int $pos, $findTokenType) : int { $tokens = $this->tokens; for ($count = \count($tokens); $pos < $count; $pos++) { - $type = $tokens[$pos][0]; - if ($type === $findTokenType) { + if ($tokens[$pos]->is($findTokenType)) { return $pos; } } @@ -7072,20 +9054,16 @@ class TokenStream * @param int|string $tokenType Token type to look for * @return bool Whether the token occurs in the given range */ - public function haveTokenInRange(int $startPos, int $endPos, $tokenType) + public function haveTokenInRange(int $startPos, int $endPos, $tokenType) : bool { $tokens = $this->tokens; for ($pos = $startPos; $pos < $endPos; $pos++) { - if ($tokens[$pos][0] === $tokenType) { + if ($tokens[$pos]->is($tokenType)) { return \true; } } return \false; } - public function haveBracesInRange(int $startPos, int $endPos) - { - return $this->haveTokenInRange($startPos, $endPos, '{') || $this->haveTokenInRange($startPos, $endPos, \T_CURLY_OPEN) || $this->haveTokenInRange($startPos, $endPos, '}'); - } public function haveTagInRange(int $startPos, int $endPos) : bool { return $this->haveTokenInRange($startPos, $endPos, \T_OPEN_TAG) || $this->haveTokenInRange($startPos, $endPos, \T_CLOSE_TAG); @@ -7104,8 +9082,8 @@ class TokenStream /** * Get the code corresponding to a token offset range, optionally adjusted for indentation. * - * @param int $from Token start position (inclusive) - * @param int $to Token end position (exclusive) + * @param int $from Token start position (inclusive) + * @param int $to Token end position (exclusive) * @param int $indent By how much the code should be indented (can be negative as well) * * @return string Code corresponding to token range, adjusted for indentation @@ -7116,23 +9094,19 @@ class TokenStream $result = ''; for ($pos = $from; $pos < $to; $pos++) { $token = $tokens[$pos]; - if (\is_array($token)) { - $type = $token[0]; - $content = $token[1]; - if ($type === \T_CONSTANT_ENCAPSED_STRING || $type === \T_ENCAPSED_AND_WHITESPACE) { - $result .= $content; + $id = $token->id; + $text = $token->text; + if ($id === \T_CONSTANT_ENCAPSED_STRING || $id === \T_ENCAPSED_AND_WHITESPACE) { + $result .= $text; + } else { + // TODO Handle non-space indentation + if ($indent < 0) { + $result .= \str_replace("\n" . \str_repeat(" ", -$indent), "\n", $text); + } elseif ($indent > 0) { + $result .= \str_replace("\n", "\n" . \str_repeat(" ", $indent), $text); } else { - // TODO Handle non-space indentation - if ($indent < 0) { - $result .= \str_replace("\n" . \str_repeat(" ", -$indent), "\n", $content); - } elseif ($indent > 0) { - $result .= \str_replace("\n", "\n" . \str_repeat(" ", $indent), $content); - } else { - $result .= $content; - } + $result .= $text; } - } else { - $result .= $token; } } return $result; @@ -7142,14 +9116,14 @@ class TokenStream * * @return int[] Token position to indentation map */ - private function calcIndentMap() + private function calcIndentMap() : array { $indentMap = []; $indent = 0; foreach ($this->tokens as $token) { $indentMap[] = $indent; - if ($token[0] === \T_WHITESPACE) { - $content = $token[1]; + if ($token->id === \T_WHITESPACE) { + $content = $token->text; $newlinePos = \strrpos($content, "\n"); if (\false !== $newlinePos) { $indent = \strlen($content) - $newlinePos - 1; @@ -7168,8 +9142,9 @@ namespace PHPUnit\PhpParser; class JsonDecoder { - /** @var \ReflectionClass[] Node type to reflection class map */ - private $reflectionClassCache; + /** @var \ReflectionClass[] Node type to reflection class map */ + private array $reflectionClassCache; + /** @return mixed */ public function decode(string $json) { $value = \json_decode($json, \true); @@ -7178,6 +9153,10 @@ class JsonDecoder } return $this->decodeRecursive($value); } + /** + * @param mixed $value + * @return mixed + */ private function decodeRecursive($value) { if (\is_array($value)) { @@ -7206,7 +9185,6 @@ class JsonDecoder throw new \RuntimeException('Node type must be a string'); } $reflectionClass = $this->reflectionClassFromNodeType($nodeType); - /** @var Node $node */ $node = $reflectionClass->newInstanceWithoutConstructor(); if (isset($value['attributes'])) { if (!\is_array($value['attributes'])) { @@ -7230,6 +9208,7 @@ class JsonDecoder } return new $className($value['text'], $value['line'] ?? -1, $value['filePos'] ?? -1, $value['tokenPos'] ?? -1, $value['endLine'] ?? -1, $value['endFilePos'] ?? -1, $value['endTokenPos'] ?? -1); } + /** @return \ReflectionClass */ private function reflectionClassFromNodeType(string $nodeType) : \ReflectionClass { if (!isset($this->reflectionClassCache[$nodeType])) { @@ -7238,6 +9217,7 @@ class JsonDecoder } return $this->reflectionClassCache[$nodeType]; } + /** @return class-string */ private function classNameFromNodeType(string $nodeType) : string { $className = 'PhpParser\\Node\\' . \strtr($nodeType, '_', '\\'); @@ -7256,464 +9236,90 @@ class JsonDecoder declare (strict_types=1); namespace PHPUnit\PhpParser; -use PHPUnit\PhpParser\Parser\Tokens; +require __DIR__ . '/compatibility_tokens.php'; class Lexer { - protected $code; - protected $tokens; - protected $pos; - protected $line; - protected $filePos; - protected $prevCloseTagHasNewline; - protected $tokenMap; - protected $dropTokens; - protected $identifierTokens; - private $attributeStartLineUsed; - private $attributeEndLineUsed; - private $attributeStartTokenPosUsed; - private $attributeEndTokenPosUsed; - private $attributeStartFilePosUsed; - private $attributeEndFilePosUsed; - private $attributeCommentsUsed; - /** - * Creates a Lexer. - * - * @param array $options Options array. Currently only the 'usedAttributes' option is supported, - * which is an array of attributes to add to the AST nodes. Possible - * attributes are: 'comments', 'startLine', 'endLine', 'startTokenPos', - * 'endTokenPos', 'startFilePos', 'endFilePos'. The option defaults to the - * first three. For more info see getNextToken() docs. - */ - public function __construct(array $options = []) - { - // Create Map from internal tokens to PhpParser tokens. - $this->defineCompatibilityTokens(); - $this->tokenMap = $this->createTokenMap(); - $this->identifierTokens = $this->createIdentifierTokenMap(); - // map of tokens to drop while lexing (the map is only used for isset lookup, - // that's why the value is simply set to 1; the value is never actually used.) - $this->dropTokens = \array_fill_keys([\T_WHITESPACE, \T_OPEN_TAG, \T_COMMENT, \T_DOC_COMMENT, \T_BAD_CHARACTER], 1); - $defaultAttributes = ['comments', 'startLine', 'endLine']; - $usedAttributes = \array_fill_keys($options['usedAttributes'] ?? $defaultAttributes, \true); - // Create individual boolean properties to make these checks faster. - $this->attributeStartLineUsed = isset($usedAttributes['startLine']); - $this->attributeEndLineUsed = isset($usedAttributes['endLine']); - $this->attributeStartTokenPosUsed = isset($usedAttributes['startTokenPos']); - $this->attributeEndTokenPosUsed = isset($usedAttributes['endTokenPos']); - $this->attributeStartFilePosUsed = isset($usedAttributes['startFilePos']); - $this->attributeEndFilePosUsed = isset($usedAttributes['endFilePos']); - $this->attributeCommentsUsed = isset($usedAttributes['comments']); - } - /** - * Initializes the lexer for lexing the provided source code. - * - * This function does not throw if lexing errors occur. Instead, errors may be retrieved using - * the getErrors() method. - * - * @param string $code The source code to lex + /** + * Tokenize the provided source code. + * + * The token array is in the same format as provided by the PhpToken::tokenize() method in + * PHP 8.0. The tokens are instances of PhpParser\Token, to abstract over a polyfill + * implementation in earlier PHP version. + * + * The token array is terminated by a sentinel token with token ID 0. + * The token array does not discard any tokens (i.e. whitespace and comments are included). + * The token position attributes are against this token array. + * + * @param string $code The source code to tokenize. * @param ErrorHandler|null $errorHandler Error handler to use for lexing errors. Defaults to - * ErrorHandler\Throwing + * ErrorHandler\Throwing. + * @return Token[] Tokens */ - public function startLexing(string $code, ErrorHandler $errorHandler = null) + public function tokenize(string $code, ?ErrorHandler $errorHandler = null) : array { if (null === $errorHandler) { $errorHandler = new ErrorHandler\Throwing(); } - $this->code = $code; - // keep the code around for __halt_compiler() handling - $this->pos = -1; - $this->line = 1; - $this->filePos = 0; - // If inline HTML occurs without preceding code, treat it as if it had a leading newline. - // This ensures proper composability, because having a newline is the "safe" assumption. - $this->prevCloseTagHasNewline = \true; $scream = \ini_set('xdebug.scream', '0'); - $this->tokens = @\token_get_all($code); - $this->postprocessTokens($errorHandler); + $tokens = @Token::tokenize($code); + $this->postprocessTokens($tokens, $errorHandler); if (\false !== $scream) { \ini_set('xdebug.scream', $scream); } - } - private function handleInvalidCharacterRange($start, $end, $line, ErrorHandler $errorHandler) - { - $tokens = []; - for ($i = $start; $i < $end; $i++) { - $chr = $this->code[$i]; - if ($chr === "\x00") { - // PHP cuts error message after null byte, so need special case - $errorMsg = 'Unexpected null byte'; - } else { - $errorMsg = \sprintf('Unexpected character "%s" (ASCII %d)', $chr, \ord($chr)); - } - $tokens[] = [\T_BAD_CHARACTER, $chr, $line]; - $errorHandler->handleError(new Error($errorMsg, ['startLine' => $line, 'endLine' => $line, 'startFilePos' => $i, 'endFilePos' => $i])); - } return $tokens; } - /** - * Check whether comment token is unterminated. - * - * @return bool - */ - private function isUnterminatedComment($token) : bool - { - return ($token[0] === \T_COMMENT || $token[0] === \T_DOC_COMMENT) && \substr($token[1], 0, 2) === '/*' && \substr($token[1], -2) !== '*/'; - } - protected function postprocessTokens(ErrorHandler $errorHandler) + private function handleInvalidCharacter(Token $token, ErrorHandler $errorHandler) : void { - // PHP's error handling for token_get_all() is rather bad, so if we want detailed - // error information we need to compute it ourselves. Invalid character errors are - // detected by finding "gaps" in the token array. Unterminated comments are detected - // by checking if a trailing comment has a "*/" at the end. - // - // Additionally, we perform a number of canonicalizations here: - // * Use the PHP 8.0 comment format, which does not include trailing whitespace anymore. - // * Use PHP 8.0 T_NAME_* tokens. - // * Use PHP 8.1 T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG and - // T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG tokens used to disambiguate intersection types. - $filePos = 0; - $line = 1; - $numTokens = \count($this->tokens); - for ($i = 0; $i < $numTokens; $i++) { - $token = $this->tokens[$i]; - // Since PHP 7.4 invalid characters are represented by a T_BAD_CHARACTER token. - // In this case we only need to emit an error. - if ($token[0] === \T_BAD_CHARACTER) { - $this->handleInvalidCharacterRange($filePos, $filePos + 1, $line, $errorHandler); - } - if ($token[0] === \T_COMMENT && \substr($token[1], 0, 2) !== '/*' && \preg_match('/(\\r\\n|\\n|\\r)$/D', $token[1], $matches)) { - $trailingNewline = $matches[0]; - $token[1] = \substr($token[1], 0, -\strlen($trailingNewline)); - $this->tokens[$i] = $token; - if (isset($this->tokens[$i + 1]) && $this->tokens[$i + 1][0] === \T_WHITESPACE) { - // Move trailing newline into following T_WHITESPACE token, if it already exists. - $this->tokens[$i + 1][1] = $trailingNewline . $this->tokens[$i + 1][1]; - $this->tokens[$i + 1][2]--; - } else { - // Otherwise, we need to create a new T_WHITESPACE token. - \array_splice($this->tokens, $i + 1, 0, [[\T_WHITESPACE, $trailingNewline, $line]]); - $numTokens++; - } - } - // Emulate PHP 8 T_NAME_* tokens, by combining sequences of T_NS_SEPARATOR and T_STRING - // into a single token. - if (\is_array($token) && ($token[0] === \T_NS_SEPARATOR || isset($this->identifierTokens[$token[0]]))) { - $lastWasSeparator = $token[0] === \T_NS_SEPARATOR; - $text = $token[1]; - for ($j = $i + 1; isset($this->tokens[$j]); $j++) { - if ($lastWasSeparator) { - if (!isset($this->identifierTokens[$this->tokens[$j][0]])) { - break; - } - $lastWasSeparator = \false; - } else { - if ($this->tokens[$j][0] !== \T_NS_SEPARATOR) { - break; - } - $lastWasSeparator = \true; - } - $text .= $this->tokens[$j][1]; - } - if ($lastWasSeparator) { - // Trailing separator is not part of the name. - $j--; - $text = \substr($text, 0, -1); - } - if ($j > $i + 1) { - if ($token[0] === \T_NS_SEPARATOR) { - $type = \T_NAME_FULLY_QUALIFIED; - } else { - if ($token[0] === \T_NAMESPACE) { - $type = \T_NAME_RELATIVE; - } else { - $type = \T_NAME_QUALIFIED; - } - } - $token = [$type, $text, $line]; - \array_splice($this->tokens, $i, $j - $i, [$token]); - $numTokens -= $j - $i - 1; - } - } - if ($token === '&') { - $next = $i + 1; - while (isset($this->tokens[$next]) && $this->tokens[$next][0] === \T_WHITESPACE) { - $next++; - } - $followedByVarOrVarArg = isset($this->tokens[$next]) && ($this->tokens[$next][0] === \T_VARIABLE || $this->tokens[$next][0] === \T_ELLIPSIS); - $this->tokens[$i] = $token = [$followedByVarOrVarArg ? \T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG : \T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG, '&', $line]; - } - $tokenValue = \is_string($token) ? $token : $token[1]; - $tokenLen = \strlen($tokenValue); - if (\substr($this->code, $filePos, $tokenLen) !== $tokenValue) { - // Something is missing, must be an invalid character - $nextFilePos = \strpos($this->code, $tokenValue, $filePos); - $badCharTokens = $this->handleInvalidCharacterRange($filePos, $nextFilePos, $line, $errorHandler); - $filePos = (int) $nextFilePos; - \array_splice($this->tokens, $i, 0, $badCharTokens); - $numTokens += \count($badCharTokens); - $i += \count($badCharTokens); - } - $filePos += $tokenLen; - $line += \substr_count($tokenValue, "\n"); - } - if ($filePos !== \strlen($this->code)) { - if (\substr($this->code, $filePos, 2) === '/*') { - // Unlike PHP, HHVM will drop unterminated comments entirely - $comment = \substr($this->code, $filePos); - $errorHandler->handleError(new Error('Unterminated comment', ['startLine' => $line, 'endLine' => $line + \substr_count($comment, "\n"), 'startFilePos' => $filePos, 'endFilePos' => $filePos + \strlen($comment)])); - // Emulate the PHP behavior - $isDocComment = isset($comment[3]) && $comment[3] === '*'; - $this->tokens[] = [$isDocComment ? \T_DOC_COMMENT : \T_COMMENT, $comment, $line]; - } else { - // Invalid characters at the end of the input - $badCharTokens = $this->handleInvalidCharacterRange($filePos, \strlen($this->code), $line, $errorHandler); - $this->tokens = \array_merge($this->tokens, $badCharTokens); - } - return; - } - if (\count($this->tokens) > 0) { - // Check for unterminated comment - $lastToken = $this->tokens[\count($this->tokens) - 1]; - if ($this->isUnterminatedComment($lastToken)) { - $errorHandler->handleError(new Error('Unterminated comment', ['startLine' => $line - \substr_count($lastToken[1], "\n"), 'endLine' => $line, 'startFilePos' => $filePos - \strlen($lastToken[1]), 'endFilePos' => $filePos])); - } - } - } - /** - * Fetches the next token. - * - * The available attributes are determined by the 'usedAttributes' option, which can - * be specified in the constructor. The following attributes are supported: - * - * * 'comments' => Array of PhpParser\Comment or PhpParser\Comment\Doc instances, - * representing all comments that occurred between the previous - * non-discarded token and the current one. - * * 'startLine' => Line in which the node starts. - * * 'endLine' => Line in which the node ends. - * * 'startTokenPos' => Offset into the token array of the first token in the node. - * * 'endTokenPos' => Offset into the token array of the last token in the node. - * * 'startFilePos' => Offset into the code string of the first character that is part of the node. - * * 'endFilePos' => Offset into the code string of the last character that is part of the node. - * - * @param mixed $value Variable to store token content in - * @param mixed $startAttributes Variable to store start attributes in - * @param mixed $endAttributes Variable to store end attributes in - * - * @return int Token id - */ - public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) : int - { - $startAttributes = []; - $endAttributes = []; - while (1) { - if (isset($this->tokens[++$this->pos])) { - $token = $this->tokens[$this->pos]; - } else { - // EOF token with ID 0 - $token = "\x00"; - } - if ($this->attributeStartLineUsed) { - $startAttributes['startLine'] = $this->line; - } - if ($this->attributeStartTokenPosUsed) { - $startAttributes['startTokenPos'] = $this->pos; - } - if ($this->attributeStartFilePosUsed) { - $startAttributes['startFilePos'] = $this->filePos; - } - if (\is_string($token)) { - $value = $token; - if (isset($token[1])) { - // bug in token_get_all - $this->filePos += 2; - $id = \ord('"'); - } else { - $this->filePos += 1; - $id = \ord($token); - } - } elseif (!isset($this->dropTokens[$token[0]])) { - $value = $token[1]; - $id = $this->tokenMap[$token[0]]; - if (\T_CLOSE_TAG === $token[0]) { - $this->prevCloseTagHasNewline = \false !== \strpos($token[1], "\n") || \false !== \strpos($token[1], "\r"); - } elseif (\T_INLINE_HTML === $token[0]) { - $startAttributes['hasLeadingNewline'] = $this->prevCloseTagHasNewline; - } - $this->line += \substr_count($value, "\n"); - $this->filePos += \strlen($value); - } else { - $origLine = $this->line; - $origFilePos = $this->filePos; - $this->line += \substr_count($token[1], "\n"); - $this->filePos += \strlen($token[1]); - if (\T_COMMENT === $token[0] || \T_DOC_COMMENT === $token[0]) { - if ($this->attributeCommentsUsed) { - $comment = \T_DOC_COMMENT === $token[0] ? new Comment\Doc($token[1], $origLine, $origFilePos, $this->pos, $this->line, $this->filePos - 1, $this->pos) : new Comment($token[1], $origLine, $origFilePos, $this->pos, $this->line, $this->filePos - 1, $this->pos); - $startAttributes['comments'][] = $comment; - } - } - continue; - } - if ($this->attributeEndLineUsed) { - $endAttributes['endLine'] = $this->line; - } - if ($this->attributeEndTokenPosUsed) { - $endAttributes['endTokenPos'] = $this->pos; - } - if ($this->attributeEndFilePosUsed) { - $endAttributes['endFilePos'] = $this->filePos - 1; - } - return $id; + $chr = $token->text; + if ($chr === "\x00") { + // PHP cuts error message after null byte, so need special case + $errorMsg = 'Unexpected null byte'; + } else { + $errorMsg = \sprintf('Unexpected character "%s" (ASCII %d)', $chr, \ord($chr)); } - throw new \RuntimeException('Reached end of lexer loop'); + $errorHandler->handleError(new Error($errorMsg, ['startLine' => $token->line, 'endLine' => $token->line, 'startFilePos' => $token->pos, 'endFilePos' => $token->pos])); } - /** - * Returns the token array for current code. - * - * The token array is in the same format as provided by the - * token_get_all() function and does not discard tokens (i.e. - * whitespace and comments are included). The token position - * attributes are against this token array. - * - * @return array Array of tokens in token_get_all() format - */ - public function getTokens() : array + private function isUnterminatedComment(Token $token) : bool { - return $this->tokens; + return $token->is([\T_COMMENT, \T_DOC_COMMENT]) && \substr($token->text, 0, 2) === '/*' && \substr($token->text, -2) !== '*/'; } /** - * Handles __halt_compiler() by returning the text after it. - * - * @return string Remaining text + * @param list $tokens */ - public function handleHaltCompiler() : string - { - // text after T_HALT_COMPILER, still including (); - $textAfter = \substr($this->code, $this->filePos); - // ensure that it is followed by (); - // this simplifies the situation, by not allowing any comments - // in between of the tokens. - if (!\preg_match('~^\\s*\\(\\s*\\)\\s*(?:;|\\?>\\r?\\n?)~', $textAfter, $matches)) { - throw new Error('__HALT_COMPILER must be followed by "();"'); - } - // prevent the lexer from returning any further tokens - $this->pos = \count($this->tokens); - // return with (); removed - return \substr($textAfter, \strlen($matches[0])); - } - private function defineCompatibilityTokens() + protected function postprocessTokens(array &$tokens, ErrorHandler $errorHandler) : void { - static $compatTokensDefined = \false; - if ($compatTokensDefined) { + // This function reports errors (bad characters and unterminated comments) in the token + // array, and performs certain canonicalizations: + // * Use PHP 8.1 T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG and + // T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG tokens used to disambiguate intersection types. + // * Add a sentinel token with ID 0. + $numTokens = \count($tokens); + if ($numTokens === 0) { + // Empty input edge case: Just add the sentinel token. + $tokens[] = new Token(0, "\x00", 1, 0); return; } - $compatTokens = [ - // PHP 7.4 - 'T_BAD_CHARACTER', - 'T_FN', - 'T_COALESCE_EQUAL', - // PHP 8.0 - 'T_NAME_QUALIFIED', - 'T_NAME_FULLY_QUALIFIED', - 'T_NAME_RELATIVE', - 'T_MATCH', - 'T_NULLSAFE_OBJECT_OPERATOR', - 'T_ATTRIBUTE', - // PHP 8.1 - 'T_ENUM', - 'T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG', - 'T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG', - 'T_READONLY', - ]; - // PHP-Parser might be used together with another library that also emulates some or all - // of these tokens. Perform a sanity-check that all already defined tokens have been - // assigned a unique ID. - $usedTokenIds = []; - foreach ($compatTokens as $token) { - if (\defined($token)) { - $tokenId = \constant($token); - $clashingToken = $usedTokenIds[$tokenId] ?? null; - if ($clashingToken !== null) { - throw new \Error(\sprintf('Token %s has same ID as token %s, ' . 'you may be using a library with broken token emulation', $token, $clashingToken)); - } - $usedTokenIds[$tokenId] = $token; - } - } - // Now define any tokens that have not yet been emulated. Try to assign IDs from -1 - // downwards, but skip any IDs that may already be in use. - $newTokenId = -1; - foreach ($compatTokens as $token) { - if (!\defined($token)) { - while (isset($usedTokenIds[$newTokenId])) { - $newTokenId--; - } - \define($token, $newTokenId); - $newTokenId--; + for ($i = 0; $i < $numTokens; $i++) { + $token = $tokens[$i]; + if ($token->id === \T_BAD_CHARACTER) { + $this->handleInvalidCharacter($token, $errorHandler); } - } - $compatTokensDefined = \true; - } - /** - * Creates the token map. - * - * The token map maps the PHP internal token identifiers - * to the identifiers used by the Parser. Additionally it - * maps T_OPEN_TAG_WITH_ECHO to T_ECHO and T_CLOSE_TAG to ';'. - * - * @return array The token map - */ - protected function createTokenMap() : array - { - $tokenMap = []; - // 256 is the minimum possible token number, as everything below - // it is an ASCII value - for ($i = 256; $i < 1000; ++$i) { - if (\T_DOUBLE_COLON === $i) { - // T_DOUBLE_COLON is equivalent to T_PAAMAYIM_NEKUDOTAYIM - $tokenMap[$i] = Tokens::T_PAAMAYIM_NEKUDOTAYIM; - } elseif (\T_OPEN_TAG_WITH_ECHO === $i) { - // T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO - $tokenMap[$i] = Tokens::T_ECHO; - } elseif (\T_CLOSE_TAG === $i) { - // T_CLOSE_TAG is equivalent to ';' - $tokenMap[$i] = \ord(';'); - } elseif ('UNKNOWN' !== ($name = \token_name($i))) { - if ('T_HASHBANG' === $name) { - // HHVM uses a special token for #! hashbang lines - $tokenMap[$i] = Tokens::T_INLINE_HTML; - } elseif (\defined($name = Tokens::class . '::' . $name)) { - // Other tokens can be mapped directly - $tokenMap[$i] = \constant($name); + if ($token->id === \ord('&')) { + $next = $i + 1; + while (isset($tokens[$next]) && $tokens[$next]->id === \T_WHITESPACE) { + $next++; } + $followedByVarOrVarArg = isset($tokens[$next]) && $tokens[$next]->is([\T_VARIABLE, \T_ELLIPSIS]); + $token->id = $followedByVarOrVarArg ? \T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG : \T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG; } } - // HHVM uses a special token for numbers that overflow to double - if (\defined('T_ONUMBER')) { - $tokenMap[\T_ONUMBER] = Tokens::T_DNUMBER; + // Check for unterminated comment + $lastToken = $tokens[$numTokens - 1]; + if ($this->isUnterminatedComment($lastToken)) { + $errorHandler->handleError(new Error('Unterminated comment', ['startLine' => $lastToken->line, 'endLine' => $lastToken->getEndLine(), 'startFilePos' => $lastToken->pos, 'endFilePos' => $lastToken->getEndPos()])); } - // HHVM also has a separate token for the __COMPILER_HALT_OFFSET__ constant - if (\defined('T_COMPILER_HALT_OFFSET')) { - $tokenMap[\T_COMPILER_HALT_OFFSET] = Tokens::T_STRING; - } - // Assign tokens for which we define compatibility constants, as token_name() does not know them. - $tokenMap[\T_FN] = Tokens::T_FN; - $tokenMap[\T_COALESCE_EQUAL] = Tokens::T_COALESCE_EQUAL; - $tokenMap[\T_NAME_QUALIFIED] = Tokens::T_NAME_QUALIFIED; - $tokenMap[\T_NAME_FULLY_QUALIFIED] = Tokens::T_NAME_FULLY_QUALIFIED; - $tokenMap[\T_NAME_RELATIVE] = Tokens::T_NAME_RELATIVE; - $tokenMap[\T_MATCH] = Tokens::T_MATCH; - $tokenMap[\T_NULLSAFE_OBJECT_OPERATOR] = Tokens::T_NULLSAFE_OBJECT_OPERATOR; - $tokenMap[\T_ATTRIBUTE] = Tokens::T_ATTRIBUTE; - $tokenMap[\T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG] = Tokens::T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG; - $tokenMap[\T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG] = Tokens::T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG; - $tokenMap[\T_ENUM] = Tokens::T_ENUM; - $tokenMap[\T_READONLY] = Tokens::T_READONLY; - return $tokenMap; - } - private function createIdentifierTokenMap() : array - { - // Based on semi_reserved production. - return \array_fill_keys([\T_STRING, \T_STATIC, \T_ABSTRACT, \T_FINAL, \T_PRIVATE, \T_PROTECTED, \T_PUBLIC, \T_READONLY, \T_INCLUDE, \T_INCLUDE_ONCE, \T_EVAL, \T_REQUIRE, \T_REQUIRE_ONCE, \T_LOGICAL_OR, \T_LOGICAL_XOR, \T_LOGICAL_AND, \T_INSTANCEOF, \T_NEW, \T_CLONE, \T_EXIT, \T_IF, \T_ELSEIF, \T_ELSE, \T_ENDIF, \T_ECHO, \T_DO, \T_WHILE, \T_ENDWHILE, \T_FOR, \T_ENDFOR, \T_FOREACH, \T_ENDFOREACH, \T_DECLARE, \T_ENDDECLARE, \T_AS, \T_TRY, \T_CATCH, \T_FINALLY, \T_THROW, \T_USE, \T_INSTEADOF, \T_GLOBAL, \T_VAR, \T_UNSET, \T_ISSET, \T_EMPTY, \T_CONTINUE, \T_GOTO, \T_FUNCTION, \T_CONST, \T_RETURN, \T_PRINT, \T_YIELD, \T_LIST, \T_SWITCH, \T_ENDSWITCH, \T_CASE, \T_DEFAULT, \T_BREAK, \T_ARRAY, \T_CALLABLE, \T_EXTENDS, \T_IMPLEMENTS, \T_NAMESPACE, \T_TRAIT, \T_INTERFACE, \T_CLASS, \T_CLASS_C, \T_TRAIT_C, \T_FUNC_C, \T_METHOD_C, \T_LINE, \T_FILE, \T_DIR, \T_NS_C, \T_HALT_COMPILER, \T_FN, \T_MATCH], \true); + // Add sentinel token. + $tokens[] = new Token(0, "\x00", $lastToken->getEndLine(), $lastToken->getEndPos()); } } */ + private array $emulators = []; + private PhpVersion $targetPhpVersion; + private PhpVersion $hostPhpVersion; /** - * @param mixed[] $options Lexer options. In addition to the usual options, - * accepts a 'phpVersion' string that specifies the - * version to emulate. Defaults to newest supported. + * @param PhpVersion|null $phpVersion PHP version to emulate. Defaults to newest supported. */ - public function __construct(array $options = []) + public function __construct(?PhpVersion $phpVersion = null) { - $this->targetPhpVersion = $options['phpVersion'] ?? Emulative::PHP_8_2; - unset($options['phpVersion']); - parent::__construct($options); - $emulators = [new FlexibleDocStringEmulator(), new FnTokenEmulator(), new MatchTokenEmulator(), new CoaleseEqualTokenEmulator(), new NumericLiteralSeparatorEmulator(), new NullsafeTokenEmulator(), new AttributeEmulator(), new EnumTokenEmulator(), new ReadonlyTokenEmulator(), new ExplicitOctalEmulator(), new ReadonlyFunctionTokenEmulator()]; + $this->targetPhpVersion = $phpVersion ?? PhpVersion::getNewestSupported(); + $this->hostPhpVersion = PhpVersion::getHostVersion(); + $emulators = [new MatchTokenEmulator(), new NullsafeTokenEmulator(), new AttributeEmulator(), new EnumTokenEmulator(), new ReadonlyTokenEmulator(), new ExplicitOctalEmulator(), new ReadonlyFunctionTokenEmulator()]; // Collect emulators that are relevant for the PHP version we're running // and the PHP version we're targeting for emulation. foreach ($emulators as $emulator) { $emulatorPhpVersion = $emulator->getPhpVersion(); if ($this->isForwardEmulationNeeded($emulatorPhpVersion)) { $this->emulators[] = $emulator; - } else { - if ($this->isReverseEmulationNeeded($emulatorPhpVersion)) { - $this->emulators[] = new ReverseEmulator($emulator); - } + } elseif ($this->isReverseEmulationNeeded($emulatorPhpVersion)) { + $this->emulators[] = new ReverseEmulator($emulator); } } } - public function startLexing(string $code, ErrorHandler $errorHandler = null) + public function tokenize(string $code, ?ErrorHandler $errorHandler = null) : array { $emulators = \array_filter($this->emulators, function ($emulator) use($code) { return $emulator->isEmulationNeeded($code); }); if (empty($emulators)) { // Nothing to emulate, yay - parent::startLexing($code, $errorHandler); - return; + return parent::tokenize($code, $errorHandler); + } + if ($errorHandler === null) { + $errorHandler = new ErrorHandler\Throwing(); } $this->patches = []; foreach ($emulators as $emulator) { $code = $emulator->preprocessCode($code, $this->patches); } $collector = new ErrorHandler\Collecting(); - parent::startLexing($code, $collector); + $tokens = parent::tokenize($code, $collector); $this->sortPatches(); - $this->fixupTokens(); + $tokens = $this->fixupTokens($tokens); $errors = $collector->getErrors(); if (!empty($errors)) { $this->fixupErrors($errors); @@ -7800,18 +9400,19 @@ class Emulative extends Lexer } } foreach ($emulators as $emulator) { - $this->tokens = $emulator->emulate($code, $this->tokens); + $tokens = $emulator->emulate($code, $tokens); } + return $tokens; } - private function isForwardEmulationNeeded(string $emulatorPhpVersion) : bool + private function isForwardEmulationNeeded(PhpVersion $emulatorPhpVersion) : bool { - return \version_compare(\PHP_VERSION, $emulatorPhpVersion, '<') && \version_compare($this->targetPhpVersion, $emulatorPhpVersion, '>='); + return $this->hostPhpVersion->older($emulatorPhpVersion) && $this->targetPhpVersion->newerOrEqual($emulatorPhpVersion); } - private function isReverseEmulationNeeded(string $emulatorPhpVersion) : bool + private function isReverseEmulationNeeded(PhpVersion $emulatorPhpVersion) : bool { - return \version_compare(\PHP_VERSION, $emulatorPhpVersion, '>=') && \version_compare($this->targetPhpVersion, $emulatorPhpVersion, '<'); + return $this->hostPhpVersion->newerOrEqual($emulatorPhpVersion) && $this->targetPhpVersion->older($emulatorPhpVersion); } - private function sortPatches() + private function sortPatches() : void { // Patches may be contributed by different emulators. // Make sure they are sorted by increasing patch position. @@ -7819,83 +9420,72 @@ class Emulative extends Lexer return $p1[0] <=> $p2[0]; }); } - private function fixupTokens() + /** + * @param list $tokens + * @return list + */ + private function fixupTokens(array $tokens) : array { if (\count($this->patches) === 0) { - return; + return $tokens; } // Load first patch $patchIdx = 0; list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx]; // We use a manual loop over the tokens, because we modify the array on the fly - $pos = 0; - for ($i = 0, $c = \count($this->tokens); $i < $c; $i++) { - $token = $this->tokens[$i]; - if (\is_string($token)) { - if ($patchPos === $pos) { - // Only support replacement for string tokens. - \assert($patchType === 'replace'); - $this->tokens[$i] = $patchText; - // Fetch the next patch - $patchIdx++; - if ($patchIdx >= \count($this->patches)) { - // No more patches, we're done - return; - } - list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx]; - } - $pos += \strlen($token); - continue; - } - $len = \strlen($token[1]); - $posDelta = 0; + $posDelta = 0; + $lineDelta = 0; + for ($i = 0, $c = \count($tokens); $i < $c; $i++) { + $token = $tokens[$i]; + $pos = $token->pos; + $token->pos += $posDelta; + $token->line += $lineDelta; + $localPosDelta = 0; + $len = \strlen($token->text); while ($patchPos >= $pos && $patchPos < $pos + $len) { $patchTextLen = \strlen($patchText); if ($patchType === 'remove') { if ($patchPos === $pos && $patchTextLen === $len) { // Remove token entirely - \array_splice($this->tokens, $i, 1, []); + \array_splice($tokens, $i, 1, []); $i--; $c--; } else { // Remove from token string - $this->tokens[$i][1] = \substr_replace($token[1], '', $patchPos - $pos + $posDelta, $patchTextLen); - $posDelta -= $patchTextLen; + $token->text = \substr_replace($token->text, '', $patchPos - $pos + $localPosDelta, $patchTextLen); + $localPosDelta -= $patchTextLen; } + $lineDelta -= \substr_count($patchText, "\n"); } elseif ($patchType === 'add') { // Insert into the token string - $this->tokens[$i][1] = \substr_replace($token[1], $patchText, $patchPos - $pos + $posDelta, 0); - $posDelta += $patchTextLen; + $token->text = \substr_replace($token->text, $patchText, $patchPos - $pos + $localPosDelta, 0); + $localPosDelta += $patchTextLen; + $lineDelta += \substr_count($patchText, "\n"); + } elseif ($patchType === 'replace') { + // Replace inside the token string + $token->text = \substr_replace($token->text, $patchText, $patchPos - $pos + $localPosDelta, $patchTextLen); } else { - if ($patchType === 'replace') { - // Replace inside the token string - $this->tokens[$i][1] = \substr_replace($token[1], $patchText, $patchPos - $pos + $posDelta, $patchTextLen); - } else { - \assert(\false); - } + \assert(\false); } // Fetch the next patch $patchIdx++; if ($patchIdx >= \count($this->patches)) { - // No more patches, we're done - return; + // No more patches. However, we still need to adjust position. + $patchPos = \PHP_INT_MAX; + break; } list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx]; - // Multiple patches may apply to the same token. Reload the current one to check - // If the new patch applies - $token = $this->tokens[$i]; } - $pos += $len; + $posDelta += $localPosDelta; } - // A patch did not apply - \assert(\false); + return $tokens; } /** * Fixup line and position information in errors. * * @param Error[] $errors */ - private function fixupErrors(array $errors) + private function fixupErrors(array $errors) : void { foreach ($errors as $error) { $attrs = $error->getAttributes(); @@ -7910,11 +9500,9 @@ class Emulative extends Lexer if ($patchType === 'add') { $posDelta += \strlen($patchText); $lineDelta += \substr_count($patchText, "\n"); - } else { - if ($patchType === 'remove') { - $posDelta -= \strlen($patchText); - $lineDelta -= \substr_count($patchText, "\n"); - } + } elseif ($patchType === 'remove') { + $posDelta -= \strlen($patchText); + $lineDelta -= \substr_count($patchText, "\n"); } } $attrs['startFilePos'] += $posDelta; @@ -7930,12 +9518,13 @@ class Emulative extends Lexer declare (strict_types=1); namespace PHPUnit\PhpParser\Lexer\TokenEmulator; -use PHPUnit\PhpParser\Lexer\Emulative; +use PHPUnit\PhpParser\PhpVersion; +use PHPUnit\PhpParser\Token; final class AttributeEmulator extends TokenEmulator { - public function getPhpVersion() : string + public function getPhpVersion() : PhpVersion { - return Emulative::PHP_8_0; + return PhpVersion::fromComponents(8, 0); } public function isEmulationNeeded(string $code) : bool { @@ -7945,16 +9534,13 @@ final class AttributeEmulator extends TokenEmulator { // We need to manually iterate and manage a count because we'll change // the tokens array on the way. - $line = 1; for ($i = 0, $c = \count($tokens); $i < $c; ++$i) { - if ($tokens[$i] === '#' && isset($tokens[$i + 1]) && $tokens[$i + 1] === '[') { - \array_splice($tokens, $i, 2, [[\T_ATTRIBUTE, '#[', $line]]); + $token = $tokens[$i]; + if ($token->text === '#' && isset($tokens[$i + 1]) && $tokens[$i + 1]->text === '[') { + \array_splice($tokens, $i, 2, [new Token(\T_ATTRIBUTE, '#[', $token->line, $token->pos)]); $c--; continue; } - if (\is_array($tokens[$i])) { - $line += \substr_count($tokens[$i][1], "\n"); - } } return $tokens; } @@ -7980,53 +9566,12 @@ final class AttributeEmulator extends TokenEmulator declare (strict_types=1); namespace PHPUnit\PhpParser\Lexer\TokenEmulator; -use PHPUnit\PhpParser\Lexer\Emulative; -final class CoaleseEqualTokenEmulator extends TokenEmulator -{ - public function getPhpVersion() : string - { - return Emulative::PHP_7_4; - } - public function isEmulationNeeded(string $code) : bool - { - return \strpos($code, '??=') !== \false; - } - public function emulate(string $code, array $tokens) : array - { - // We need to manually iterate and manage a count because we'll change - // the tokens array on the way - $line = 1; - for ($i = 0, $c = \count($tokens); $i < $c; ++$i) { - if (isset($tokens[$i + 1])) { - if ($tokens[$i][0] === \T_COALESCE && $tokens[$i + 1] === '=') { - \array_splice($tokens, $i, 2, [[\T_COALESCE_EQUAL, '??=', $line]]); - $c--; - continue; - } - } - if (\is_array($tokens[$i])) { - $line += \substr_count($tokens[$i][1], "\n"); - } - } - return $tokens; - } - public function reverseEmulate(string $code, array $tokens) : array - { - // ??= was not valid code previously, don't bother. - return $tokens; - } -} -id === \T_WHITESPACE && $tokens[$pos + 2]->id === \T_STRING; } } resolveIntegerOrFloatToken($tokens[$i + 1][1]); - \array_splice($tokens, $i, 2, [[$tokenKind, '0' . $tokens[$i + 1][1], $tokens[$i][2]]]); + $token = $tokens[$i]; + if ($token->id == \T_LNUMBER && $token->text === '0' && isset($tokens[$i + 1]) && $tokens[$i + 1]->id == \T_STRING && \preg_match('/[oO][0-7]+(?:_[0-7]+)*/', $tokens[$i + 1]->text)) { + $tokenKind = $this->resolveIntegerOrFloatToken($tokens[$i + 1]->text); + \array_splice($tokens, $i, 2, [new Token($tokenKind, '0' . $tokens[$i + 1]->text, $token->line, $token->pos)]); $c--; } } @@ -8086,124 +9633,36 @@ class ExplicitOctalEmulator extends TokenEmulator declare (strict_types=1); namespace PHPUnit\PhpParser\Lexer\TokenEmulator; -use PHPUnit\PhpParser\Lexer\Emulative; -final class FlexibleDocStringEmulator extends TokenEmulator -{ - const FLEXIBLE_DOC_STRING_REGEX = <<<'REGEX' -/<<<[ \t]*(['"]?)([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)\1\r?\n -(?:.*\r?\n)*? -(?\h*)\2(?![a-zA-Z0-9_\x80-\xff])(?(?:;?[\r\n])?)/x -REGEX; - public function getPhpVersion() : string - { - return Emulative::PHP_7_3; - } - public function isEmulationNeeded(string $code) : bool - { - return \strpos($code, '<<<') !== \false; - } - public function emulate(string $code, array $tokens) : array - { - // Handled by preprocessing + fixup. - return $tokens; - } - public function reverseEmulate(string $code, array $tokens) : array - { - // Not supported. - return $tokens; - } - public function preprocessCode(string $code, array &$patches) : string - { - if (!\preg_match_all(self::FLEXIBLE_DOC_STRING_REGEX, $code, $matches, \PREG_SET_ORDER | \PREG_OFFSET_CAPTURE)) { - // No heredoc/nowdoc found - return $code; - } - // Keep track of how much we need to adjust string offsets due to the modifications we - // already made - $posDelta = 0; - foreach ($matches as $match) { - $indentation = $match['indentation'][0]; - $indentationStart = $match['indentation'][1]; - $separator = $match['separator'][0]; - $separatorStart = $match['separator'][1]; - if ($indentation === '' && $separator !== '') { - // Ordinary heredoc/nowdoc - continue; - } - if ($indentation !== '') { - // Remove indentation - $indentationLen = \strlen($indentation); - $code = \substr_replace($code, '', $indentationStart + $posDelta, $indentationLen); - $patches[] = [$indentationStart + $posDelta, 'add', $indentation]; - $posDelta -= $indentationLen; - } - if ($separator === '') { - // Insert newline as separator - $code = \substr_replace($code, "\n", $separatorStart + $posDelta, 0); - $patches[] = [$separatorStart + $posDelta, 'remove', "\n"]; - $posDelta += 1; - } - } - return $code; - } -} -getKeywordString()) !== \false; } + /** @param Token[] $tokens */ protected function isKeywordContext(array $tokens, int $pos) : bool { $previousNonSpaceToken = $this->getPreviousNonSpaceToken($tokens, $pos); - return $previousNonSpaceToken === null || $previousNonSpaceToken[0] !== \T_OBJECT_OPERATOR; + return $previousNonSpaceToken === null || $previousNonSpaceToken->id !== \T_OBJECT_OPERATOR; } public function emulate(string $code, array $tokens) : array { $keywordString = $this->getKeywordString(); foreach ($tokens as $i => $token) { - if ($token[0] === \T_STRING && \strtolower($token[1]) === $keywordString && $this->isKeywordContext($tokens, $i)) { - $tokens[$i][0] = $this->getKeywordToken(); + if ($token->id === \T_STRING && \strtolower($token->text) === $keywordString && $this->isKeywordContext($tokens, $i)) { + $token->id = $this->getKeywordToken(); } } return $tokens; } - /** - * @param mixed[] $tokens - * @return array|string|null - */ - private function getPreviousNonSpaceToken(array $tokens, int $start) + /** @param Token[] $tokens */ + private function getPreviousNonSpaceToken(array $tokens, int $start) : ?Token { for ($i = $start - 1; $i >= 0; --$i) { - if ($tokens[$i][0] === \T_WHITESPACE) { + if ($tokens[$i]->id === \T_WHITESPACE) { continue; } return $tokens[$i]; @@ -8213,9 +9672,9 @@ abstract class KeywordEmulator extends TokenEmulator public function reverseEmulate(string $code, array $tokens) : array { $keywordToken = $this->getKeywordToken(); - foreach ($tokens as $i => $token) { - if ($token[0] === $keywordToken) { - $tokens[$i][0] = \T_STRING; + foreach ($tokens as $token) { + if ($token->id === $keywordToken) { + $token->id = \T_STRING; } } return $tokens; @@ -8226,12 +9685,12 @@ abstract class KeywordEmulator extends TokenEmulator declare (strict_types=1); namespace PHPUnit\PhpParser\Lexer\TokenEmulator; -use PHPUnit\PhpParser\Lexer\Emulative; +use PHPUnit\PhpParser\PhpVersion; final class MatchTokenEmulator extends KeywordEmulator { - public function getPhpVersion() : string + public function getPhpVersion() : PhpVersion { - return Emulative::PHP_8_0; + return PhpVersion::fromComponents(8, 0); } public function getKeywordString() : string { @@ -8247,12 +9706,13 @@ final class MatchTokenEmulator extends KeywordEmulator declare (strict_types=1); namespace PHPUnit\PhpParser\Lexer\TokenEmulator; -use PHPUnit\PhpParser\Lexer\Emulative; +use PHPUnit\PhpParser\PhpVersion; +use PHPUnit\PhpParser\Token; final class NullsafeTokenEmulator extends TokenEmulator { - public function getPhpVersion() : string + public function getPhpVersion() : PhpVersion { - return Emulative::PHP_8_0; + return PhpVersion::fromComponents(8, 0); } public function isEmulationNeeded(string $code) : bool { @@ -8262,26 +9722,24 @@ final class NullsafeTokenEmulator extends TokenEmulator { // We need to manually iterate and manage a count because we'll change // the tokens array on the way - $line = 1; for ($i = 0, $c = \count($tokens); $i < $c; ++$i) { - if ($tokens[$i] === '?' && isset($tokens[$i + 1]) && $tokens[$i + 1][0] === \T_OBJECT_OPERATOR) { - \array_splice($tokens, $i, 2, [[\T_NULLSAFE_OBJECT_OPERATOR, '?->', $line]]); + $token = $tokens[$i]; + if ($token->text === '?' && isset($tokens[$i + 1]) && $tokens[$i + 1]->id === \T_OBJECT_OPERATOR) { + \array_splice($tokens, $i, 2, [new Token(\T_NULLSAFE_OBJECT_OPERATOR, '?->', $token->line, $token->pos)]); $c--; continue; } // Handle ?-> inside encapsed string. - if ($tokens[$i][0] === \T_ENCAPSED_AND_WHITESPACE && isset($tokens[$i - 1]) && $tokens[$i - 1][0] === \T_VARIABLE && \preg_match('/^\\?->([a-zA-Z_\\x80-\\xff][a-zA-Z0-9_\\x80-\\xff]*)/', $tokens[$i][1], $matches)) { - $replacement = [[\T_NULLSAFE_OBJECT_OPERATOR, '?->', $line], [\T_STRING, $matches[1], $line]]; - if (\strlen($matches[0]) !== \strlen($tokens[$i][1])) { - $replacement[] = [\T_ENCAPSED_AND_WHITESPACE, \substr($tokens[$i][1], \strlen($matches[0])), $line]; + if ($token->id === \T_ENCAPSED_AND_WHITESPACE && isset($tokens[$i - 1]) && $tokens[$i - 1]->id === \T_VARIABLE && \preg_match('/^\\?->([a-zA-Z_\\x80-\\xff][a-zA-Z0-9_\\x80-\\xff]*)/', $token->text, $matches)) { + $replacement = [new Token(\T_NULLSAFE_OBJECT_OPERATOR, '?->', $token->line, $token->pos), new Token(\T_STRING, $matches[1], $token->line, $token->pos + 3)]; + $matchLen = \strlen($matches[0]); + if ($matchLen !== \strlen($token->text)) { + $replacement[] = new Token(\T_ENCAPSED_AND_WHITESPACE, \substr($token->text, $matchLen), $token->line, $token->pos + $matchLen); } \array_splice($tokens, $i, 1, $replacement); $c += \count($replacement) - 1; continue; } - if (\is_array($tokens[$i])) { - $line += \substr_count($tokens[$i][1], "\n"); - } } return $tokens; } @@ -8296,95 +9754,7 @@ final class NullsafeTokenEmulator extends TokenEmulator declare (strict_types=1); namespace PHPUnit\PhpParser\Lexer\TokenEmulator; -use PHPUnit\PhpParser\Lexer\Emulative; -final class NumericLiteralSeparatorEmulator extends TokenEmulator -{ - const BIN = '(?:0b[01]+(?:_[01]+)*)'; - const HEX = '(?:0x[0-9a-f]+(?:_[0-9a-f]+)*)'; - const DEC = '(?:[0-9]+(?:_[0-9]+)*)'; - const SIMPLE_FLOAT = '(?:' . self::DEC . '\\.' . self::DEC . '?|\\.' . self::DEC . ')'; - const EXP = '(?:e[+-]?' . self::DEC . ')'; - const FLOAT = '(?:' . self::SIMPLE_FLOAT . self::EXP . '?|' . self::DEC . self::EXP . ')'; - const NUMBER = '~' . self::FLOAT . '|' . self::BIN . '|' . self::HEX . '|' . self::DEC . '~iA'; - public function getPhpVersion() : string - { - return Emulative::PHP_7_4; - } - public function isEmulationNeeded(string $code) : bool - { - return \preg_match('~[0-9]_[0-9]~', $code) || \preg_match('~0x[0-9a-f]+_[0-9a-f]~i', $code); - } - public function emulate(string $code, array $tokens) : array - { - // We need to manually iterate and manage a count because we'll change - // the tokens array on the way - $codeOffset = 0; - for ($i = 0, $c = \count($tokens); $i < $c; ++$i) { - $token = $tokens[$i]; - $tokenLen = \strlen(\is_array($token) ? $token[1] : $token); - if ($token[0] !== \T_LNUMBER && $token[0] !== \T_DNUMBER) { - $codeOffset += $tokenLen; - continue; - } - $res = \preg_match(self::NUMBER, $code, $matches, 0, $codeOffset); - \assert($res, "No number at number token position"); - $match = $matches[0]; - $matchLen = \strlen($match); - if ($matchLen === $tokenLen) { - // Original token already holds the full number. - $codeOffset += $tokenLen; - continue; - } - $tokenKind = $this->resolveIntegerOrFloatToken($match); - $newTokens = [[$tokenKind, $match, $token[2]]]; - $numTokens = 1; - $len = $tokenLen; - while ($matchLen > $len) { - $nextToken = $tokens[$i + $numTokens]; - $nextTokenText = \is_array($nextToken) ? $nextToken[1] : $nextToken; - $nextTokenLen = \strlen($nextTokenText); - $numTokens++; - if ($matchLen < $len + $nextTokenLen) { - // Split trailing characters into a partial token. - \assert(\is_array($nextToken), "Partial token should be an array token"); - $partialText = \substr($nextTokenText, $matchLen - $len); - $newTokens[] = [$nextToken[0], $partialText, $nextToken[2]]; - break; - } - $len += $nextTokenLen; - } - \array_splice($tokens, $i, $numTokens, $newTokens); - $c -= $numTokens - \count($newTokens); - $codeOffset += $matchLen; - } - return $tokens; - } - private function resolveIntegerOrFloatToken(string $str) : int - { - $str = \str_replace('_', '', $str); - if (\stripos($str, '0b') === 0) { - $num = \bindec($str); - } elseif (\stripos($str, '0x') === 0) { - $num = \hexdec($str); - } elseif (\stripos($str, '0') === 0 && \ctype_digit($str)) { - $num = \octdec($str); - } else { - $num = +$str; - } - return \is_float($num) ? \T_DNUMBER : \T_LNUMBER; - } - public function reverseEmulate(string $code, array $tokens) : array - { - // Numeric separators were not legal code previously, don't bother. - return $tokens; - } -} -text === '(' || $tokens[$pos + 1]->id === \T_WHITESPACE && isset($tokens[$pos + 2]) && $tokens[$pos + 2]->text === '(')); } } emulator = $emulator; } - public function getPhpVersion() : string + public function getPhpVersion() : PhpVersion { return $this->emulator->getPhpVersion(); } @@ -8483,19 +9854,24 @@ final class ReverseEmulator extends TokenEmulator declare (strict_types=1); namespace PHPUnit\PhpParser\Lexer\TokenEmulator; +use PHPUnit\PhpParser\PhpVersion; +use PHPUnit\PhpParser\Token; /** @internal */ abstract class TokenEmulator { - public abstract function getPhpVersion() : string; + public abstract function getPhpVersion() : PhpVersion; public abstract function isEmulationNeeded(string $code) : bool; /** - * @return array Modified Tokens + * @param Token[] $tokens Original tokens + * @return Token[] Modified Tokens */ public abstract function emulate(string $code, array $tokens) : array; /** - * @return array Modified Tokens + * @param Token[] $tokens Original tokens + * @return Token[] Modified Tokens */ public abstract function reverseEmulate(string $code, array $tokens) : array; + /** @param array{int, string, string}[] $patches */ public function preprocessCode(string $code, array &$patches) : string { return $code; @@ -8506,19 +9882,81 @@ abstract class TokenEmulator declare (strict_types=1); namespace PHPUnit\PhpParser; +/** + * Modifiers used (as a bit mask) by various flags subnodes, for example on classes, functions, + * properties and constants. + */ +final class Modifiers +{ + public const PUBLIC = 1; + public const PROTECTED = 2; + public const PRIVATE = 4; + public const STATIC = 8; + public const ABSTRACT = 16; + public const FINAL = 32; + public const READONLY = 64; + public const VISIBILITY_MASK = 1 | 2 | 4; + /** + * @internal + */ + public static function verifyClassModifier(int $a, int $b) : void + { + if ($a & Modifiers::ABSTRACT && $b & Modifiers::ABSTRACT) { + throw new Error('Multiple abstract modifiers are not allowed'); + } + if ($a & Modifiers::FINAL && $b & Modifiers::FINAL) { + throw new Error('Multiple final modifiers are not allowed'); + } + if ($a & Modifiers::READONLY && $b & Modifiers::READONLY) { + throw new Error('Multiple readonly modifiers are not allowed'); + } + if ($a & 48 && $b & 48) { + throw new Error('Cannot use the final modifier on an abstract class'); + } + } + /** + * @internal + */ + public static function verifyModifier(int $a, int $b) : void + { + if ($a & Modifiers::VISIBILITY_MASK && $b & Modifiers::VISIBILITY_MASK) { + throw new Error('Multiple access type modifiers are not allowed'); + } + if ($a & Modifiers::ABSTRACT && $b & Modifiers::ABSTRACT) { + throw new Error('Multiple abstract modifiers are not allowed'); + } + if ($a & Modifiers::STATIC && $b & Modifiers::STATIC) { + throw new Error('Multiple static modifiers are not allowed'); + } + if ($a & Modifiers::FINAL && $b & Modifiers::FINAL) { + throw new Error('Multiple final modifiers are not allowed'); + } + if ($a & Modifiers::READONLY && $b & Modifiers::READONLY) { + throw new Error('Multiple readonly modifiers are not allowed'); + } + if ($a & 48 && $b & 48) { + throw new Error('Cannot use the final modifier on an abstract class member'); + } + } +} + [aliasName => originalName]] */ - protected $aliases = []; + protected array $aliases = []; /** @var Name[][] Same as $aliases but preserving original case */ - protected $origAliases = []; + protected array $origAliases = []; /** @var ErrorHandler Error handler */ - protected $errorHandler; + protected ErrorHandler $errorHandler; /** * Create a name context. * @@ -8535,7 +9973,7 @@ class NameContext * * @param Name|null $namespace Null is the global namespace */ - public function startNamespace(Name $namespace = null) + public function startNamespace(?Name $namespace = null) : void { $this->namespace = $namespace; $this->origAliases = $this->aliases = [Stmt\Use_::TYPE_NORMAL => [], Stmt\Use_::TYPE_FUNCTION => [], Stmt\Use_::TYPE_CONSTANT => []]; @@ -8543,12 +9981,12 @@ class NameContext /** * Add an alias / import. * - * @param Name $name Original name - * @param string $aliasName Aliased name - * @param int $type One of Stmt\Use_::TYPE_* - * @param array $errorAttrs Attributes to use to report an error + * @param Name $name Original name + * @param string $aliasName Aliased name + * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_* + * @param array $errorAttrs Attributes to use to report an error */ - public function addAlias(Name $name, string $aliasName, int $type, array $errorAttrs = []) + public function addAlias(Name $name, string $aliasName, int $type, array $errorAttrs = []) : void { // Constant names are case sensitive, everything else case insensitive if ($type === Stmt\Use_::TYPE_CONSTANT) { @@ -8569,7 +10007,7 @@ class NameContext * * @return null|Name Namespace (or null if global namespace) */ - public function getNamespace() + public function getNamespace() : ?Name { return $this->namespace; } @@ -8577,11 +10015,11 @@ class NameContext * Get resolved name. * * @param Name $name Name to resolve - * @param int $type One of Stmt\Use_::TYPE_{FUNCTION|CONSTANT} + * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_{FUNCTION|CONSTANT} * * @return null|Name Resolved name, or null if static resolution is not possible */ - public function getResolvedName(Name $name, int $type) + public function getResolvedName(Name $name, int $type) : ?Name { // don't resolve special class names if ($type === Stmt\Use_::TYPE_NORMAL && $name->isSpecialClassName()) { @@ -8624,7 +10062,7 @@ class NameContext * Get possible ways of writing a fully qualified name (e.g., by making use of aliases). * * @param string $name Fully-qualified name (without leading namespace separator) - * @param int $type One of Stmt\Use_::TYPE_* + * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_* * * @return Name[] Possible representations of the name */ @@ -8674,7 +10112,7 @@ class NameContext * Get shortest representation of this fully-qualified name. * * @param string $name Fully-qualified name (without leading namespace separator) - * @param int $type One of Stmt\Use_::TYPE_* + * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_* * * @return Name Shortest representation */ @@ -8693,7 +10131,7 @@ class NameContext } return $shortestName; } - private function resolveAlias(Name $name, $type) + private function resolveAlias(Name $name, int $type) : ?FullyQualified { $firstPart = $name->getFirst(); if ($name->isQualified()) { @@ -8714,7 +10152,7 @@ class NameContext // No applicable aliases return null; } - private function getNamespaceRelativeName(string $name, string $lcName, int $type) + private function getNamespaceRelativeName(string $name, string $lcName, int $type) : ?Name { if (null === $this->namespace) { return new Name($name); @@ -8732,7 +10170,7 @@ class NameContext } return null; } - private function normalizeConstName(string $name) + private function normalizeConstName(string $name) : string { $nsSep = \strrpos($name, '\\'); if (\false === $nsSep) { @@ -8760,13 +10198,15 @@ interface Node /** * Gets the names of the sub nodes. * - * @return array Names of sub nodes + * @return string[] Names of sub nodes */ public function getSubNodeNames() : array; /** * Gets line the node started in (alias of getStartLine). * * @return int Start line (or -1 if not available) + * + * @deprecated Use getStartLine() instead */ public function getLine() : int; /** @@ -8834,7 +10274,7 @@ interface Node * * @return null|Comment\Doc Doc comment object or null */ - public function getDocComment(); + public function getDocComment() : ?Comment\Doc; /** * Sets the doc comment of the node. * @@ -8842,27 +10282,21 @@ interface Node * * @param Comment\Doc $docComment Doc comment to set */ - public function setDocComment(Comment\Doc $docComment); + public function setDocComment(Comment\Doc $docComment) : void; /** * Sets an attribute on a node. * - * @param string $key - * @param mixed $value + * @param mixed $value */ - public function setAttribute(string $key, $value); + public function setAttribute(string $key, $value) : void; /** * Returns whether an attribute exists. - * - * @param string $key - * - * @return bool */ public function hasAttribute(string $key) : bool; /** * Returns the value of an attribute. * - * @param string $key - * @param mixed $default + * @param mixed $default * * @return mixed */ @@ -8870,43 +10304,42 @@ interface Node /** * Returns all the attributes of this node. * - * @return array + * @return array */ public function getAttributes() : array; /** * Replaces all the attributes of this node. * - * @param array $attributes + * @param array $attributes */ - public function setAttributes(array $attributes); + public function setAttributes(array $attributes) : void; } $attributes Additional attributes * @param Identifier|null $name Parameter name (for named parameters) */ - public function __construct(Expr $value, bool $byRef = \false, bool $unpack = \false, array $attributes = [], Identifier $name = null) + public function __construct(Expr $value, bool $byRef = \false, bool $unpack = \false, array $attributes = [], ?Identifier $name = null) { $this->attributes = $attributes; $this->name = $name; @@ -8928,18 +10361,61 @@ class Arg extends NodeAbstract declare (strict_types=1); namespace PHPUnit\PhpParser\Node; +use PHPUnit\PhpParser\NodeAbstract; +class ArrayItem extends NodeAbstract +{ + /** @var null|Expr Key */ + public ?Expr $key; + /** @var Expr Value */ + public Expr $value; + /** @var bool Whether to assign by reference */ + public bool $byRef; + /** @var bool Whether to unpack the argument */ + public bool $unpack; + /** + * Constructs an array item node. + * + * @param Expr $value Value + * @param null|Expr $key Key + * @param bool $byRef Whether to assign by reference + * @param array $attributes Additional attributes + */ + public function __construct(Expr $value, ?Expr $key = null, bool $byRef = \false, array $attributes = [], bool $unpack = \false) + { + $this->attributes = $attributes; + $this->key = $key; + $this->value = $value; + $this->byRef = $byRef; + $this->unpack = $unpack; + } + public function getSubNodeNames() : array + { + return ['key', 'value', 'byRef', 'unpack']; + } + public function getType() : string + { + return 'ArrayItem'; + } +} +// @deprecated compatibility alias +\class_alias(ArrayItem::class, Expr\ArrayItem::class); + Attribute arguments */ + public array $args; /** - * @param Node\Name $name Attribute name - * @param Arg[] $args Attribute arguments - * @param array $attributes Additional node attributes + * @param Node\Name $name Attribute name + * @param list $args Attribute arguments + * @param array $attributes Additional node attributes */ public function __construct(Name $name, array $args = [], array $attributes = []) { @@ -8961,15 +10437,14 @@ class Attribute extends NodeAbstract declare (strict_types=1); namespace PHPUnit\PhpParser\Node; -use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\NodeAbstract; class AttributeGroup extends NodeAbstract { /** @var Attribute[] Attributes */ - public $attrs; + public array $attrs; /** * @param Attribute[] $attrs PHP attributes - * @param array $attributes Additional node attributes + * @param array $attributes Additional node attributes */ public function __construct(array $attrs, array $attributes = []) { @@ -8990,6 +10465,42 @@ class AttributeGroup extends NodeAbstract declare (strict_types=1); namespace PHPUnit\PhpParser\Node; +use PHPUnit\PhpParser\NodeAbstract; +class ClosureUse extends NodeAbstract +{ + /** @var Expr\Variable Variable to use */ + public Expr\Variable $var; + /** @var bool Whether to use by reference */ + public bool $byRef; + /** + * Constructs a closure use node. + * + * @param Expr\Variable $var Variable to use + * @param bool $byRef Whether to use by reference + * @param array $attributes Additional attributes + */ + public function __construct(Expr\Variable $var, bool $byRef = \false, array $attributes = []) + { + $this->attributes = $attributes; + $this->var = $var; + $this->byRef = $byRef; + } + public function getSubNodeNames() : array + { + return ['var', 'byRef']; + } + public function getType() : string + { + return 'ClosureUse'; + } +} +// @deprecated compatibility alias +\class_alias(ClosureUse::class, Expr\ClosureUse::class); + $attributes Additional attributes */ public function __construct($name, Expr $value, array $attributes = []) { @@ -9040,6 +10551,43 @@ class Const_ extends NodeAbstract declare (strict_types=1); namespace PHPUnit\PhpParser\Node; +use PHPUnit\PhpParser\Node; +use PHPUnit\PhpParser\NodeAbstract; +class DeclareItem extends NodeAbstract +{ + /** @var Node\Identifier Key */ + public Identifier $key; + /** @var Node\Expr Value */ + public Expr $value; + /** + * Constructs a declare key=>value pair node. + * + * @param string|Node\Identifier $key Key + * @param Node\Expr $value Value + * @param array $attributes Additional attributes + */ + public function __construct($key, Node\Expr $value, array $attributes = []) + { + $this->attributes = $attributes; + $this->key = \is_string($key) ? new Node\Identifier($key) : $key; + $this->value = $value; + } + public function getSubNodeNames() : array + { + return ['key', 'value']; + } + public function getType() : string + { + return 'DeclareItem'; + } +} +// @deprecated compatibility alias +\class_alias(DeclareItem::class, Stmt\DeclareDeclare::class); + $attributes Additional attributes */ - public function __construct(Expr $var, Expr $dim = null, array $attributes = []) + public function __construct(Expr $var, ?Expr $dim = null, array $attributes = []) { $this->attributes = $attributes; $this->var = $var; @@ -9081,64 +10629,30 @@ class ArrayDimFetch extends Expr attributes = $attributes; - $this->key = $key; - $this->value = $value; - $this->byRef = $byRef; - $this->unpack = $unpack; - } - public function getSubNodeNames() : array - { - return ['key', 'value', 'byRef', 'unpack']; - } - public function getType() : string - { - return 'Expr_ArrayItem'; - } -} +require __DIR__ . '/../ArrayItem.php'; $attributes Additional attributes */ public function __construct(array $items = [], array $attributes = []) { @@ -9164,36 +10678,42 @@ use PHPUnit\PhpParser\Node\Expr; use PHPUnit\PhpParser\Node\FunctionLike; class ArrowFunction extends Expr implements FunctionLike { - /** @var bool */ - public $static; - /** @var bool */ - public $byRef; + /** @var bool Whether the closure is static */ + public bool $static; + /** @var bool Whether to return by reference */ + public bool $byRef; /** @var Node\Param[] */ - public $params = []; + public array $params = []; /** @var null|Node\Identifier|Node\Name|Node\ComplexType */ - public $returnType; - /** @var Expr */ - public $expr; + public ?Node $returnType; + /** @var Expr Expression body */ + public Expr $expr; /** @var Node\AttributeGroup[] */ - public $attrGroups; - /** - * @param array $subNodes Array of the following optional subnodes: - * 'static' => false : Whether the closure is static - * 'byRef' => false : Whether to return by reference - * 'params' => array() : Parameters - * 'returnType' => null : Return type - * 'expr' => Expr : Expression body - * 'attrGroups' => array() : PHP attribute groups - * @param array $attributes Additional attributes - */ - public function __construct(array $subNodes = [], array $attributes = []) + public array $attrGroups; + /** + * @param array{ + * expr: Expr, + * static?: bool, + * byRef?: bool, + * params?: Node\Param[], + * returnType?: null|Node\Identifier|Node\Name|Node\ComplexType, + * attrGroups?: Node\AttributeGroup[] + * } $subNodes Array of the following subnodes: + * 'expr' : Expression body + * 'static' => false : Whether the closure is static + * 'byRef' => false : Whether to return by reference + * 'params' => array() : Parameters + * 'returnType' => null : Return type + * 'attrGroups' => array() : PHP attribute groups + * @param array $attributes Additional attributes + */ + public function __construct(array $subNodes, array $attributes = []) { $this->attributes = $attributes; $this->static = $subNodes['static'] ?? \false; $this->byRef = $subNodes['byRef'] ?? \false; $this->params = $subNodes['params'] ?? []; - $returnType = $subNodes['returnType'] ?? null; - $this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType; + $this->returnType = $subNodes['returnType'] ?? null; $this->expr = $subNodes['expr']; $this->attrGroups = $subNodes['attrGroups'] ?? []; } @@ -9238,15 +10758,15 @@ use PHPUnit\PhpParser\Node\Expr; class Assign extends Expr { /** @var Expr Variable */ - public $var; + public Expr $var; /** @var Expr Expression */ - public $expr; + public Expr $expr; /** * Constructs an assignment node. * - * @param Expr $var Variable - * @param Expr $expr Expression - * @param array $attributes Additional attributes + * @param Expr $var Variable + * @param Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Expr $var, Expr $expr, array $attributes = []) { @@ -9272,15 +10792,15 @@ use PHPUnit\PhpParser\Node\Expr; abstract class AssignOp extends Expr { /** @var Expr Variable */ - public $var; + public Expr $var; /** @var Expr Expression */ - public $expr; + public Expr $expr; /** * Constructs a compound assignment operation node. * - * @param Expr $var Variable - * @param Expr $expr Expression - * @param array $attributes Additional attributes + * @param Expr $var Variable + * @param Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Expr $var, Expr $expr, array $attributes = []) { @@ -9471,15 +10991,15 @@ use PHPUnit\PhpParser\Node\Expr; class AssignRef extends Expr { /** @var Expr Variable reference is assigned to */ - public $var; + public Expr $var; /** @var Expr Variable which is referenced */ - public $expr; + public Expr $expr; /** * Constructs an assignment node. * - * @param Expr $var Variable - * @param Expr $expr Expression - * @param array $attributes Additional attributes + * @param Expr $var Variable + * @param Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Expr $var, Expr $expr, array $attributes = []) { @@ -9505,15 +11025,15 @@ use PHPUnit\PhpParser\Node\Expr; abstract class BinaryOp extends Expr { /** @var Expr The left hand side expression */ - public $left; + public Expr $left; /** @var Expr The right hand side expression */ - public $right; + public Expr $right; /** * Constructs a binary operator node. * - * @param Expr $left The left hand side expression - * @param Expr $right The right hand side expression - * @param array $attributes Additional attributes + * @param Expr $left The left hand side expression + * @param Expr $right The right hand side expression + * @param array $attributes Additional attributes */ public function __construct(Expr $left, Expr $right, array $attributes = []) { @@ -9530,8 +11050,6 @@ abstract class BinaryOp extends Expr * * In the case there are multiple possible sigils for an operator, this method does not * necessarily return the one used in the parsed code. - * - * @return string */ public abstract function getOperatorSigil() : string; } @@ -10003,12 +11521,12 @@ use PHPUnit\PhpParser\Node\Expr; class BitwiseNot extends Expr { /** @var Expr Expression */ - public $expr; + public Expr $expr; /** * Constructs a bitwise not node. * - * @param Expr $expr Expression - * @param array $attributes Additional attributes + * @param Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Expr $expr, array $attributes = []) { @@ -10033,12 +11551,12 @@ use PHPUnit\PhpParser\Node\Expr; class BooleanNot extends Expr { /** @var Expr Expression */ - public $expr; + public Expr $expr; /** * Constructs a boolean not node. * - * @param Expr $expr Expression - * @param array $attributes Additional attributes + * @param Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Expr $expr, array $attributes = []) { @@ -10076,12 +11594,8 @@ abstract class CallLike extends Expr */ public function isFirstClassCallable() : bool { - foreach ($this->getRawArgs() as $arg) { - if ($arg instanceof VariadicPlaceholder) { - return \true; - } - } - return \false; + $rawArgs = $this->getRawArgs(); + return \count($rawArgs) === 1 && \current($rawArgs) instanceof VariadicPlaceholder; } /** * Assert that this is not a first-class callable and return only ordinary Args. @@ -10103,12 +11617,12 @@ use PHPUnit\PhpParser\Node\Expr; abstract class Cast extends Expr { /** @var Expr Expression */ - public $expr; + public Expr $expr; /** * Constructs a cast node. * - * @param Expr $expr Expression - * @param array $attributes Additional attributes + * @param Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Expr $expr, array $attributes = []) { @@ -10155,11 +11669,11 @@ use PHPUnit\PhpParser\Node\Expr\Cast; class Double extends Cast { // For use in "kind" attribute - const KIND_DOUBLE = 1; + public const KIND_DOUBLE = 1; // "double" syntax - const KIND_FLOAT = 2; + public const KIND_FLOAT = 2; // "float" syntax - const KIND_REAL = 3; + public const KIND_REAL = 3; // "real" syntax public function getType() : string { @@ -10223,23 +11737,24 @@ class Unset_ extends Cast declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Expr; +use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\Node\Expr; use PHPUnit\PhpParser\Node\Identifier; use PHPUnit\PhpParser\Node\Name; class ClassConstFetch extends Expr { /** @var Name|Expr Class name */ - public $class; - /** @var Identifier|Error Constant name */ - public $name; + public Node $class; + /** @var Identifier|Expr|Error Constant name */ + public Node $name; /** * Constructs a class const fetch node. * - * @param Name|Expr $class Class name - * @param string|Identifier|Error $name Constant name - * @param array $attributes Additional attributes + * @param Name|Expr $class Class name + * @param string|Identifier|Expr|Error $name Constant name + * @param array $attributes Additional attributes */ - public function __construct($class, $name, array $attributes = []) + public function __construct(Node $class, $name, array $attributes = []) { $this->attributes = $attributes; $this->class = $class; @@ -10263,12 +11778,12 @@ use PHPUnit\PhpParser\Node\Expr; class Clone_ extends Expr { /** @var Expr Expression */ - public $expr; + public Expr $expr; /** * Constructs a clone node. * - * @param Expr $expr Expression - * @param array $attributes Additional attributes + * @param Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Expr $expr, array $attributes = []) { @@ -10290,36 +11805,45 @@ declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Expr; use PHPUnit\PhpParser\Node; +use PHPUnit\PhpParser\Node\ClosureUse; use PHPUnit\PhpParser\Node\Expr; use PHPUnit\PhpParser\Node\FunctionLike; class Closure extends Expr implements FunctionLike { /** @var bool Whether the closure is static */ - public $static; + public bool $static; /** @var bool Whether to return by reference */ - public $byRef; + public bool $byRef; /** @var Node\Param[] Parameters */ - public $params; + public array $params; /** @var ClosureUse[] use()s */ - public $uses; + public array $uses; /** @var null|Node\Identifier|Node\Name|Node\ComplexType Return type */ - public $returnType; + public ?Node $returnType; /** @var Node\Stmt[] Statements */ - public $stmts; + public array $stmts; /** @var Node\AttributeGroup[] PHP attribute groups */ - public $attrGroups; + public array $attrGroups; /** * Constructs a lambda function node. * - * @param array $subNodes Array of the following optional subnodes: - * 'static' => false : Whether the closure is static - * 'byRef' => false : Whether to return by reference - * 'params' => array(): Parameters - * 'uses' => array(): use()s - * 'returnType' => null : Return type - * 'stmts' => array(): Statements - * 'attrGroups' => array(): PHP attributes groups - * @param array $attributes Additional attributes + * @param array{ + * static?: bool, + * byRef?: bool, + * params?: Node\Param[], + * uses?: ClosureUse[], + * returnType?: null|Node\Identifier|Node\Name|Node\ComplexType, + * stmts?: Node\Stmt[], + * attrGroups?: Node\AttributeGroup[], + * } $subNodes Array of the following optional subnodes: + * 'static' => false : Whether the closure is static + * 'byRef' => false : Whether to return by reference + * 'params' => array(): Parameters + * 'uses' => array(): use()s + * 'returnType' => null : Return type + * 'stmts' => array(): Statements + * 'attrGroups' => array(): PHP attributes groups + * @param array $attributes Additional attributes */ public function __construct(array $subNodes = [], array $attributes = []) { @@ -10328,8 +11852,7 @@ class Closure extends Expr implements FunctionLike $this->byRef = $subNodes['byRef'] ?? \false; $this->params = $subNodes['params'] ?? []; $this->uses = $subNodes['uses'] ?? []; - $returnType = $subNodes['returnType'] ?? null; - $this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType; + $this->returnType = $subNodes['returnType'] ?? null; $this->stmts = $subNodes['stmts'] ?? []; $this->attrGroups = $subNodes['attrGroups'] ?? []; } @@ -10366,37 +11889,9 @@ class Closure extends Expr implements FunctionLike attributes = $attributes; - $this->var = $var; - $this->byRef = $byRef; - } - public function getSubNodeNames() : array - { - return ['var', 'byRef']; - } - public function getType() : string - { - return 'Expr_ClosureUse'; - } -} +require __DIR__ . '/../ClosureUse.php'; $attributes Additional attributes */ public function __construct(Name $name, array $attributes = []) { @@ -10437,12 +11932,12 @@ use PHPUnit\PhpParser\Node\Expr; class Empty_ extends Expr { /** @var Expr Expression */ - public $expr; + public Expr $expr; /** * Constructs an empty() node. * - * @param Expr $expr Expression - * @param array $attributes Additional attributes + * @param Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Expr $expr, array $attributes = []) { @@ -10475,7 +11970,7 @@ class Error extends Expr /** * Constructs an error node. * - * @param array $attributes Additional attributes + * @param array $attributes Additional attributes */ public function __construct(array $attributes = []) { @@ -10499,12 +11994,12 @@ use PHPUnit\PhpParser\Node\Expr; class ErrorSuppress extends Expr { /** @var Expr Expression */ - public $expr; + public Expr $expr; /** * Constructs an error suppress node. * - * @param Expr $expr Expression - * @param array $attributes Additional attributes + * @param Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Expr $expr, array $attributes = []) { @@ -10529,12 +12024,12 @@ use PHPUnit\PhpParser\Node\Expr; class Eval_ extends Expr { /** @var Expr Expression */ - public $expr; + public Expr $expr; /** * Constructs an eval() node. * - * @param Expr $expr Expression - * @param array $attributes Additional attributes + * @param Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Expr $expr, array $attributes = []) { @@ -10559,17 +12054,17 @@ use PHPUnit\PhpParser\Node\Expr; class Exit_ extends Expr { /* For use in "kind" attribute */ - const KIND_EXIT = 1; - const KIND_DIE = 2; + public const KIND_EXIT = 1; + public const KIND_DIE = 2; /** @var null|Expr Expression */ - public $expr; + public ?Expr $expr; /** * Constructs an exit() node. * - * @param null|Expr $expr Expression - * @param array $attributes Additional attributes + * @param null|Expr $expr Expression + * @param array $attributes Additional attributes */ - public function __construct(Expr $expr = null, array $attributes = []) + public function __construct(?Expr $expr = null, array $attributes = []) { $this->attributes = $attributes; $this->expr = $expr; @@ -10593,17 +12088,17 @@ use PHPUnit\PhpParser\Node\Expr; class FuncCall extends CallLike { /** @var Node\Name|Expr Function name */ - public $name; + public Node $name; /** @var array Arguments */ - public $args; + public array $args; /** * Constructs a function call node. * - * @param Node\Name|Expr $name Function name - * @param array $args Arguments - * @param array $attributes Additional attributes + * @param Node\Name|Expr $name Function name + * @param array $args Arguments + * @param array $attributes Additional attributes */ - public function __construct($name, array $args = [], array $attributes = []) + public function __construct(Node $name, array $args = [], array $attributes = []) { $this->attributes = $attributes; $this->name = $name; @@ -10630,20 +12125,20 @@ namespace PHPUnit\PhpParser\Node\Expr; use PHPUnit\PhpParser\Node\Expr; class Include_ extends Expr { - const TYPE_INCLUDE = 1; - const TYPE_INCLUDE_ONCE = 2; - const TYPE_REQUIRE = 3; - const TYPE_REQUIRE_ONCE = 4; + public const TYPE_INCLUDE = 1; + public const TYPE_INCLUDE_ONCE = 2; + public const TYPE_REQUIRE = 3; + public const TYPE_REQUIRE_ONCE = 4; /** @var Expr Expression */ - public $expr; + public Expr $expr; /** @var int Type of include */ - public $type; + public int $type; /** * Constructs an include node. * - * @param Expr $expr Expression - * @param int $type Type of include - * @param array $attributes Additional attributes + * @param Expr $expr Expression + * @param int $type Type of include + * @param array $attributes Additional attributes */ public function __construct(Expr $expr, int $type, array $attributes = []) { @@ -10665,22 +12160,23 @@ class Include_ extends Expr declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Expr; +use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\Node\Expr; use PHPUnit\PhpParser\Node\Name; class Instanceof_ extends Expr { /** @var Expr Expression */ - public $expr; + public Expr $expr; /** @var Name|Expr Class name */ - public $class; + public Node $class; /** * Constructs an instanceof check node. * - * @param Expr $expr Expression - * @param Name|Expr $class Class name - * @param array $attributes Additional attributes + * @param Expr $expr Expression + * @param Name|Expr $class Class name + * @param array $attributes Additional attributes */ - public function __construct(Expr $expr, $class, array $attributes = []) + public function __construct(Expr $expr, Node $class, array $attributes = []) { $this->attributes = $attributes; $this->expr = $expr; @@ -10704,12 +12200,12 @@ use PHPUnit\PhpParser\Node\Expr; class Isset_ extends Expr { /** @var Expr[] Variables */ - public $vars; + public array $vars; /** * Constructs an array node. * - * @param Expr[] $vars Variables - * @param array $attributes Additional attributes + * @param Expr[] $vars Variables + * @param array $attributes Additional attributes */ public function __construct(array $vars, array $attributes = []) { @@ -10730,16 +12226,22 @@ class Isset_ extends Expr declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Expr; +use PHPUnit\PhpParser\Node\ArrayItem; use PHPUnit\PhpParser\Node\Expr; class List_ extends Expr { + // For use in "kind" attribute + public const KIND_LIST = 1; + // list() syntax + public const KIND_ARRAY = 2; + // [] syntax /** @var (ArrayItem|null)[] List of items to assign to */ - public $items; + public array $items; /** * Constructs a list() destructuring node. * - * @param (ArrayItem|null)[] $items List of items to assign to - * @param array $attributes Additional attributes + * @param (ArrayItem|null)[] $items List of items to assign to + * @param array $attributes Additional attributes */ public function __construct(array $items, array $attributes = []) { @@ -10764,12 +12266,14 @@ use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\Node\MatchArm; class Match_ extends Node\Expr { - /** @var Node\Expr */ - public $cond; + /** @var Node\Expr Condition */ + public Node\Expr $cond; /** @var MatchArm[] */ - public $arms; + public array $arms; /** + * @param Node\Expr $cond Condition * @param MatchArm[] $arms + * @param array $attributes Additional attributes */ public function __construct(Node\Expr $cond, array $arms = [], array $attributes = []) { @@ -10791,6 +12295,7 @@ class Match_ extends Node\Expr declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Expr; +use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\Node\Arg; use PHPUnit\PhpParser\Node\Expr; use PHPUnit\PhpParser\Node\Identifier; @@ -10798,18 +12303,18 @@ use PHPUnit\PhpParser\Node\VariadicPlaceholder; class MethodCall extends CallLike { /** @var Expr Variable holding object */ - public $var; + public Expr $var; /** @var Identifier|Expr Method name */ - public $name; + public Node $name; /** @var array Arguments */ - public $args; + public array $args; /** * Constructs a function call node. * - * @param Expr $var Variable holding object - * @param string|Identifier|Expr $name Method name - * @param array $args Arguments - * @param array $attributes Additional attributes + * @param Expr $var Variable holding object + * @param string|Identifier|Expr $name Method name + * @param array $args Arguments + * @param array $attributes Additional attributes */ public function __construct(Expr $var, $name, array $args = [], array $attributes = []) { @@ -10843,17 +12348,17 @@ use PHPUnit\PhpParser\Node\VariadicPlaceholder; class New_ extends CallLike { /** @var Node\Name|Expr|Node\Stmt\Class_ Class name */ - public $class; + public Node $class; /** @var array Arguments */ - public $args; + public array $args; /** * Constructs a function call node. * - * @param Node\Name|Expr|Node\Stmt\Class_ $class Class name (or class node for anonymous classes) - * @param array $args Arguments - * @param array $attributes Additional attributes + * @param Node\Name|Expr|Node\Stmt\Class_ $class Class name (or class node for anonymous classes) + * @param array $args Arguments + * @param array $attributes Additional attributes */ - public function __construct($class, array $args = [], array $attributes = []) + public function __construct(Node $class, array $args = [], array $attributes = []) { $this->attributes = $attributes; $this->class = $class; @@ -10877,6 +12382,7 @@ class New_ extends CallLike declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Expr; +use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\Node\Arg; use PHPUnit\PhpParser\Node\Expr; use PHPUnit\PhpParser\Node\Identifier; @@ -10884,18 +12390,18 @@ use PHPUnit\PhpParser\Node\VariadicPlaceholder; class NullsafeMethodCall extends CallLike { /** @var Expr Variable holding object */ - public $var; + public Expr $var; /** @var Identifier|Expr Method name */ - public $name; + public Node $name; /** @var array Arguments */ - public $args; + public array $args; /** * Constructs a nullsafe method call node. * - * @param Expr $var Variable holding object - * @param string|Identifier|Expr $name Method name - * @param array $args Arguments - * @param array $attributes Additional attributes + * @param Expr $var Variable holding object + * @param string|Identifier|Expr $name Method name + * @param array $args Arguments + * @param array $attributes Additional attributes */ public function __construct(Expr $var, $name, array $args = [], array $attributes = []) { @@ -10922,20 +12428,21 @@ class NullsafeMethodCall extends CallLike declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Expr; +use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\Node\Expr; use PHPUnit\PhpParser\Node\Identifier; class NullsafePropertyFetch extends Expr { /** @var Expr Variable holding object */ - public $var; + public Expr $var; /** @var Identifier|Expr Property name */ - public $name; + public Node $name; /** * Constructs a nullsafe property fetch node. * - * @param Expr $var Variable holding object - * @param string|Identifier|Expr $name Property name - * @param array $attributes Additional attributes + * @param Expr $var Variable holding object + * @param string|Identifier|Expr $name Property name + * @param array $attributes Additional attributes */ public function __construct(Expr $var, $name, array $attributes = []) { @@ -10961,12 +12468,12 @@ use PHPUnit\PhpParser\Node\Expr; class PostDec extends Expr { /** @var Expr Variable */ - public $var; + public Expr $var; /** * Constructs a post decrement node. * - * @param Expr $var Variable - * @param array $attributes Additional attributes + * @param Expr $var Variable + * @param array $attributes Additional attributes */ public function __construct(Expr $var, array $attributes = []) { @@ -10991,12 +12498,12 @@ use PHPUnit\PhpParser\Node\Expr; class PostInc extends Expr { /** @var Expr Variable */ - public $var; + public Expr $var; /** * Constructs a post increment node. * - * @param Expr $var Variable - * @param array $attributes Additional attributes + * @param Expr $var Variable + * @param array $attributes Additional attributes */ public function __construct(Expr $var, array $attributes = []) { @@ -11021,12 +12528,12 @@ use PHPUnit\PhpParser\Node\Expr; class PreDec extends Expr { /** @var Expr Variable */ - public $var; + public Expr $var; /** * Constructs a pre decrement node. * - * @param Expr $var Variable - * @param array $attributes Additional attributes + * @param Expr $var Variable + * @param array $attributes Additional attributes */ public function __construct(Expr $var, array $attributes = []) { @@ -11051,12 +12558,12 @@ use PHPUnit\PhpParser\Node\Expr; class PreInc extends Expr { /** @var Expr Variable */ - public $var; + public Expr $var; /** * Constructs a pre increment node. * - * @param Expr $var Variable - * @param array $attributes Additional attributes + * @param Expr $var Variable + * @param array $attributes Additional attributes */ public function __construct(Expr $var, array $attributes = []) { @@ -11081,12 +12588,12 @@ use PHPUnit\PhpParser\Node\Expr; class Print_ extends Expr { /** @var Expr Expression */ - public $expr; + public Expr $expr; /** * Constructs an print() node. * - * @param Expr $expr Expression - * @param array $attributes Additional attributes + * @param Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Expr $expr, array $attributes = []) { @@ -11107,20 +12614,21 @@ class Print_ extends Expr declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Expr; +use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\Node\Expr; use PHPUnit\PhpParser\Node\Identifier; class PropertyFetch extends Expr { /** @var Expr Variable holding object */ - public $var; + public Expr $var; /** @var Identifier|Expr Property name */ - public $name; + public Node $name; /** * Constructs a function call node. * - * @param Expr $var Variable holding object - * @param string|Identifier|Expr $name Property name - * @param array $attributes Additional attributes + * @param Expr $var Variable holding object + * @param string|Identifier|Expr $name Property name + * @param array $attributes Additional attributes */ public function __construct(Expr $var, $name, array $attributes = []) { @@ -11143,15 +12651,16 @@ declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Expr; use PHPUnit\PhpParser\Node\Expr; +use PHPUnit\PhpParser\Node\InterpolatedStringPart; class ShellExec extends Expr { - /** @var array Encapsed string array */ - public $parts; + /** @var (Expr|InterpolatedStringPart)[] Interpolated string array */ + public array $parts; /** * Constructs a shell exec (backtick) node. * - * @param array $parts Encapsed string array - * @param array $attributes Additional attributes + * @param (Expr|InterpolatedStringPart)[] $parts Interpolated string array + * @param array $attributes Additional attributes */ public function __construct(array $parts, array $attributes = []) { @@ -11180,20 +12689,20 @@ use PHPUnit\PhpParser\Node\VariadicPlaceholder; class StaticCall extends CallLike { /** @var Node\Name|Expr Class name */ - public $class; + public Node $class; /** @var Identifier|Expr Method name */ - public $name; + public Node $name; /** @var array Arguments */ - public $args; + public array $args; /** * Constructs a static method call node. * - * @param Node\Name|Expr $class Class name - * @param string|Identifier|Expr $name Method name - * @param array $args Arguments - * @param array $attributes Additional attributes + * @param Node\Name|Expr $class Class name + * @param string|Identifier|Expr $name Method name + * @param array $args Arguments + * @param array $attributes Additional attributes */ - public function __construct($class, $name, array $args = [], array $attributes = []) + public function __construct(Node $class, $name, array $args = [], array $attributes = []) { $this->attributes = $attributes; $this->class = $class; @@ -11218,23 +12727,24 @@ class StaticCall extends CallLike declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Expr; +use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\Node\Expr; use PHPUnit\PhpParser\Node\Name; use PHPUnit\PhpParser\Node\VarLikeIdentifier; class StaticPropertyFetch extends Expr { /** @var Name|Expr Class name */ - public $class; + public Node $class; /** @var VarLikeIdentifier|Expr Property name */ - public $name; + public Node $name; /** * Constructs a static property fetch node. * - * @param Name|Expr $class Class name - * @param string|VarLikeIdentifier|Expr $name Property name - * @param array $attributes Additional attributes + * @param Name|Expr $class Class name + * @param string|VarLikeIdentifier|Expr $name Property name + * @param array $attributes Additional attributes */ - public function __construct($class, $name, array $attributes = []) + public function __construct(Node $class, $name, array $attributes = []) { $this->attributes = $attributes; $this->class = $class; @@ -11258,20 +12768,20 @@ use PHPUnit\PhpParser\Node\Expr; class Ternary extends Expr { /** @var Expr Condition */ - public $cond; + public Expr $cond; /** @var null|Expr Expression for true */ - public $if; + public ?Expr $if; /** @var Expr Expression for false */ - public $else; + public Expr $else; /** * Constructs a ternary operator node. * - * @param Expr $cond Condition - * @param null|Expr $if Expression for true - * @param Expr $else Expression for false - * @param array $attributes Additional attributes + * @param Expr $cond Condition + * @param null|Expr $if Expression for true + * @param Expr $else Expression for false + * @param array $attributes Additional attributes */ - public function __construct(Expr $cond, $if, Expr $else, array $attributes = []) + public function __construct(Expr $cond, ?Expr $if, Expr $else, array $attributes = []) { $this->attributes = $attributes; $this->cond = $cond; @@ -11296,12 +12806,12 @@ use PHPUnit\PhpParser\Node; class Throw_ extends Node\Expr { /** @var Node\Expr Expression */ - public $expr; + public Node\Expr $expr; /** * Constructs a throw expression node. * - * @param Node\Expr $expr Expression - * @param array $attributes Additional attributes + * @param Node\Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Node\Expr $expr, array $attributes = []) { @@ -11326,12 +12836,12 @@ use PHPUnit\PhpParser\Node\Expr; class UnaryMinus extends Expr { /** @var Expr Expression */ - public $expr; + public Expr $expr; /** * Constructs a unary minus node. * - * @param Expr $expr Expression - * @param array $attributes Additional attributes + * @param Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Expr $expr, array $attributes = []) { @@ -11356,12 +12866,12 @@ use PHPUnit\PhpParser\Node\Expr; class UnaryPlus extends Expr { /** @var Expr Expression */ - public $expr; + public Expr $expr; /** * Constructs a unary plus node. * - * @param Expr $expr Expression - * @param array $attributes Additional attributes + * @param Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Expr $expr, array $attributes = []) { @@ -11390,8 +12900,8 @@ class Variable extends Expr /** * Constructs a variable node. * - * @param string|Expr $name Name - * @param array $attributes Additional attributes + * @param string|Expr $name Name + * @param array $attributes Additional attributes */ public function __construct($name, array $attributes = []) { @@ -11416,12 +12926,12 @@ use PHPUnit\PhpParser\Node\Expr; class YieldFrom extends Expr { /** @var Expr Expression to yield from */ - public $expr; + public Expr $expr; /** * Constructs an "yield from" node. * - * @param Expr $expr Expression - * @param array $attributes Additional attributes + * @param Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Expr $expr, array $attributes = []) { @@ -11446,17 +12956,17 @@ use PHPUnit\PhpParser\Node\Expr; class Yield_ extends Expr { /** @var null|Expr Key expression */ - public $key; + public ?Expr $key; /** @var null|Expr Value expression */ - public $value; + public ?Expr $value; /** * Constructs a yield expression node. * - * @param null|Expr $value Value expression - * @param null|Expr $key Key expression - * @param array $attributes Additional attributes + * @param null|Expr $value Value expression + * @param null|Expr $key Key expression + * @param array $attributes Additional attributes */ - public function __construct(Expr $value = null, Expr $key = null, array $attributes = []) + public function __construct(?Expr $value = null, ?Expr $key = null, array $attributes = []) { $this->attributes = $attributes; $this->key = $key; @@ -11481,8 +12991,6 @@ interface FunctionLike extends Node { /** * Whether to return by reference - * - * @return bool */ public function returnsByRef() : bool; /** @@ -11502,7 +13010,7 @@ interface FunctionLike extends Node * * @return Stmt[]|null */ - public function getStmts(); + public function getStmts() : ?array; /** * Get PHP attribute groups. * @@ -11522,13 +13030,14 @@ use PHPUnit\PhpParser\NodeAbstract; class Identifier extends NodeAbstract { /** @var string Identifier as string */ - public $name; - private static $specialClassNames = ['self' => \true, 'parent' => \true, 'static' => \true]; + public string $name; + /** @var array */ + private static array $specialClassNames = ['self' => \true, 'parent' => \true, 'static' => \true]; /** * Constructs an identifier node. * - * @param string $name Identifier as string - * @param array $attributes Additional attributes + * @param string $name Identifier as string + * @param array $attributes Additional attributes */ public function __construct(string $name, array $attributes = []) { @@ -11586,15 +13095,46 @@ declare (strict_types=1); namespace PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\NodeAbstract; +class InterpolatedStringPart extends NodeAbstract +{ + /** @var string String value */ + public string $value; + /** + * Constructs a node representing a string part of an interpolated string. + * + * @param string $value String value + * @param array $attributes Additional attributes + */ + public function __construct(string $value, array $attributes = []) + { + $this->attributes = $attributes; + $this->value = $value; + } + public function getSubNodeNames() : array + { + return ['value']; + } + public function getType() : string + { + return 'InterpolatedStringPart'; + } +} +// @deprecated compatibility alias +\class_alias(InterpolatedStringPart::class, Scalar\EncapsedStringPart::class); + $attributes Additional attributes */ public function __construct(array $types, array $attributes = []) { @@ -11619,14 +13159,14 @@ use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\NodeAbstract; class MatchArm extends NodeAbstract { - /** @var null|Node\Expr[] */ - public $conds; + /** @var null|list */ + public ?array $conds; /** @var Node\Expr */ - public $body; + public Expr $body; /** - * @param null|Node\Expr[] $conds + * @param null|list $conds */ - public function __construct($conds, Node\Expr $body, array $attributes = []) + public function __construct(?array $conds, Node\Expr $body, array $attributes = []) { $this->conds = $conds; $this->body = $body; @@ -11649,23 +13189,33 @@ namespace PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\NodeAbstract; class Name extends NodeAbstract { - /** @var string[] Parts of the name */ - public $parts; - private static $specialClassNames = ['self' => \true, 'parent' => \true, 'static' => \true]; + /** @var string Name as string */ + public string $name; + /** @var array */ + private static array $specialClassNames = ['self' => \true, 'parent' => \true, 'static' => \true]; /** * Constructs a name node. * - * @param string|string[]|self $name Name as string, part array or Name instance (copy ctor) - * @param array $attributes Additional attributes + * @param string|string[]|self $name Name as string, part array or Name instance (copy ctor) + * @param array $attributes Additional attributes */ - public function __construct($name, array $attributes = []) + public final function __construct($name, array $attributes = []) { $this->attributes = $attributes; - $this->parts = self::prepareName($name); + $this->name = self::prepareName($name); } public function getSubNodeNames() : array { - return ['parts']; + return ['name']; + } + /** + * Get parts of name (split by the namespace separator). + * + * @return string[] Parts of name + */ + public function getParts() : array + { + return \explode('\\', $this->name); } /** * Gets the first part of the name, i.e. everything before the first namespace separator. @@ -11674,7 +13224,10 @@ class Name extends NodeAbstract */ public function getFirst() : string { - return $this->parts[0]; + if (\false !== ($pos = \strpos($this->name, '\\'))) { + return \substr($this->name, 0, $pos); + } + return $this->name; } /** * Gets the last part of the name, i.e. everything after the last namespace separator. @@ -11683,7 +13236,10 @@ class Name extends NodeAbstract */ public function getLast() : string { - return $this->parts[\count($this->parts) - 1]; + if (\false !== ($pos = \strrpos($this->name, '\\'))) { + return \substr($this->name, $pos + 1); + } + return $this->name; } /** * Checks whether the name is unqualified. (E.g. Name) @@ -11692,7 +13248,7 @@ class Name extends NodeAbstract */ public function isUnqualified() : bool { - return 1 === \count($this->parts); + return \false === \strpos($this->name, '\\'); } /** * Checks whether the name is qualified. (E.g. Name\Name) @@ -11701,7 +13257,7 @@ class Name extends NodeAbstract */ public function isQualified() : bool { - return 1 < \count($this->parts); + return \false !== \strpos($this->name, '\\'); } /** * Checks whether the name is fully qualified. (E.g. \Name) @@ -11729,7 +13285,7 @@ class Name extends NodeAbstract */ public function toString() : string { - return \implode('\\', $this->parts); + return $this->name; } /** * Returns a string representation of the name as it would occur in code (e.g., including @@ -11749,7 +13305,7 @@ class Name extends NodeAbstract */ public function toLowerString() : string { - return \strtolower(\implode('\\', $this->parts)); + return \strtolower($this->name); } /** * Checks whether the identifier is a special class name (self, parent or static). @@ -11758,7 +13314,7 @@ class Name extends NodeAbstract */ public function isSpecialClassName() : bool { - return \count($this->parts) === 1 && isset(self::$specialClassNames[\strtolower($this->parts[0])]); + return isset(self::$specialClassNames[\strtolower($this->name)]); } /** * Returns a string representation of the name by imploding the namespace parts with the @@ -11768,7 +13324,7 @@ class Name extends NodeAbstract */ public function __toString() : string { - return \implode('\\', $this->parts); + return $this->name; } /** * Gets a slice of a name (similar to array_slice). @@ -11781,14 +13337,22 @@ class Name extends NodeAbstract * * Offset and length have the same meaning as in array_slice(). * - * @param int $offset Offset to start the slice at (may be negative) + * @param int $offset Offset to start the slice at (may be negative) * @param int|null $length Length of the slice (may be negative) * * @return static|null Sliced name */ - public function slice(int $offset, int $length = null) + public function slice(int $offset, ?int $length = null) { - $numParts = \count($this->parts); + if ($offset === 1 && $length === null) { + // Short-circuit the common case. + if (\false !== ($pos = \strpos($this->name, '\\'))) { + return new static(\substr($this->name, $pos + 1)); + } + return null; + } + $parts = \explode('\\', $this->name); + $numParts = \count($parts); $realOffset = $offset < 0 ? $offset + $numParts : $offset; if ($realOffset < 0 || $realOffset > $numParts) { throw new \OutOfBoundsException(\sprintf('Offset %d is out of bounds', $offset)); @@ -11805,7 +13369,7 @@ class Name extends NodeAbstract // Empty slice is represented as null return null; } - return new static(\array_slice($this->parts, $realOffset, $realLength), $this->attributes); + return new static(\array_slice($parts, $realOffset, $realLength), $this->attributes); } /** * Concatenate two names, yielding a new Name instance. @@ -11818,9 +13382,9 @@ class Name extends NodeAbstract * Name::concat($namespace, $shortName) * where $namespace is a Name node or null will work as expected. * - * @param string|string[]|self|null $name1 The first name - * @param string|string[]|self|null $name2 The second name - * @param array $attributes Attributes to assign to concatenated name + * @param string|string[]|self|null $name1 The first name + * @param string|string[]|self|null $name2 The second name + * @param array $attributes Attributes to assign to concatenated name * * @return static|null Concatenated name */ @@ -11828,36 +13392,40 @@ class Name extends NodeAbstract { if (null === $name1 && null === $name2) { return null; - } elseif (null === $name1) { - return new static(self::prepareName($name2), $attributes); - } elseif (null === $name2) { - return new static(self::prepareName($name1), $attributes); + } + if (null === $name1) { + return new static($name2, $attributes); + } + if (null === $name2) { + return new static($name1, $attributes); } else { - return new static(\array_merge(self::prepareName($name1), self::prepareName($name2)), $attributes); + return new static(self::prepareName($name1) . '\\' . self::prepareName($name2), $attributes); } } /** * Prepares a (string, array or Name node) name for use in name changing methods by converting - * it to an array. + * it to a string. * * @param string|string[]|self $name Name to prepare * - * @return string[] Prepared name + * @return string Prepared name */ - private static function prepareName($name) : array + private static function prepareName($name) : string { if (\is_string($name)) { if ('' === $name) { throw new \InvalidArgumentException('Name cannot be empty'); } - return \explode('\\', $name); - } elseif (\is_array($name)) { + return $name; + } + if (\is_array($name)) { if (empty($name)) { throw new \InvalidArgumentException('Name cannot be empty'); } - return $name; - } elseif ($name instanceof self) { - return $name->parts; + return \implode('\\', $name); + } + if ($name instanceof self) { + return $name->name; } throw new \InvalidArgumentException('Expected string, array of parts or Name instance'); } @@ -11975,20 +13543,21 @@ class Relative extends \PHPUnit\PhpParser\Node\Name declare (strict_types=1); namespace PHPUnit\PhpParser\Node; +use PHPUnit\PhpParser\Node; class NullableType extends ComplexType { /** @var Identifier|Name Type */ - public $type; + public Node $type; /** * Constructs a nullable type (wrapping another type). * - * @param string|Identifier|Name $type Type - * @param array $attributes Additional attributes + * @param Identifier|Name $type Type + * @param array $attributes Additional attributes */ - public function __construct($type, array $attributes = []) + public function __construct(Node $type, array $attributes = []) { $this->attributes = $attributes; - $this->type = \is_string($type) ? new Identifier($type) : $type; + $this->type = $type; } public function getSubNodeNames() : array { @@ -12004,39 +13573,41 @@ class NullableType extends ComplexType declare (strict_types=1); namespace PHPUnit\PhpParser\Node; +use PHPUnit\PhpParser\Modifiers; +use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\NodeAbstract; class Param extends NodeAbstract { /** @var null|Identifier|Name|ComplexType Type declaration */ - public $type; + public ?Node $type; /** @var bool Whether parameter is passed by reference */ - public $byRef; + public bool $byRef; /** @var bool Whether this is a variadic argument */ - public $variadic; + public bool $variadic; /** @var Expr\Variable|Expr\Error Parameter variable */ - public $var; + public Expr $var; /** @var null|Expr Default value */ - public $default; - /** @var int */ - public $flags; + public ?Expr $default; + /** @var int Optional visibility flags */ + public int $flags; /** @var AttributeGroup[] PHP attribute groups */ - public $attrGroups; + public array $attrGroups; /** * Constructs a parameter node. * - * @param Expr\Variable|Expr\Error $var Parameter variable - * @param null|Expr $default Default value - * @param null|string|Identifier|Name|ComplexType $type Type declaration - * @param bool $byRef Whether is passed by reference - * @param bool $variadic Whether this is a variadic argument - * @param array $attributes Additional attributes - * @param int $flags Optional visibility flags - * @param AttributeGroup[] $attrGroups PHP attribute groups + * @param Expr\Variable|Expr\Error $var Parameter variable + * @param null|Expr $default Default value + * @param null|Identifier|Name|ComplexType $type Type declaration + * @param bool $byRef Whether is passed by reference + * @param bool $variadic Whether this is a variadic argument + * @param array $attributes Additional attributes + * @param int $flags Optional visibility flags + * @param list $attrGroups PHP attribute groups */ - public function __construct($var, Expr $default = null, $type = null, bool $byRef = \false, bool $variadic = \false, array $attributes = [], int $flags = 0, array $attrGroups = []) + public function __construct(Expr $var, ?Expr $default = null, ?Node $type = null, bool $byRef = \false, bool $variadic = \false, array $attributes = [], int $flags = 0, array $attrGroups = []) { $this->attributes = $attributes; - $this->type = \is_string($type) ? new Identifier($type) : $type; + $this->type = $type; $this->byRef = $byRef; $this->variadic = $variadic; $this->var = $var; @@ -12052,7 +13623,67 @@ class Param extends NodeAbstract { return 'Param'; } + /** + * Whether this parameter uses constructor property promotion. + */ + public function isPromoted() : bool + { + return $this->flags !== 0; + } + public function isPublic() : bool + { + return (bool) ($this->flags & Modifiers::PUBLIC); + } + public function isProtected() : bool + { + return (bool) ($this->flags & Modifiers::PROTECTED); + } + public function isPrivate() : bool + { + return (bool) ($this->flags & Modifiers::PRIVATE); + } + public function isReadonly() : bool + { + return (bool) ($this->flags & Modifiers::READONLY); + } +} + $attributes Additional attributes + */ + public function __construct($name, ?Node\Expr $default = null, array $attributes = []) + { + $this->attributes = $attributes; + $this->name = \is_string($name) ? new Node\VarLikeIdentifier($name) : $name; + $this->default = $default; + } + public function getSubNodeNames() : array + { + return ['name', 'default']; + } + public function getType() : string + { + return 'PropertyItem'; + } } +// @deprecated compatibility alias +\class_alias(PropertyItem::class, Stmt\PropertyProperty::class); $attributes Additional attributes */ public function __construct(float $value, array $attributes = []) { @@ -12089,11 +13738,11 @@ class DNumber extends Scalar /** * @param mixed[] $attributes */ - public static function fromString(string $str, array $attributes = []) : DNumber + public static function fromString(string $str, array $attributes = []) : Float_ { $attributes['rawValue'] = $str; $float = self::parse($str); - return new DNumber($float, $attributes); + return new Float_($float, $attributes); } /** * @internal @@ -12129,70 +13778,11 @@ class DNumber extends Scalar } public function getType() : string { - return 'Scalar_DNumber'; - } -} -attributes = $attributes; - $this->parts = $parts; - } - public function getSubNodeNames() : array - { - return ['parts']; - } - public function getType() : string - { - return 'Scalar_Encapsed'; - } -} -attributes = $attributes; - $this->value = $value; - } - public function getSubNodeNames() : array - { - return ['value']; - } - public function getType() : string - { - return 'Scalar_EncapsedStringPart'; + return 'Scalar_Float'; } } +// @deprecated compatibility alias +\class_alias(Float_::class, DNumber::class); $attributes Additional attributes */ public function __construct(int $value, array $attributes = []) { @@ -12225,29 +13815,29 @@ class LNumber extends Scalar return ['value']; } /** - * Constructs an LNumber node from a string number literal. + * Constructs an Int node from a string number literal. * - * @param string $str String number literal (decimal, octal, hex or binary) - * @param array $attributes Additional attributes - * @param bool $allowInvalidOctal Whether to allow invalid octal numbers (PHP 5) + * @param string $str String number literal (decimal, octal, hex or binary) + * @param array $attributes Additional attributes + * @param bool $allowInvalidOctal Whether to allow invalid octal numbers (PHP 5) * - * @return LNumber The constructed LNumber, including kind attribute + * @return Int_ The constructed LNumber, including kind attribute */ - public static function fromString(string $str, array $attributes = [], bool $allowInvalidOctal = \false) : LNumber + public static function fromString(string $str, array $attributes = [], bool $allowInvalidOctal = \false) : Int_ { $attributes['rawValue'] = $str; $str = \str_replace('_', '', $str); if ('0' !== $str[0] || '0' === $str) { - $attributes['kind'] = LNumber::KIND_DEC; - return new LNumber((int) $str, $attributes); + $attributes['kind'] = Int_::KIND_DEC; + return new Int_((int) $str, $attributes); } if ('x' === $str[1] || 'X' === $str[1]) { - $attributes['kind'] = LNumber::KIND_HEX; - return new LNumber(\hexdec($str), $attributes); + $attributes['kind'] = Int_::KIND_HEX; + return new Int_(\hexdec($str), $attributes); } if ('b' === $str[1] || 'B' === $str[1]) { - $attributes['kind'] = LNumber::KIND_BIN; - return new LNumber(\bindec($str), $attributes); + $attributes['kind'] = Int_::KIND_BIN; + return new Int_(\bindec($str), $attributes); } if (!$allowInvalidOctal && \strpbrk($str, '89')) { throw new Error('Invalid numeric literal', $attributes); @@ -12257,14 +13847,56 @@ class LNumber extends Scalar $str = \substr($str, 2); } // use intval instead of octdec to get proper cutting behavior with malformed numbers - $attributes['kind'] = LNumber::KIND_OCT; - return new LNumber(\intval($str, 8), $attributes); + $attributes['kind'] = Int_::KIND_OCT; + return new Int_(\intval($str, 8), $attributes); } public function getType() : string { - return 'Scalar_LNumber'; + return 'Scalar_Int'; } } +// @deprecated compatibility alias +\class_alias(Int_::class, LNumber::class); + $attributes Additional attributes + */ + public function __construct(array $parts, array $attributes = []) + { + $this->attributes = $attributes; + $this->parts = $parts; + } + public function getSubNodeNames() : array + { + return ['parts']; + } + public function getType() : string + { + return 'Scalar_InterpolatedString'; + } +} +// @deprecated compatibility alias +\class_alias(InterpolatedString::class, Encapsed::class); + $attributes Additional attributes */ public function __construct(array $attributes = []) { @@ -12439,18 +14071,19 @@ use PHPUnit\PhpParser\Node\Scalar; class String_ extends Scalar { /* For use in "kind" attribute */ - const KIND_SINGLE_QUOTED = 1; - const KIND_DOUBLE_QUOTED = 2; - const KIND_HEREDOC = 3; - const KIND_NOWDOC = 4; + public const KIND_SINGLE_QUOTED = 1; + public const KIND_DOUBLE_QUOTED = 2; + public const KIND_HEREDOC = 3; + public const KIND_NOWDOC = 4; /** @var string String value */ - public $value; - protected static $replacements = ['\\' => '\\', '$' => '$', 'n' => "\n", 'r' => "\r", 't' => "\t", 'f' => "\f", 'v' => "\v", 'e' => "\x1b"]; + public string $value; + /** @var array Escaped character to its decoded value */ + protected static array $replacements = ['\\' => '\\', '$' => '$', 'n' => "\n", 'r' => "\r", 't' => "\t", 'f' => "\f", 'v' => "\v", 'e' => "\x1b"]; /** * Constructs a string scalar node. * - * @param string $value Value of the string - * @param array $attributes Additional attributes + * @param string $value Value of the string + * @param array $attributes Additional attributes */ public function __construct(string $value, array $attributes = []) { @@ -12462,6 +14095,7 @@ class String_ extends Scalar return ['value']; } /** + * @param array $attributes * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes */ public static function fromString(string $str, array $attributes = [], bool $parseUnicodeEscape = \true) : self @@ -12498,13 +14132,13 @@ class String_ extends Scalar * * Parses escape sequences in strings (all string types apart from single quoted). * - * @param string $str String without quotes + * @param string $str String without quotes * @param null|string $quote Quote type * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes * * @return string String with escape sequences parsed */ - public static function parseEscapeSequences(string $str, $quote, bool $parseUnicodeEscape = \true) : string + public static function parseEscapeSequences(string $str, ?string $quote, bool $parseUnicodeEscape = \true) : string { if (null !== $quote) { $str = \str_replace('\\' . $quote, $quote, $str); @@ -12517,10 +14151,14 @@ class String_ extends Scalar $str = $matches[1]; if (isset(self::$replacements[$str])) { return self::$replacements[$str]; - } elseif ('x' === $str[0] || 'X' === $str[0]) { + } + if ('x' === $str[0] || 'X' === $str[0]) { return \chr(\hexdec(\substr($str, 1))); - } elseif ('u' === $str[0]) { - return self::codePointToUtf8(\hexdec($matches[2])); + } + if ('u' === $str[0]) { + $dec = \hexdec($matches[2]); + // If it overflowed to float, treat as INT_MAX, it will throw an error anyway. + return self::codePointToUtf8(\is_int($dec) ? $dec : \PHP_INT_MAX); } else { return \chr(\octdec($str)); } @@ -12559,6 +14197,43 @@ class String_ extends Scalar declare (strict_types=1); namespace PHPUnit\PhpParser\Node; +use PHPUnit\PhpParser\Node; +use PHPUnit\PhpParser\NodeAbstract; +class StaticVar extends NodeAbstract +{ + /** @var Expr\Variable Variable */ + public Expr\Variable $var; + /** @var null|Node\Expr Default value */ + public ?Expr $default; + /** + * Constructs a static variable node. + * + * @param Expr\Variable $var Name + * @param null|Node\Expr $default Default value + * @param array $attributes Additional attributes + */ + public function __construct(Expr\Variable $var, ?Node\Expr $default = null, array $attributes = []) + { + $this->attributes = $attributes; + $this->var = $var; + $this->default = $default; + } + public function getSubNodeNames() : array + { + return ['var', 'default']; + } + public function getType() : string + { + return 'StaticVar'; + } +} +// @deprecated compatibility alias +\class_alias(StaticVar::class, Stmt\StaticVar::class); + $attributes Additional attributes + */ + public function __construct(array $stmts, array $attributes = []) + { + $this->attributes = $attributes; + $this->stmts = $stmts; + } + public function getType() : string + { + return 'Stmt_Block'; + } + public function getSubNodeNames() : array + { + return ['stmts']; + } +} + $attributes Additional attributes */ - public function __construct(Node\Expr $num = null, array $attributes = []) + public function __construct(?Node\Expr $num = null, array $attributes = []) { $this->attributes = $attributes; $this->num = $num; @@ -12602,17 +14307,17 @@ use PHPUnit\PhpParser\Node; class Case_ extends Node\Stmt { /** @var null|Node\Expr Condition (null for default) */ - public $cond; + public ?Node\Expr $cond; /** @var Node\Stmt[] Statements */ - public $stmts; + public array $stmts; /** * Constructs a case node. * - * @param null|Node\Expr $cond Condition (null for default) - * @param Node\Stmt[] $stmts Statements - * @param array $attributes Additional attributes + * @param null|Node\Expr $cond Condition (null for default) + * @param Node\Stmt[] $stmts Statements + * @param array $attributes Additional attributes */ - public function __construct($cond, array $stmts = [], array $attributes = []) + public function __construct(?Node\Expr $cond, array $stmts = [], array $attributes = []) { $this->attributes = $attributes; $this->cond = $cond; @@ -12637,20 +14342,20 @@ use PHPUnit\PhpParser\Node\Expr; class Catch_ extends Node\Stmt { /** @var Node\Name[] Types of exceptions to catch */ - public $types; + public array $types; /** @var Expr\Variable|null Variable for exception */ - public $var; + public ?Expr\Variable $var; /** @var Node\Stmt[] Statements */ - public $stmts; + public array $stmts; /** * Constructs a catch node. * - * @param Node\Name[] $types Types of exceptions to catch - * @param Expr\Variable|null $var Variable for exception - * @param Node\Stmt[] $stmts Statements - * @param array $attributes Additional attributes + * @param Node\Name[] $types Types of exceptions to catch + * @param Expr\Variable|null $var Variable for exception + * @param Node\Stmt[] $stmts Statements + * @param array $attributes Additional attributes */ - public function __construct(array $types, Expr\Variable $var = null, array $stmts = [], array $attributes = []) + public function __construct(array $types, ?Expr\Variable $var = null, array $stmts = [], array $attributes = []) { $this->attributes = $attributes; $this->types = $types; @@ -12671,69 +14376,66 @@ class Catch_ extends Node\Stmt declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Stmt; +use PHPUnit\PhpParser\Modifiers; use PHPUnit\PhpParser\Node; class ClassConst extends Node\Stmt { /** @var int Modifiers */ - public $flags; + public int $flags; /** @var Node\Const_[] Constant declarations */ - public $consts; - /** @var Node\AttributeGroup[] */ - public $attrGroups; + public array $consts; + /** @var Node\AttributeGroup[] PHP attribute groups */ + public array $attrGroups; + /** @var Node\Identifier|Node\Name|Node\ComplexType|null Type declaration */ + public ?Node $type; /** * Constructs a class const list node. * - * @param Node\Const_[] $consts Constant declarations - * @param int $flags Modifiers - * @param array $attributes Additional attributes - * @param Node\AttributeGroup[] $attrGroups PHP attribute groups + * @param Node\Const_[] $consts Constant declarations + * @param int $flags Modifiers + * @param array $attributes Additional attributes + * @param list $attrGroups PHP attribute groups + * @param null|Node\Identifier|Node\Name|Node\ComplexType $type Type declaration */ - public function __construct(array $consts, int $flags = 0, array $attributes = [], array $attrGroups = []) + public function __construct(array $consts, int $flags = 0, array $attributes = [], array $attrGroups = [], ?Node $type = null) { $this->attributes = $attributes; $this->flags = $flags; $this->consts = $consts; $this->attrGroups = $attrGroups; + $this->type = $type; } public function getSubNodeNames() : array { - return ['attrGroups', 'flags', 'consts']; + return ['attrGroups', 'flags', 'type', 'consts']; } /** * Whether constant is explicitly or implicitly public. - * - * @return bool */ public function isPublic() : bool { - return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; + return ($this->flags & Modifiers::PUBLIC) !== 0 || ($this->flags & Modifiers::VISIBILITY_MASK) === 0; } /** * Whether constant is protected. - * - * @return bool */ public function isProtected() : bool { - return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); + return (bool) ($this->flags & Modifiers::PROTECTED); } /** * Whether constant is private. - * - * @return bool */ public function isPrivate() : bool { - return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); + return (bool) ($this->flags & Modifiers::PRIVATE); } /** * Whether constant is final. - * - * @return bool */ public function isFinal() : bool { - return (bool) ($this->flags & Class_::MODIFIER_FINAL); + return (bool) ($this->flags & Modifiers::FINAL); } public function getType() : string { @@ -12746,16 +14448,17 @@ declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Stmt; use PHPUnit\PhpParser\Node; +use PHPUnit\PhpParser\Node\PropertyItem; abstract class ClassLike extends Node\Stmt { /** @var Node\Identifier|null Name */ - public $name; + public ?Node\Identifier $name; /** @var Node\Stmt[] Statements */ - public $stmts; + public array $stmts; /** @var Node\AttributeGroup[] PHP attribute groups */ - public $attrGroups; + public array $attrGroups; /** @var Node\Name|null Namespaced name (if using NameResolver) */ - public $namespacedName; + public ?Node\Name $namespacedName; /** * @return TraitUse[] */ @@ -12802,12 +14505,12 @@ abstract class ClassLike extends Node\Stmt * * @return Property|null Property node or null if the property does not exist */ - public function getProperty(string $name) + public function getProperty(string $name) : ?Property { foreach ($this->stmts as $stmt) { if ($stmt instanceof Property) { foreach ($stmt->props as $prop) { - if ($prop instanceof PropertyProperty && $name === $prop->name->toString()) { + if ($prop instanceof PropertyItem && $name === $prop->name->toString()) { return $stmt; } } @@ -12837,7 +14540,7 @@ abstract class ClassLike extends Node\Stmt * * @return ClassMethod|null Method node or null if the method does not exist */ - public function getMethod(string $name) + public function getMethod(string $name) : ?ClassMethod { $lowerName = \strtolower($name); foreach ($this->stmts as $stmt) { @@ -12853,37 +14556,46 @@ abstract class ClassLike extends Node\Stmt declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Stmt; +use PHPUnit\PhpParser\Modifiers; use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\Node\FunctionLike; class ClassMethod extends Node\Stmt implements FunctionLike { /** @var int Flags */ - public $flags; + public int $flags; /** @var bool Whether to return by reference */ - public $byRef; + public bool $byRef; /** @var Node\Identifier Name */ - public $name; + public Node\Identifier $name; /** @var Node\Param[] Parameters */ - public $params; + public array $params; /** @var null|Node\Identifier|Node\Name|Node\ComplexType Return type */ - public $returnType; + public ?Node $returnType; /** @var Node\Stmt[]|null Statements */ - public $stmts; + public ?array $stmts; /** @var Node\AttributeGroup[] PHP attribute groups */ - public $attrGroups; - private static $magicNames = ['__construct' => \true, '__destruct' => \true, '__call' => \true, '__callstatic' => \true, '__get' => \true, '__set' => \true, '__isset' => \true, '__unset' => \true, '__sleep' => \true, '__wakeup' => \true, '__tostring' => \true, '__set_state' => \true, '__clone' => \true, '__invoke' => \true, '__debuginfo' => \true, '__serialize' => \true, '__unserialize' => \true]; + public array $attrGroups; + /** @var array */ + private static array $magicNames = ['__construct' => \true, '__destruct' => \true, '__call' => \true, '__callstatic' => \true, '__get' => \true, '__set' => \true, '__isset' => \true, '__unset' => \true, '__sleep' => \true, '__wakeup' => \true, '__tostring' => \true, '__set_state' => \true, '__clone' => \true, '__invoke' => \true, '__debuginfo' => \true, '__serialize' => \true, '__unserialize' => \true]; /** * Constructs a class method node. * * @param string|Node\Identifier $name Name - * @param array $subNodes Array of the following optional subnodes: - * 'flags => MODIFIER_PUBLIC: Flags - * 'byRef' => false : Whether to return by reference - * 'params' => array() : Parameters - * 'returnType' => null : Return type - * 'stmts' => array() : Statements - * 'attrGroups' => array() : PHP attribute groups - * @param array $attributes Additional attributes + * @param array{ + * flags?: int, + * byRef?: bool, + * params?: Node\Param[], + * returnType?: null|Node\Identifier|Node\Name|Node\ComplexType, + * stmts?: Node\Stmt[]|null, + * attrGroups?: Node\AttributeGroup[], + * } $subNodes Array of the following optional subnodes: + * 'flags => 0 : Flags + * 'byRef' => false : Whether to return by reference + * 'params' => array() : Parameters + * 'returnType' => null : Return type + * 'stmts' => array() : Statements + * 'attrGroups' => array() : PHP attribute groups + * @param array $attributes Additional attributes */ public function __construct($name, array $subNodes = [], array $attributes = []) { @@ -12892,8 +14604,7 @@ class ClassMethod extends Node\Stmt implements FunctionLike $this->byRef = $subNodes['byRef'] ?? \false; $this->name = \is_string($name) ? new Node\Identifier($name) : $name; $this->params = $subNodes['params'] ?? []; - $returnType = $subNodes['returnType'] ?? null; - $this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType; + $this->returnType = $subNodes['returnType'] ?? null; $this->stmts = \array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : []; $this->attrGroups = $subNodes['attrGroups'] ?? []; } @@ -12913,7 +14624,7 @@ class ClassMethod extends Node\Stmt implements FunctionLike { return $this->returnType; } - public function getStmts() + public function getStmts() : ?array { return $this->stmts; } @@ -12923,62 +14634,48 @@ class ClassMethod extends Node\Stmt implements FunctionLike } /** * Whether the method is explicitly or implicitly public. - * - * @return bool */ public function isPublic() : bool { - return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; + return ($this->flags & Modifiers::PUBLIC) !== 0 || ($this->flags & Modifiers::VISIBILITY_MASK) === 0; } /** * Whether the method is protected. - * - * @return bool */ public function isProtected() : bool { - return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); + return (bool) ($this->flags & Modifiers::PROTECTED); } /** * Whether the method is private. - * - * @return bool */ public function isPrivate() : bool { - return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); + return (bool) ($this->flags & Modifiers::PRIVATE); } /** * Whether the method is abstract. - * - * @return bool */ public function isAbstract() : bool { - return (bool) ($this->flags & Class_::MODIFIER_ABSTRACT); + return (bool) ($this->flags & Modifiers::ABSTRACT); } /** * Whether the method is final. - * - * @return bool */ public function isFinal() : bool { - return (bool) ($this->flags & Class_::MODIFIER_FINAL); + return (bool) ($this->flags & Modifiers::FINAL); } /** * Whether the method is static. - * - * @return bool */ public function isStatic() : bool { - return (bool) ($this->flags & Class_::MODIFIER_STATIC); + return (bool) ($this->flags & Modifiers::STATIC); } /** * Whether the method is magic. - * - * @return bool */ public function isMagic() : bool { @@ -12994,36 +14691,50 @@ class ClassMethod extends Node\Stmt implements FunctionLike declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Stmt; -use PHPUnit\PhpParser\Error; +use PHPUnit\PhpParser\Modifiers; use PHPUnit\PhpParser\Node; class Class_ extends ClassLike { - const MODIFIER_PUBLIC = 1; - const MODIFIER_PROTECTED = 2; - const MODIFIER_PRIVATE = 4; - const MODIFIER_STATIC = 8; - const MODIFIER_ABSTRACT = 16; - const MODIFIER_FINAL = 32; - const MODIFIER_READONLY = 64; - const VISIBILITY_MODIFIER_MASK = 7; + /** @deprecated Use Modifiers::PUBLIC instead */ + public const MODIFIER_PUBLIC = 1; + /** @deprecated Use Modifiers::PROTECTED instead */ + public const MODIFIER_PROTECTED = 2; + /** @deprecated Use Modifiers::PRIVATE instead */ + public const MODIFIER_PRIVATE = 4; + /** @deprecated Use Modifiers::STATIC instead */ + public const MODIFIER_STATIC = 8; + /** @deprecated Use Modifiers::ABSTRACT instead */ + public const MODIFIER_ABSTRACT = 16; + /** @deprecated Use Modifiers::FINAL instead */ + public const MODIFIER_FINAL = 32; + /** @deprecated Use Modifiers::READONLY instead */ + public const MODIFIER_READONLY = 64; + /** @deprecated Use Modifiers::VISIBILITY_MASK instead */ + public const VISIBILITY_MODIFIER_MASK = 7; // 1 | 2 | 4 - /** @var int Type */ - public $flags; + /** @var int Modifiers */ + public int $flags; /** @var null|Node\Name Name of extended class */ - public $extends; + public ?Node\Name $extends; /** @var Node\Name[] Names of implemented interfaces */ - public $implements; + public array $implements; /** * Constructs a class node. * * @param string|Node\Identifier|null $name Name - * @param array $subNodes Array of the following optional subnodes: - * 'flags' => 0 : Flags - * 'extends' => null : Name of extended class - * 'implements' => array(): Names of implemented interfaces - * 'stmts' => array(): Statements - * 'attrGroups' => array(): PHP attribute groups - * @param array $attributes Additional attributes + * @param array{ + * flags?: int, + * extends?: Node\Name|null, + * implements?: Node\Name[], + * stmts?: Node\Stmt[], + * attrGroups?: Node\AttributeGroup[], + * } $subNodes Array of the following optional subnodes: + * 'flags' => 0 : Flags + * 'extends' => null : Name of extended class + * 'implements' => array(): Names of implemented interfaces + * 'stmts' => array(): Statements + * 'attrGroups' => array(): PHP attribute groups + * @param array $attributes Additional attributes */ public function __construct($name, array $subNodes = [], array $attributes = []) { @@ -13041,77 +14752,29 @@ class Class_ extends ClassLike } /** * Whether the class is explicitly abstract. - * - * @return bool */ public function isAbstract() : bool { - return (bool) ($this->flags & self::MODIFIER_ABSTRACT); + return (bool) ($this->flags & Modifiers::ABSTRACT); } /** * Whether the class is final. - * - * @return bool */ public function isFinal() : bool { - return (bool) ($this->flags & self::MODIFIER_FINAL); + return (bool) ($this->flags & Modifiers::FINAL); } public function isReadonly() : bool { - return (bool) ($this->flags & self::MODIFIER_READONLY); + return (bool) ($this->flags & Modifiers::READONLY); } /** * Whether the class is anonymous. - * - * @return bool */ public function isAnonymous() : bool { return null === $this->name; } - /** - * @internal - */ - public static function verifyClassModifier($a, $b) - { - if ($a & self::MODIFIER_ABSTRACT && $b & self::MODIFIER_ABSTRACT) { - throw new Error('Multiple abstract modifiers are not allowed'); - } - if ($a & self::MODIFIER_FINAL && $b & self::MODIFIER_FINAL) { - throw new Error('Multiple final modifiers are not allowed'); - } - if ($a & self::MODIFIER_READONLY && $b & self::MODIFIER_READONLY) { - throw new Error('Multiple readonly modifiers are not allowed'); - } - if ($a & 48 && $b & 48) { - throw new Error('Cannot use the final modifier on an abstract class'); - } - } - /** - * @internal - */ - public static function verifyModifier($a, $b) - { - if ($a & self::VISIBILITY_MODIFIER_MASK && $b & self::VISIBILITY_MODIFIER_MASK) { - throw new Error('Multiple access type modifiers are not allowed'); - } - if ($a & self::MODIFIER_ABSTRACT && $b & self::MODIFIER_ABSTRACT) { - throw new Error('Multiple abstract modifiers are not allowed'); - } - if ($a & self::MODIFIER_STATIC && $b & self::MODIFIER_STATIC) { - throw new Error('Multiple static modifiers are not allowed'); - } - if ($a & self::MODIFIER_FINAL && $b & self::MODIFIER_FINAL) { - throw new Error('Multiple final modifiers are not allowed'); - } - if ($a & self::MODIFIER_READONLY && $b & self::MODIFIER_READONLY) { - throw new Error('Multiple readonly modifiers are not allowed'); - } - if ($a & 48 && $b & 48) { - throw new Error('Cannot use the final modifier on an abstract class member'); - } - } public function getType() : string { return 'Stmt_Class'; @@ -13126,12 +14789,12 @@ use PHPUnit\PhpParser\Node; class Const_ extends Node\Stmt { /** @var Node\Const_[] Constant declarations */ - public $consts; + public array $consts; /** * Constructs a const list node. * - * @param Node\Const_[] $consts Constant declarations - * @param array $attributes Additional attributes + * @param Node\Const_[] $consts Constant declarations + * @param array $attributes Additional attributes */ public function __construct(array $consts, array $attributes = []) { @@ -13156,14 +14819,14 @@ use PHPUnit\PhpParser\Node; class Continue_ extends Node\Stmt { /** @var null|Node\Expr Number of loops to continue */ - public $num; + public ?Node\Expr $num; /** * Constructs a continue node. * - * @param null|Node\Expr $num Number of loops to continue - * @param array $attributes Additional attributes + * @param null|Node\Expr $num Number of loops to continue + * @param array $attributes Additional attributes */ - public function __construct(Node\Expr $num = null, array $attributes = []) + public function __construct(?Node\Expr $num = null, array $attributes = []) { $this->attributes = $attributes; $this->num = $num; @@ -13180,57 +14843,30 @@ class Continue_ extends Node\Stmt value pair node. - * - * @param string|Node\Identifier $key Key - * @param Node\Expr $value Value - * @param array $attributes Additional attributes - */ - public function __construct($key, Node\Expr $value, array $attributes = []) - { - $this->attributes = $attributes; - $this->key = \is_string($key) ? new Node\Identifier($key) : $key; - $this->value = $value; - } - public function getSubNodeNames() : array - { - return ['key', 'value']; - } - public function getType() : string - { - return 'Stmt_DeclareDeclare'; - } -} +require __DIR__ . '/../DeclareItem.php'; $attributes Additional attributes */ - public function __construct(array $declares, array $stmts = null, array $attributes = []) + public function __construct(array $declares, ?array $stmts = null, array $attributes = []) { $this->attributes = $attributes; $this->declares = $declares; @@ -13254,15 +14890,15 @@ use PHPUnit\PhpParser\Node; class Do_ extends Node\Stmt { /** @var Node\Stmt[] Statements */ - public $stmts; + public array $stmts; /** @var Node\Expr Condition */ - public $cond; + public Node\Expr $cond; /** * Constructs a do while node. * - * @param Node\Expr $cond Condition - * @param Node\Stmt[] $stmts Statements - * @param array $attributes Additional attributes + * @param Node\Expr $cond Condition + * @param Node\Stmt[] $stmts Statements + * @param array $attributes Additional attributes */ public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = []) { @@ -13288,12 +14924,12 @@ use PHPUnit\PhpParser\Node; class Echo_ extends Node\Stmt { /** @var Node\Expr[] Expressions */ - public $exprs; + public array $exprs; /** * Constructs an echo node. * - * @param Node\Expr[] $exprs Expressions - * @param array $attributes Additional attributes + * @param Node\Expr[] $exprs Expressions + * @param array $attributes Additional attributes */ public function __construct(array $exprs, array $attributes = []) { @@ -13318,15 +14954,15 @@ use PHPUnit\PhpParser\Node; class ElseIf_ extends Node\Stmt { /** @var Node\Expr Condition */ - public $cond; + public Node\Expr $cond; /** @var Node\Stmt[] Statements */ - public $stmts; + public array $stmts; /** * Constructs an elseif node. * - * @param Node\Expr $cond Condition - * @param Node\Stmt[] $stmts Statements - * @param array $attributes Additional attributes + * @param Node\Expr $cond Condition + * @param Node\Stmt[] $stmts Statements + * @param array $attributes Additional attributes */ public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = []) { @@ -13352,12 +14988,12 @@ use PHPUnit\PhpParser\Node; class Else_ extends Node\Stmt { /** @var Node\Stmt[] Statements */ - public $stmts; + public array $stmts; /** * Constructs an else node. * - * @param Node\Stmt[] $stmts Statements - * @param array $attributes Additional attributes + * @param Node\Stmt[] $stmts Statements + * @param array $attributes Additional attributes */ public function __construct(array $stmts = [], array $attributes = []) { @@ -13383,18 +15019,18 @@ use PHPUnit\PhpParser\Node\AttributeGroup; class EnumCase extends Node\Stmt { /** @var Node\Identifier Enum case name */ - public $name; + public Node\Identifier $name; /** @var Node\Expr|null Enum case expression */ - public $expr; + public ?Node\Expr $expr; /** @var Node\AttributeGroup[] PHP attribute groups */ - public $attrGroups; + public array $attrGroups; /** - * @param string|Node\Identifier $name Enum case name - * @param Node\Expr|null $expr Enum case expression - * @param AttributeGroup[] $attrGroups PHP attribute groups - * @param array $attributes Additional attributes + * @param string|Node\Identifier $name Enum case name + * @param Node\Expr|null $expr Enum case expression + * @param list $attrGroups PHP attribute groups + * @param array $attributes Additional attributes */ - public function __construct($name, Node\Expr $expr = null, array $attrGroups = [], array $attributes = []) + public function __construct($name, ?Node\Expr $expr = null, array $attrGroups = [], array $attributes = []) { parent::__construct($attributes); $this->name = \is_string($name) ? new Node\Identifier($name) : $name; @@ -13419,17 +15055,22 @@ use PHPUnit\PhpParser\Node; class Enum_ extends ClassLike { /** @var null|Node\Identifier Scalar Type */ - public $scalarType; + public ?Node $scalarType; /** @var Node\Name[] Names of implemented interfaces */ - public $implements; + public array $implements; /** - * @param string|Node\Identifier|null $name Name - * @param array $subNodes Array of the following optional subnodes: - * 'scalarType' => null : Scalar type - * 'implements' => array() : Names of implemented interfaces - * 'stmts' => array() : Statements - * 'attrGroups' => array() : PHP attribute groups - * @param array $attributes Additional attributes + * @param string|Node\Identifier|null $name Name + * @param array{ + * scalarType?: Node\Identifier|null, + * implements?: Node\Name[], + * stmts?: Node\Stmt[], + * attrGroups?: Node\AttributeGroup[], + * } $subNodes Array of the following optional subnodes: + * 'scalarType' => null : Scalar type + * 'implements' => array() : Names of implemented interfaces + * 'stmts' => array() : Statements + * 'attrGroups' => array() : PHP attribute groups + * @param array $attributes Additional attributes */ public function __construct($name, array $subNodes = [], array $attributes = []) { @@ -13461,12 +15102,12 @@ use PHPUnit\PhpParser\Node; class Expression extends Node\Stmt { /** @var Node\Expr Expression */ - public $expr; + public Node\Expr $expr; /** * Constructs an expression statement. * - * @param Node\Expr $expr Expression - * @param array $attributes Additional attributes + * @param Node\Expr $expr Expression + * @param array $attributes Additional attributes */ public function __construct(Node\Expr $expr, array $attributes = []) { @@ -13491,12 +15132,12 @@ use PHPUnit\PhpParser\Node; class Finally_ extends Node\Stmt { /** @var Node\Stmt[] Statements */ - public $stmts; + public array $stmts; /** * Constructs a finally node. * - * @param Node\Stmt[] $stmts Statements - * @param array $attributes Additional attributes + * @param Node\Stmt[] $stmts Statements + * @param array $attributes Additional attributes */ public function __construct(array $stmts = [], array $attributes = []) { @@ -13521,22 +15162,27 @@ use PHPUnit\PhpParser\Node; class For_ extends Node\Stmt { /** @var Node\Expr[] Init expressions */ - public $init; + public array $init; /** @var Node\Expr[] Loop conditions */ - public $cond; + public array $cond; /** @var Node\Expr[] Loop expressions */ - public $loop; + public array $loop; /** @var Node\Stmt[] Statements */ - public $stmts; + public array $stmts; /** * Constructs a for loop node. * - * @param array $subNodes Array of the following optional subnodes: - * 'init' => array(): Init expressions - * 'cond' => array(): Loop conditions - * 'loop' => array(): Loop expressions - * 'stmts' => array(): Statements - * @param array $attributes Additional attributes + * @param array{ + * init?: Node\Expr[], + * cond?: Node\Expr[], + * loop?: Node\Expr[], + * stmts?: Node\Stmt[], + * } $subNodes Array of the following optional subnodes: + * 'init' => array(): Init expressions + * 'cond' => array(): Loop conditions + * 'loop' => array(): Loop expressions + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes */ public function __construct(array $subNodes = [], array $attributes = []) { @@ -13564,25 +15210,29 @@ use PHPUnit\PhpParser\Node; class Foreach_ extends Node\Stmt { /** @var Node\Expr Expression to iterate */ - public $expr; + public Node\Expr $expr; /** @var null|Node\Expr Variable to assign key to */ - public $keyVar; + public ?Node\Expr $keyVar; /** @var bool Whether to assign value by reference */ - public $byRef; + public bool $byRef; /** @var Node\Expr Variable to assign value to */ - public $valueVar; + public Node\Expr $valueVar; /** @var Node\Stmt[] Statements */ - public $stmts; + public array $stmts; /** * Constructs a foreach node. * - * @param Node\Expr $expr Expression to iterate - * @param Node\Expr $valueVar Variable to assign value to - * @param array $subNodes Array of the following optional subnodes: - * 'keyVar' => null : Variable to assign key to - * 'byRef' => false : Whether to assign value by reference - * 'stmts' => array(): Statements - * @param array $attributes Additional attributes + * @param Node\Expr $expr Expression to iterate + * @param Node\Expr $valueVar Variable to assign value to + * @param array{ + * keyVar?: Node\Expr|null, + * byRef?: bool, + * stmts?: Node\Stmt[], + * } $subNodes Array of the following optional subnodes: + * 'keyVar' => null : Variable to assign key to + * 'byRef' => false : Whether to assign value by reference + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes */ public function __construct(Node\Expr $expr, Node\Expr $valueVar, array $subNodes = [], array $attributes = []) { @@ -13612,30 +15262,36 @@ use PHPUnit\PhpParser\Node\FunctionLike; class Function_ extends Node\Stmt implements FunctionLike { /** @var bool Whether function returns by reference */ - public $byRef; + public bool $byRef; /** @var Node\Identifier Name */ - public $name; + public Node\Identifier $name; /** @var Node\Param[] Parameters */ - public $params; + public array $params; /** @var null|Node\Identifier|Node\Name|Node\ComplexType Return type */ - public $returnType; + public ?Node $returnType; /** @var Node\Stmt[] Statements */ - public $stmts; + public array $stmts; /** @var Node\AttributeGroup[] PHP attribute groups */ - public $attrGroups; + public array $attrGroups; /** @var Node\Name|null Namespaced name (if using NameResolver) */ - public $namespacedName; + public ?Node\Name $namespacedName; /** * Constructs a function node. * * @param string|Node\Identifier $name Name - * @param array $subNodes Array of the following optional subnodes: - * 'byRef' => false : Whether to return by reference - * 'params' => array(): Parameters - * 'returnType' => null : Return type - * 'stmts' => array(): Statements - * 'attrGroups' => array(): PHP attribute groups - * @param array $attributes Additional attributes + * @param array{ + * byRef?: bool, + * params?: Node\Param[], + * returnType?: null|Node\Identifier|Node\Name|Node\ComplexType, + * stmts?: Node\Stmt[], + * attrGroups?: Node\AttributeGroup[], + * } $subNodes Array of the following optional subnodes: + * 'byRef' => false : Whether to return by reference + * 'params' => array(): Parameters + * 'returnType' => null : Return type + * 'stmts' => array(): Statements + * 'attrGroups' => array(): PHP attribute groups + * @param array $attributes Additional attributes */ public function __construct($name, array $subNodes = [], array $attributes = []) { @@ -13643,8 +15299,7 @@ class Function_ extends Node\Stmt implements FunctionLike $this->byRef = $subNodes['byRef'] ?? \false; $this->name = \is_string($name) ? new Node\Identifier($name) : $name; $this->params = $subNodes['params'] ?? []; - $returnType = $subNodes['returnType'] ?? null; - $this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType; + $this->returnType = $subNodes['returnType'] ?? null; $this->stmts = $subNodes['stmts'] ?? []; $this->attrGroups = $subNodes['attrGroups'] ?? []; } @@ -13687,12 +15342,12 @@ use PHPUnit\PhpParser\Node; class Global_ extends Node\Stmt { /** @var Node\Expr[] Variables */ - public $vars; + public array $vars; /** * Constructs a global variables list node. * - * @param Node\Expr[] $vars Variables to unset - * @param array $attributes Additional attributes + * @param Node\Expr[] $vars Variables to unset + * @param array $attributes Additional attributes */ public function __construct(array $vars, array $attributes = []) { @@ -13718,12 +15373,12 @@ use PHPUnit\PhpParser\Node\Stmt; class Goto_ extends Stmt { /** @var Identifier Name of label to jump to */ - public $name; + public Identifier $name; /** * Constructs a goto node. * - * @param string|Identifier $name Name of label to jump to - * @param array $attributes Additional attributes + * @param string|Identifier $name Name of label to jump to + * @param array $attributes Additional attributes */ public function __construct($name, array $attributes = []) { @@ -13746,21 +15401,24 @@ namespace PHPUnit\PhpParser\Node\Stmt; use PHPUnit\PhpParser\Node\Name; use PHPUnit\PhpParser\Node\Stmt; +use PHPUnit\PhpParser\Node\UseItem; class GroupUse extends Stmt { - /** @var int Type of group use */ - public $type; + /** + * @var Use_::TYPE_* Type of group use + */ + public int $type; /** @var Name Prefix for uses */ - public $prefix; - /** @var UseUse[] Uses */ - public $uses; + public Name $prefix; + /** @var UseItem[] Uses */ + public array $uses; /** * Constructs a group use node. * - * @param Name $prefix Prefix for uses - * @param UseUse[] $uses Uses - * @param int $type Type of group use - * @param array $attributes Additional attributes + * @param Name $prefix Prefix for uses + * @param UseItem[] $uses Uses + * @param Use_::TYPE_* $type Type of group use + * @param array $attributes Additional attributes */ public function __construct(Name $prefix, array $uses, int $type = Use_::TYPE_NORMAL, array $attributes = []) { @@ -13787,12 +15445,12 @@ use PHPUnit\PhpParser\Node\Stmt; class HaltCompiler extends Stmt { /** @var string Remaining text after halt compiler statement. */ - public $remaining; + public string $remaining; /** * Constructs a __halt_compiler node. * - * @param string $remaining Remaining text after halt compiler statement. - * @param array $attributes Additional attributes + * @param string $remaining Remaining text after halt compiler statement. + * @param array $attributes Additional attributes */ public function __construct(string $remaining, array $attributes = []) { @@ -13817,22 +15475,26 @@ use PHPUnit\PhpParser\Node; class If_ extends Node\Stmt { /** @var Node\Expr Condition expression */ - public $cond; + public Node\Expr $cond; /** @var Node\Stmt[] Statements */ - public $stmts; + public array $stmts; /** @var ElseIf_[] Elseif clauses */ - public $elseifs; + public array $elseifs; /** @var null|Else_ Else clause */ - public $else; + public ?Else_ $else; /** * Constructs an if node. * - * @param Node\Expr $cond Condition - * @param array $subNodes Array of the following optional subnodes: - * 'stmts' => array(): Statements - * 'elseifs' => array(): Elseif clauses - * 'else' => null : Else clause - * @param array $attributes Additional attributes + * @param Node\Expr $cond Condition + * @param array{ + * stmts?: Node\Stmt[], + * elseifs?: ElseIf_[], + * else?: Else_|null, + * } $subNodes Array of the following optional subnodes: + * 'stmts' => array(): Statements + * 'elseifs' => array(): Elseif clauses + * 'else' => null : Else clause + * @param array $attributes Additional attributes */ public function __construct(Node\Expr $cond, array $subNodes = [], array $attributes = []) { @@ -13860,12 +15522,12 @@ use PHPUnit\PhpParser\Node\Stmt; class InlineHTML extends Stmt { /** @var string String */ - public $value; + public string $value; /** * Constructs an inline HTML node. * - * @param string $value String - * @param array $attributes Additional attributes + * @param string $value String + * @param array $attributes Additional attributes */ public function __construct(string $value, array $attributes = []) { @@ -13890,16 +15552,20 @@ use PHPUnit\PhpParser\Node; class Interface_ extends ClassLike { /** @var Node\Name[] Extended interfaces */ - public $extends; + public array $extends; /** * Constructs a class node. * * @param string|Node\Identifier $name Name - * @param array $subNodes Array of the following optional subnodes: - * 'extends' => array(): Name of extended interfaces - * 'stmts' => array(): Statements - * 'attrGroups' => array(): PHP attribute groups - * @param array $attributes Additional attributes + * @param array{ + * extends?: Node\Name[], + * stmts?: Node\Stmt[], + * attrGroups?: Node\AttributeGroup[], + * } $subNodes Array of the following optional subnodes: + * 'extends' => array(): Name of extended interfaces + * 'stmts' => array(): Statements + * 'attrGroups' => array(): PHP attribute groups + * @param array $attributes Additional attributes */ public function __construct($name, array $subNodes = [], array $attributes = []) { @@ -13928,12 +15594,12 @@ use PHPUnit\PhpParser\Node\Stmt; class Label extends Stmt { /** @var Identifier Name */ - public $name; + public Identifier $name; /** * Constructs a label node. * - * @param string|Identifier $name Name - * @param array $attributes Additional attributes + * @param string|Identifier $name Name + * @param array $attributes Additional attributes */ public function __construct($name, array $attributes = []) { @@ -13958,20 +15624,20 @@ use PHPUnit\PhpParser\Node; class Namespace_ extends Node\Stmt { /* For use in the "kind" attribute */ - const KIND_SEMICOLON = 1; - const KIND_BRACED = 2; + public const KIND_SEMICOLON = 1; + public const KIND_BRACED = 2; /** @var null|Node\Name Name */ - public $name; + public ?Node\Name $name; /** @var Node\Stmt[] Statements */ public $stmts; /** * Constructs a namespace node. * - * @param null|Node\Name $name Name - * @param null|Node\Stmt[] $stmts Statements - * @param array $attributes Additional attributes + * @param null|Node\Name $name Name + * @param null|Node\Stmt[] $stmts Statements + * @param array $attributes Additional attributes */ - public function __construct(Node\Name $name = null, $stmts = [], array $attributes = []) + public function __construct(?Node\Name $name = null, ?array $stmts = [], array $attributes = []) { $this->attributes = $attributes; $this->name = $name; @@ -14009,35 +15675,37 @@ class Nop extends Node\Stmt declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Stmt; +use PHPUnit\PhpParser\Modifiers; use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\Node\ComplexType; use PHPUnit\PhpParser\Node\Identifier; use PHPUnit\PhpParser\Node\Name; +use PHPUnit\PhpParser\Node\PropertyItem; class Property extends Node\Stmt { /** @var int Modifiers */ - public $flags; - /** @var PropertyProperty[] Properties */ - public $props; + public int $flags; + /** @var PropertyItem[] Properties */ + public array $props; /** @var null|Identifier|Name|ComplexType Type declaration */ - public $type; + public ?Node $type; /** @var Node\AttributeGroup[] PHP attribute groups */ - public $attrGroups; + public array $attrGroups; /** * Constructs a class property list node. * - * @param int $flags Modifiers - * @param PropertyProperty[] $props Properties - * @param array $attributes Additional attributes - * @param null|string|Identifier|Name|ComplexType $type Type declaration - * @param Node\AttributeGroup[] $attrGroups PHP attribute groups + * @param int $flags Modifiers + * @param PropertyItem[] $props Properties + * @param array $attributes Additional attributes + * @param null|Identifier|Name|ComplexType $type Type declaration + * @param Node\AttributeGroup[] $attrGroups PHP attribute groups */ - public function __construct(int $flags, array $props, array $attributes = [], $type = null, array $attrGroups = []) + public function __construct(int $flags, array $props, array $attributes = [], ?Node $type = null, array $attrGroups = []) { $this->attributes = $attributes; $this->flags = $flags; $this->props = $props; - $this->type = \is_string($type) ? new Identifier($type) : $type; + $this->type = $type; $this->attrGroups = $attrGroups; } public function getSubNodeNames() : array @@ -14046,48 +15714,38 @@ class Property extends Node\Stmt } /** * Whether the property is explicitly or implicitly public. - * - * @return bool */ public function isPublic() : bool { - return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; + return ($this->flags & Modifiers::PUBLIC) !== 0 || ($this->flags & Modifiers::VISIBILITY_MASK) === 0; } /** * Whether the property is protected. - * - * @return bool */ public function isProtected() : bool { - return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); + return (bool) ($this->flags & Modifiers::PROTECTED); } /** * Whether the property is private. - * - * @return bool */ public function isPrivate() : bool { - return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); + return (bool) ($this->flags & Modifiers::PRIVATE); } /** * Whether the property is static. - * - * @return bool */ public function isStatic() : bool { - return (bool) ($this->flags & Class_::MODIFIER_STATIC); + return (bool) ($this->flags & Modifiers::STATIC); } /** * Whether the property is readonly. - * - * @return bool */ public function isReadonly() : bool { - return (bool) ($this->flags & Class_::MODIFIER_READONLY); + return (bool) ($this->flags & Modifiers::READONLY); } public function getType() : string { @@ -14097,37 +15755,9 @@ class Property extends Node\Stmt attributes = $attributes; - $this->name = \is_string($name) ? new Node\VarLikeIdentifier($name) : $name; - $this->default = $default; - } - public function getSubNodeNames() : array - { - return ['name', 'default']; - } - public function getType() : string - { - return 'Stmt_PropertyProperty'; - } -} +require __DIR__ . '/../PropertyItem.php'; $attributes Additional attributes */ - public function __construct(Node\Expr $expr = null, array $attributes = []) + public function __construct(?Node\Expr $expr = null, array $attributes = []) { $this->attributes = $attributes; $this->expr = $expr; @@ -14161,53 +15791,25 @@ class Return_ extends Node\Stmt attributes = $attributes; - $this->var = $var; - $this->default = $default; - } - public function getSubNodeNames() : array - { - return ['var', 'default']; - } - public function getType() : string - { - return 'Stmt_StaticVar'; - } -} +require __DIR__ . '/../StaticVar.php'; $attributes Additional attributes */ public function __construct(array $vars, array $attributes = []) { @@ -14232,15 +15834,15 @@ use PHPUnit\PhpParser\Node; class Switch_ extends Node\Stmt { /** @var Node\Expr Condition */ - public $cond; + public Node\Expr $cond; /** @var Case_[] Case list */ - public $cases; + public array $cases; /** * Constructs a case node. * - * @param Node\Expr $cond Condition - * @param Case_[] $cases Case list - * @param array $attributes Additional attributes + * @param Node\Expr $cond Condition + * @param Case_[] $cases Case list + * @param array $attributes Additional attributes */ public function __construct(Node\Expr $cond, array $cases, array $attributes = []) { @@ -14262,49 +15864,19 @@ class Switch_ extends Node\Stmt declare (strict_types=1); namespace PHPUnit\PhpParser\Node\Stmt; -use PHPUnit\PhpParser\Node; -class Throw_ extends Node\Stmt -{ - /** @var Node\Expr Expression */ - public $expr; - /** - * Constructs a legacy throw statement node. - * - * @param Node\Expr $expr Expression - * @param array $attributes Additional attributes - */ - public function __construct(Node\Expr $expr, array $attributes = []) - { - $this->attributes = $attributes; - $this->expr = $expr; - } - public function getSubNodeNames() : array - { - return ['expr']; - } - public function getType() : string - { - return 'Stmt_Throw'; - } -} - $attributes Additional attributes */ public function __construct(array $traits, array $adaptations = [], array $attributes = []) { @@ -14330,9 +15902,9 @@ use PHPUnit\PhpParser\Node; abstract class TraitUseAdaptation extends Node\Stmt { /** @var Node\Name|null Trait name */ - public $trait; + public ?Node\Name $trait; /** @var Node\Identifier Method name */ - public $method; + public Node\Identifier $method; } $attributes Additional attributes */ - public function __construct($trait, $method, $newModifier, $newName, array $attributes = []) + public function __construct(?Node\Name $trait, $method, ?int $newModifier, $newName, array $attributes = []) { $this->attributes = $attributes; $this->trait = $trait; @@ -14381,14 +15953,14 @@ use PHPUnit\PhpParser\Node; class Precedence extends Node\Stmt\TraitUseAdaptation { /** @var Node\Name[] Overwritten traits */ - public $insteadof; + public array $insteadof; /** * Constructs a trait use precedence adaptation node. * - * @param Node\Name $trait Trait name - * @param string|Node\Identifier $method Method name - * @param Node\Name[] $insteadof Overwritten traits - * @param array $attributes Additional attributes + * @param Node\Name $trait Trait name + * @param string|Node\Identifier $method Method name + * @param Node\Name[] $insteadof Overwritten traits + * @param array $attributes Additional attributes */ public function __construct(Node\Name $trait, $method, array $insteadof, array $attributes = []) { @@ -14418,10 +15990,13 @@ class Trait_ extends ClassLike * Constructs a trait node. * * @param string|Node\Identifier $name Name - * @param array $subNodes Array of the following optional subnodes: - * 'stmts' => array(): Statements - * 'attrGroups' => array(): PHP attribute groups - * @param array $attributes Additional attributes + * @param array{ + * stmts?: Node\Stmt[], + * attrGroups?: Node\AttributeGroup[], + * } $subNodes Array of the following optional subnodes: + * 'stmts' => array(): Statements + * 'attrGroups' => array(): PHP attribute groups + * @param array $attributes Additional attributes */ public function __construct($name, array $subNodes = [], array $attributes = []) { @@ -14448,20 +16023,20 @@ use PHPUnit\PhpParser\Node; class TryCatch extends Node\Stmt { /** @var Node\Stmt[] Statements */ - public $stmts; + public array $stmts; /** @var Catch_[] Catches */ - public $catches; + public array $catches; /** @var null|Finally_ Optional finally node */ - public $finally; + public ?Finally_ $finally; /** * Constructs a try catch node. * - * @param Node\Stmt[] $stmts Statements - * @param Catch_[] $catches Catches - * @param null|Finally_ $finally Optional finally node - * @param array $attributes Additional attributes + * @param Node\Stmt[] $stmts Statements + * @param Catch_[] $catches Catches + * @param null|Finally_ $finally Optional finally node + * @param array $attributes Additional attributes */ - public function __construct(array $stmts, array $catches, Finally_ $finally = null, array $attributes = []) + public function __construct(array $stmts, array $catches, ?Finally_ $finally = null, array $attributes = []) { $this->attributes = $attributes; $this->stmts = $stmts; @@ -14486,12 +16061,12 @@ use PHPUnit\PhpParser\Node; class Unset_ extends Node\Stmt { /** @var Node\Expr[] Variables to unset */ - public $vars; + public array $vars; /** * Constructs an unset node. * - * @param Node\Expr[] $vars Variables to unset - * @param array $attributes Additional attributes + * @param Node\Expr[] $vars Variables to unset + * @param array $attributes Additional attributes */ public function __construct(array $vars, array $attributes = []) { @@ -14510,60 +16085,16 @@ class Unset_ extends Node\Stmt attributes = $attributes; - $this->type = $type; - $this->name = $name; - $this->alias = \is_string($alias) ? new Identifier($alias) : $alias; - } - public function getSubNodeNames() : array - { - return ['type', 'name', 'alias']; - } - /** - * Get alias. If not explicitly given this is the last component of the used name. - * - * @return Identifier - */ - public function getAlias() : Identifier - { - if (null !== $this->alias) { - return $this->alias; - } - return new Identifier($this->name->getLast()); - } - public function getType() : string - { - return 'Stmt_UseUse'; - } -} +require __DIR__ . '/../UseItem.php'; $attributes Additional attributes */ public function __construct(array $uses, int $type = self::TYPE_NORMAL, array $attributes = []) { @@ -14613,15 +16144,15 @@ use PHPUnit\PhpParser\Node; class While_ extends Node\Stmt { /** @var Node\Expr Condition */ - public $cond; + public Node\Expr $cond; /** @var Node\Stmt[] Statements */ - public $stmts; + public array $stmts; /** * Constructs a while node. * - * @param Node\Expr $cond Condition - * @param Node\Stmt[] $stmts Statements - * @param array $attributes Additional attributes + * @param Node\Expr $cond Condition + * @param Node\Stmt[] $stmts Statements + * @param array $attributes Additional attributes */ public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = []) { @@ -14646,12 +16177,12 @@ namespace PHPUnit\PhpParser\Node; class UnionType extends ComplexType { /** @var (Identifier|Name|IntersectionType)[] Types */ - public $types; + public array $types; /** * Constructs a union type. * - * @param (Identifier|Name|IntersectionType)[] $types Types - * @param array $attributes Additional attributes + * @param (Identifier|Name|IntersectionType)[] $types Types + * @param array $attributes Additional attributes */ public function __construct(array $types, array $attributes = []) { @@ -14672,6 +16203,60 @@ class UnionType extends ComplexType declare (strict_types=1); namespace PHPUnit\PhpParser\Node; +use PHPUnit\PhpParser\Node; +use PHPUnit\PhpParser\NodeAbstract; +use PHPUnit\PhpParser\Node\Stmt\Use_; +class UseItem extends NodeAbstract +{ + /** + * @var Use_::TYPE_* One of the Stmt\Use_::TYPE_* constants. Will only differ from TYPE_UNKNOWN for mixed group uses + */ + public int $type; + /** @var Node\Name Namespace, class, function or constant to alias */ + public Name $name; + /** @var Identifier|null Alias */ + public ?Identifier $alias; + /** + * Constructs an alias (use) item node. + * + * @param Node\Name $name Namespace/Class to alias + * @param null|string|Identifier $alias Alias + * @param Use_::TYPE_* $type Type of the use element (for mixed group use only) + * @param array $attributes Additional attributes + */ + public function __construct(Node\Name $name, $alias = null, int $type = Use_::TYPE_UNKNOWN, array $attributes = []) + { + $this->attributes = $attributes; + $this->type = $type; + $this->name = $name; + $this->alias = \is_string($alias) ? new Identifier($alias) : $alias; + } + public function getSubNodeNames() : array + { + return ['type', 'name', 'alias']; + } + /** + * Get alias. If not explicitly given this is the last component of the used name. + */ + public function getAlias() : Identifier + { + if (null !== $this->alias) { + return $this->alias; + } + return new Identifier($this->name->getLast()); + } + public function getType() : string + { + return 'UseItem'; + } +} +// @deprecated compatibility alias +\class_alias(UseItem::class, Stmt\UseUse::class); + $attributes Additional attributes */ public function __construct(array $attributes = []) { @@ -14722,11 +16307,12 @@ namespace PHPUnit\PhpParser; abstract class NodeAbstract implements Node, \JsonSerializable { - protected $attributes; + /** @var array Attributes */ + protected array $attributes; /** * Creates a Node. * - * @param array $attributes Array of attributes + * @param array $attributes Array of attributes */ public function __construct(array $attributes = []) { @@ -14827,7 +16413,7 @@ abstract class NodeAbstract implements Node, \JsonSerializable * * @return null|Comment\Doc Doc comment object or null */ - public function getDocComment() + public function getDocComment() : ?Comment\Doc { $comments = $this->getComments(); for ($i = \count($comments) - 1; $i >= 0; $i--) { @@ -14845,7 +16431,7 @@ abstract class NodeAbstract implements Node, \JsonSerializable * * @param Comment\Doc $docComment Doc comment to set */ - public function setDocComment(Comment\Doc $docComment) + public function setDocComment(Comment\Doc $docComment) : void { $comments = $this->getComments(); for ($i = \count($comments) - 1; $i >= 0; $i--) { @@ -14860,7 +16446,7 @@ abstract class NodeAbstract implements Node, \JsonSerializable $comments[] = $docComment; $this->setAttribute('comments', $comments); } - public function setAttribute(string $key, $value) + public function setAttribute(string $key, $value) : void { $this->attributes[$key] = $value; } @@ -14879,12 +16465,12 @@ abstract class NodeAbstract implements Node, \JsonSerializable { return $this->attributes; } - public function setAttributes(array $attributes) + public function setAttributes(array $attributes) : void { $this->attributes = $attributes; } /** - * @return array + * @return array */ public function jsonSerialize() : array { @@ -14896,16 +16482,24 @@ abstract class NodeAbstract implements Node, \JsonSerializable declare (strict_types=1); namespace PHPUnit\PhpParser; +use PHPUnit\PhpParser\Node\Expr\Array_; use PHPUnit\PhpParser\Node\Expr\Include_; -use PHPUnit\PhpParser\Node\Stmt\Class_; +use PHPUnit\PhpParser\Node\Expr\List_; +use PHPUnit\PhpParser\Node\Scalar\Int_; +use PHPUnit\PhpParser\Node\Scalar\InterpolatedString; +use PHPUnit\PhpParser\Node\Scalar\String_; use PHPUnit\PhpParser\Node\Stmt\GroupUse; use PHPUnit\PhpParser\Node\Stmt\Use_; -use PHPUnit\PhpParser\Node\Stmt\UseUse; +use PHPUnit\PhpParser\Node\UseItem; class NodeDumper { - private $dumpComments; - private $dumpPositions; - private $code; + private bool $dumpComments; + private bool $dumpPositions; + private bool $dumpOtherAttributes; + private ?string $code; + private string $res; + private string $nl; + private const IGNORE_ATTRIBUTES = ['comments' => \true, 'startLine' => \true, 'endLine' => \true, 'startFilePos' => \true, 'endFilePos' => \true, 'startTokenPos' => \true, 'endTokenPos' => \true]; /** * Constructs a NodeDumper. * @@ -14913,6 +16507,7 @@ class NodeDumper * * bool dumpComments: Whether comments should be dumped. * * bool dumpPositions: Whether line/offset information should be dumped. To dump offset * information, the code needs to be passed to dump(). + * * bool dumpOtherAttributes: Whether non-comment, non-position attributes should be dumped. * * @param array $options Options (see description) */ @@ -14920,124 +16515,178 @@ class NodeDumper { $this->dumpComments = !empty($options['dumpComments']); $this->dumpPositions = !empty($options['dumpPositions']); + $this->dumpOtherAttributes = !empty($options['dumpOtherAttributes']); } /** * Dumps a node or array. * - * @param array|Node $node Node or array to dump + * @param array|Node $node Node or array to dump * @param string|null $code Code corresponding to dumped AST. This only needs to be passed if * the dumpPositions option is enabled and the dumping of node offsets * is desired. * * @return string Dumped value */ - public function dump($node, string $code = null) : string + public function dump($node, ?string $code = null) : string { $this->code = $code; - return $this->dumpRecursive($node); + $this->res = ''; + $this->nl = "\n"; + $this->dumpRecursive($node, \false); + return $this->res; } - protected function dumpRecursive($node) + /** @param mixed $node */ + protected function dumpRecursive($node, bool $indent = \true) : void { + if ($indent) { + $this->nl .= " "; + } if ($node instanceof Node) { - $r = $node->getType(); + $this->res .= $node->getType(); if ($this->dumpPositions && null !== ($p = $this->dumpPosition($node))) { - $r .= $p; + $this->res .= $p; } - $r .= '('; + $this->res .= '('; foreach ($node->getSubNodeNames() as $key) { - $r .= "\n " . $key . ': '; + $this->res .= "{$this->nl} " . $key . ': '; $value = $node->{$key}; - if (null === $value) { - $r .= 'null'; - } elseif (\false === $value) { - $r .= 'false'; - } elseif (\true === $value) { - $r .= 'true'; - } elseif (\is_scalar($value)) { + if (\is_int($value)) { if ('flags' === $key || 'newModifier' === $key) { - $r .= $this->dumpFlags($value); - } elseif ('type' === $key && $node instanceof Include_) { - $r .= $this->dumpIncludeType($value); - } elseif ('type' === $key && ($node instanceof Use_ || $node instanceof UseUse || $node instanceof GroupUse)) { - $r .= $this->dumpUseType($value); - } else { - $r .= $value; + $this->res .= $this->dumpFlags($value); + continue; + } + if ('type' === $key && $node instanceof Include_) { + $this->res .= $this->dumpIncludeType($value); + continue; + } + if ('type' === $key && ($node instanceof Use_ || $node instanceof UseItem || $node instanceof GroupUse)) { + $this->res .= $this->dumpUseType($value); + continue; } - } else { - $r .= \str_replace("\n", "\n ", $this->dumpRecursive($value)); } + $this->dumpRecursive($value); } if ($this->dumpComments && ($comments = $node->getComments())) { - $r .= "\n comments: " . \str_replace("\n", "\n ", $this->dumpRecursive($comments)); + $this->res .= "{$this->nl} comments: "; + $this->dumpRecursive($comments); } + if ($this->dumpOtherAttributes) { + foreach ($node->getAttributes() as $key => $value) { + if (isset(self::IGNORE_ATTRIBUTES[$key])) { + continue; + } + $this->res .= "{$this->nl} {$key}: "; + if (\is_int($value)) { + if ('kind' === $key) { + if ($node instanceof Int_) { + $this->res .= $this->dumpIntKind($value); + continue; + } + if ($node instanceof String_ || $node instanceof InterpolatedString) { + $this->res .= $this->dumpStringKind($value); + continue; + } + if ($node instanceof Array_) { + $this->res .= $this->dumpArrayKind($value); + continue; + } + if ($node instanceof List_) { + $this->res .= $this->dumpListKind($value); + continue; + } + } + } + $this->dumpRecursive($value); + } + } + $this->res .= "{$this->nl})"; } elseif (\is_array($node)) { - $r = 'array('; + $this->res .= 'array('; foreach ($node as $key => $value) { - $r .= "\n " . $key . ': '; - if (null === $value) { - $r .= 'null'; - } elseif (\false === $value) { - $r .= 'false'; - } elseif (\true === $value) { - $r .= 'true'; - } elseif (\is_scalar($value)) { - $r .= $value; - } else { - $r .= \str_replace("\n", "\n ", $this->dumpRecursive($value)); - } + $this->res .= "{$this->nl} " . $key . ': '; + $this->dumpRecursive($value); } + $this->res .= "{$this->nl})"; } elseif ($node instanceof Comment) { - return $node->getReformattedText(); + $this->res .= \str_replace("\n", $this->nl, $node->getReformattedText()); + } elseif (\is_string($node)) { + $this->res .= \str_replace("\n", $this->nl, (string) $node); + } elseif (\is_int($node) || \is_float($node)) { + $this->res .= $node; + } elseif (null === $node) { + $this->res .= 'null'; + } elseif (\false === $node) { + $this->res .= 'false'; + } elseif (\true === $node) { + $this->res .= 'true'; } else { throw new \InvalidArgumentException('Can only dump nodes and arrays.'); } - return $r . "\n)"; + if ($indent) { + $this->nl = \substr($this->nl, 0, -4); + } } - protected function dumpFlags($flags) + protected function dumpFlags(int $flags) : string { $strs = []; - if ($flags & Class_::MODIFIER_PUBLIC) { - $strs[] = 'MODIFIER_PUBLIC'; + if ($flags & Modifiers::PUBLIC) { + $strs[] = 'PUBLIC'; } - if ($flags & Class_::MODIFIER_PROTECTED) { - $strs[] = 'MODIFIER_PROTECTED'; + if ($flags & Modifiers::PROTECTED) { + $strs[] = 'PROTECTED'; } - if ($flags & Class_::MODIFIER_PRIVATE) { - $strs[] = 'MODIFIER_PRIVATE'; + if ($flags & Modifiers::PRIVATE) { + $strs[] = 'PRIVATE'; } - if ($flags & Class_::MODIFIER_ABSTRACT) { - $strs[] = 'MODIFIER_ABSTRACT'; + if ($flags & Modifiers::ABSTRACT) { + $strs[] = 'ABSTRACT'; } - if ($flags & Class_::MODIFIER_STATIC) { - $strs[] = 'MODIFIER_STATIC'; + if ($flags & Modifiers::STATIC) { + $strs[] = 'STATIC'; } - if ($flags & Class_::MODIFIER_FINAL) { - $strs[] = 'MODIFIER_FINAL'; + if ($flags & Modifiers::FINAL) { + $strs[] = 'FINAL'; } - if ($flags & Class_::MODIFIER_READONLY) { - $strs[] = 'MODIFIER_READONLY'; + if ($flags & Modifiers::READONLY) { + $strs[] = 'READONLY'; } if ($strs) { return \implode(' | ', $strs) . ' (' . $flags . ')'; } else { - return $flags; + return (string) $flags; } } - protected function dumpIncludeType($type) + /** @param array $map */ + private function dumpEnum(int $value, array $map) : string { - $map = [Include_::TYPE_INCLUDE => 'TYPE_INCLUDE', Include_::TYPE_INCLUDE_ONCE => 'TYPE_INCLUDE_ONCE', Include_::TYPE_REQUIRE => 'TYPE_REQUIRE', Include_::TYPE_REQUIRE_ONCE => 'TYPE_REQUIRE_ONCE']; - if (!isset($map[$type])) { - return $type; + if (!isset($map[$value])) { + return (string) $value; } - return $map[$type] . ' (' . $type . ')'; + return $map[$value] . ' (' . $value . ')'; } - protected function dumpUseType($type) + private function dumpIncludeType(int $type) : string { - $map = [Use_::TYPE_UNKNOWN => 'TYPE_UNKNOWN', Use_::TYPE_NORMAL => 'TYPE_NORMAL', Use_::TYPE_FUNCTION => 'TYPE_FUNCTION', Use_::TYPE_CONSTANT => 'TYPE_CONSTANT']; - if (!isset($map[$type])) { - return $type; - } - return $map[$type] . ' (' . $type . ')'; + return $this->dumpEnum($type, [Include_::TYPE_INCLUDE => 'TYPE_INCLUDE', Include_::TYPE_INCLUDE_ONCE => 'TYPE_INCLUDE_ONCE', Include_::TYPE_REQUIRE => 'TYPE_REQUIRE', Include_::TYPE_REQUIRE_ONCE => 'TYPE_REQUIRE_ONCE']); + } + private function dumpUseType(int $type) : string + { + return $this->dumpEnum($type, [Use_::TYPE_UNKNOWN => 'TYPE_UNKNOWN', Use_::TYPE_NORMAL => 'TYPE_NORMAL', Use_::TYPE_FUNCTION => 'TYPE_FUNCTION', Use_::TYPE_CONSTANT => 'TYPE_CONSTANT']); + } + private function dumpIntKind(int $kind) : string + { + return $this->dumpEnum($kind, [Int_::KIND_BIN => 'KIND_BIN', Int_::KIND_OCT => 'KIND_OCT', Int_::KIND_DEC => 'KIND_DEC', Int_::KIND_HEX => 'KIND_HEX']); + } + private function dumpStringKind(int $kind) : string + { + return $this->dumpEnum($kind, [String_::KIND_SINGLE_QUOTED => 'KIND_SINGLE_QUOTED', String_::KIND_DOUBLE_QUOTED => 'KIND_DOUBLE_QUOTED', String_::KIND_HEREDOC => 'KIND_HEREDOC', String_::KIND_NOWDOC => 'KIND_NOWDOC']); + } + private function dumpArrayKind(int $kind) : string + { + return $this->dumpEnum($kind, [Array_::KIND_LONG => 'KIND_LONG', Array_::KIND_SHORT => 'KIND_SHORT']); + } + private function dumpListKind(int $kind) : string + { + return $this->dumpEnum($kind, [List_::KIND_LIST => 'KIND_LIST', List_::KIND_ARRAY => 'KIND_ARRAY']); } /** * Dump node position, if possible. @@ -15046,7 +16695,7 @@ class NodeDumper * * @return string|null Dump of position, or null if position information not available */ - protected function dumpPosition(Node $node) + protected function dumpPosition(Node $node) : ?string { if (!$node->hasAttribute('startLine') || !$node->hasAttribute('endLine')) { return null; @@ -15060,7 +16709,7 @@ class NodeDumper return "[{$start} - {$end}]"; } // Copied from Error class - private function toColumn($code, $pos) + private function toColumn(string $code, int $pos) : int { if ($pos > \strlen($code)) { throw new \RuntimeException('Invalid position information'); @@ -15084,29 +16733,32 @@ class NodeFinder /** * Find all nodes satisfying a filter callback. * - * @param Node|Node[] $nodes Single node or array of nodes to search in - * @param callable $filter Filter callback: function(Node $node) : bool + * @param Node|Node[] $nodes Single node or array of nodes to search in + * @param callable $filter Filter callback: function(Node $node) : bool * * @return Node[] Found nodes satisfying the filter callback */ public function find($nodes, callable $filter) : array { + if ($nodes === []) { + return []; + } if (!\is_array($nodes)) { $nodes = [$nodes]; } $visitor = new FindingVisitor($filter); - $traverser = new NodeTraverser(); - $traverser->addVisitor($visitor); + $traverser = new NodeTraverser($visitor); $traverser->traverse($nodes); return $visitor->getFoundNodes(); } /** * Find all nodes that are instances of a certain class. + * @template TNode as Node * * @param Node|Node[] $nodes Single node or array of nodes to search in - * @param string $class Class name + * @param class-string $class Class name * - * @return Node[] Found nodes (all instances of $class) + * @return TNode[] Found nodes (all instances of $class) */ public function findInstanceOf($nodes, string $class) : array { @@ -15117,31 +16769,35 @@ class NodeFinder /** * Find first node satisfying a filter callback. * - * @param Node|Node[] $nodes Single node or array of nodes to search in - * @param callable $filter Filter callback: function(Node $node) : bool + * @param Node|Node[] $nodes Single node or array of nodes to search in + * @param callable $filter Filter callback: function(Node $node) : bool * * @return null|Node Found node (or null if none found) */ - public function findFirst($nodes, callable $filter) + public function findFirst($nodes, callable $filter) : ?Node { + if ($nodes === []) { + return null; + } if (!\is_array($nodes)) { $nodes = [$nodes]; } $visitor = new FirstFindingVisitor($filter); - $traverser = new NodeTraverser(); - $traverser->addVisitor($visitor); + $traverser = new NodeTraverser($visitor); $traverser->traverse($nodes); return $visitor->getFoundNode(); } /** * Find first node that is an instance of a certain class. * - * @param Node|Node[] $nodes Single node or array of nodes to search in - * @param string $class Class name + * @template TNode as Node * - * @return null|Node Found node, which is an instance of $class (or null if none found) + * @param Node|Node[] $nodes Single node or array of nodes to search in + * @param class-string $class Class name + * + * @return null|TNode Found node, which is an instance of $class (or null if none found) */ - public function findFirstInstanceOf($nodes, string $class) + public function findFirstInstanceOf($nodes, string $class) : ?Node { return $this->findFirst($nodes, function ($node) use($class) { return $node instanceof $class; @@ -15156,65 +16812,51 @@ namespace PHPUnit\PhpParser; class NodeTraverser implements NodeTraverserInterface { /** - * If NodeVisitor::enterNode() returns DONT_TRAVERSE_CHILDREN, child nodes - * of the current node will not be traversed for any visitors. - * - * For subsequent visitors enterNode() will still be called on the current - * node and leaveNode() will also be invoked for the current node. + * @deprecated Use NodeVisitor::DONT_TRAVERSE_CHILDREN instead. */ - const DONT_TRAVERSE_CHILDREN = 1; + public const DONT_TRAVERSE_CHILDREN = NodeVisitor::DONT_TRAVERSE_CHILDREN; /** - * If NodeVisitor::enterNode() or NodeVisitor::leaveNode() returns - * STOP_TRAVERSAL, traversal is aborted. - * - * The afterTraverse() method will still be invoked. + * @deprecated Use NodeVisitor::STOP_TRAVERSAL instead. */ - const STOP_TRAVERSAL = 2; + public const STOP_TRAVERSAL = NodeVisitor::STOP_TRAVERSAL; /** - * If NodeVisitor::leaveNode() returns REMOVE_NODE for a node that occurs - * in an array, it will be removed from the array. - * - * For subsequent visitors leaveNode() will still be invoked for the - * removed node. + * @deprecated Use NodeVisitor::REMOVE_NODE instead. */ - const REMOVE_NODE = 3; + public const REMOVE_NODE = NodeVisitor::REMOVE_NODE; /** - * If NodeVisitor::enterNode() returns DONT_TRAVERSE_CURRENT_AND_CHILDREN, child nodes - * of the current node will not be traversed for any visitors. - * - * For subsequent visitors enterNode() will not be called as well. - * leaveNode() will be invoked for visitors that has enterNode() method invoked. + * @deprecated Use NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN instead. */ - const DONT_TRAVERSE_CURRENT_AND_CHILDREN = 4; - /** @var NodeVisitor[] Visitors */ - protected $visitors = []; + public const DONT_TRAVERSE_CURRENT_AND_CHILDREN = NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN; + /** @var list Visitors */ + protected array $visitors = []; /** @var bool Whether traversal should be stopped */ - protected $stopTraversal; - public function __construct() + protected bool $stopTraversal; + /** + * Create a traverser with the given visitors. + * + * @param NodeVisitor ...$visitors Node visitors + */ + public function __construct(NodeVisitor ...$visitors) { - // for BC + $this->visitors = $visitors; } /** * Adds a visitor. * * @param NodeVisitor $visitor Visitor to add */ - public function addVisitor(NodeVisitor $visitor) + public function addVisitor(NodeVisitor $visitor) : void { $this->visitors[] = $visitor; } /** * Removes an added visitor. - * - * @param NodeVisitor $visitor */ - public function removeVisitor(NodeVisitor $visitor) + public function removeVisitor(NodeVisitor $visitor) : void { - foreach ($this->visitors as $index => $storedVisitor) { - if ($storedVisitor === $visitor) { - unset($this->visitors[$index]); - break; - } + $index = \array_search($visitor, $this->visitors); + if ($index !== \false) { + \array_splice($this->visitors, $index, 1, []); } } /** @@ -15233,7 +16875,8 @@ class NodeTraverser implements NodeTraverserInterface } } $nodes = $this->traverseArray($nodes); - foreach ($this->visitors as $visitor) { + for ($i = \count($this->visitors) - 1; $i >= 0; --$i) { + $visitor = $this->visitors[$i]; if (null !== ($return = $visitor->afterTraverse($nodes))) { $nodes = $return; } @@ -15244,69 +16887,69 @@ class NodeTraverser implements NodeTraverserInterface * Recursively traverse a node. * * @param Node $node Node to traverse. - * - * @return Node Result of traversal (may be original node or new one) */ - protected function traverseNode(Node $node) : Node + protected function traverseNode(Node $node) : void { foreach ($node->getSubNodeNames() as $name) { - $subNode =& $node->{$name}; + $subNode = $node->{$name}; if (\is_array($subNode)) { - $subNode = $this->traverseArray($subNode); + $node->{$name} = $this->traverseArray($subNode); if ($this->stopTraversal) { break; } } elseif ($subNode instanceof Node) { $traverseChildren = \true; - $breakVisitorIndex = null; + $visitorIndex = -1; foreach ($this->visitors as $visitorIndex => $visitor) { $return = $visitor->enterNode($subNode); if (null !== $return) { if ($return instanceof Node) { $this->ensureReplacementReasonable($subNode, $return); - $subNode = $return; - } elseif (self::DONT_TRAVERSE_CHILDREN === $return) { + $subNode = $node->{$name} = $return; + } elseif (NodeVisitor::DONT_TRAVERSE_CHILDREN === $return) { $traverseChildren = \false; - } elseif (self::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) { + } elseif (NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) { $traverseChildren = \false; - $breakVisitorIndex = $visitorIndex; break; - } elseif (self::STOP_TRAVERSAL === $return) { + } elseif (NodeVisitor::STOP_TRAVERSAL === $return) { $this->stopTraversal = \true; break 2; + } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) { + $node->{$name} = null; + continue 2; } else { throw new \LogicException('enterNode() returned invalid value of type ' . \gettype($return)); } } } if ($traverseChildren) { - $subNode = $this->traverseNode($subNode); + $this->traverseNode($subNode); if ($this->stopTraversal) { break; } } - foreach ($this->visitors as $visitorIndex => $visitor) { + for (; $visitorIndex >= 0; --$visitorIndex) { + $visitor = $this->visitors[$visitorIndex]; $return = $visitor->leaveNode($subNode); if (null !== $return) { if ($return instanceof Node) { $this->ensureReplacementReasonable($subNode, $return); - $subNode = $return; - } elseif (self::STOP_TRAVERSAL === $return) { + $subNode = $node->{$name} = $return; + } elseif (NodeVisitor::STOP_TRAVERSAL === $return) { $this->stopTraversal = \true; break 2; + } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) { + $node->{$name} = null; + break; } elseif (\is_array($return)) { throw new \LogicException('leaveNode() may only return an array ' . 'if the parent structure is an array'); } else { throw new \LogicException('leaveNode() returned invalid value of type ' . \gettype($return)); } } - if ($breakVisitorIndex === $visitorIndex) { - break; - } } } } - return $node; } /** * Recursively traverse array (usually of nodes). @@ -15318,60 +16961,65 @@ class NodeTraverser implements NodeTraverserInterface protected function traverseArray(array $nodes) : array { $doNodes = []; - foreach ($nodes as $i => &$node) { + foreach ($nodes as $i => $node) { if ($node instanceof Node) { $traverseChildren = \true; - $breakVisitorIndex = null; + $visitorIndex = -1; foreach ($this->visitors as $visitorIndex => $visitor) { $return = $visitor->enterNode($node); if (null !== $return) { if ($return instanceof Node) { $this->ensureReplacementReasonable($node, $return); - $node = $return; - } elseif (self::DONT_TRAVERSE_CHILDREN === $return) { + $nodes[$i] = $node = $return; + } elseif (\is_array($return)) { + $doNodes[] = [$i, $return]; + continue 2; + } elseif (NodeVisitor::REMOVE_NODE === $return) { + $doNodes[] = [$i, []]; + continue 2; + } elseif (NodeVisitor::DONT_TRAVERSE_CHILDREN === $return) { $traverseChildren = \false; - } elseif (self::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) { + } elseif (NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) { $traverseChildren = \false; - $breakVisitorIndex = $visitorIndex; break; - } elseif (self::STOP_TRAVERSAL === $return) { + } elseif (NodeVisitor::STOP_TRAVERSAL === $return) { $this->stopTraversal = \true; break 2; + } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) { + throw new \LogicException('REPLACE_WITH_NULL can not be used if the parent structure is an array'); } else { throw new \LogicException('enterNode() returned invalid value of type ' . \gettype($return)); } } } if ($traverseChildren) { - $node = $this->traverseNode($node); + $this->traverseNode($node); if ($this->stopTraversal) { break; } } - foreach ($this->visitors as $visitorIndex => $visitor) { + for (; $visitorIndex >= 0; --$visitorIndex) { + $visitor = $this->visitors[$visitorIndex]; $return = $visitor->leaveNode($node); if (null !== $return) { if ($return instanceof Node) { $this->ensureReplacementReasonable($node, $return); - $node = $return; + $nodes[$i] = $node = $return; } elseif (\is_array($return)) { $doNodes[] = [$i, $return]; break; - } elseif (self::REMOVE_NODE === $return) { + } elseif (NodeVisitor::REMOVE_NODE === $return) { $doNodes[] = [$i, []]; break; - } elseif (self::STOP_TRAVERSAL === $return) { + } elseif (NodeVisitor::STOP_TRAVERSAL === $return) { $this->stopTraversal = \true; break 2; - } elseif (\false === $return) { - throw new \LogicException('bool(false) return from leaveNode() no longer supported. ' . 'Return NodeTraverser::REMOVE_NODE instead'); + } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) { + throw new \LogicException('REPLACE_WITH_NULL can not be used if the parent structure is an array'); } else { throw new \LogicException('leaveNode() returned invalid value of type ' . \gettype($return)); } } - if ($breakVisitorIndex === $visitorIndex) { - break; - } } } elseif (\is_array($node)) { throw new \LogicException('Invalid node structure: Contains nested arrays'); @@ -15384,7 +17032,7 @@ class NodeTraverser implements NodeTraverserInterface } return $nodes; } - private function ensureReplacementReasonable($old, $new) + private function ensureReplacementReasonable(Node $old, Node $new) : void { if ($old instanceof Node\Stmt && $new instanceof Node\Expr) { throw new \LogicException("Trying to replace statement ({$old->getType()}) " . "with expression ({$new->getType()}). Are you missing a " . "Stmt_Expression wrapper?"); @@ -15406,13 +17054,11 @@ interface NodeTraverserInterface * * @param NodeVisitor $visitor Visitor to add */ - public function addVisitor(NodeVisitor $visitor); + public function addVisitor(NodeVisitor $visitor) : void; /** * Removes an added visitor. - * - * @param NodeVisitor $visitor */ - public function removeVisitor(NodeVisitor $visitor); + public function removeVisitor(NodeVisitor $visitor) : void; /** * Traverses an array of nodes using the registered visitors. * @@ -15429,6 +17075,43 @@ namespace PHPUnit\PhpParser; interface NodeVisitor { + /** + * If NodeVisitor::enterNode() returns DONT_TRAVERSE_CHILDREN, child nodes + * of the current node will not be traversed for any visitors. + * + * For subsequent visitors enterNode() will still be called on the current + * node and leaveNode() will also be invoked for the current node. + */ + public const DONT_TRAVERSE_CHILDREN = 1; + /** + * If NodeVisitor::enterNode() or NodeVisitor::leaveNode() returns + * STOP_TRAVERSAL, traversal is aborted. + * + * The afterTraverse() method will still be invoked. + */ + public const STOP_TRAVERSAL = 2; + /** + * If NodeVisitor::leaveNode() returns REMOVE_NODE for a node that occurs + * in an array, it will be removed from the array. + * + * For subsequent visitors leaveNode() will still be invoked for the + * removed node. + */ + public const REMOVE_NODE = 3; + /** + * If NodeVisitor::enterNode() returns DONT_TRAVERSE_CURRENT_AND_CHILDREN, child nodes + * of the current node will not be traversed for any visitors. + * + * For subsequent visitors enterNode() will not be called as well. + * leaveNode() will be invoked for visitors that has enterNode() method invoked. + */ + public const DONT_TRAVERSE_CURRENT_AND_CHILDREN = 4; + /** + * If NodeVisitor::enterNode() or NodeVisitor::leaveNode() returns REPLACE_WITH_NULL, + * the node will be replaced with null. This is not a legal return value if the node is part + * of an array, rather than another node. + */ + public const REPLACE_WITH_NULL = 5; /** * Called once before traversal. * @@ -15447,16 +17130,25 @@ interface NodeVisitor * Return value semantics: * * null * => $node stays as-is - * * NodeTraverser::DONT_TRAVERSE_CHILDREN + * * array (of Nodes) + * => The return value is merged into the parent array (at the position of the $node) + * * NodeVisitor::REMOVE_NODE + * => $node is removed from the parent array + * * NodeVisitor::REPLACE_WITH_NULL + * => $node is replaced with null + * * NodeVisitor::DONT_TRAVERSE_CHILDREN * => Children of $node are not traversed. $node stays as-is - * * NodeTraverser::STOP_TRAVERSAL + * * NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN + * => Further visitors for the current node are skipped, and its children are not + * traversed. $node stays as-is. + * * NodeVisitor::STOP_TRAVERSAL * => Traversal is aborted. $node stays as-is * * otherwise * => $node is set to the return value * * @param Node $node Node * - * @return null|int|Node Replacement node (or special return value) + * @return null|int|Node|Node[] Replacement node (or special return value) */ public function enterNode(Node $node); /** @@ -15465,9 +17157,11 @@ interface NodeVisitor * Return value semantics: * * null * => $node stays as-is - * * NodeTraverser::REMOVE_NODE + * * NodeVisitor::REMOVE_NODE * => $node is removed from the parent array - * * NodeTraverser::STOP_TRAVERSAL + * * NodeVisitor::REPLACE_WITH_NULL + * => $node is replaced with null + * * NodeVisitor::STOP_TRAVERSAL * => Traversal is aborted. $node stays as-is * * array (of Nodes) * => The return value is merged into the parent array (at the position of the $node) @@ -15518,6 +17212,80 @@ class CloningVisitor extends NodeVisitorAbstract declare (strict_types=1); namespace PHPUnit\PhpParser\NodeVisitor; +use PHPUnit\PhpParser\Comment; +use PHPUnit\PhpParser\Node; +use PHPUnit\PhpParser\NodeVisitorAbstract; +use PHPUnit\PhpParser\Token; +class CommentAnnotatingVisitor extends NodeVisitorAbstract +{ + /** @var int Last seen token start position */ + private int $pos = 0; + /** @var Token[] Token array */ + private array $tokens; + /** @var list Token positions of comments */ + private array $commentPositions = []; + /** + * Create a comment annotation visitor. + * + * @param Token[] $tokens Token array + */ + public function __construct(array $tokens) + { + $this->tokens = $tokens; + // Collect positions of comments. We use this to avoid traversing parts of the AST where + // there are no comments. + foreach ($tokens as $i => $token) { + if ($token->id === \T_COMMENT || $token->id === \T_DOC_COMMENT) { + $this->commentPositions[] = $i; + } + } + } + public function enterNode(Node $node) + { + $nextCommentPos = \current($this->commentPositions); + if ($nextCommentPos === \false) { + // No more comments. + return self::STOP_TRAVERSAL; + } + $oldPos = $this->pos; + $this->pos = $pos = $node->getStartTokenPos(); + if ($nextCommentPos > $oldPos && $nextCommentPos < $pos) { + $comments = []; + while (--$pos >= $oldPos) { + $token = $this->tokens[$pos]; + if ($token->id === \T_DOC_COMMENT) { + $comments[] = new Comment\Doc($token->text, $token->line, $token->pos, $pos, $token->getEndLine(), $token->getEndPos() - 1, $pos); + continue; + } + if ($token->id === \T_COMMENT) { + $comments[] = new Comment($token->text, $token->line, $token->pos, $pos, $token->getEndLine(), $token->getEndPos() - 1, $pos); + continue; + } + if ($token->id !== \T_WHITESPACE) { + break; + } + } + if (!empty($comments)) { + $node->setAttribute('comments', \array_reverse($comments)); + } + do { + $nextCommentPos = \next($this->commentPositions); + } while ($nextCommentPos !== \false && $nextCommentPos < $this->pos); + } + $endPos = $node->getEndTokenPos(); + if ($nextCommentPos > $endPos) { + // Skip children if there are no comments located inside this node. + $this->pos = $endPos; + return self::DONT_TRAVERSE_CHILDREN; + } + return null; + } +} +filterCallback = $filterCallback; @@ -15545,7 +17313,7 @@ class FindingVisitor extends NodeVisitorAbstract { return $this->foundNodes; } - public function beforeTraverse(array $nodes) + public function beforeTraverse(array $nodes) : ?array { $this->foundNodes = []; return null; @@ -15565,7 +17333,7 @@ declare (strict_types=1); namespace PHPUnit\PhpParser\NodeVisitor; use PHPUnit\PhpParser\Node; -use PHPUnit\PhpParser\NodeTraverser; +use PHPUnit\PhpParser\NodeVisitor; use PHPUnit\PhpParser\NodeVisitorAbstract; /** * This visitor can be used to find the first node satisfying some criterion determined by @@ -15576,7 +17344,7 @@ class FirstFindingVisitor extends NodeVisitorAbstract /** @var callable Filter callback */ protected $filterCallback; /** @var null|Node Found node */ - protected $foundNode; + protected ?Node $foundNode; public function __construct(callable $filterCallback) { $this->filterCallback = $filterCallback; @@ -15588,11 +17356,11 @@ class FirstFindingVisitor extends NodeVisitorAbstract * * @return null|Node Found node (or null if not found) */ - public function getFoundNode() + public function getFoundNode() : ?Node { return $this->foundNode; } - public function beforeTraverse(array $nodes) + public function beforeTraverse(array $nodes) : ?array { $this->foundNode = null; return null; @@ -15602,7 +17370,7 @@ class FirstFindingVisitor extends NodeVisitorAbstract $filterCallback = $this->filterCallback; if ($filterCallback($node)) { $this->foundNode = $node; - return NodeTraverser::STOP_TRAVERSAL; + return NodeVisitor::STOP_TRAVERSAL; } return null; } @@ -15623,11 +17391,11 @@ use PHPUnit\PhpParser\NodeVisitorAbstract; class NameResolver extends NodeVisitorAbstract { /** @var NameContext Naming context */ - protected $nameContext; + protected NameContext $nameContext; /** @var bool Whether to preserve original names */ - protected $preserveOriginalNames; + protected bool $preserveOriginalNames; /** @var bool Whether to replace resolved nodes in place, or to add resolvedNode attributes */ - protected $replaceNodes; + protected bool $replaceNodes; /** * Constructs a name resolution visitor. * @@ -15639,9 +17407,9 @@ class NameResolver extends NodeVisitorAbstract * namespacedName attribute, as usual.) * * @param ErrorHandler|null $errorHandler Error handler - * @param array $options Options + * @param array{preserveOriginalNames?: bool, replaceNodes?: bool} $options Options */ - public function __construct(ErrorHandler $errorHandler = null, array $options = []) + public function __construct(?ErrorHandler $errorHandler = null, array $options = []) { $this->nameContext = new NameContext($errorHandler ?? new ErrorHandler\Throwing()); $this->preserveOriginalNames = $options['preserveOriginalNames'] ?? \false; @@ -15649,14 +17417,12 @@ class NameResolver extends NodeVisitorAbstract } /** * Get name resolution context. - * - * @return NameContext */ public function getNameContext() : NameContext { return $this->nameContext; } - public function beforeTraverse(array $nodes) + public function beforeTraverse(array $nodes) : ?array { $this->nameContext->startNamespace(); return null; @@ -15683,6 +17449,8 @@ class NameResolver extends NodeVisitorAbstract $this->resolveAttrGroups($node); if (null !== $node->name) { $this->addNamespacedName($node); + } else { + $node->namespacedName = null; } } elseif ($node instanceof Stmt\Interface_) { foreach ($node->extends as &$interface) { @@ -15695,9 +17463,7 @@ class NameResolver extends NodeVisitorAbstract $interface = $this->resolveClassName($interface); } $this->resolveAttrGroups($node); - if (null !== $node->name) { - $this->addNamespacedName($node); - } + $this->addNamespacedName($node); } elseif ($node instanceof Stmt\Trait_) { $this->resolveAttrGroups($node); $this->addNamespacedName($node); @@ -15717,46 +17483,46 @@ class NameResolver extends NodeVisitorAbstract foreach ($node->consts as $const) { $this->addNamespacedName($const); } - } else { - if ($node instanceof Stmt\ClassConst) { - $this->resolveAttrGroups($node); - } else { - if ($node instanceof Stmt\EnumCase) { - $this->resolveAttrGroups($node); - } elseif ($node instanceof Expr\StaticCall || $node instanceof Expr\StaticPropertyFetch || $node instanceof Expr\ClassConstFetch || $node instanceof Expr\New_ || $node instanceof Expr\Instanceof_) { - if ($node->class instanceof Name) { - $node->class = $this->resolveClassName($node->class); - } - } elseif ($node instanceof Stmt\Catch_) { - foreach ($node->types as &$type) { - $type = $this->resolveClassName($type); - } - } elseif ($node instanceof Expr\FuncCall) { - if ($node->name instanceof Name) { - $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_FUNCTION); - } - } elseif ($node instanceof Expr\ConstFetch) { - $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_CONSTANT); - } elseif ($node instanceof Stmt\TraitUse) { - foreach ($node->traits as &$trait) { - $trait = $this->resolveClassName($trait); - } - foreach ($node->adaptations as $adaptation) { - if (null !== $adaptation->trait) { - $adaptation->trait = $this->resolveClassName($adaptation->trait); - } - if ($adaptation instanceof Stmt\TraitUseAdaptation\Precedence) { - foreach ($adaptation->insteadof as &$insteadof) { - $insteadof = $this->resolveClassName($insteadof); - } - } + } elseif ($node instanceof Stmt\ClassConst) { + if (null !== $node->type) { + $node->type = $this->resolveType($node->type); + } + $this->resolveAttrGroups($node); + } elseif ($node instanceof Stmt\EnumCase) { + $this->resolveAttrGroups($node); + } elseif ($node instanceof Expr\StaticCall || $node instanceof Expr\StaticPropertyFetch || $node instanceof Expr\ClassConstFetch || $node instanceof Expr\New_ || $node instanceof Expr\Instanceof_) { + if ($node->class instanceof Name) { + $node->class = $this->resolveClassName($node->class); + } + } elseif ($node instanceof Stmt\Catch_) { + foreach ($node->types as &$type) { + $type = $this->resolveClassName($type); + } + } elseif ($node instanceof Expr\FuncCall) { + if ($node->name instanceof Name) { + $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_FUNCTION); + } + } elseif ($node instanceof Expr\ConstFetch) { + $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_CONSTANT); + } elseif ($node instanceof Stmt\TraitUse) { + foreach ($node->traits as &$trait) { + $trait = $this->resolveClassName($trait); + } + foreach ($node->adaptations as $adaptation) { + if (null !== $adaptation->trait) { + $adaptation->trait = $this->resolveClassName($adaptation->trait); + } + if ($adaptation instanceof Stmt\TraitUseAdaptation\Precedence) { + foreach ($adaptation->insteadof as &$insteadof) { + $insteadof = $this->resolveClassName($insteadof); } } } } return null; } - private function addAlias(Stmt\UseUse $use, int $type, Name $prefix = null) + /** @param Stmt\Use_::TYPE_* $type */ + private function addAlias(Node\UseItem $use, int $type, ?Name $prefix = null) : void { // Add prefix for group uses $name = $prefix ? Name::concat($prefix, $use->name) : $use->name; @@ -15764,8 +17530,8 @@ class NameResolver extends NodeVisitorAbstract $type |= $use->type; $this->nameContext->addAlias($name, (string) $use->getAlias(), $type, $use->getAttributes()); } - /** @param Stmt\Function_|Stmt\ClassMethod|Expr\Closure $node */ - private function resolveSignature($node) + /** @param Stmt\Function_|Stmt\ClassMethod|Expr\Closure|Expr\ArrowFunction $node */ + private function resolveSignature($node) : void { foreach ($node->params as $param) { $param->type = $this->resolveType($param->type); @@ -15773,7 +17539,12 @@ class NameResolver extends NodeVisitorAbstract } $node->returnType = $this->resolveType($node->returnType); } - private function resolveType($node) + /** + * @template T of Node\Identifier|Name|Node\ComplexType|null + * @param T $node + * @return T + */ + private function resolveType(?Node $node) : ?Node { if ($node instanceof Name) { return $this->resolveClassName($node); @@ -15794,7 +17565,7 @@ class NameResolver extends NodeVisitorAbstract * Resolve name, according to name resolver options. * * @param Name $name Function or constant name to resolve - * @param int $type One of Stmt\Use_::TYPE_* + * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_* * * @return Name Resolved name, or original name with attribute */ @@ -15824,15 +17595,15 @@ class NameResolver extends NodeVisitorAbstract $name->setAttribute('namespacedName', FullyQualified::concat($this->nameContext->getNamespace(), $name, $name->getAttributes())); return $name; } - protected function resolveClassName(Name $name) + protected function resolveClassName(Name $name) : Name { return $this->resolveName($name, Stmt\Use_::TYPE_NORMAL); } - protected function addNamespacedName(Node $node) + protected function addNamespacedName(Node $node) : void { $node->namespacedName = Name::concat($this->nameContext->getNamespace(), (string) $node->name); } - protected function resolveAttrGroups(Node $node) + protected function resolveAttrGroups(Node $node) : void { foreach ($node->attrGroups as $attrGroup) { foreach ($attrGroup->attrs as $attr) { @@ -15862,7 +17633,7 @@ final class NodeConnectingVisitor extends NodeVisitorAbstract /** * @var Node[] */ - private $stack = []; + private array $stack = []; /** * @var ?Node */ @@ -15894,10 +17665,10 @@ final class NodeConnectingVisitor extends NodeVisitorAbstract declare (strict_types=1); namespace PHPUnit\PhpParser\NodeVisitor; -use function array_pop; -use function count; use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\NodeVisitorAbstract; +use function array_pop; +use function count; /** * Visitor that connects a child node to its parent node. * @@ -15909,7 +17680,7 @@ final class ParentConnectingVisitor extends NodeVisitorAbstract /** * @var Node[] */ - private $stack = []; + private array $stack = []; public function beforeTraverse(array $nodes) { $this->stack = []; @@ -15934,7 +17705,7 @@ namespace PHPUnit\PhpParser; /** * @codeCoverageIgnore */ -class NodeVisitorAbstract implements NodeVisitor +abstract class NodeVisitorAbstract implements NodeVisitor { public function beforeTraverse(array $nodes) { @@ -15970,66 +17741,21 @@ interface Parser * @return Node\Stmt[]|null Array of statements (or null non-throwing error handler is used and * the parser was unable to recover from an error). */ - public function parse(string $code, ErrorHandler $errorHandler = null); -} -parsers = $parsers; - } - public function parse(string $code, ErrorHandler $errorHandler = null) - { - if (null === $errorHandler) { - $errorHandler = new ErrorHandler\Throwing(); - } - list($firstStmts, $firstError) = $this->tryParse($this->parsers[0], $errorHandler, $code); - if ($firstError === null) { - return $firstStmts; - } - for ($i = 1, $c = \count($this->parsers); $i < $c; ++$i) { - list($stmts, $error) = $this->tryParse($this->parsers[$i], $errorHandler, $code); - if ($error === null) { - return $stmts; - } - } - throw $firstError; - } - private function tryParse(Parser $parser, ErrorHandler $errorHandler, $code) - { - $stmts = null; - $error = null; - try { - $stmts = $parser->parse($code, $errorHandler); - } catch (Error $error) { - } - return [$stmts, $error]; - } + public function getTokens() : array; } '", "T_IS_GREATER_OR_EQUAL", "T_SL", "T_SR", "'+'", "'-'", "'.'", "'*'", "'/'", "'%'", "'!'", "T_INSTANCEOF", "'~'", "T_INC", "T_DEC", "T_INT_CAST", "T_DOUBLE_CAST", "T_STRING_CAST", "T_ARRAY_CAST", "T_OBJECT_CAST", "T_BOOL_CAST", "T_UNSET_CAST", "'@'", "T_POW", "'['", "T_NEW", "T_CLONE", "T_EXIT", "T_IF", "T_ELSEIF", "T_ELSE", "T_ENDIF", "T_LNUMBER", "T_DNUMBER", "T_STRING", "T_STRING_VARNAME", "T_VARIABLE", "T_NUM_STRING", "T_INLINE_HTML", "T_ENCAPSED_AND_WHITESPACE", "T_CONSTANT_ENCAPSED_STRING", "T_ECHO", "T_DO", "T_WHILE", "T_ENDWHILE", "T_FOR", "T_ENDFOR", "T_FOREACH", "T_ENDFOREACH", "T_DECLARE", "T_ENDDECLARE", "T_AS", "T_SWITCH", "T_MATCH", "T_ENDSWITCH", "T_CASE", "T_DEFAULT", "T_BREAK", "T_CONTINUE", "T_GOTO", "T_FUNCTION", "T_FN", "T_CONST", "T_RETURN", "T_TRY", "T_CATCH", "T_FINALLY", "T_USE", "T_INSTEADOF", "T_GLOBAL", "T_STATIC", "T_ABSTRACT", "T_FINAL", "T_PRIVATE", "T_PROTECTED", "T_PUBLIC", "T_READONLY", "T_VAR", "T_UNSET", "T_ISSET", "T_EMPTY", "T_HALT_COMPILER", "T_CLASS", "T_TRAIT", "T_INTERFACE", "T_EXTENDS", "T_IMPLEMENTS", "T_OBJECT_OPERATOR", "T_LIST", "T_ARRAY", "T_CALLABLE", "T_CLASS_C", "T_TRAIT_C", "T_METHOD_C", "T_FUNC_C", "T_LINE", "T_FILE", "T_START_HEREDOC", "T_END_HEREDOC", "T_DOLLAR_OPEN_CURLY_BRACES", "T_CURLY_OPEN", "T_PAAMAYIM_NEKUDOTAYIM", "T_NAMESPACE", "T_NS_C", "T_DIR", "T_NS_SEPARATOR", "T_ELLIPSIS", "T_NAME_FULLY_QUALIFIED", "T_NAME_QUALIFIED", "T_NAME_RELATIVE", "';'", "'{'", "'}'", "'('", "')'", "'\$'", "'`'", "']'", "'\"'", "T_ENUM", "T_NULLSAFE_OBJECT_OPERATOR", "T_ATTRIBUTE"); - protected $tokenToSymbol = array(0, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 56, 164, 168, 161, 55, 168, 168, 159, 160, 53, 50, 8, 51, 52, 54, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 31, 156, 44, 16, 46, 30, 68, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 70, 168, 163, 36, 168, 162, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 157, 35, 158, 58, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43, 45, 47, 48, 49, 57, 59, 60, 61, 62, 63, 64, 65, 66, 67, 69, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 165, 131, 132, 133, 166, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 167); - protected $action = array(700, 670, 671, 672, 673, 674, 286, 675, 676, 677, 713, 714, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 0, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32767, -32767, -32767, -32767, 245, 246, 242, 243, 244, -32766, -32766, 678, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, 1229, 245, 246, 1230, 679, 680, 681, 682, 683, 684, 685, 899, 900, 747, -32766, -32766, -32766, -32766, -32766, -32766, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 716, 739, 717, 718, 719, 720, 708, 709, 710, 738, 711, 712, 697, 698, 699, 701, 702, 703, 741, 742, 743, 744, 745, 746, 875, 704, 705, 706, 707, 737, 728, 726, 727, 723, 724, 1046, 715, 721, 722, 729, 730, 732, 731, 733, 734, 55, 56, 425, 57, 58, 725, 736, 735, 755, 59, 60, -226, 61, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, 337, -32767, -32767, -32767, -32767, 29, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 620, -32766, -32766, -32766, -32766, 62, 63, 1046, -32766, -32766, -32766, 64, 419, 65, 294, 295, 66, 67, 68, 69, 70, 71, 72, 73, 823, 25, 302, 74, 418, 984, 986, 669, 668, 1100, 1101, 1078, 755, 755, 767, 1220, 768, 470, -32766, -32766, -32766, 341, 749, 824, 54, -32767, -32767, -32767, -32767, 98, 99, 100, 101, 102, 220, 221, 222, 362, 876, -32766, 27, -32766, -32766, -32766, -32766, -32766, 1046, 493, 126, 1080, 1079, 1081, 370, 1068, 930, 207, 478, 479, 952, 953, 954, 951, 950, 949, 128, 480, 481, 803, 1106, 1107, 1108, 1109, 1103, 1104, 319, 32, 297, 10, 211, -515, 1110, 1105, 669, 668, 1080, 1079, 1081, 220, 221, 222, 41, 364, 341, 334, 421, 336, 426, -128, -128, -128, 313, 1046, 469, -4, 824, 54, 812, 770, 207, 40, 21, 427, -128, 471, -128, 472, -128, 473, -128, 1046, 428, 220, 221, 222, -32766, 33, 34, 429, 361, 327, 52, 35, 474, -32766, -32766, -32766, 342, 357, 358, 475, 476, 48, 207, 249, 669, 668, 477, 443, 300, 795, 846, 430, 431, 28, -32766, 814, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32767, -32767, -32767, -32767, -32767, 952, 953, 954, 951, 950, 949, 422, 755, 424, 426, 826, 634, -128, -32766, -32766, 469, 824, 54, 288, 812, 1151, 755, 40, 21, 427, 317, 471, 345, 472, 129, 473, 9, 1186, 428, 769, 360, 324, 905, 33, 34, 429, 361, 1046, 415, 35, 474, 944, 1068, 315, 125, 357, 358, 475, 476, -32766, -32766, -32766, 926, 302, 477, 121, 1068, 759, 846, 430, 431, 669, 668, 423, 755, 1152, 809, 1046, 480, 766, -32766, 805, -32766, -32766, -32766, -32766, -261, 127, 347, 436, 841, 341, 1078, 1200, 426, 446, 826, 634, -4, 807, 469, 824, 54, 436, 812, 341, 755, 40, 21, 427, 444, 471, 130, 472, 1068, 473, 346, 767, 428, 768, -211, -211, -211, 33, 34, 429, 361, 308, 1076, 35, 474, -32766, -32766, -32766, 1046, 357, 358, 475, 476, -32766, -32766, -32766, 906, 120, 477, 539, 1068, 795, 846, 430, 431, 436, -32766, 341, -32766, -32766, -32766, 1046, 480, 810, -32766, 925, -32766, -32766, 754, 1080, 1079, 1081, 49, -32766, -32766, -32766, 749, 751, 426, 1201, 826, 634, -211, 30, 469, 669, 668, 436, 812, 341, 75, 40, 21, 427, -32766, 471, 1064, 472, 124, 473, 669, 668, 428, 212, -210, -210, -210, 33, 34, 429, 361, 51, 1186, 35, 474, 755, -32766, -32766, -32766, 357, 358, 475, 476, 213, 824, 54, 221, 222, 477, 20, 581, 795, 846, 430, 431, 220, 221, 222, 755, 222, 247, 78, 79, 80, 81, 341, 207, 517, 103, 104, 105, 752, 307, 131, 637, 1068, 207, 341, 207, 122, 826, 634, -210, 36, 106, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 1112, 307, 346, 436, 214, 341, 824, 54, 426, 123, 250, 129, 134, 106, 469, -32766, 572, 1112, 812, 245, 246, 40, 21, 427, 251, 471, 252, 472, 341, 473, 453, 22, 428, 207, 899, 900, 638, 33, 34, 429, 824, 54, -86, 35, 474, 220, 221, 222, 314, 357, 358, 100, 101, 102, 239, 240, 241, 645, 477, -230, 458, 589, 135, 374, 596, 597, 207, 760, 640, 648, 642, 941, 654, 929, 662, 822, 133, 307, 837, 426, -32766, 106, 749, 43, 44, 469, 45, 442, 46, 812, 826, 634, 40, 21, 427, 47, 471, 50, 472, 53, 473, 132, 608, 428, 302, 604, -280, -32766, 33, 34, 429, 824, 54, 426, 35, 474, 755, 957, -84, 469, 357, 358, 521, 812, 628, 363, 40, 21, 427, 477, 471, 575, 472, -515, 473, 847, 616, 428, -423, -32766, 11, 646, 33, 34, 429, 824, 54, 445, 35, 474, 462, 285, 578, 1111, 357, 358, 593, 369, 848, 594, 290, 826, 634, 477, 0, 0, 532, 0, 0, 325, 0, 0, 0, 0, 0, 651, 0, 0, 0, 322, 326, 0, 0, 0, 426, 0, 0, 0, 0, 323, 469, 316, 318, -516, 812, 862, 634, 40, 21, 427, 0, 471, 0, 472, 0, 473, 1158, 0, 428, 0, -414, 6, 7, 33, 34, 429, 824, 54, 426, 35, 474, 12, 14, 373, 469, 357, 358, -424, 812, 563, 754, 40, 21, 427, 477, 471, 248, 472, 839, 473, 38, 39, 428, 657, 658, 765, 813, 33, 34, 429, 821, 800, 815, 35, 474, 215, 216, 878, 869, 357, 358, 217, 870, 218, 798, 863, 826, 634, 477, 860, 858, 936, 937, 934, 820, 209, 804, 806, 808, 811, 933, 763, 764, 1100, 1101, 935, 659, 78, 335, 426, 359, 1102, 635, 639, 641, 469, 643, 644, 647, 812, 826, 634, 40, 21, 427, 649, 471, 650, 472, 652, 473, 653, 636, 428, 796, 1226, 1228, 762, 33, 34, 429, 215, 216, 845, 35, 474, 761, 217, 844, 218, 357, 358, 1227, 843, 1060, 831, 1048, 842, 1049, 477, 559, 209, 1106, 1107, 1108, 1109, 1103, 1104, 398, 1100, 1101, 829, 942, 867, 1110, 1105, 868, 1102, 457, 1225, 1194, 1192, 1177, 1157, 219, 1190, 1091, 917, 1198, 1188, 0, 826, 634, 24, -433, 26, 31, 37, 42, 76, 77, 210, 287, 292, 293, 308, 309, 310, 311, 339, 356, 416, 0, -227, -226, 16, 17, 18, 393, 454, 461, 463, 467, 553, 625, 1051, 559, 1054, 1106, 1107, 1108, 1109, 1103, 1104, 398, 907, 1116, 1050, 1026, 564, 1110, 1105, 1025, 1093, 1055, 0, 1044, 0, 1057, 1056, 219, 1059, 1058, 1075, 0, 1191, 1176, 1172, 1189, 1090, 1223, 1117, 1171, 600); - protected $actionCheck = array(2, 3, 4, 5, 6, 7, 14, 9, 10, 11, 12, 13, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 0, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 9, 10, 11, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 69, 70, 53, 54, 55, 9, 10, 57, 30, 116, 32, 33, 34, 35, 36, 37, 38, 80, 69, 70, 83, 71, 72, 73, 74, 75, 76, 77, 135, 136, 80, 33, 34, 35, 36, 37, 38, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 31, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 13, 134, 135, 136, 137, 138, 139, 140, 141, 142, 3, 4, 5, 6, 7, 148, 149, 150, 82, 12, 13, 160, 15, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 8, 44, 45, 46, 47, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 80, 33, 34, 35, 36, 50, 51, 13, 9, 10, 11, 56, 128, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 1, 70, 71, 72, 73, 59, 60, 37, 38, 78, 79, 80, 82, 82, 106, 85, 108, 86, 9, 10, 11, 161, 80, 1, 2, 44, 45, 46, 47, 48, 49, 50, 51, 52, 9, 10, 11, 106, 156, 30, 8, 32, 33, 34, 35, 36, 13, 116, 8, 153, 154, 155, 8, 122, 158, 30, 125, 126, 116, 117, 118, 119, 120, 121, 31, 134, 135, 156, 137, 138, 139, 140, 141, 142, 143, 145, 146, 8, 8, 133, 149, 150, 37, 38, 153, 154, 155, 9, 10, 11, 159, 8, 161, 162, 8, 164, 74, 75, 76, 77, 8, 13, 80, 0, 1, 2, 84, 158, 30, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 13, 98, 9, 10, 11, 9, 103, 104, 105, 106, 8, 70, 109, 110, 9, 10, 11, 8, 115, 116, 117, 118, 70, 30, 31, 37, 38, 124, 31, 8, 127, 128, 129, 130, 8, 30, 156, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 116, 117, 118, 119, 120, 121, 8, 82, 8, 74, 156, 157, 158, 33, 34, 80, 1, 2, 8, 84, 163, 82, 87, 88, 89, 133, 91, 70, 93, 152, 95, 108, 82, 98, 158, 8, 113, 160, 103, 104, 105, 106, 13, 108, 109, 110, 123, 122, 113, 157, 115, 116, 117, 118, 9, 10, 11, 156, 71, 124, 157, 122, 127, 128, 129, 130, 37, 38, 8, 82, 160, 156, 13, 134, 156, 30, 156, 32, 33, 34, 35, 158, 157, 148, 159, 122, 161, 80, 1, 74, 133, 156, 157, 158, 156, 80, 1, 2, 159, 84, 161, 82, 87, 88, 89, 157, 91, 157, 93, 122, 95, 161, 106, 98, 108, 100, 101, 102, 103, 104, 105, 106, 159, 116, 109, 110, 9, 10, 11, 13, 115, 116, 117, 118, 9, 10, 11, 160, 16, 124, 81, 122, 127, 128, 129, 130, 159, 30, 161, 32, 33, 34, 13, 134, 156, 30, 156, 32, 33, 153, 153, 154, 155, 70, 9, 10, 11, 80, 80, 74, 160, 156, 157, 158, 14, 80, 37, 38, 159, 84, 161, 152, 87, 88, 89, 30, 91, 160, 93, 14, 95, 37, 38, 98, 16, 100, 101, 102, 103, 104, 105, 106, 70, 82, 109, 110, 82, 33, 34, 35, 115, 116, 117, 118, 16, 1, 2, 10, 11, 124, 160, 85, 127, 128, 129, 130, 9, 10, 11, 82, 11, 14, 157, 9, 10, 11, 161, 30, 85, 53, 54, 55, 154, 57, 157, 31, 122, 30, 161, 30, 157, 156, 157, 158, 30, 69, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 144, 57, 161, 159, 16, 161, 1, 2, 74, 157, 16, 152, 157, 69, 80, 116, 161, 144, 84, 69, 70, 87, 88, 89, 16, 91, 16, 93, 161, 95, 75, 76, 98, 30, 135, 136, 31, 103, 104, 105, 1, 2, 31, 109, 110, 9, 10, 11, 31, 115, 116, 50, 51, 52, 50, 51, 52, 31, 124, 160, 75, 76, 101, 102, 111, 112, 30, 156, 157, 31, 31, 156, 157, 156, 157, 31, 31, 57, 38, 74, 33, 69, 80, 70, 70, 80, 70, 89, 70, 84, 156, 157, 87, 88, 89, 70, 91, 70, 93, 70, 95, 70, 96, 98, 71, 77, 82, 85, 103, 104, 105, 1, 2, 74, 109, 110, 82, 82, 97, 80, 115, 116, 85, 84, 92, 106, 87, 88, 89, 124, 91, 90, 93, 133, 95, 128, 94, 98, 147, 116, 97, 31, 103, 104, 105, 1, 2, 97, 109, 110, 97, 97, 100, 144, 115, 116, 100, 106, 128, 113, 161, 156, 157, 124, -1, -1, 151, -1, -1, 114, -1, -1, -1, -1, -1, 31, -1, -1, -1, 131, 131, -1, -1, -1, 74, -1, -1, -1, -1, 132, 80, 133, 133, 133, 84, 156, 157, 87, 88, 89, -1, 91, -1, 93, -1, 95, 144, -1, 98, -1, 147, 147, 147, 103, 104, 105, 1, 2, 74, 109, 110, 147, 147, 147, 80, 115, 116, 147, 84, 151, 153, 87, 88, 89, 124, 91, 31, 93, 152, 95, 156, 156, 98, 156, 156, 156, 156, 103, 104, 105, 156, 156, 156, 109, 110, 50, 51, 156, 156, 115, 116, 56, 156, 58, 156, 156, 156, 157, 124, 156, 156, 156, 156, 156, 156, 70, 156, 156, 156, 156, 156, 156, 156, 78, 79, 156, 158, 157, 157, 74, 157, 86, 157, 157, 157, 80, 157, 157, 157, 84, 156, 157, 87, 88, 89, 157, 91, 157, 93, 157, 95, 157, 157, 98, 158, 158, 158, 158, 103, 104, 105, 50, 51, 158, 109, 110, 158, 56, 158, 58, 115, 116, 158, 158, 158, 158, 158, 158, 158, 124, 135, 70, 137, 138, 139, 140, 141, 142, 143, 78, 79, 158, 158, 158, 149, 150, 158, 86, 158, 158, 158, 158, 158, 164, 159, 158, 158, 158, 158, 158, -1, 156, 157, 159, 162, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, -1, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 135, 160, 137, 138, 139, 140, 141, 142, 143, 160, 160, 160, 160, 160, 149, 150, 160, 160, 163, -1, 162, -1, 163, 163, 159, 163, 163, 163, -1, 163, 163, 163, 163, 163, 163, 163, 163, 163); - protected $actionBase = array(0, 229, 310, 390, 470, 103, 325, 325, 784, -2, -2, 149, -2, -2, -2, 660, 765, 799, 765, 589, 694, 870, 870, 870, 252, 404, 404, 404, 514, 177, 177, 918, 434, 118, 295, 313, 240, 491, 491, 491, 491, 138, 138, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 89, 206, 773, 550, 535, 775, 776, 777, 912, 709, 913, 856, 857, 700, 858, 859, 862, 863, 864, 855, 865, 935, 866, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 322, 592, 285, 319, 232, 44, 691, 691, 691, 691, 691, 691, 691, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 582, 530, 530, 530, 594, 860, 658, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 500, -21, -21, 492, 702, 420, 355, 216, 549, 151, 26, 26, 331, 331, 331, 331, 331, 46, 46, 5, 5, 5, 5, 153, 188, 188, 188, 188, 121, 121, 121, 121, 314, 314, 394, 394, 362, 300, 298, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 67, 656, 656, 659, 659, 522, 554, 554, 554, 554, 679, -59, -59, 381, 462, 462, 462, 528, 717, 854, 382, 382, 382, 382, 382, 382, 561, 561, 561, -3, -3, -3, 692, 115, 137, 115, 137, 678, 732, 450, 732, 338, 677, -15, 510, 810, 468, 707, 850, 711, 853, 572, 735, 267, 529, 654, 674, 463, 529, 529, 529, 529, 654, 610, 640, 608, 463, 529, 463, 718, 323, 496, 89, 570, 507, 675, 778, 293, 670, 780, 290, 373, 332, 566, 278, 435, 733, 781, 914, 917, 385, 715, 675, 675, 675, 352, 511, 278, -8, 605, 605, 605, 605, 156, 605, 605, 605, 605, 251, 276, 375, 402, 779, 657, 657, 690, 872, 869, 869, 657, 689, 657, 690, 874, 874, 874, 874, 657, 657, 657, 657, 869, 869, 869, 688, 869, 239, 703, 704, 704, 874, 742, 743, 657, 657, 712, 869, 869, 869, 712, 695, 874, 701, 741, 277, 869, 874, 672, 689, 672, 657, 701, 672, 689, 689, 672, 22, 666, 668, 873, 875, 887, 790, 662, 685, 879, 880, 876, 878, 871, 699, 744, 745, 497, 669, 671, 673, 680, 719, 682, 713, 674, 667, 667, 667, 655, 720, 655, 667, 667, 667, 667, 667, 667, 667, 667, 916, 646, 731, 714, 653, 749, 553, 573, 791, 664, 811, 900, 893, 867, 919, 881, 898, 655, 920, 739, 247, 643, 882, 783, 786, 655, 883, 655, 792, 655, 902, 812, 686, 813, 814, 667, 910, 921, 923, 924, 925, 927, 928, 929, 930, 684, 931, 750, 696, 894, 299, 877, 718, 729, 705, 788, 751, 820, 328, 932, 823, 655, 655, 794, 785, 655, 795, 756, 740, 890, 757, 895, 933, 664, 708, 896, 655, 706, 825, 934, 328, 681, 683, 888, 661, 761, 886, 911, 885, 796, 649, 663, 829, 830, 831, 693, 763, 891, 892, 889, 764, 803, 665, 805, 697, 832, 807, 884, 768, 833, 834, 899, 676, 730, 710, 698, 687, 809, 835, 897, 769, 770, 771, 848, 772, 849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 138, 138, 138, -2, -2, -2, -2, 0, 0, -2, 0, 0, 0, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 0, 0, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 599, -21, -21, -21, -21, 599, -21, -21, -21, -21, -21, -21, -21, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, -21, 599, 599, 599, -21, 382, -21, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 599, 0, 0, 599, -21, 599, -21, 599, -21, -21, 599, 599, 599, 599, 599, 599, 599, -21, -21, -21, -21, -21, -21, 0, 561, 561, 561, 561, -21, -21, -21, -21, 382, 382, 382, 382, 382, 382, 259, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 561, 561, -3, -3, 382, 382, 382, 382, 382, 259, 382, 382, 463, 689, 689, 689, 137, 137, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, 463, 0, 463, 0, 382, 463, 689, 463, 657, 137, 689, 689, 463, 869, 616, 616, 616, 616, 328, 278, 0, 0, 689, 689, 0, 0, 0, 0, 0, 689, 0, 0, 0, 0, 0, 0, 869, 0, 0, 0, 0, 0, 667, 247, 0, 705, 335, 0, 0, 0, 0, 0, 0, 705, 335, 347, 347, 0, 684, 667, 667, 667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 328); - protected $actionDefault = array(3, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 544, 544, 499, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 299, 299, 299, 32767, 32767, 32767, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 32767, 32767, 32767, 32767, 32767, 32767, 383, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 389, 549, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 364, 365, 367, 368, 298, 552, 533, 247, 390, 548, 297, 249, 327, 503, 32767, 32767, 32767, 329, 122, 258, 203, 502, 125, 296, 234, 382, 384, 328, 303, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 302, 458, 361, 360, 359, 460, 32767, 459, 496, 496, 499, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 325, 487, 486, 326, 456, 330, 457, 333, 461, 464, 331, 332, 349, 350, 347, 348, 351, 462, 463, 480, 481, 478, 479, 301, 352, 353, 354, 355, 482, 483, 484, 485, 32767, 32767, 543, 543, 32767, 32767, 282, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 340, 341, 471, 472, 32767, 238, 238, 238, 238, 283, 238, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 335, 336, 334, 466, 467, 465, 432, 32767, 32767, 32767, 434, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 504, 32767, 32767, 32767, 32767, 32767, 517, 421, 171, 32767, 413, 32767, 171, 171, 171, 171, 32767, 222, 224, 167, 32767, 171, 32767, 490, 32767, 32767, 32767, 32767, 522, 345, 32767, 32767, 116, 32767, 32767, 32767, 559, 32767, 517, 32767, 116, 32767, 32767, 32767, 32767, 358, 337, 338, 339, 32767, 32767, 521, 515, 474, 475, 476, 477, 32767, 468, 469, 470, 473, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 429, 435, 435, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 520, 519, 32767, 414, 498, 188, 186, 186, 32767, 208, 208, 32767, 32767, 190, 491, 510, 32767, 190, 173, 32767, 400, 175, 498, 32767, 32767, 240, 32767, 240, 32767, 400, 240, 32767, 32767, 240, 32767, 415, 439, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 379, 380, 493, 506, 32767, 507, 32767, 413, 343, 344, 346, 322, 32767, 324, 369, 370, 371, 372, 373, 374, 375, 377, 32767, 419, 32767, 422, 32767, 32767, 32767, 257, 32767, 557, 32767, 32767, 306, 557, 32767, 32767, 32767, 551, 32767, 32767, 300, 32767, 32767, 32767, 32767, 253, 32767, 169, 32767, 541, 32767, 558, 32767, 515, 32767, 342, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 516, 32767, 32767, 32767, 32767, 229, 32767, 452, 32767, 116, 32767, 32767, 32767, 189, 32767, 32767, 304, 248, 32767, 32767, 550, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 114, 32767, 170, 32767, 32767, 32767, 191, 32767, 32767, 515, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 295, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 515, 32767, 32767, 233, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 415, 32767, 276, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 127, 127, 3, 127, 127, 260, 3, 260, 127, 260, 260, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 216, 219, 208, 208, 164, 127, 127, 268); - protected $goto = array(166, 140, 140, 140, 166, 187, 168, 144, 147, 141, 142, 143, 149, 163, 163, 163, 163, 144, 144, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 138, 159, 160, 161, 162, 184, 139, 185, 494, 495, 377, 496, 500, 501, 502, 503, 504, 505, 506, 507, 970, 164, 145, 146, 148, 171, 176, 186, 203, 253, 256, 258, 260, 263, 264, 265, 266, 267, 268, 269, 277, 278, 279, 280, 303, 304, 328, 329, 330, 394, 395, 396, 543, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 150, 151, 152, 167, 153, 169, 154, 204, 170, 155, 156, 157, 205, 158, 136, 621, 561, 757, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 1113, 629, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 758, 520, 531, 509, 656, 556, 1183, 750, 509, 592, 786, 1183, 888, 612, 613, 884, 617, 618, 624, 626, 631, 633, 817, 855, 855, 855, 855, 850, 856, 174, 891, 891, 1205, 1205, 177, 178, 179, 401, 402, 403, 404, 173, 202, 206, 208, 257, 259, 261, 262, 270, 271, 272, 273, 274, 275, 281, 282, 283, 284, 305, 306, 331, 332, 333, 406, 407, 408, 409, 175, 180, 254, 255, 181, 182, 183, 498, 498, 498, 498, 498, 498, 861, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 510, 586, 538, 601, 602, 510, 545, 546, 547, 548, 549, 550, 551, 552, 554, 587, 1209, 560, 350, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 400, 607, 537, 537, 569, 533, 909, 535, 535, 497, 499, 525, 541, 570, 573, 584, 591, 298, 296, 296, 296, 298, 289, 299, 611, 378, 511, 614, 595, 947, 375, 511, 437, 437, 437, 437, 437, 437, 1163, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 1077, 948, 338, 1175, 321, 1077, 898, 898, 898, 898, 606, 898, 898, 1217, 1217, 1202, 753, 576, 605, 756, 1077, 1077, 1077, 1077, 1077, 1077, 1069, 384, 384, 384, 391, 1217, 877, 859, 857, 859, 655, 466, 512, 886, 881, 753, 384, 753, 384, 968, 384, 895, 385, 588, 353, 414, 384, 1231, 1019, 542, 1197, 1197, 1197, 568, 1094, 386, 386, 386, 904, 915, 515, 1029, 19, 15, 372, 389, 915, 940, 448, 450, 632, 340, 1216, 1216, 1114, 615, 938, 840, 555, 775, 386, 913, 1070, 1073, 1074, 399, 1069, 1182, 660, 23, 1216, 773, 1182, 544, 603, 1066, 1219, 1071, 1174, 1071, 519, 1199, 1199, 1199, 1089, 1088, 1072, 343, 523, 534, 519, 519, 772, 351, 352, 13, 579, 583, 627, 1061, 388, 782, 562, 771, 515, 783, 1181, 3, 4, 918, 956, 865, 451, 574, 1160, 464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 514, 529, 0, 0, 0, 0, 514, 0, 529, 0, 0, 0, 0, 610, 513, 516, 439, 440, 1067, 619, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 780, 1224, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 778, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 301, 301); - protected $gotoCheck = array(43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 57, 69, 15, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 128, 9, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 16, 102, 32, 69, 32, 32, 120, 6, 69, 32, 29, 120, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 50, 69, 69, 69, 69, 69, 69, 27, 77, 77, 77, 77, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 119, 119, 119, 119, 119, 119, 33, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 67, 110, 67, 67, 119, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 142, 57, 72, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 51, 51, 51, 51, 51, 51, 84, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 5, 5, 5, 5, 5, 5, 5, 63, 46, 124, 63, 129, 98, 63, 124, 57, 57, 57, 57, 57, 57, 133, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 98, 127, 82, 127, 57, 57, 57, 57, 57, 49, 57, 57, 144, 144, 140, 11, 40, 40, 14, 57, 57, 57, 57, 57, 57, 82, 13, 13, 13, 48, 144, 14, 14, 14, 14, 14, 57, 14, 14, 14, 11, 13, 11, 13, 102, 13, 79, 11, 70, 70, 70, 13, 13, 103, 2, 9, 9, 9, 2, 34, 125, 125, 125, 81, 13, 13, 34, 34, 34, 34, 17, 13, 8, 8, 8, 8, 18, 143, 143, 8, 8, 8, 9, 34, 25, 125, 85, 82, 82, 82, 125, 82, 121, 74, 34, 143, 24, 121, 47, 34, 116, 143, 82, 82, 82, 47, 121, 121, 121, 126, 126, 82, 58, 58, 58, 47, 47, 23, 72, 72, 58, 62, 62, 62, 114, 12, 23, 12, 23, 13, 26, 121, 30, 30, 86, 100, 71, 65, 66, 132, 109, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 9, -1, -1, -1, -1, 9, -1, 9, -1, -1, -1, -1, 13, 9, 9, 9, 9, 13, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 9, -1, -1, -1, -1, -1, 102, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 5); - protected $gotoBase = array(0, 0, -172, 0, 0, 353, 201, 0, 477, 149, 0, 110, 195, 117, 426, 112, 203, 140, 171, 0, 0, 0, 0, 168, 164, 157, 119, 27, 0, 205, -118, 0, -428, 266, 51, 0, 0, 0, 0, 0, 388, 0, 0, -24, 0, 0, 345, 484, 146, 133, 209, 75, 0, 0, 0, 0, 0, 107, 161, 0, 0, 0, 222, -77, 0, 106, 97, -343, 0, -94, 135, 123, -129, 0, 129, 0, 0, -50, 0, 143, 0, 159, 64, 0, 338, 132, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 0, 121, 0, 165, 156, 0, 0, 0, 0, 0, 87, 273, 259, 0, 0, 114, 0, 150, 0, 0, -5, -91, 200, 0, 0, 84, 154, 202, 77, -48, 178, 0, 0, 93, 187, 0, 0, 0, 0, 0, 0, 136, 0, 286, 167, 102, 0, 0); - protected $gotoDefault = array(-32768, 468, 664, 2, 665, 835, 740, 748, 598, 482, 630, 582, 380, 1193, 792, 793, 794, 381, 368, 483, 379, 410, 405, 781, 774, 776, 784, 172, 411, 787, 1, 789, 518, 825, 1020, 365, 797, 366, 590, 799, 527, 801, 802, 137, 382, 383, 528, 484, 390, 577, 816, 276, 387, 818, 367, 819, 828, 371, 465, 455, 460, 530, 557, 609, 432, 447, 571, 565, 536, 1086, 566, 864, 349, 872, 661, 880, 883, 485, 558, 894, 452, 902, 1099, 397, 908, 914, 919, 291, 922, 417, 412, 585, 927, 928, 5, 932, 622, 623, 8, 312, 955, 599, 969, 420, 1039, 1041, 486, 487, 522, 459, 508, 526, 488, 1062, 441, 413, 1065, 433, 489, 490, 434, 435, 1083, 355, 1168, 354, 449, 320, 1155, 580, 1118, 456, 1208, 1164, 348, 491, 492, 376, 1187, 392, 1203, 438, 1210, 1218, 344, 540, 567); - protected $ruleToNonTerminal = array(0, 1, 3, 3, 2, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 9, 10, 11, 11, 12, 12, 13, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 18, 18, 19, 19, 21, 21, 17, 17, 22, 22, 23, 23, 24, 24, 25, 25, 20, 20, 26, 28, 28, 29, 30, 30, 32, 31, 31, 31, 31, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 14, 14, 54, 54, 56, 55, 55, 48, 48, 58, 58, 59, 59, 60, 60, 61, 61, 15, 16, 16, 16, 64, 64, 64, 65, 65, 68, 68, 66, 66, 70, 70, 41, 41, 50, 50, 53, 53, 53, 52, 52, 71, 42, 42, 42, 42, 72, 72, 73, 73, 74, 74, 39, 39, 35, 35, 75, 37, 37, 76, 36, 36, 38, 38, 49, 49, 49, 62, 62, 78, 78, 79, 79, 81, 81, 81, 80, 80, 63, 63, 82, 82, 82, 83, 83, 84, 84, 84, 44, 44, 85, 85, 85, 45, 45, 86, 86, 87, 87, 67, 88, 88, 88, 88, 93, 93, 94, 94, 95, 95, 95, 95, 95, 96, 97, 97, 92, 92, 89, 89, 91, 91, 99, 99, 98, 98, 98, 98, 98, 98, 90, 90, 101, 100, 100, 46, 46, 40, 40, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 34, 34, 47, 47, 106, 106, 107, 107, 107, 107, 113, 102, 102, 109, 109, 115, 115, 116, 117, 118, 118, 118, 118, 118, 118, 118, 69, 69, 57, 57, 57, 57, 103, 103, 122, 122, 119, 119, 123, 123, 123, 123, 104, 104, 104, 108, 108, 108, 114, 114, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 27, 27, 27, 27, 27, 27, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 112, 112, 105, 105, 105, 105, 129, 129, 132, 132, 131, 131, 133, 133, 51, 51, 51, 51, 135, 135, 134, 134, 134, 134, 134, 136, 136, 121, 121, 124, 124, 120, 120, 138, 137, 137, 137, 137, 125, 125, 125, 125, 111, 111, 126, 126, 126, 126, 77, 139, 139, 140, 140, 140, 110, 110, 141, 141, 142, 142, 142, 142, 142, 127, 127, 127, 127, 144, 145, 143, 143, 143, 143, 143, 143, 143, 146, 146, 146); - protected $ruleToLength = array(1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 5, 4, 3, 4, 2, 3, 1, 1, 7, 6, 3, 1, 3, 1, 3, 1, 1, 3, 1, 3, 1, 2, 3, 1, 3, 3, 1, 3, 2, 0, 1, 1, 1, 1, 1, 3, 5, 8, 3, 5, 9, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 1, 2, 2, 5, 7, 9, 5, 6, 3, 3, 2, 2, 1, 1, 1, 0, 2, 8, 0, 4, 1, 3, 0, 1, 0, 1, 0, 1, 1, 1, 10, 7, 6, 5, 1, 2, 2, 0, 2, 0, 2, 0, 2, 1, 3, 1, 4, 1, 4, 1, 1, 4, 1, 3, 3, 3, 4, 4, 5, 0, 2, 4, 3, 1, 1, 1, 4, 0, 2, 3, 0, 2, 4, 0, 2, 0, 3, 1, 2, 1, 1, 0, 1, 3, 4, 6, 1, 1, 1, 0, 1, 0, 2, 2, 3, 3, 1, 3, 1, 2, 2, 3, 1, 1, 2, 4, 3, 1, 1, 3, 2, 0, 1, 3, 3, 9, 3, 1, 3, 0, 2, 4, 5, 4, 4, 4, 3, 1, 1, 1, 3, 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, 3, 1, 0, 1, 1, 3, 3, 4, 4, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 5, 4, 3, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 3, 2, 1, 2, 10, 11, 3, 3, 2, 4, 4, 3, 4, 4, 4, 4, 7, 3, 2, 0, 4, 1, 3, 2, 1, 2, 2, 4, 6, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, 0, 2, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 3, 1, 4, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 4, 3, 1, 3, 1, 1, 3, 3, 0, 2, 0, 1, 3, 1, 3, 1, 1, 1, 1, 1, 6, 4, 3, 4, 2, 4, 4, 1, 3, 1, 2, 1, 1, 4, 1, 1, 3, 6, 4, 4, 4, 4, 1, 4, 0, 1, 1, 3, 1, 1, 4, 3, 1, 1, 1, 0, 0, 2, 3, 1, 3, 1, 4, 2, 2, 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, 3, 6, 3, 1, 1, 1); - protected function initReduceCallbacks() - { - $this->reduceCallbacks = [0 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 1 => function ($stackPos) { +class Php7 extends \PHPUnit\PhpParser\ParserAbstract +{ + public const YYERRTOK = 256; + public const T_THROW = 257; + public const T_INCLUDE = 258; + public const T_INCLUDE_ONCE = 259; + public const T_EVAL = 260; + public const T_REQUIRE = 261; + public const T_REQUIRE_ONCE = 262; + public const T_LOGICAL_OR = 263; + public const T_LOGICAL_XOR = 264; + public const T_LOGICAL_AND = 265; + public const T_PRINT = 266; + public const T_YIELD = 267; + public const T_DOUBLE_ARROW = 268; + public const T_YIELD_FROM = 269; + public const T_PLUS_EQUAL = 270; + public const T_MINUS_EQUAL = 271; + public const T_MUL_EQUAL = 272; + public const T_DIV_EQUAL = 273; + public const T_CONCAT_EQUAL = 274; + public const T_MOD_EQUAL = 275; + public const T_AND_EQUAL = 276; + public const T_OR_EQUAL = 277; + public const T_XOR_EQUAL = 278; + public const T_SL_EQUAL = 279; + public const T_SR_EQUAL = 280; + public const T_POW_EQUAL = 281; + public const T_COALESCE_EQUAL = 282; + public const T_COALESCE = 283; + public const T_BOOLEAN_OR = 284; + public const T_BOOLEAN_AND = 285; + public const T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG = 286; + public const T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG = 287; + public const T_IS_EQUAL = 288; + public const T_IS_NOT_EQUAL = 289; + public const T_IS_IDENTICAL = 290; + public const T_IS_NOT_IDENTICAL = 291; + public const T_SPACESHIP = 292; + public const T_IS_SMALLER_OR_EQUAL = 293; + public const T_IS_GREATER_OR_EQUAL = 294; + public const T_SL = 295; + public const T_SR = 296; + public const T_INSTANCEOF = 297; + public const T_INC = 298; + public const T_DEC = 299; + public const T_INT_CAST = 300; + public const T_DOUBLE_CAST = 301; + public const T_STRING_CAST = 302; + public const T_ARRAY_CAST = 303; + public const T_OBJECT_CAST = 304; + public const T_BOOL_CAST = 305; + public const T_UNSET_CAST = 306; + public const T_POW = 307; + public const T_NEW = 308; + public const T_CLONE = 309; + public const T_EXIT = 310; + public const T_IF = 311; + public const T_ELSEIF = 312; + public const T_ELSE = 313; + public const T_ENDIF = 314; + public const T_LNUMBER = 315; + public const T_DNUMBER = 316; + public const T_STRING = 317; + public const T_STRING_VARNAME = 318; + public const T_VARIABLE = 319; + public const T_NUM_STRING = 320; + public const T_INLINE_HTML = 321; + public const T_ENCAPSED_AND_WHITESPACE = 322; + public const T_CONSTANT_ENCAPSED_STRING = 323; + public const T_ECHO = 324; + public const T_DO = 325; + public const T_WHILE = 326; + public const T_ENDWHILE = 327; + public const T_FOR = 328; + public const T_ENDFOR = 329; + public const T_FOREACH = 330; + public const T_ENDFOREACH = 331; + public const T_DECLARE = 332; + public const T_ENDDECLARE = 333; + public const T_AS = 334; + public const T_SWITCH = 335; + public const T_MATCH = 336; + public const T_ENDSWITCH = 337; + public const T_CASE = 338; + public const T_DEFAULT = 339; + public const T_BREAK = 340; + public const T_CONTINUE = 341; + public const T_GOTO = 342; + public const T_FUNCTION = 343; + public const T_FN = 344; + public const T_CONST = 345; + public const T_RETURN = 346; + public const T_TRY = 347; + public const T_CATCH = 348; + public const T_FINALLY = 349; + public const T_USE = 350; + public const T_INSTEADOF = 351; + public const T_GLOBAL = 352; + public const T_STATIC = 353; + public const T_ABSTRACT = 354; + public const T_FINAL = 355; + public const T_PRIVATE = 356; + public const T_PROTECTED = 357; + public const T_PUBLIC = 358; + public const T_READONLY = 359; + public const T_VAR = 360; + public const T_UNSET = 361; + public const T_ISSET = 362; + public const T_EMPTY = 363; + public const T_HALT_COMPILER = 364; + public const T_CLASS = 365; + public const T_TRAIT = 366; + public const T_INTERFACE = 367; + public const T_ENUM = 368; + public const T_EXTENDS = 369; + public const T_IMPLEMENTS = 370; + public const T_OBJECT_OPERATOR = 371; + public const T_NULLSAFE_OBJECT_OPERATOR = 372; + public const T_LIST = 373; + public const T_ARRAY = 374; + public const T_CALLABLE = 375; + public const T_CLASS_C = 376; + public const T_TRAIT_C = 377; + public const T_METHOD_C = 378; + public const T_FUNC_C = 379; + public const T_LINE = 380; + public const T_FILE = 381; + public const T_START_HEREDOC = 382; + public const T_END_HEREDOC = 383; + public const T_DOLLAR_OPEN_CURLY_BRACES = 384; + public const T_CURLY_OPEN = 385; + public const T_PAAMAYIM_NEKUDOTAYIM = 386; + public const T_NAMESPACE = 387; + public const T_NS_C = 388; + public const T_DIR = 389; + public const T_NS_SEPARATOR = 390; + public const T_ELLIPSIS = 391; + public const T_NAME_FULLY_QUALIFIED = 392; + public const T_NAME_QUALIFIED = 393; + public const T_NAME_RELATIVE = 394; + public const T_ATTRIBUTE = 395; + protected int $tokenToSymbolMapSize = 396; + protected int $actionTableSize = 1258; + protected int $gotoTableSize = 567; + protected int $invalidSymbol = 168; + protected int $errorSymbol = 1; + protected int $defaultAction = -32766; + protected int $unexpectedTokenRule = 32767; + protected int $YY2TBLSTATE = 435; + protected int $numNonLeafStates = 739; + protected array $symbolToName = array("EOF", "error", "T_THROW", "T_INCLUDE", "T_INCLUDE_ONCE", "T_EVAL", "T_REQUIRE", "T_REQUIRE_ONCE", "','", "T_LOGICAL_OR", "T_LOGICAL_XOR", "T_LOGICAL_AND", "T_PRINT", "T_YIELD", "T_DOUBLE_ARROW", "T_YIELD_FROM", "'='", "T_PLUS_EQUAL", "T_MINUS_EQUAL", "T_MUL_EQUAL", "T_DIV_EQUAL", "T_CONCAT_EQUAL", "T_MOD_EQUAL", "T_AND_EQUAL", "T_OR_EQUAL", "T_XOR_EQUAL", "T_SL_EQUAL", "T_SR_EQUAL", "T_POW_EQUAL", "T_COALESCE_EQUAL", "'?'", "':'", "T_COALESCE", "T_BOOLEAN_OR", "T_BOOLEAN_AND", "'|'", "'^'", "T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG", "T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG", "T_IS_EQUAL", "T_IS_NOT_EQUAL", "T_IS_IDENTICAL", "T_IS_NOT_IDENTICAL", "T_SPACESHIP", "'<'", "T_IS_SMALLER_OR_EQUAL", "'>'", "T_IS_GREATER_OR_EQUAL", "T_SL", "T_SR", "'+'", "'-'", "'.'", "'*'", "'/'", "'%'", "'!'", "T_INSTANCEOF", "'~'", "T_INC", "T_DEC", "T_INT_CAST", "T_DOUBLE_CAST", "T_STRING_CAST", "T_ARRAY_CAST", "T_OBJECT_CAST", "T_BOOL_CAST", "T_UNSET_CAST", "'@'", "T_POW", "'['", "T_NEW", "T_CLONE", "T_EXIT", "T_IF", "T_ELSEIF", "T_ELSE", "T_ENDIF", "T_LNUMBER", "T_DNUMBER", "T_STRING", "T_STRING_VARNAME", "T_VARIABLE", "T_NUM_STRING", "T_INLINE_HTML", "T_ENCAPSED_AND_WHITESPACE", "T_CONSTANT_ENCAPSED_STRING", "T_ECHO", "T_DO", "T_WHILE", "T_ENDWHILE", "T_FOR", "T_ENDFOR", "T_FOREACH", "T_ENDFOREACH", "T_DECLARE", "T_ENDDECLARE", "T_AS", "T_SWITCH", "T_MATCH", "T_ENDSWITCH", "T_CASE", "T_DEFAULT", "T_BREAK", "T_CONTINUE", "T_GOTO", "T_FUNCTION", "T_FN", "T_CONST", "T_RETURN", "T_TRY", "T_CATCH", "T_FINALLY", "T_USE", "T_INSTEADOF", "T_GLOBAL", "T_STATIC", "T_ABSTRACT", "T_FINAL", "T_PRIVATE", "T_PROTECTED", "T_PUBLIC", "T_READONLY", "T_VAR", "T_UNSET", "T_ISSET", "T_EMPTY", "T_HALT_COMPILER", "T_CLASS", "T_TRAIT", "T_INTERFACE", "T_ENUM", "T_EXTENDS", "T_IMPLEMENTS", "T_OBJECT_OPERATOR", "T_NULLSAFE_OBJECT_OPERATOR", "T_LIST", "T_ARRAY", "T_CALLABLE", "T_CLASS_C", "T_TRAIT_C", "T_METHOD_C", "T_FUNC_C", "T_LINE", "T_FILE", "T_START_HEREDOC", "T_END_HEREDOC", "T_DOLLAR_OPEN_CURLY_BRACES", "T_CURLY_OPEN", "T_PAAMAYIM_NEKUDOTAYIM", "T_NAMESPACE", "T_NS_C", "T_DIR", "T_NS_SEPARATOR", "T_ELLIPSIS", "T_NAME_FULLY_QUALIFIED", "T_NAME_QUALIFIED", "T_NAME_RELATIVE", "T_ATTRIBUTE", "';'", "']'", "'('", "')'", "'{'", "'}'", "'`'", "'\"'", "'\$'"); + protected array $tokenToSymbol = array(0, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 56, 166, 168, 167, 55, 168, 168, 161, 162, 53, 50, 8, 51, 52, 54, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 31, 159, 44, 16, 46, 30, 68, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 70, 168, 160, 36, 168, 165, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 163, 35, 164, 58, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43, 45, 47, 48, 49, 57, 59, 60, 61, 62, 63, 64, 65, 66, 67, 69, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158); + protected array $action = array(133, 134, 135, 582, 136, 137, 0, 751, 752, 753, 138, 38, -32766, -32766, -32766, 151, -32766, -32766, -32766, -32767, -32767, -32767, -32767, 102, 103, 104, 105, 106, 1112, 1113, 1114, 1111, 1110, 1109, 1115, 745, 744, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32767, -32767, -32767, -32767, -32767, 1245, 837, -32766, 1322, 754, -32766, -32766, -32766, -32766, -594, -32766, -32766, -32766, 104, 105, 106, -594, 1306, 265, 139, 404, 758, 759, 760, 761, 990, -32766, 429, -32766, -32766, -16, -32766, 242, 1027, 815, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 791, 583, 792, 793, 794, 795, 783, 784, 345, 346, 786, 787, 772, 773, 774, 776, 777, 778, 356, 818, 819, 820, 821, 822, 584, 779, 780, 585, 586, -32766, 803, 801, 802, 814, 798, 799, 835, 826, 587, 588, 797, 589, 590, 591, 592, 593, 594, 826, 459, 460, 461, 1036, 800, 595, 596, 941, 140, 2, 133, 134, 135, 582, 136, 137, 1060, 751, 752, 753, 138, 38, -328, -110, -110, 1326, 290, 23, -110, -32766, -32766, -32766, 1325, 35, -110, 1112, 1113, 1114, 1111, 1110, 1109, 1115, 612, -32766, 129, 745, 744, 107, 108, 109, -32766, 274, -32766, -32766, -32766, -32766, -32766, -32766, -32766, 828, 991, -194, 145, 110, 298, 754, 836, 75, -32766, -32766, -32766, 1351, 142, 326, 1352, -594, 326, -594, 254, 265, 139, 404, 758, 759, 760, 761, 82, -272, 429, -32766, 326, -32766, -32766, -32766, -32766, 815, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 791, 583, 792, 793, 794, 795, 783, 784, 345, 346, 786, 787, 772, 773, 774, 776, 777, 778, 356, 818, 819, 820, 821, 822, 584, 779, 780, 585, 586, 830, 803, 801, 802, 814, 798, 799, 712, 309, 587, 588, 797, 589, 590, 591, 592, 593, 594, -78, 83, 84, 85, -85, 800, 595, 596, 311, 149, 775, 746, 747, 748, 749, 750, 725, 751, 752, 753, 788, 789, 37, -328, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 323, 274, 482, -32766, -32766, -32766, -58, -32766, -32766, -32766, 959, 960, 127, 110, -194, 961, 339, 754, -32766, -32766, -32766, 955, -85, 291, -32766, 1088, -32766, -32766, -32766, -32766, -32766, 755, 756, 757, 758, 759, 760, 761, -193, -32766, 824, -32766, -32766, -32766, -367, 429, -367, 815, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 791, 813, 792, 793, 794, 795, 783, 784, 785, 812, 786, 787, 772, 773, 774, 776, 777, 778, 817, 818, 819, 820, 821, 822, 823, 779, 780, 781, 782, -548, 803, 801, 802, 814, 798, 799, 340, 327, 790, 796, 797, 804, 805, 807, 806, 808, 809, 1033, 391, 606, 7, -32766, 800, 811, 810, 50, 51, 52, 513, 53, 54, 831, 1240, 1239, 1241, 55, 56, -110, 57, 1036, 920, 1090, -110, 1036, -110, 291, 483, 745, 744, 305, 382, 381, -110, -110, -110, -110, -110, -110, -110, -110, 423, 920, 283, -548, -548, 152, 290, 380, 381, 1245, 715, 467, 468, 58, 59, 370, 21, 423, -545, 60, 556, 61, 248, 249, 62, 63, 64, 65, 66, 67, 68, 69, -548, 28, 267, 70, 445, 514, 1104, 374, -342, 1272, 1273, 515, -193, 835, 154, 832, -544, 1270, 42, 25, 516, 389, 517, 241, 518, 920, 519, 298, 1238, 520, 521, 910, 920, 441, 44, 45, 446, 377, 376, -32766, 46, 522, 1023, 1022, 1021, 1024, 368, 338, 442, 1278, -545, -545, 910, 1231, 443, 524, 525, 526, 835, 1245, 835, 1036, 716, 1341, 1236, -545, 155, 528, 529, -32766, 1259, 1260, 1261, 1262, 1256, 1257, 297, -551, 943, -545, -544, -544, 1263, 1258, 290, 1035, 1240, 1239, 1241, 298, 444, 1036, 71, 1266, 841, -544, 321, 322, 326, -153, -153, -153, 920, 1240, 1239, 1241, 922, -550, 910, -544, 710, 943, -591, -32766, -153, 910, -153, 357, -153, -591, -153, 862, 1033, 863, 1089, 36, 251, 922, 737, 156, 375, 710, 717, 862, -585, 863, -585, 75, 158, -546, 835, 959, 960, 326, 1036, -57, 523, 920, -32766, -32766, 362, 896, 955, -110, -110, -110, 32, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 745, 744, 656, 26, 835, -110, -110, 720, 745, 744, -110, 33, 834, 922, 124, 910, -110, 710, -153, 125, 922, 675, 676, 130, 710, -32766, 150, 407, 131, 1150, 1152, 48, 144, -546, -546, 378, 379, -32766, 383, 384, -543, 28, 159, 1238, 920, 160, 298, 1059, -546, 75, -32766, -32766, -32766, 835, -32766, 326, -32766, 1270, -32766, -87, 910, -32766, -546, 647, 648, 161, -32766, -32766, -32766, -4, 920, -84, -32766, -32766, 727, 162, 287, 163, -32766, 420, -302, -78, -73, -72, -71, 141, 287, -32766, -70, 326, 976, 745, 744, 1231, 710, 299, 300, -69, -68, -67, -298, -591, -66, -591, -543, -543, -65, 528, 529, -46, 1259, 1260, 1261, 1262, 1256, 1257, -18, 74, 148, -543, 273, 284, 1263, 1258, 126, -543, 726, 910, -32766, 729, 919, 147, 73, -543, 1238, 922, 690, 322, 326, 710, 279, -32766, -32766, -32766, 280, -32766, 285, -32766, 286, -32766, 332, 288, -32766, 910, 289, 292, 49, -32766, -32766, -32766, 293, 274, 1033, -32766, -32766, 937, 110, -50, 685, -32766, 420, 146, 691, 826, 701, 375, 703, 436, -32766, 1353, 20, 561, 296, 645, 1036, 835, 959, 960, 1119, -543, -543, 523, -32766, 692, 693, 306, 527, 955, -110, -110, -110, 132, 922, 834, -543, 464, 710, 283, 662, 657, -32766, 1240, 1239, 1241, 678, 304, 1238, 283, -543, 10, 301, 302, 493, -32766, -32766, -32766, 663, -32766, 922, -32766, 679, -32766, 710, -4, -32766, 373, 40, -508, 956, -32766, -32766, -32766, -275, 731, -32766, -32766, -32766, 920, 303, 128, 1238, -32766, 420, 310, 0, 567, 0, -32766, -32766, -32766, -32766, -32766, 0, -32766, 0, -32766, -32766, 0, -32766, 0, 1277, -498, 0, -32766, -32766, -32766, -32766, 1279, 0, -32766, -32766, 8, 1238, 24, 372, -32766, 420, 920, 1267, -32766, -32766, -32766, 610, -32766, -32766, -32766, 939, -32766, 298, -579, -32766, 846, 41, 734, 488, -32766, -32766, -32766, -32766, 735, 854, -32766, -32766, 901, 1238, 574, 1000, -32766, 420, 977, 984, -32766, -32766, -32766, 974, -32766, -32766, -32766, 985, -32766, 910, 899, -32766, 972, 1093, 1096, 1097, -32766, -32766, -32766, 1094, 1095, 1101, -32766, -32766, 1292, -250, -250, -250, -32766, 420, 1310, 375, 1344, 650, 28, 267, -578, -32766, -577, -551, -550, -549, 959, 960, -492, 1, 835, 523, 29, 910, 1270, 30, 896, 955, -110, -110, -110, 39, 43, 47, 72, 76, 77, 78, 79, -249, -249, -249, 80, 81, 143, 375, 153, 157, 897, 247, 328, 357, 358, 359, 360, 361, 959, 960, 922, 362, 1231, 523, 710, -250, 363, 364, 896, 955, -110, -110, -110, 365, 366, 367, 369, 529, 28, 1259, 1260, 1261, 1262, 1256, 1257, 437, 555, 1348, -273, -272, 835, 1263, 1258, 13, 1270, 14, -32766, 15, 16, 18, 922, 73, 1238, 1350, 710, -249, 322, 326, 406, -32766, -32766, -32766, 484, -32766, 485, -32766, 492, -32766, 495, 496, -32766, 497, 498, 502, 503, -32766, -32766, -32766, 504, 511, 1231, -32766, -32766, 572, 696, 1249, 1190, -32766, 420, 1268, 1062, 1061, 1042, 1226, 1038, 529, -32766, 1259, 1260, 1261, 1262, 1256, 1257, -277, -102, 12, 17, 27, 295, 1263, 1258, 405, 603, 607, 636, 702, 1194, 1244, 1191, 73, 34, 1323, 0, 320, 322, 326, 371, 711, 714, 718, 719, 721, 722, 723, 724, 0, 728, 713, 0, 857, 856, 865, 949, 992, 864, 1349, 948, 946, 947, 950, 1222, 930, 940, 928, 982, 983, 634, 1347, 1304, 1293, 1311, 1320, 0, 1207, 0, 1271, 0, 326); + protected array $actionCheck = array(2, 3, 4, 5, 6, 7, 0, 9, 10, 11, 12, 13, 9, 10, 11, 14, 9, 10, 11, 44, 45, 46, 47, 48, 49, 50, 51, 52, 116, 117, 118, 119, 120, 121, 122, 37, 38, 30, 116, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 1, 1, 9, 1, 57, 9, 10, 11, 137, 1, 9, 10, 11, 50, 51, 52, 8, 1, 71, 72, 73, 74, 75, 76, 77, 31, 30, 80, 32, 33, 31, 30, 14, 1, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 116, 128, 129, 130, 131, 132, 133, 82, 80, 136, 137, 138, 139, 140, 141, 142, 143, 144, 80, 129, 130, 131, 138, 150, 151, 152, 1, 154, 8, 2, 3, 4, 5, 6, 7, 162, 9, 10, 11, 12, 13, 8, 117, 118, 1, 161, 8, 122, 9, 10, 11, 8, 8, 128, 116, 117, 118, 119, 120, 121, 122, 51, 137, 8, 37, 38, 53, 54, 55, 30, 57, 32, 33, 34, 35, 36, 37, 38, 80, 159, 8, 8, 69, 158, 57, 159, 161, 9, 10, 11, 80, 163, 167, 83, 160, 167, 162, 8, 71, 72, 73, 74, 75, 76, 77, 163, 162, 80, 30, 167, 32, 33, 34, 35, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 156, 128, 129, 130, 131, 132, 133, 163, 8, 136, 137, 138, 139, 140, 141, 142, 143, 144, 16, 9, 10, 11, 31, 150, 151, 152, 8, 154, 2, 3, 4, 5, 6, 7, 163, 9, 10, 11, 12, 13, 30, 162, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 8, 57, 31, 9, 10, 11, 16, 9, 10, 11, 117, 118, 14, 69, 162, 122, 8, 57, 9, 10, 11, 128, 97, 30, 30, 1, 32, 33, 34, 35, 36, 71, 72, 73, 74, 75, 76, 77, 8, 30, 80, 32, 33, 34, 106, 80, 108, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 70, 128, 129, 130, 131, 132, 133, 8, 70, 136, 137, 138, 139, 140, 141, 142, 143, 144, 116, 106, 1, 108, 116, 150, 151, 152, 2, 3, 4, 5, 6, 7, 80, 155, 156, 157, 12, 13, 101, 15, 138, 1, 164, 106, 138, 108, 30, 163, 37, 38, 113, 106, 107, 116, 117, 118, 119, 120, 121, 122, 123, 116, 1, 161, 134, 135, 14, 161, 106, 107, 1, 31, 134, 135, 50, 51, 8, 101, 116, 70, 56, 85, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 163, 70, 71, 72, 73, 74, 123, 8, 164, 78, 79, 80, 162, 82, 14, 156, 70, 86, 87, 88, 89, 8, 91, 97, 93, 1, 95, 158, 80, 98, 99, 84, 1, 8, 103, 104, 105, 106, 107, 116, 109, 110, 119, 120, 121, 122, 115, 116, 8, 146, 134, 135, 84, 122, 8, 124, 125, 126, 82, 1, 82, 138, 31, 85, 116, 149, 14, 136, 137, 116, 139, 140, 141, 142, 143, 144, 145, 161, 122, 163, 134, 135, 151, 152, 161, 137, 155, 156, 157, 158, 8, 138, 161, 1, 8, 149, 165, 166, 167, 75, 76, 77, 1, 155, 156, 157, 159, 161, 84, 163, 163, 122, 1, 137, 90, 84, 92, 161, 94, 8, 96, 106, 116, 108, 159, 147, 148, 159, 163, 14, 106, 163, 31, 106, 160, 108, 162, 161, 14, 70, 82, 117, 118, 167, 138, 16, 122, 1, 9, 10, 161, 127, 128, 129, 130, 131, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 37, 38, 75, 76, 82, 117, 118, 31, 37, 38, 122, 14, 155, 159, 16, 84, 128, 163, 164, 16, 159, 75, 76, 16, 163, 137, 101, 102, 16, 59, 60, 70, 16, 134, 135, 106, 107, 74, 106, 107, 70, 70, 16, 80, 1, 16, 158, 1, 149, 161, 87, 88, 89, 82, 91, 167, 93, 86, 95, 31, 84, 98, 163, 111, 112, 16, 103, 104, 105, 0, 1, 31, 109, 110, 31, 16, 30, 16, 115, 116, 35, 31, 31, 31, 31, 163, 30, 124, 31, 167, 159, 37, 38, 122, 163, 134, 135, 31, 31, 31, 35, 160, 31, 162, 134, 135, 31, 136, 137, 31, 139, 140, 141, 142, 143, 144, 31, 154, 31, 149, 31, 31, 151, 152, 163, 70, 31, 84, 74, 31, 31, 31, 161, 163, 80, 159, 80, 166, 167, 163, 35, 87, 88, 89, 35, 91, 35, 93, 35, 95, 35, 37, 98, 84, 37, 37, 70, 103, 104, 105, 37, 57, 116, 109, 110, 38, 69, 31, 77, 115, 116, 70, 116, 80, 80, 106, 92, 108, 124, 83, 97, 89, 113, 113, 138, 82, 117, 118, 82, 134, 135, 122, 85, 137, 138, 114, 127, 128, 129, 130, 131, 31, 159, 155, 149, 97, 163, 161, 96, 90, 74, 155, 156, 157, 94, 133, 80, 161, 163, 150, 134, 135, 97, 87, 88, 89, 100, 91, 159, 93, 100, 95, 163, 164, 98, 149, 159, 149, 128, 103, 104, 105, 162, 164, 74, 109, 110, 1, 132, 163, 80, 115, 116, 132, -1, 153, -1, 87, 88, 89, 124, 91, -1, 93, -1, 95, 137, -1, 98, -1, 146, 149, -1, 103, 104, 105, 74, 146, -1, 109, 110, 149, 80, 149, 149, 115, 116, 1, 160, 87, 88, 89, 153, 91, 124, 93, 154, 95, 158, 161, 98, 160, 159, 159, 102, 103, 104, 105, 74, 159, 159, 109, 110, 159, 80, 81, 159, 115, 116, 159, 159, 87, 88, 89, 159, 91, 124, 93, 159, 95, 84, 159, 98, 159, 159, 159, 159, 103, 104, 105, 159, 159, 159, 109, 110, 160, 100, 101, 102, 115, 116, 160, 106, 160, 160, 70, 71, 161, 124, 161, 161, 161, 161, 117, 118, 161, 161, 82, 122, 161, 84, 86, 161, 127, 128, 129, 130, 131, 161, 161, 161, 161, 161, 161, 161, 161, 100, 101, 102, 161, 161, 161, 106, 161, 161, 164, 161, 161, 161, 161, 161, 161, 161, 117, 118, 159, 161, 122, 122, 163, 164, 161, 161, 127, 128, 129, 130, 131, 161, 161, 161, 161, 137, 70, 139, 140, 141, 142, 143, 144, 161, 161, 164, 162, 162, 82, 151, 152, 162, 86, 162, 74, 162, 162, 162, 159, 161, 80, 164, 163, 164, 166, 167, 162, 87, 88, 89, 162, 91, 162, 93, 162, 95, 162, 162, 98, 162, 162, 162, 162, 103, 104, 105, 162, 162, 122, 109, 110, 162, 162, 162, 162, 115, 116, 162, 162, 162, 162, 162, 162, 137, 124, 139, 140, 141, 142, 143, 144, 162, 162, 162, 162, 162, 162, 151, 152, 162, 162, 162, 162, 162, 162, 162, 162, 161, 163, 162, -1, 163, 166, 167, 163, 163, 163, 163, 163, 163, 163, 163, 163, -1, 163, 163, -1, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -1, 165, -1, 166, -1, 167); + protected array $actionBase = array(0, -2, 152, 549, 764, 941, 981, 751, 617, 310, 123, 877, 556, 671, 671, 738, 671, 472, 626, 789, 63, 305, 305, 789, 305, 493, 493, 493, 658, 658, 658, 658, 749, 749, 897, 897, 929, 865, 831, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 51, 45, 451, 692, 1036, 1044, 1040, 1045, 1034, 1033, 1039, 1041, 1046, 1083, 1084, 795, 1085, 1086, 1082, 1087, 1042, 889, 1035, 1043, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 44, 343, 664, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 52, 52, 52, 666, 666, 47, 354, 980, 203, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 665, 339, 164, 164, 7, 7, 7, 7, 7, 50, 369, 583, -25, -25, -25, -25, 448, 741, 501, 408, 283, 338, 394, 334, 334, 14, 14, 531, 531, 9, 9, 531, 531, 531, 478, 478, 478, 478, 441, 471, 552, 428, 824, 53, 53, 53, 53, 824, 824, 824, 824, 826, 1089, 824, 824, 824, 594, 750, 750, 781, 138, 138, 138, 750, 540, 503, 503, 540, 238, 503, 67, 135, -78, 805, 377, 499, -78, 362, 656, 636, 59, 743, 624, 743, 1032, 481, 802, 802, 514, 773, 746, 878, 1064, 1049, 821, 1080, 825, 1081, 15, 370, 745, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1090, 443, 1032, 384, 1090, 1090, 1090, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 647, 384, 622, 641, 384, 810, 443, 51, 817, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 780, 316, 51, 45, 150, 150, 490, 83, 150, 150, 150, 150, 51, 51, 51, 51, 624, 799, 797, 627, 834, 375, 799, 799, 799, 270, 158, 69, 197, 740, 760, 345, 788, 788, 801, 900, 900, 788, 798, 788, 801, 914, 788, 788, 900, 900, 835, 180, 550, 353, 524, 565, 900, 279, 788, 788, 788, 788, 816, 571, 788, 214, 198, 788, 788, 816, 811, 785, 145, 777, 900, 900, 900, 816, 500, 777, 777, 777, 839, 845, 765, 784, 337, 297, 611, 169, 822, 784, 784, 788, 538, 765, 784, 765, 784, 837, 784, 784, 784, 765, 784, 798, 431, 784, 721, 607, 163, 784, 6, 915, 916, 723, 917, 912, 918, 964, 919, 923, 1054, 899, 930, 913, 924, 965, 906, 903, 794, 693, 698, 827, 783, 896, 792, 792, 792, 894, 792, 792, 792, 792, 792, 792, 792, 792, 693, 823, 830, 787, 933, 702, 707, 1011, 819, 926, 1088, 932, 1013, 925, 772, 711, 977, 934, 774, 1050, 935, 936, 986, 1014, 846, 1017, 963, 796, 979, 1065, 836, 945, 1055, 792, 915, 923, 735, 913, 924, 906, 903, 770, 766, 762, 763, 761, 752, 747, 748, 782, 1018, 893, 833, 880, 940, 895, 693, 886, 971, 1047, 990, 992, 1053, 803, 791, 888, 1066, 946, 952, 953, 1056, 1019, 1057, 838, 973, 775, 994, 820, 1067, 996, 997, 999, 1000, 1058, 1068, 1059, 891, 1060, 849, 814, 966, 807, 1069, 1, 806, 808, 818, 955, 484, 931, 1061, 1070, 1071, 1001, 1002, 1006, 1072, 1073, 927, 852, 975, 815, 976, 967, 855, 856, 525, 813, 1020, 800, 804, 812, 577, 640, 1074, 1075, 1076, 928, 790, 786, 860, 864, 1021, 809, 1022, 1077, 649, 867, 724, 1078, 1012, 744, 754, 281, 654, 335, 756, 779, 1063, 829, 776, 778, 954, 754, 793, 869, 1079, 870, 871, 872, 1007, 876, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 456, 456, 456, 456, 456, 456, 305, 305, 305, 305, 305, 456, 456, 456, 456, 456, 456, 456, 305, 305, 0, 0, 305, 0, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 473, 473, 289, 289, 473, 289, 473, 473, 473, 473, 473, 473, 473, 473, 473, 0, 289, 289, 289, 289, 289, 289, 289, 289, 473, 835, 473, 138, 138, 138, 138, 473, 473, 473, -88, -88, 473, 238, 473, 473, 138, 138, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 0, 0, 384, 503, 473, 798, 798, 798, 798, 473, 473, 473, 473, 503, 503, 473, 473, 473, 0, 0, 0, 0, 0, 0, 0, 0, 384, 0, 0, 384, 0, 0, 798, 798, 473, 238, 835, 168, 473, 0, 0, 0, 0, 384, 798, 384, 443, 788, 503, 503, 788, 443, 443, 150, 51, 168, 620, 620, 620, 620, 0, 0, 624, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, 798, 0, 835, 0, 798, 798, 798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 798, 0, 0, 900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 914, 0, 0, 0, 0, 0, 0, 798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 792, 803, 0, 803, 0, 792, 792, 792, 0, 0, 0, 0, 813, 809); + protected array $actionDefault = array(3, 32767, 102, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 100, 32767, 32767, 32767, 32767, 597, 597, 597, 597, 32767, 32767, 254, 102, 32767, 32767, 470, 387, 387, 387, 32767, 32767, 541, 541, 541, 541, 541, 541, 32767, 32767, 32767, 32767, 32767, 32767, 470, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 100, 32767, 32767, 32767, 36, 7, 8, 10, 11, 49, 17, 324, 32767, 32767, 32767, 32767, 102, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 590, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 474, 453, 454, 456, 457, 386, 542, 596, 327, 593, 385, 145, 339, 329, 242, 330, 258, 475, 259, 476, 479, 480, 215, 287, 382, 149, 150, 417, 471, 419, 469, 473, 418, 392, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 390, 391, 472, 450, 449, 448, 32767, 32767, 415, 416, 32767, 420, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 102, 32767, 389, 423, 421, 422, 439, 440, 437, 438, 441, 32767, 32767, 32767, 442, 443, 444, 445, 316, 32767, 32767, 366, 364, 316, 111, 32767, 32767, 430, 431, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 535, 447, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 102, 32767, 100, 537, 412, 414, 504, 425, 426, 424, 393, 32767, 511, 32767, 102, 32767, 513, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 536, 32767, 543, 543, 32767, 497, 100, 195, 32767, 32767, 512, 32767, 195, 195, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 604, 497, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 32767, 195, 110, 32767, 32767, 32767, 100, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 190, 32767, 268, 270, 102, 558, 195, 32767, 516, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 509, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 497, 435, 138, 32767, 138, 543, 427, 428, 429, 499, 543, 543, 543, 312, 289, 32767, 32767, 32767, 32767, 514, 514, 100, 100, 100, 100, 509, 32767, 32767, 32767, 32767, 111, 99, 99, 99, 99, 99, 103, 101, 32767, 32767, 32767, 32767, 223, 99, 32767, 101, 101, 32767, 32767, 223, 225, 212, 101, 227, 32767, 562, 563, 223, 101, 227, 227, 227, 247, 247, 486, 318, 101, 99, 101, 101, 197, 318, 318, 32767, 101, 486, 318, 486, 318, 199, 318, 318, 318, 486, 318, 32767, 101, 318, 214, 99, 99, 318, 32767, 32767, 32767, 499, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 222, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 530, 32767, 547, 560, 433, 434, 436, 545, 458, 459, 460, 461, 462, 463, 464, 466, 592, 32767, 503, 32767, 32767, 32767, 338, 32767, 602, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 603, 32767, 543, 32767, 32767, 32767, 32767, 432, 9, 74, 492, 42, 43, 51, 57, 520, 521, 522, 523, 517, 518, 524, 519, 32767, 32767, 525, 568, 32767, 32767, 544, 595, 32767, 32767, 32767, 32767, 32767, 32767, 138, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 530, 32767, 136, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 526, 32767, 32767, 32767, 543, 32767, 32767, 32767, 32767, 314, 311, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 543, 32767, 32767, 32767, 32767, 32767, 291, 32767, 308, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 286, 32767, 32767, 381, 499, 294, 296, 297, 32767, 32767, 32767, 32767, 360, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 152, 152, 3, 3, 341, 152, 152, 152, 341, 341, 152, 341, 341, 341, 152, 152, 152, 152, 152, 152, 280, 185, 262, 265, 247, 247, 152, 352, 152); + protected array $goto = array(196, 196, 1034, 1065, 697, 431, 661, 621, 658, 319, 706, 425, 313, 314, 335, 576, 430, 336, 432, 638, 654, 655, 852, 672, 673, 674, 853, 167, 167, 167, 167, 221, 197, 193, 193, 177, 179, 216, 193, 193, 193, 193, 193, 194, 194, 194, 194, 194, 194, 188, 189, 190, 191, 192, 218, 216, 219, 536, 537, 421, 538, 540, 541, 542, 543, 544, 545, 546, 547, 1136, 168, 169, 170, 195, 171, 172, 173, 166, 174, 175, 176, 178, 215, 217, 220, 238, 243, 244, 246, 257, 258, 259, 260, 261, 262, 263, 264, 268, 269, 270, 271, 281, 282, 316, 317, 318, 426, 427, 428, 581, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 180, 237, 181, 198, 199, 200, 239, 188, 189, 190, 191, 192, 218, 1136, 201, 182, 183, 184, 202, 198, 185, 240, 203, 201, 165, 204, 205, 186, 206, 207, 208, 187, 209, 210, 211, 212, 213, 214, 855, 466, 466, 278, 278, 278, 278, 623, 623, 351, 466, 1269, 600, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1287, 1287, 599, 1100, 1287, 709, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 508, 700, 458, 1098, 975, 559, 552, 860, 419, 909, 904, 905, 918, 861, 906, 858, 907, 908, 859, 848, 827, 912, 354, 354, 354, 354, 396, 399, 560, 601, 605, 1087, 1082, 1083, 1084, 341, 552, 559, 568, 569, 344, 579, 602, 616, 617, 408, 409, 1232, 440, 479, 670, 22, 671, 886, 412, 413, 414, 481, 684, 349, 1237, 415, 1237, 1107, 1108, 347, 833, 1034, 1034, 1237, 573, 848, 1034, 1327, 1034, 1034, 1040, 1039, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1319, 1319, 1319, 1319, 1237, 893, 851, 893, 893, 1237, 1237, 1237, 1237, 1233, 1234, 1237, 1237, 1237, 833, 355, 833, 843, 996, 252, 252, 1043, 1044, 1037, 1037, 355, 355, 681, 952, 394, 926, 1029, 1045, 1046, 927, 1235, 1295, 1296, 942, 355, 355, 942, 913, 355, 914, 1354, 250, 250, 250, 250, 245, 253, 548, 548, 548, 548, 554, 604, 1285, 1285, 355, 355, 1285, 571, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 539, 539, 342, 424, 539, 611, 539, 539, 539, 539, 539, 539, 539, 539, 539, 566, 476, 1312, 1313, 733, 637, 639, 325, 308, 659, 848, 343, 342, 683, 687, 1010, 695, 704, 1006, 660, 1298, 609, 624, 627, 628, 629, 630, 651, 652, 653, 708, 1216, 944, 1314, 1315, 1217, 1220, 945, 1221, 1337, 1337, 686, 352, 353, 868, 553, 563, 450, 450, 450, 553, 1309, 563, 1309, 1133, 397, 462, 1337, 1058, 880, 1309, 1185, 867, 500, 5, 501, 6, 469, 580, 470, 471, 507, 554, 878, 1340, 1340, 1345, 1346, 433, 438, 550, 666, 550, 433, 682, 1321, 1321, 1321, 1321, 550, 337, 1041, 1041, 931, 1123, 873, 665, 1052, 1048, 1049, 619, 845, 876, 324, 275, 324, 1015, 967, 410, 705, 577, 614, 1305, 456, 872, 403, 664, 994, 969, 969, 969, 969, 866, 870, 456, 963, 970, 881, 869, 1070, 1074, 631, 633, 635, 1227, 1230, 958, 615, 978, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 999, 1018, 450, 971, 1073, 732, 477, 1228, 1307, 1307, 1073, 736, 968, 551, 1008, 1003, 882, 694, 1075, 1071, 829, 255, 255, 980, 0, 1118, 0, 1013, 1013, 694, 0, 0, 0, 694, 1116, 885); + protected array $gotoCheck = array(42, 42, 73, 127, 73, 66, 66, 56, 56, 66, 9, 66, 66, 66, 66, 66, 66, 66, 66, 66, 86, 86, 26, 86, 86, 86, 27, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 15, 149, 149, 23, 23, 23, 23, 108, 108, 97, 149, 108, 130, 108, 108, 108, 108, 108, 108, 108, 108, 108, 170, 170, 8, 8, 170, 8, 170, 170, 170, 170, 170, 170, 170, 170, 170, 8, 8, 83, 8, 49, 76, 76, 15, 43, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 22, 6, 15, 24, 24, 24, 24, 59, 59, 59, 59, 59, 15, 15, 15, 15, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 82, 82, 20, 83, 84, 82, 76, 82, 45, 82, 82, 82, 84, 82, 179, 73, 82, 73, 144, 144, 82, 12, 73, 73, 73, 172, 22, 73, 181, 73, 73, 118, 118, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 9, 9, 9, 9, 73, 25, 25, 25, 25, 73, 73, 73, 73, 20, 20, 73, 73, 73, 12, 14, 12, 20, 103, 5, 5, 119, 119, 89, 89, 14, 14, 89, 89, 62, 73, 89, 89, 89, 73, 20, 20, 20, 9, 14, 14, 9, 65, 14, 65, 14, 5, 5, 5, 5, 5, 5, 107, 107, 107, 107, 14, 107, 171, 171, 14, 14, 171, 104, 171, 171, 171, 171, 171, 171, 171, 171, 171, 173, 173, 168, 13, 173, 13, 173, 173, 173, 173, 173, 173, 173, 173, 173, 48, 176, 176, 176, 48, 48, 48, 169, 169, 48, 22, 168, 168, 48, 48, 48, 48, 48, 48, 64, 14, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 79, 79, 178, 178, 79, 79, 79, 79, 182, 182, 14, 97, 97, 35, 9, 9, 23, 23, 23, 9, 130, 9, 130, 150, 9, 9, 182, 114, 35, 130, 151, 35, 155, 46, 155, 46, 9, 9, 9, 9, 155, 14, 9, 182, 182, 9, 9, 117, 113, 19, 120, 19, 117, 116, 130, 130, 130, 130, 19, 29, 117, 117, 17, 17, 39, 117, 117, 117, 117, 17, 18, 9, 24, 24, 24, 17, 93, 93, 93, 2, 2, 130, 19, 17, 28, 17, 17, 19, 19, 19, 19, 17, 37, 19, 19, 19, 16, 16, 16, 16, 85, 85, 85, 17, 14, 92, 80, 16, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 50, 110, 23, 50, 130, 50, 157, 160, 130, 130, 130, 99, 16, 50, 50, 50, 41, 7, 132, 129, 7, 5, 5, 96, -1, 147, -1, 107, 107, 7, -1, -1, -1, 7, 16, 16); + protected array $gotoBase = array(0, 0, -221, 0, 0, 311, 200, 541, 179, -10, 0, 0, -30, 32, 11, -185, 56, 9, 173, 196, -146, 0, -59, 163, 219, 291, 18, 22, 159, 175, 0, 0, 0, 0, 0, 54, 0, 165, 0, 153, 0, 106, -1, 189, 0, 230, -291, 0, -330, 186, 519, 0, 0, 0, 0, 0, -33, 0, 0, 181, 0, 0, 280, 0, 158, 321, -236, 0, 0, 0, 0, 0, 0, -5, 0, 0, -140, 0, 0, 4, 174, 44, -246, -76, -220, 33, -698, 0, 0, 37, 0, 0, 188, 184, 0, 0, 111, -311, 0, 135, 0, 0, 0, 276, 313, 0, 0, 317, -71, 0, 162, 0, 0, 183, 166, 0, 182, 187, -3, 29, 172, 0, 0, 0, 0, 0, 0, 1, 0, 176, 167, 0, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -12, 0, 0, 112, 0, 130, 190, 168, 0, 0, 0, -51, 0, 97, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 71, 67, -56, 110, 241, 125, 0, 0, 82, 0, 42, 229, 0, 242, 113, 0, 0); + protected array $gotoDefault = array(-32768, 512, 740, 4, 741, 935, 816, 825, 597, 530, 707, 348, 625, 422, 1303, 911, 1122, 578, 844, 1246, 1254, 457, 847, 330, 730, 923, 894, 895, 400, 386, 392, 398, 649, 626, 494, 879, 453, 871, 486, 874, 452, 883, 164, 418, 510, 887, 3, 890, 557, 921, 973, 387, 898, 388, 677, 900, 562, 902, 903, 395, 401, 402, 1127, 570, 622, 915, 256, 564, 916, 385, 917, 925, 390, 393, 688, 465, 505, 499, 411, 1102, 565, 608, 646, 447, 473, 620, 632, 618, 480, 434, 416, 329, 957, 965, 487, 463, 979, 350, 987, 738, 1135, 640, 489, 995, 641, 1002, 1005, 531, 532, 478, 1017, 272, 1020, 490, 19, 667, 1031, 1032, 668, 642, 1054, 643, 669, 644, 1056, 472, 598, 1064, 454, 1072, 1291, 455, 1076, 266, 1079, 277, 417, 435, 1085, 1086, 9, 1092, 698, 699, 11, 276, 509, 1117, 689, 451, 1134, 439, 1204, 1206, 558, 491, 1224, 1223, 680, 506, 1229, 448, 1294, 449, 533, 474, 315, 534, 1338, 307, 333, 312, 549, 294, 334, 535, 475, 1300, 1308, 331, 31, 1328, 1339, 575, 613); + protected array $ruleToNonTerminal = array(0, 1, 3, 3, 2, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 9, 10, 11, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18, 21, 21, 22, 23, 23, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 29, 30, 30, 32, 34, 34, 28, 36, 36, 33, 38, 38, 35, 35, 37, 37, 39, 39, 31, 40, 40, 41, 43, 44, 44, 45, 45, 46, 46, 48, 47, 47, 47, 47, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 25, 25, 50, 69, 69, 72, 72, 71, 70, 70, 63, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 26, 26, 27, 27, 27, 27, 27, 88, 88, 90, 90, 83, 83, 91, 91, 92, 92, 92, 84, 84, 87, 87, 85, 85, 93, 94, 94, 57, 57, 65, 65, 68, 68, 68, 67, 95, 95, 96, 58, 58, 58, 58, 97, 97, 98, 98, 99, 99, 100, 101, 101, 102, 102, 103, 103, 55, 55, 51, 51, 105, 53, 53, 106, 52, 52, 54, 54, 64, 64, 64, 64, 81, 81, 109, 109, 111, 111, 112, 112, 112, 112, 110, 110, 110, 114, 114, 114, 114, 89, 89, 117, 117, 117, 118, 118, 115, 115, 119, 119, 121, 121, 122, 122, 116, 123, 123, 120, 124, 124, 124, 124, 113, 113, 82, 82, 82, 20, 20, 20, 126, 125, 125, 127, 127, 127, 127, 60, 128, 128, 129, 61, 131, 131, 132, 132, 133, 133, 86, 134, 134, 134, 134, 134, 134, 134, 139, 139, 140, 140, 141, 141, 141, 141, 141, 142, 143, 143, 138, 138, 135, 135, 137, 137, 145, 145, 144, 144, 144, 144, 144, 144, 144, 136, 146, 146, 148, 147, 147, 62, 104, 149, 149, 56, 56, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 156, 150, 150, 155, 155, 158, 159, 159, 160, 161, 162, 162, 162, 162, 19, 19, 73, 73, 73, 73, 151, 151, 151, 151, 164, 164, 152, 152, 154, 154, 154, 157, 157, 170, 170, 170, 170, 170, 170, 170, 170, 170, 171, 171, 171, 108, 173, 173, 173, 173, 153, 153, 153, 153, 153, 153, 153, 153, 59, 59, 167, 167, 167, 167, 174, 174, 163, 163, 163, 175, 175, 175, 175, 175, 175, 74, 74, 66, 66, 66, 66, 130, 130, 130, 130, 178, 177, 166, 166, 166, 166, 166, 166, 166, 165, 165, 165, 176, 176, 176, 176, 107, 172, 180, 180, 179, 179, 181, 181, 181, 181, 181, 181, 181, 181, 169, 169, 169, 169, 168, 183, 182, 182, 182, 182, 182, 182, 182, 182, 184, 184, 184, 184); + protected array $ruleToLength = array(1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 2, 1, 3, 4, 1, 2, 0, 1, 1, 1, 1, 4, 3, 5, 4, 3, 4, 2, 3, 1, 1, 7, 6, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 3, 1, 3, 1, 2, 2, 3, 1, 3, 2, 3, 1, 3, 3, 2, 0, 1, 1, 1, 1, 1, 3, 7, 10, 5, 7, 9, 5, 3, 3, 3, 3, 3, 3, 1, 2, 5, 7, 9, 6, 5, 6, 3, 2, 1, 1, 1, 1, 0, 2, 1, 3, 8, 0, 4, 2, 1, 3, 0, 1, 0, 1, 0, 1, 3, 1, 1, 1, 8, 9, 7, 8, 7, 6, 8, 0, 2, 0, 2, 1, 2, 1, 2, 1, 1, 1, 0, 2, 0, 2, 0, 2, 2, 1, 3, 1, 4, 1, 4, 1, 1, 4, 2, 1, 3, 3, 3, 4, 4, 5, 0, 2, 4, 3, 1, 1, 7, 0, 2, 1, 3, 3, 4, 1, 4, 0, 2, 5, 0, 2, 6, 0, 2, 0, 3, 1, 2, 1, 1, 2, 0, 1, 3, 0, 2, 1, 1, 1, 1, 6, 8, 6, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 3, 1, 1, 2, 1, 1, 0, 1, 0, 2, 2, 2, 4, 3, 1, 1, 3, 1, 2, 2, 3, 2, 3, 1, 1, 2, 3, 1, 1, 3, 2, 0, 1, 5, 5, 6, 10, 3, 5, 1, 1, 3, 0, 2, 4, 5, 4, 4, 4, 3, 1, 1, 1, 1, 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, 1, 1, 3, 2, 2, 3, 1, 0, 1, 1, 3, 3, 3, 4, 4, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 3, 4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 2, 1, 2, 4, 2, 2, 8, 9, 8, 9, 9, 10, 9, 10, 8, 3, 2, 0, 4, 2, 1, 3, 2, 1, 2, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 0, 3, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 5, 3, 3, 4, 1, 1, 3, 1, 1, 1, 1, 1, 3, 2, 3, 0, 1, 1, 3, 1, 1, 1, 1, 1, 3, 1, 1, 4, 4, 1, 4, 4, 0, 1, 1, 1, 3, 3, 1, 4, 2, 2, 1, 3, 1, 4, 4, 3, 3, 3, 3, 1, 3, 1, 1, 3, 1, 1, 4, 1, 1, 1, 3, 1, 1, 2, 1, 3, 4, 3, 2, 0, 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, 3, 3, 6, 3, 1, 1, 2, 1); + protected function initReduceCallbacks() : void + { + $this->reduceCallbacks = [0 => null, 1 => function ($stackPos) { $this->semValue = $this->handleNamespaces($this->semStack[$stackPos - (1 - 1)]); }, 2 => function ($stackPos) { - if (\is_array($this->semStack[$stackPos - (2 - 2)])) { - $this->semValue = \array_merge($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)]); - } else { + if ($this->semStack[$stackPos - (2 - 2)] !== null) { $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; } + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; }, 3 => function ($stackPos) { $this->semValue = array(); }, 4 => function ($stackPos) { - $startAttributes = $this->lookaheadStartAttributes; - if (isset($startAttributes['comments'])) { - $nop = new Stmt\Nop($this->createCommentNopAttributes($startAttributes['comments'])); - } else { - $nop = null; - } + $nop = $this->maybeCreateZeroLengthNop($this->tokenPos); if ($nop !== null) { $this->semStack[$stackPos - (1 - 1)][] = $nop; } $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 5 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 6 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 7 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 8 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 9 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 10 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 11 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 12 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 13 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 14 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 15 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 16 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 17 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 18 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 19 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 20 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 21 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 22 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 23 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 24 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 25 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 26 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 27 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 28 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 29 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 30 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 31 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 32 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 33 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 34 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 35 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 36 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 37 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 38 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 39 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 40 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 41 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 42 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 43 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 44 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 45 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 46 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 47 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 48 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 49 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 50 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 51 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 52 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 53 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 54 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 55 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 56 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 57 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 58 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 59 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 60 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 61 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 62 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 63 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 64 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 65 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 66 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 67 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 68 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 69 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 70 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 71 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 72 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 73 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 74 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 75 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 76 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 77 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 78 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 79 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 80 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 81 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 82 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 83 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 84 => function ($stackPos) { - $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 85 => function ($stackPos) { - $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + }, 5 => null, 6 => null, 7 => null, 8 => null, 9 => null, 10 => null, 11 => null, 12 => null, 13 => null, 14 => null, 15 => null, 16 => null, 17 => null, 18 => null, 19 => null, 20 => null, 21 => null, 22 => null, 23 => null, 24 => null, 25 => null, 26 => null, 27 => null, 28 => null, 29 => null, 30 => null, 31 => null, 32 => null, 33 => null, 34 => null, 35 => null, 36 => null, 37 => null, 38 => null, 39 => null, 40 => null, 41 => null, 42 => null, 43 => null, 44 => null, 45 => null, 46 => null, 47 => null, 48 => null, 49 => null, 50 => null, 51 => null, 52 => null, 53 => null, 54 => null, 55 => null, 56 => null, 57 => null, 58 => null, 59 => null, 60 => null, 61 => null, 62 => null, 63 => null, 64 => null, 65 => null, 66 => null, 67 => null, 68 => null, 69 => null, 70 => null, 71 => null, 72 => null, 73 => null, 74 => null, 75 => null, 76 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + if ($this->semValue === "emitError(new Error('Cannot use "getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos]))); + } + }, 77 => null, 78 => null, 79 => null, 80 => null, 81 => null, 82 => null, 83 => null, 84 => null, 85 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 86 => function ($stackPos) { - $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 87 => function ($stackPos) { - $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 88 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 89 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 90 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 91 => function ($stackPos) { - $this->semValue = new Name(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 92 => function ($stackPos) { - $this->semValue = new Expr\Variable(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 93 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 94 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 95 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 94 => null, 95 => function ($stackPos) { + $this->semValue = new Name(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 96 => function ($stackPos) { - $this->semValue = new Stmt\HaltCompiler($this->lexer->handleHaltCompiler(), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Variable(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 97 => function ($stackPos) { - $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos - (3 - 2)], null, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); - $this->checkNamespace($this->semValue); + /* nothing */ }, 98 => function ($stackPos) { - $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos - (5 - 2)], $this->semStack[$stackPos - (5 - 4)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); - $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); - $this->checkNamespace($this->semValue); + /* nothing */ }, 99 => function ($stackPos) { - $this->semValue = new Stmt\Namespace_(null, $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); - $this->checkNamespace($this->semValue); + /* nothing */ }, 100 => function ($stackPos) { - $this->semValue = new Stmt\Use_($this->semStack[$stackPos - (3 - 2)], Stmt\Use_::TYPE_NORMAL, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 101 => function ($stackPos) { - $this->semValue = new Stmt\Use_($this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 2)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 102 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 103 => function ($stackPos) { - $this->semValue = new Stmt\Const_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->emitError(new Error('A trailing comma is not allowed here', $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos]))); + }, 101 => null, 102 => null, 103 => function ($stackPos) { + $this->semValue = new Node\Attribute($this->semStack[$stackPos - (1 - 1)], [], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 104 => function ($stackPos) { - $this->semValue = Stmt\Use_::TYPE_FUNCTION; + $this->semValue = new Node\Attribute($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 105 => function ($stackPos) { - $this->semValue = Stmt\Use_::TYPE_CONSTANT; + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 106 => function ($stackPos) { - $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 6)], $this->semStack[$stackPos - (7 - 2)], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes); + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; }, 107 => function ($stackPos) { - $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes); + $this->semValue = new Node\AttributeGroup($this->semStack[$stackPos - (4 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 108 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + }, 109 => function ($stackPos) { + $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + }, 110 => function ($stackPos) { + $this->semValue = []; + }, 111 => null, 112 => null, 113 => null, 114 => null, 115 => function ($stackPos) { + $this->semValue = new Stmt\HaltCompiler($this->handleHaltCompiler(), $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 116 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos - (3 - 2)], null, $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); + $this->checkNamespace($this->semValue); + }, 117 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos - (5 - 2)], $this->semStack[$stackPos - (5 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($this->semValue); + }, 118 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_(null, $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($this->semValue); + }, 119 => function ($stackPos) { + $this->semValue = new Stmt\Use_($this->semStack[$stackPos - (3 - 2)], Stmt\Use_::TYPE_NORMAL, $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 120 => function ($stackPos) { + $this->semValue = new Stmt\Use_($this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 121 => null, 122 => function ($stackPos) { + $this->semValue = new Stmt\Const_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 123 => function ($stackPos) { + $this->semValue = Stmt\Use_::TYPE_FUNCTION; + }, 124 => function ($stackPos) { + $this->semValue = Stmt\Use_::TYPE_CONSTANT; + }, 125 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 6)], $this->semStack[$stackPos - (7 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (7 - 1)], $this->tokenEndStack[$stackPos])); + }, 126 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 5)], Stmt\Use_::TYPE_UNKNOWN, $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos])); + }, 127 => null, 128 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 109 => function ($stackPos) { + }, 129 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 110 => function ($stackPos) { + }, 130 => null, 131 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 111 => function ($stackPos) { + }, 132 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 112 => function ($stackPos) { + }, 133 => null, 134 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 113 => function ($stackPos) { + }, 135 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 114 => function ($stackPos) { - $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + }, 136 => function ($stackPos) { + $this->semValue = new Node\UseItem($this->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); $this->checkUseUse($this->semValue, $stackPos - (1 - 1)); - }, 115 => function ($stackPos) { - $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + }, 137 => function ($stackPos) { + $this->semValue = new Node\UseItem($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); $this->checkUseUse($this->semValue, $stackPos - (3 - 3)); - }, 116 => function ($stackPos) { - $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + }, 138 => function ($stackPos) { + $this->semValue = new Node\UseItem($this->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); $this->checkUseUse($this->semValue, $stackPos - (1 - 1)); - }, 117 => function ($stackPos) { - $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + }, 139 => function ($stackPos) { + $this->semValue = new Node\UseItem($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); $this->checkUseUse($this->semValue, $stackPos - (3 - 3)); - }, 118 => function ($stackPos) { + }, 140 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (1 - 1)]; $this->semValue->type = Stmt\Use_::TYPE_NORMAL; - }, 119 => function ($stackPos) { + }, 141 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (2 - 2)]; $this->semValue->type = $this->semStack[$stackPos - (2 - 1)]; - }, 120 => function ($stackPos) { + }, 142 => null, 143 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 121 => function ($stackPos) { + }, 144 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 122 => function ($stackPos) { - $this->semValue = new Node\Const_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 123 => function ($stackPos) { + }, 145 => function ($stackPos) { + $this->semValue = new Node\Const_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 146 => null, 147 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 124 => function ($stackPos) { + }, 148 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 125 => function ($stackPos) { - $this->semValue = new Node\Const_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 126 => function ($stackPos) { - if (\is_array($this->semStack[$stackPos - (2 - 2)])) { - $this->semValue = \array_merge($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)]); - } else { + }, 149 => function ($stackPos) { + $this->semValue = new Node\Const_(new Node\Identifier($this->semStack[$stackPos - (3 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos - (3 - 1)])), $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 150 => function ($stackPos) { + $this->semValue = new Node\Const_(new Node\Identifier($this->semStack[$stackPos - (3 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos - (3 - 1)])), $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 151 => function ($stackPos) { + if ($this->semStack[$stackPos - (2 - 2)] !== null) { $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; } - }, 127 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + }, 152 => function ($stackPos) { $this->semValue = array(); - }, 128 => function ($stackPos) { - $startAttributes = $this->lookaheadStartAttributes; - if (isset($startAttributes['comments'])) { - $nop = new Stmt\Nop($this->createCommentNopAttributes($startAttributes['comments'])); - } else { - $nop = null; - } + }, 153 => function ($stackPos) { + $nop = $this->maybeCreateZeroLengthNop($this->tokenPos); if ($nop !== null) { $this->semStack[$stackPos - (1 - 1)][] = $nop; } $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 129 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 130 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 131 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 132 => function ($stackPos) { - throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 133 => function ($stackPos) { - if ($this->semStack[$stackPos - (3 - 2)]) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; - $attrs = $this->startAttributeStack[$stackPos - (3 - 1)]; - $stmts = $this->semValue; - if (!empty($attrs['comments'])) { - $stmts[0]->setAttribute('comments', \array_merge($attrs['comments'], $stmts[0]->getAttribute('comments', []))); - } - } else { - $startAttributes = $this->startAttributeStack[$stackPos - (3 - 1)]; - if (isset($startAttributes['comments'])) { - $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes); - } else { - $this->semValue = null; - } - if (null === $this->semValue) { - $this->semValue = array(); - } - } - }, 134 => function ($stackPos) { - $this->semValue = new Stmt\If_($this->semStack[$stackPos - (5 - 2)], ['stmts' => \is_array($this->semStack[$stackPos - (5 - 3)]) ? $this->semStack[$stackPos - (5 - 3)] : array($this->semStack[$stackPos - (5 - 3)]), 'elseifs' => $this->semStack[$stackPos - (5 - 4)], 'else' => $this->semStack[$stackPos - (5 - 5)]], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); - }, 135 => function ($stackPos) { - $this->semValue = new Stmt\If_($this->semStack[$stackPos - (8 - 2)], ['stmts' => $this->semStack[$stackPos - (8 - 4)], 'elseifs' => $this->semStack[$stackPos - (8 - 5)], 'else' => $this->semStack[$stackPos - (8 - 6)]], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes); - }, 136 => function ($stackPos) { - $this->semValue = new Stmt\While_($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 137 => function ($stackPos) { - $this->semValue = new Stmt\Do_($this->semStack[$stackPos - (5 - 4)], \is_array($this->semStack[$stackPos - (5 - 2)]) ? $this->semStack[$stackPos - (5 - 2)] : array($this->semStack[$stackPos - (5 - 2)]), $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); - }, 138 => function ($stackPos) { - $this->semValue = new Stmt\For_(['init' => $this->semStack[$stackPos - (9 - 3)], 'cond' => $this->semStack[$stackPos - (9 - 5)], 'loop' => $this->semStack[$stackPos - (9 - 7)], 'stmts' => $this->semStack[$stackPos - (9 - 9)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes); - }, 139 => function ($stackPos) { - $this->semValue = new Stmt\Switch_($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 140 => function ($stackPos) { - $this->semValue = new Stmt\Break_(null, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 141 => function ($stackPos) { - $this->semValue = new Stmt\Break_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 142 => function ($stackPos) { - $this->semValue = new Stmt\Continue_(null, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 143 => function ($stackPos) { - $this->semValue = new Stmt\Continue_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 144 => function ($stackPos) { - $this->semValue = new Stmt\Return_(null, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 145 => function ($stackPos) { - $this->semValue = new Stmt\Return_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 146 => function ($stackPos) { - $this->semValue = new Stmt\Global_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 147 => function ($stackPos) { - $this->semValue = new Stmt\Static_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 148 => function ($stackPos) { - $this->semValue = new Stmt\Echo_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 149 => function ($stackPos) { - $this->semValue = new Stmt\InlineHTML($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 150 => function ($stackPos) { - $this->semValue = new Stmt\Expression($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 151 => function ($stackPos) { - $this->semValue = new Stmt\Expression($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 152 => function ($stackPos) { - $this->semValue = new Stmt\Unset_($this->semStack[$stackPos - (5 - 3)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); - }, 153 => function ($stackPos) { - $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$stackPos - (7 - 5)][1], 'stmts' => $this->semStack[$stackPos - (7 - 7)]], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes); - }, 154 => function ($stackPos) { - $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (9 - 3)], $this->semStack[$stackPos - (9 - 7)][0], ['keyVar' => $this->semStack[$stackPos - (9 - 5)], 'byRef' => $this->semStack[$stackPos - (9 - 7)][1], 'stmts' => $this->semStack[$stackPos - (9 - 9)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes); - }, 155 => function ($stackPos) { - $this->semValue = new Stmt\Declare_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); - }, 156 => function ($stackPos) { - $this->semValue = new Stmt\TryCatch($this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 5)], $this->semStack[$stackPos - (6 - 6)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes); - $this->checkTryCatch($this->semValue); - }, 157 => function ($stackPos) { - $this->semValue = new Stmt\Throw_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + }, 154 => null, 155 => null, 156 => null, 157 => function ($stackPos) { + throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 158 => function ($stackPos) { - $this->semValue = new Stmt\Goto_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Block($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 159 => function ($stackPos) { - $this->semValue = new Stmt\Label($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\If_($this->semStack[$stackPos - (7 - 3)], ['stmts' => $this->semStack[$stackPos - (7 - 5)], 'elseifs' => $this->semStack[$stackPos - (7 - 6)], 'else' => $this->semStack[$stackPos - (7 - 7)]], $this->getAttributes($this->tokenStartStack[$stackPos - (7 - 1)], $this->tokenEndStack[$stackPos])); }, 160 => function ($stackPos) { - $this->semValue = new Stmt\Expression($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\If_($this->semStack[$stackPos - (10 - 3)], ['stmts' => $this->semStack[$stackPos - (10 - 6)], 'elseifs' => $this->semStack[$stackPos - (10 - 7)], 'else' => $this->semStack[$stackPos - (10 - 8)]], $this->getAttributes($this->tokenStartStack[$stackPos - (10 - 1)], $this->tokenEndStack[$stackPos])); }, 161 => function ($stackPos) { - $this->semValue = array(); - /* means: no statement */ + $this->semValue = new Stmt\While_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 162 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Stmt\Do_($this->semStack[$stackPos - (7 - 5)], $this->semStack[$stackPos - (7 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (7 - 1)], $this->tokenEndStack[$stackPos])); }, 163 => function ($stackPos) { - $startAttributes = $this->startAttributeStack[$stackPos - (1 - 1)]; - if (isset($startAttributes['comments'])) { - $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes); - } else { - $this->semValue = null; - } - if ($this->semValue === null) { - $this->semValue = array(); - } - /* means: no statement */ + $this->semValue = new Stmt\For_(['init' => $this->semStack[$stackPos - (9 - 3)], 'cond' => $this->semStack[$stackPos - (9 - 5)], 'loop' => $this->semStack[$stackPos - (9 - 7)], 'stmts' => $this->semStack[$stackPos - (9 - 9)]], $this->getAttributes($this->tokenStartStack[$stackPos - (9 - 1)], $this->tokenEndStack[$stackPos])); }, 164 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = new Stmt\Switch_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 165 => function ($stackPos) { - $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + $this->semValue = new Stmt\Break_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 166 => function ($stackPos) { - $this->semValue = new Stmt\Catch_(array($this->semStack[$stackPos - (8 - 3)]), $this->semStack[$stackPos - (8 - 4)], $this->semStack[$stackPos - (8 - 7)], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Continue_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 167 => function ($stackPos) { - $this->semValue = null; + $this->semValue = new Stmt\Return_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 168 => function ($stackPos) { - $this->semValue = new Stmt\Finally_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Global_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 169 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + $this->semValue = new Stmt\Static_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 170 => function ($stackPos) { - $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; - $this->semValue = $this->semStack[$stackPos - (3 - 1)]; + $this->semValue = new Stmt\Echo_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 171 => function ($stackPos) { - $this->semValue = \false; + $this->semValue = new Stmt\InlineHTML($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + $this->semValue->setAttribute('hasLeadingNewline', $this->inlineHtmlHasLeadingNewline($stackPos - (1 - 1))); }, 172 => function ($stackPos) { - $this->semValue = \true; + $this->semValue = new Stmt\Expression($this->semStack[$stackPos - (2 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 173 => function ($stackPos) { - $this->semValue = \false; + $this->semValue = new Stmt\Unset_($this->semStack[$stackPos - (5 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 174 => function ($stackPos) { - $this->semValue = \true; + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$stackPos - (7 - 5)][1], 'stmts' => $this->semStack[$stackPos - (7 - 7)]], $this->getAttributes($this->tokenStartStack[$stackPos - (7 - 1)], $this->tokenEndStack[$stackPos])); }, 175 => function ($stackPos) { - $this->semValue = \false; + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (9 - 3)], $this->semStack[$stackPos - (9 - 7)][0], ['keyVar' => $this->semStack[$stackPos - (9 - 5)], 'byRef' => $this->semStack[$stackPos - (9 - 7)][1], 'stmts' => $this->semStack[$stackPos - (9 - 9)]], $this->getAttributes($this->tokenStartStack[$stackPos - (9 - 1)], $this->tokenEndStack[$stackPos])); }, 176 => function ($stackPos) { - $this->semValue = \true; + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (6 - 3)], new Expr\Error($this->getAttributes($this->tokenStartStack[$stackPos - (6 - 4)], $this->tokenEndStack[$stackPos - (6 - 4)])), ['stmts' => $this->semStack[$stackPos - (6 - 6)]], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos])); }, 177 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Stmt\Declare_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 178 => function ($stackPos) { - $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\TryCatch($this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 5)], $this->semStack[$stackPos - (6 - 6)], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos])); + $this->checkTryCatch($this->semValue); }, 179 => function ($stackPos) { - $this->semValue = new Stmt\Function_($this->semStack[$stackPos - (10 - 3)], ['byRef' => $this->semStack[$stackPos - (10 - 2)], 'params' => $this->semStack[$stackPos - (10 - 5)], 'returnType' => $this->semStack[$stackPos - (10 - 7)], 'stmts' => $this->semStack[$stackPos - (10 - 9)]], $this->startAttributeStack[$stackPos - (10 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Goto_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 180 => function ($stackPos) { - $this->semValue = new Stmt\Class_($this->semStack[$stackPos - (7 - 2)], ['type' => $this->semStack[$stackPos - (7 - 1)], 'extends' => $this->semStack[$stackPos - (7 - 3)], 'implements' => $this->semStack[$stackPos - (7 - 4)], 'stmts' => $this->semStack[$stackPos - (7 - 6)]], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes); - $this->checkClass($this->semValue, $stackPos - (7 - 2)); + $this->semValue = new Stmt\Label($this->semStack[$stackPos - (2 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 181 => function ($stackPos) { - $this->semValue = new Stmt\Interface_($this->semStack[$stackPos - (6 - 2)], ['extends' => $this->semStack[$stackPos - (6 - 3)], 'stmts' => $this->semStack[$stackPos - (6 - 5)]], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes); - $this->checkInterface($this->semValue, $stackPos - (6 - 2)); - }, 182 => function ($stackPos) { - $this->semValue = new Stmt\Trait_($this->semStack[$stackPos - (5 - 2)], ['stmts' => $this->semStack[$stackPos - (5 - 4)]], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); - }, 183 => function ($stackPos) { - $this->semValue = 0; + $this->semValue = null; + /* means: no statement */ + }, 182 => null, 183 => function ($stackPos) { + $this->semValue = $this->maybeCreateNop($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos]); }, 184 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + if ($this->semStack[$stackPos - (1 - 1)] instanceof Stmt\Block) { + $this->semValue = $this->semStack[$stackPos - (1 - 1)]->stmts; + } else { + if ($this->semStack[$stackPos - (1 - 1)] === null) { + $this->semValue = []; + } else { + $this->semValue = [$this->semStack[$stackPos - (1 - 1)]]; + } + } }, 185 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_FINAL; + $this->semValue = array(); }, 186 => function ($stackPos) { - $this->semValue = null; + $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; }, 187 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 188 => function ($stackPos) { - $this->semValue = array(); + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; }, 189 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = new Stmt\Catch_($this->semStack[$stackPos - (8 - 3)], $this->semStack[$stackPos - (8 - 4)], $this->semStack[$stackPos - (8 - 7)], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos])); }, 190 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = null; }, 191 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 2)]; - }, 192 => function ($stackPos) { + $this->semValue = new Stmt\Finally_($this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 192 => null, 193 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 193 => function ($stackPos) { + }, 194 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 194 => function ($stackPos) { - $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]); }, 195 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (4 - 2)]; + $this->semValue = \false; }, 196 => function ($stackPos) { - $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]); + $this->semValue = \true; }, 197 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (4 - 2)]; + $this->semValue = \false; }, 198 => function ($stackPos) { - $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]); + $this->semValue = \true; }, 199 => function ($stackPos) { - $this->semValue = null; + $this->semValue = \false; }, 200 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (4 - 2)]; + $this->semValue = \true; }, 201 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 202 => function ($stackPos) { - $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; - $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 203 => function ($stackPos) { - $this->semValue = new Stmt\DeclareDeclare($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 204 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + }, 202 => function ($stackPos) { + $this->semValue = []; + }, 203 => null, 204 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 205 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (4 - 3)]; + $this->semValue = new Stmt\Function_($this->semStack[$stackPos - (8 - 3)], ['byRef' => $this->semStack[$stackPos - (8 - 2)], 'params' => $this->semStack[$stackPos - (8 - 5)], 'returnType' => $this->semStack[$stackPos - (8 - 7)], 'stmts' => $this->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos])); }, 206 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (4 - 2)]; + $this->semValue = new Stmt\Function_($this->semStack[$stackPos - (9 - 4)], ['byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 6)], 'returnType' => $this->semStack[$stackPos - (9 - 8)], 'stmts' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => $this->semStack[$stackPos - (9 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (9 - 1)], $this->tokenEndStack[$stackPos])); }, 207 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (5 - 3)]; + $this->semValue = new Stmt\Class_($this->semStack[$stackPos - (7 - 2)], ['type' => $this->semStack[$stackPos - (7 - 1)], 'extends' => $this->semStack[$stackPos - (7 - 3)], 'implements' => $this->semStack[$stackPos - (7 - 4)], 'stmts' => $this->semStack[$stackPos - (7 - 6)], 'attrGroups' => []], $this->getAttributes($this->tokenStartStack[$stackPos - (7 - 1)], $this->tokenEndStack[$stackPos])); + $this->checkClass($this->semValue, $stackPos - (7 - 2)); }, 208 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = new Stmt\Class_($this->semStack[$stackPos - (8 - 3)], ['type' => $this->semStack[$stackPos - (8 - 2)], 'extends' => $this->semStack[$stackPos - (8 - 4)], 'implements' => $this->semStack[$stackPos - (8 - 5)], 'stmts' => $this->semStack[$stackPos - (8 - 7)], 'attrGroups' => $this->semStack[$stackPos - (8 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos])); + $this->checkClass($this->semValue, $stackPos - (8 - 3)); }, 209 => function ($stackPos) { - $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + $this->semValue = new Stmt\Interface_($this->semStack[$stackPos - (7 - 3)], ['extends' => $this->semStack[$stackPos - (7 - 4)], 'stmts' => $this->semStack[$stackPos - (7 - 6)], 'attrGroups' => $this->semStack[$stackPos - (7 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (7 - 1)], $this->tokenEndStack[$stackPos])); + $this->checkInterface($this->semValue, $stackPos - (7 - 3)); }, 210 => function ($stackPos) { - $this->semValue = new Stmt\Case_($this->semStack[$stackPos - (4 - 2)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Trait_($this->semStack[$stackPos - (6 - 3)], ['stmts' => $this->semStack[$stackPos - (6 - 5)], 'attrGroups' => $this->semStack[$stackPos - (6 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos])); }, 211 => function ($stackPos) { - $this->semValue = new Stmt\Case_(null, $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Enum_($this->semStack[$stackPos - (8 - 3)], ['scalarType' => $this->semStack[$stackPos - (8 - 4)], 'implements' => $this->semStack[$stackPos - (8 - 5)], 'stmts' => $this->semStack[$stackPos - (8 - 7)], 'attrGroups' => $this->semStack[$stackPos - (8 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos])); + $this->checkEnum($this->semValue, $stackPos - (8 - 3)); }, 212 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; + $this->semValue = null; }, 213 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; + $this->semValue = $this->semStack[$stackPos - (2 - 2)]; }, 214 => function ($stackPos) { - $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]); + $this->semValue = null; }, 215 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (4 - 2)]; + $this->semValue = $this->semStack[$stackPos - (2 - 2)]; }, 216 => function ($stackPos) { - $this->semValue = array(); - }, 217 => function ($stackPos) { - $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 218 => function ($stackPos) { - $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos - (3 - 2)], \is_array($this->semStack[$stackPos - (3 - 3)]) ? $this->semStack[$stackPos - (3 - 3)] : array($this->semStack[$stackPos - (3 - 3)]), $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 219 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = 0; + }, 217 => null, 218 => null, 219 => function ($stackPos) { + $this->checkClassModifier($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2)); + $this->semValue = $this->semStack[$stackPos - (2 - 1)] | $this->semStack[$stackPos - (2 - 2)]; }, 220 => function ($stackPos) { - $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + $this->semValue = Modifiers::ABSTRACT; }, 221 => function ($stackPos) { - $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos - (4 - 2)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = Modifiers::FINAL; }, 222 => function ($stackPos) { - $this->semValue = null; + $this->semValue = Modifiers::READONLY; }, 223 => function ($stackPos) { - $this->semValue = new Stmt\Else_(\is_array($this->semStack[$stackPos - (2 - 2)]) ? $this->semStack[$stackPos - (2 - 2)] : array($this->semStack[$stackPos - (2 - 2)]), $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 224 => function ($stackPos) { $this->semValue = null; + }, 224 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (2 - 2)]; }, 225 => function ($stackPos) { - $this->semValue = new Stmt\Else_($this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = array(); }, 226 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)], \false); + $this->semValue = $this->semStack[$stackPos - (2 - 2)]; }, 227 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (2 - 2)], \true); - }, 228 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)], \false); - }, 229 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 230 => function ($stackPos) { $this->semValue = array(); - }, 231 => function ($stackPos) { + }, 228 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (2 - 2)]; + }, 229 => null, 230 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 232 => function ($stackPos) { + }, 231 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 233 => function ($stackPos) { - $this->semValue = new Node\Param($this->semStack[$stackPos - (4 - 4)], null, $this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 2)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - $this->checkParam($this->semValue); - }, 234 => function ($stackPos) { - $this->semValue = new Node\Param($this->semStack[$stackPos - (6 - 4)], $this->semStack[$stackPos - (6 - 6)], $this->semStack[$stackPos - (6 - 1)], $this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 3)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes); - $this->checkParam($this->semValue); - }, 235 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + }, 232 => null, 233 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (4 - 2)]; + }, 234 => null, 235 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (4 - 2)]; }, 236 => function ($stackPos) { - $this->semValue = new Node\Identifier('array', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + if ($this->semStack[$stackPos - (1 - 1)] instanceof Stmt\Block) { + $this->semValue = $this->semStack[$stackPos - (1 - 1)]->stmts; + } else { + if ($this->semStack[$stackPos - (1 - 1)] === null) { + $this->semValue = []; + } else { + $this->semValue = [$this->semStack[$stackPos - (1 - 1)]]; + } + } }, 237 => function ($stackPos) { - $this->semValue = new Node\Identifier('callable', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 238 => function ($stackPos) { - $this->semValue = null; - }, 239 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 240 => function ($stackPos) { $this->semValue = null; + }, 238 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (4 - 2)]; + }, 239 => null, 240 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 241 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 2)]; + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; }, 242 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = new Node\DeclareItem($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 243 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (3 - 2)]; }, 244 => function ($stackPos) { - $this->semValue = array(new Node\Arg($this->semStack[$stackPos - (3 - 2)], \false, \false, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes)); + $this->semValue = $this->semStack[$stackPos - (4 - 3)]; }, 245 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + $this->semValue = $this->semStack[$stackPos - (4 - 2)]; }, 246 => function ($stackPos) { - $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; - $this->semValue = $this->semStack[$stackPos - (3 - 1)]; + $this->semValue = $this->semStack[$stackPos - (5 - 3)]; }, 247 => function ($stackPos) { - $this->semValue = new Node\Arg($this->semStack[$stackPos - (1 - 1)], \false, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = array(); }, 248 => function ($stackPos) { - $this->semValue = new Node\Arg($this->semStack[$stackPos - (2 - 2)], \true, \false, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; }, 249 => function ($stackPos) { - $this->semValue = new Node\Arg($this->semStack[$stackPos - (2 - 2)], \false, \true, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Case_($this->semStack[$stackPos - (4 - 2)], $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 250 => function ($stackPos) { - $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; - $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 251 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 252 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 253 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Case_(null, $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 251 => null, 252 => null, 253 => function ($stackPos) { + $this->semValue = new Expr\Match_($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 6)], $this->getAttributes($this->tokenStartStack[$stackPos - (7 - 1)], $this->tokenEndStack[$stackPos])); }, 254 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 255 => function ($stackPos) { - $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; - $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 256 => function ($stackPos) { + $this->semValue = []; + }, 255 => null, 256 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 257 => function ($stackPos) { - $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos - (1 - 1)], null, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; }, 258 => function ($stackPos) { - $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\MatchArm($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 259 => function ($stackPos) { - if ($this->semStack[$stackPos - (2 - 2)] !== null) { - $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - } + $this->semValue = new Node\MatchArm(null, $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 260 => function ($stackPos) { - $this->semValue = array(); - }, 261 => function ($stackPos) { - $startAttributes = $this->lookaheadStartAttributes; - if (isset($startAttributes['comments'])) { - $nop = new Stmt\Nop($this->createCommentNopAttributes($startAttributes['comments'])); - } else { - $nop = null; - } - if ($nop !== null) { - $this->semStack[$stackPos - (1 - 1)][] = $nop; - } $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + }, 261 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (4 - 2)]; }, 262 => function ($stackPos) { - $this->semValue = new Stmt\Property($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - $this->checkProperty($this->semValue, $stackPos - (3 - 1)); + $this->semValue = array(); }, 263 => function ($stackPos) { - $this->semValue = new Stmt\ClassConst($this->semStack[$stackPos - (3 - 2)], 0, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; }, 264 => function ($stackPos) { - $this->semValue = new Stmt\ClassMethod($this->semStack[$stackPos - (9 - 4)], ['type' => $this->semStack[$stackPos - (9 - 1)], 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 6)], 'returnType' => $this->semStack[$stackPos - (9 - 8)], 'stmts' => $this->semStack[$stackPos - (9 - 9)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes); - $this->checkClassMethod($this->semValue, $stackPos - (9 - 1)); + $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 265 => function ($stackPos) { - $this->semValue = new Stmt\TraitUse($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 266 => function ($stackPos) { $this->semValue = array(); + }, 266 => function ($stackPos) { + $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; }, 267 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 6)], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos])); + $this->fixupAlternativeElse($this->semValue); }, 268 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = null; }, 269 => function ($stackPos) { - $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + $this->semValue = new Stmt\Else_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 270 => function ($stackPos) { - $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = null; }, 271 => function ($stackPos) { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (5 - 1)][0], $this->semStack[$stackPos - (5 - 1)][1], $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 4)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Else_($this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + $this->fixupAlternativeElse($this->semValue); }, 272 => function ($stackPos) { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], $this->semStack[$stackPos - (4 - 3)], null, $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (1 - 1)], \false); }, 273 => function ($stackPos) { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], null, $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (2 - 2)], \true); }, 274 => function ($stackPos) { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], null, $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (1 - 1)], \false); }, 275 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); - }, 276 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 277 => function ($stackPos) { - $this->semValue = array(null, $this->semStack[$stackPos - (1 - 1)]); + $this->semValue = array($this->fixupArrayDestructuring($this->semStack[$stackPos - (1 - 1)]), \false); + }, 276 => null, 277 => function ($stackPos) { + $this->semValue = array(); }, 278 => function ($stackPos) { - $this->semValue = null; + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 279 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; }, 280 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 281 => function ($stackPos) { $this->semValue = 0; + }, 281 => function ($stackPos) { + $this->checkModifier($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2)); + $this->semValue = $this->semStack[$stackPos - (2 - 1)] | $this->semStack[$stackPos - (2 - 2)]; }, 282 => function ($stackPos) { - $this->semValue = 0; + $this->semValue = Modifiers::PUBLIC; }, 283 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = Modifiers::PROTECTED; }, 284 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = Modifiers::PRIVATE; }, 285 => function ($stackPos) { - $this->checkModifier($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2)); - $this->semValue = $this->semStack[$stackPos - (2 - 1)] | $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = Modifiers::READONLY; }, 286 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; + $this->semValue = new Node\Param($this->semStack[$stackPos - (6 - 6)], null, $this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 4)], $this->semStack[$stackPos - (6 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos]), $this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 1)]); + $this->checkParam($this->semValue); }, 287 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; + $this->semValue = new Node\Param($this->semStack[$stackPos - (8 - 6)], $this->semStack[$stackPos - (8 - 8)], $this->semStack[$stackPos - (8 - 3)], $this->semStack[$stackPos - (8 - 4)], $this->semStack[$stackPos - (8 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos]), $this->semStack[$stackPos - (8 - 2)], $this->semStack[$stackPos - (8 - 1)]); + $this->checkParam($this->semValue); }, 288 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; - }, 289 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_STATIC; - }, 290 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + $this->semValue = new Node\Param(new Expr\Error($this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos])), null, $this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 4)], $this->semStack[$stackPos - (6 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos]), $this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 1)]); + }, 289 => null, 290 => function ($stackPos) { + $this->semValue = new Node\NullableType($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 291 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_FINAL; - }, 292 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 293 => function ($stackPos) { - $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; - $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 294 => function ($stackPos) { - $this->semValue = new Node\VarLikeIdentifier(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Node\UnionType($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 292 => null, 293 => null, 294 => function ($stackPos) { + $this->semValue = new Node\Name('static', $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 295 => function ($stackPos) { - $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos - (1 - 1)], null, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = $this->handleBuiltinTypes($this->semStack[$stackPos - (1 - 1)]); }, 296 => function ($stackPos) { - $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\Identifier('array', $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 297 => function ($stackPos) { - $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; - $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 298 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 299 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = new Node\Identifier('callable', $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 298 => null, 299 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; }, 300 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); }, 301 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 302 => function ($stackPos) { - $this->semValue = new Expr\Assign($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 303 => function ($stackPos) { - $this->semValue = new Expr\Assign($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; + }, 302 => null, 303 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; }, 304 => function ($stackPos) { - $this->semValue = new Expr\AssignRef($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); }, 305 => function ($stackPos) { - $this->semValue = new Expr\AssignRef($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; }, 306 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); }, 307 => function ($stackPos) { - $this->semValue = new Expr\Clone_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; }, 308 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Plus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\IntersectionType($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 309 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Minus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); }, 310 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Mul($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; }, 311 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Div($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 312 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Concat($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 313 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Mod($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\IntersectionType($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 312 => null, 313 => function ($stackPos) { + $this->semValue = new Node\NullableType($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 314 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 315 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 316 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 317 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 318 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\UnionType($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 315 => null, 316 => function ($stackPos) { + $this->semValue = null; + }, 317 => null, 318 => function ($stackPos) { + $this->semValue = null; }, 319 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Pow($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = $this->semStack[$stackPos - (2 - 2)]; }, 320 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Coalesce($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = null; }, 321 => function ($stackPos) { - $this->semValue = new Expr\PostInc($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = array(); }, 322 => function ($stackPos) { - $this->semValue = new Expr\PreInc($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = $this->semStack[$stackPos - (4 - 2)]; }, 323 => function ($stackPos) { - $this->semValue = new Expr\PostDec($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (3 - 2)]); }, 324 => function ($stackPos) { - $this->semValue = new Expr\PreDec($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Node\VariadicPlaceholder($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 325 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 326 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; }, 327 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\Arg($this->semStack[$stackPos - (1 - 1)], \false, \false, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 328 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\Arg($this->semStack[$stackPos - (2 - 2)], \true, \false, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 329 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\Arg($this->semStack[$stackPos - (2 - 2)], \false, \true, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 330 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 331 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 332 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\Arg($this->semStack[$stackPos - (3 - 3)], \false, \false, $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos]), $this->semStack[$stackPos - (3 - 1)]); + }, 331 => null, 332 => function ($stackPos) { + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; }, 333 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 334 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 335 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 336 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + }, 334 => null, 335 => null, 336 => function ($stackPos) { + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; }, 337 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 338 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\StaticVar($this->semStack[$stackPos - (1 - 1)], null, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 339 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\StaticVar($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 340 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + if ($this->semStack[$stackPos - (2 - 2)] !== null) { + $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + } else { + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + } }, 341 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = array(); }, 342 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $nop = $this->maybeCreateZeroLengthNop($this->tokenPos); + if ($nop !== null) { + $this->semStack[$stackPos - (1 - 1)][] = $nop; + } + $this->semValue = $this->semStack[$stackPos - (1 - 1)]; }, 343 => function ($stackPos) { - $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Property($this->semStack[$stackPos - (5 - 2)], $this->semStack[$stackPos - (5 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos]), $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 1)]); + $this->checkProperty($this->semValue, $stackPos - (5 - 2)); }, 344 => function ($stackPos) { - $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\ClassConst($this->semStack[$stackPos - (5 - 4)], $this->semStack[$stackPos - (5 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos]), $this->semStack[$stackPos - (5 - 1)]); + $this->checkClassConst($this->semValue, $stackPos - (5 - 2)); }, 345 => function ($stackPos) { - $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\ClassConst($this->semStack[$stackPos - (6 - 5)], $this->semStack[$stackPos - (6 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos]), $this->semStack[$stackPos - (6 - 1)], $this->semStack[$stackPos - (6 - 4)]); + $this->checkClassConst($this->semValue, $stackPos - (6 - 2)); }, 346 => function ($stackPos) { - $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\ClassMethod($this->semStack[$stackPos - (10 - 5)], ['type' => $this->semStack[$stackPos - (10 - 2)], 'byRef' => $this->semStack[$stackPos - (10 - 4)], 'params' => $this->semStack[$stackPos - (10 - 7)], 'returnType' => $this->semStack[$stackPos - (10 - 9)], 'stmts' => $this->semStack[$stackPos - (10 - 10)], 'attrGroups' => $this->semStack[$stackPos - (10 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (10 - 1)], $this->tokenEndStack[$stackPos])); + $this->checkClassMethod($this->semValue, $stackPos - (10 - 2)); }, 347 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\TraitUse($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 348 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\EnumCase($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 4)], $this->semStack[$stackPos - (5 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 349 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = null; + /* will be skipped */ }, 350 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = array(); }, 351 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; }, 352 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = array(); }, 353 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; }, 354 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 355 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (5 - 1)][0], $this->semStack[$stackPos - (5 - 1)][1], $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 356 => function ($stackPos) { - $this->semValue = new Expr\Instanceof_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], $this->semStack[$stackPos - (4 - 3)], null, $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 357 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], null, $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 358 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], null, $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 359 => function ($stackPos) { - $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (5 - 1)], $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); - }, 360 => function ($stackPos) { - $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (4 - 1)], null, $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 361 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); + }, 360 => null, 361 => function ($stackPos) { + $this->semValue = array(null, $this->semStack[$stackPos - (1 - 1)]); }, 362 => function ($stackPos) { - $this->semValue = new Expr\Isset_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 363 => function ($stackPos) { - $this->semValue = new Expr\Empty_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 364 => function ($stackPos) { - $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 365 => function ($stackPos) { - $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = null; + }, 363 => null, 364 => null, 365 => function ($stackPos) { + $this->semValue = 0; }, 366 => function ($stackPos) { - $this->semValue = new Expr\Eval_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 367 => function ($stackPos) { - $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 368 => function ($stackPos) { - $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 369 => function ($stackPos) { - $this->semValue = new Expr\Cast\Int_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = 0; + }, 367 => null, 368 => null, 369 => function ($stackPos) { + $this->checkModifier($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2)); + $this->semValue = $this->semStack[$stackPos - (2 - 1)] | $this->semStack[$stackPos - (2 - 2)]; }, 370 => function ($stackPos) { - $attrs = $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes; - $attrs['kind'] = $this->getFloatCastKind($this->semStack[$stackPos - (2 - 1)]); - $this->semValue = new Expr\Cast\Double($this->semStack[$stackPos - (2 - 2)], $attrs); + $this->semValue = Modifiers::PUBLIC; }, 371 => function ($stackPos) { - $this->semValue = new Expr\Cast\String_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = Modifiers::PROTECTED; }, 372 => function ($stackPos) { - $this->semValue = new Expr\Cast\Array_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = Modifiers::PRIVATE; }, 373 => function ($stackPos) { - $this->semValue = new Expr\Cast\Object_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = Modifiers::STATIC; }, 374 => function ($stackPos) { - $this->semValue = new Expr\Cast\Bool_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = Modifiers::ABSTRACT; }, 375 => function ($stackPos) { - $this->semValue = new Expr\Cast\Unset_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = Modifiers::FINAL; }, 376 => function ($stackPos) { - $attrs = $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes; - $attrs['kind'] = \strtolower($this->semStack[$stackPos - (2 - 1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; - $this->semValue = new Expr\Exit_($this->semStack[$stackPos - (2 - 2)], $attrs); - }, 377 => function ($stackPos) { - $this->semValue = new Expr\ErrorSuppress($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 378 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = Modifiers::READONLY; + }, 377 => null, 378 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 379 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; }, 380 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Node\VarLikeIdentifier(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 381 => function ($stackPos) { - $this->semValue = new Expr\ShellExec($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\PropertyItem($this->semStack[$stackPos - (1 - 1)], null, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 382 => function ($stackPos) { - $this->semValue = new Expr\Print_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 383 => function ($stackPos) { - $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 384 => function ($stackPos) { - $this->semValue = new Expr\YieldFrom($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 385 => function ($stackPos) { - $this->semValue = new Expr\Closure(['static' => \false, 'byRef' => $this->semStack[$stackPos - (10 - 2)], 'params' => $this->semStack[$stackPos - (10 - 4)], 'uses' => $this->semStack[$stackPos - (10 - 6)], 'returnType' => $this->semStack[$stackPos - (10 - 7)], 'stmts' => $this->semStack[$stackPos - (10 - 9)]], $this->startAttributeStack[$stackPos - (10 - 1)] + $this->endAttributes); + $this->semValue = new Node\PropertyItem($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 383 => null, 384 => null, 385 => function ($stackPos) { + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; }, 386 => function ($stackPos) { - $this->semValue = new Expr\Closure(['static' => \true, 'byRef' => $this->semStack[$stackPos - (11 - 3)], 'params' => $this->semStack[$stackPos - (11 - 5)], 'uses' => $this->semStack[$stackPos - (11 - 7)], 'returnType' => $this->semStack[$stackPos - (11 - 8)], 'stmts' => $this->semStack[$stackPos - (11 - 10)]], $this->startAttributeStack[$stackPos - (11 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 387 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; - }, 388 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; - }, 389 => function ($stackPos) { - $this->semValue = new Expr\Yield_($this->semStack[$stackPos - (2 - 2)], null, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 390 => function ($stackPos) { - $this->semValue = new Expr\Yield_($this->semStack[$stackPos - (4 - 4)], $this->semStack[$stackPos - (4 - 2)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = array(); + }, 388 => null, 389 => null, 390 => function ($stackPos) { + $this->semValue = new Expr\Assign($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 391 => function ($stackPos) { - $attrs = $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes; - $attrs['kind'] = Expr\Array_::KIND_LONG; - $this->semValue = new Expr\Array_($this->semStack[$stackPos - (4 - 3)], $attrs); + $this->semValue = new Expr\Assign($this->fixupArrayDestructuring($this->semStack[$stackPos - (3 - 1)]), $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 392 => function ($stackPos) { - $attrs = $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes; - $attrs['kind'] = Expr\Array_::KIND_SHORT; - $this->semValue = new Expr\Array_($this->semStack[$stackPos - (3 - 2)], $attrs); + $this->semValue = new Expr\Assign($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 393 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignRef($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 394 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch(Scalar\String_::fromString($this->semStack[$stackPos - (4 - 1)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes), $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 395 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 396 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 397 => function ($stackPos) { - $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$stackPos - (7 - 3)], 'implements' => $this->semStack[$stackPos - (7 - 4)], 'stmts' => $this->semStack[$stackPos - (7 - 6)]], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes), $this->semStack[$stackPos - (7 - 2)]); - $this->checkClass($this->semValue[0], -1); + $this->semValue = new Expr\AssignRef($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + if (!$this->phpVersion->allowsAssignNewByReference()) { + $this->emitError(new Error('Cannot assign new by reference', $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos]))); + } + }, 395 => null, 396 => null, 397 => function ($stackPos) { + $this->semValue = new Expr\Clone_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 398 => function ($stackPos) { - $this->semValue = new Expr\New_($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\Plus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 399 => function ($stackPos) { - list($class, $ctorArgs) = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\Minus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 400 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = new Expr\AssignOp\Mul($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 401 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (4 - 3)]; + $this->semValue = new Expr\AssignOp\Div($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 402 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + $this->semValue = new Expr\AssignOp\Concat($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 403 => function ($stackPos) { - $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; - $this->semValue = $this->semStack[$stackPos - (3 - 1)]; + $this->semValue = new Expr\AssignOp\Mod($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 404 => function ($stackPos) { - $this->semValue = new Expr\ClosureUse($this->semStack[$stackPos - (2 - 2)], $this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 405 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 406 => function ($stackPos) { - $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 407 => function ($stackPos) { - $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 408 => function ($stackPos) { - $this->semValue = new Expr\StaticCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 409 => function ($stackPos) { - $this->semValue = new Expr\StaticCall($this->semStack[$stackPos - (6 - 1)], $this->semStack[$stackPos - (6 - 4)], $this->semStack[$stackPos - (6 - 6)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\Pow($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 410 => function ($stackPos) { - $this->semValue = $this->fixupPhp5StaticPropCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\Coalesce($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 411 => function ($stackPos) { - $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\PostInc($this->semStack[$stackPos - (2 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 412 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\PreInc($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 413 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\PostDec($this->semStack[$stackPos - (2 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 414 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\PreDec($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 415 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 416 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 417 => function ($stackPos) { - $this->semValue = new Name\FullyQualified(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 418 => function ($stackPos) { - $this->semValue = new Name\Relative(\substr($this->semStack[$stackPos - (1 - 1)], 10), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 419 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 420 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 421 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 422 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 423 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 424 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 425 => function ($stackPos) { - $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 426 => function ($stackPos) { - $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 427 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 428 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 429 => function ($stackPos) { - $this->semValue = null; + $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 430 => function ($stackPos) { - $this->semValue = null; + $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 431 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 432 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 433 => function ($stackPos) { - $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$stackPos - (1 - 1)], '`', \false), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes)); + $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 434 => function ($stackPos) { - foreach ($this->semStack[$stackPos - (1 - 1)] as $s) { - if ($s instanceof Node\Scalar\EncapsedStringPart) { - $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', \false); - } - } - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 435 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 436 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 437 => function ($stackPos) { - $this->semValue = $this->parseLNumber($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes, \true); + $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 438 => function ($stackPos) { - $this->semValue = Scalar\DNumber::fromString($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 439 => function ($stackPos) { - $this->semValue = Scalar\String_::fromString($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes, \false); + $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 440 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 441 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 442 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 443 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 444 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 445 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 446 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Instanceof_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 447 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; }, 448 => function ($stackPos) { - $this->semValue = $this->parseDocString($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes, $this->startAttributeStack[$stackPos - (3 - 3)] + $this->endAttributeStack[$stackPos - (3 - 3)], \false); + $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (5 - 1)], $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 449 => function ($stackPos) { - $this->semValue = $this->parseDocString($this->semStack[$stackPos - (2 - 1)], '', $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes, $this->startAttributeStack[$stackPos - (2 - 2)] + $this->endAttributeStack[$stackPos - (2 - 2)], \false); + $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (4 - 1)], null, $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 450 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 451 => function ($stackPos) { - $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Isset_($this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 452 => function ($stackPos) { - $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Empty_($this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 453 => function ($stackPos) { - $this->semValue = new Expr\Array_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 454 => function ($stackPos) { - $this->semValue = new Expr\Array_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 455 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\Eval_($this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 456 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 457 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 458 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Cast\Int_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 459 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $attrs = $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos]); + $attrs['kind'] = $this->getFloatCastKind($this->semStack[$stackPos - (2 - 1)]); + $this->semValue = new Expr\Cast\Double($this->semStack[$stackPos - (2 - 2)], $attrs); }, 460 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Cast\String_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 461 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Cast\Array_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 462 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Cast\Object_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 463 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Cast\Bool_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 464 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Cast\Unset_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 465 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $attrs = $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos]); + $attrs['kind'] = \strtolower($this->semStack[$stackPos - (2 - 1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; + $this->semValue = new Expr\Exit_($this->semStack[$stackPos - (2 - 2)], $attrs); }, 466 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 467 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 468 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\ErrorSuppress($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); + }, 467 => null, 468 => function ($stackPos) { + $this->semValue = new Expr\ShellExec($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 469 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Print_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 470 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Yield_(null, null, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 471 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Yield_($this->semStack[$stackPos - (2 - 2)], null, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 472 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Yield_($this->semStack[$stackPos - (4 - 4)], $this->semStack[$stackPos - (4 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 473 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\YieldFrom($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 474 => function ($stackPos) { - $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Throw_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 475 => function ($stackPos) { - $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $this->semStack[$stackPos - (8 - 2)], 'params' => $this->semStack[$stackPos - (8 - 4)], 'returnType' => $this->semStack[$stackPos - (8 - 6)], 'expr' => $this->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos])); }, 476 => function ($stackPos) { - $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'returnType' => $this->semStack[$stackPos - (9 - 7)], 'expr' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $this->getAttributes($this->tokenStartStack[$stackPos - (9 - 1)], $this->tokenEndStack[$stackPos])); }, 477 => function ($stackPos) { - $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Closure(['static' => \false, 'byRef' => $this->semStack[$stackPos - (8 - 2)], 'params' => $this->semStack[$stackPos - (8 - 4)], 'uses' => $this->semStack[$stackPos - (8 - 6)], 'returnType' => $this->semStack[$stackPos - (8 - 7)], 'stmts' => $this->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos])); }, 478 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Closure(['static' => \true, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'uses' => $this->semStack[$stackPos - (9 - 7)], 'returnType' => $this->semStack[$stackPos - (9 - 8)], 'stmts' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $this->getAttributes($this->tokenStartStack[$stackPos - (9 - 1)], $this->tokenEndStack[$stackPos])); }, 479 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'returnType' => $this->semStack[$stackPos - (9 - 7)], 'expr' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => $this->semStack[$stackPos - (9 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (9 - 1)], $this->tokenEndStack[$stackPos])); }, 480 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $this->semStack[$stackPos - (10 - 4)], 'params' => $this->semStack[$stackPos - (10 - 6)], 'returnType' => $this->semStack[$stackPos - (10 - 8)], 'expr' => $this->semStack[$stackPos - (10 - 10)], 'attrGroups' => $this->semStack[$stackPos - (10 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (10 - 1)], $this->tokenEndStack[$stackPos])); }, 481 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Closure(['static' => \false, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'uses' => $this->semStack[$stackPos - (9 - 7)], 'returnType' => $this->semStack[$stackPos - (9 - 8)], 'stmts' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => $this->semStack[$stackPos - (9 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (9 - 1)], $this->tokenEndStack[$stackPos])); }, 482 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Closure(['static' => \true, 'byRef' => $this->semStack[$stackPos - (10 - 4)], 'params' => $this->semStack[$stackPos - (10 - 6)], 'uses' => $this->semStack[$stackPos - (10 - 8)], 'returnType' => $this->semStack[$stackPos - (10 - 9)], 'stmts' => $this->semStack[$stackPos - (10 - 10)], 'attrGroups' => $this->semStack[$stackPos - (10 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (10 - 1)], $this->tokenEndStack[$stackPos])); }, 483 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = array(new Stmt\Class_(null, ['type' => $this->semStack[$stackPos - (8 - 2)], 'extends' => $this->semStack[$stackPos - (8 - 4)], 'implements' => $this->semStack[$stackPos - (8 - 5)], 'stmts' => $this->semStack[$stackPos - (8 - 7)], 'attrGroups' => $this->semStack[$stackPos - (8 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos])), $this->semStack[$stackPos - (8 - 3)]); + $this->checkClass($this->semValue[0], -1); }, 484 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\New_($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 485 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + list($class, $ctorArgs) = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = new Expr\New_($class, $ctorArgs, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 486 => function ($stackPos) { - $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (5 - 1)], $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); + $this->semValue = array(); }, 487 => function ($stackPos) { - $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (4 - 1)], null, $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 488 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 489 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + $this->semValue = $this->semStack[$stackPos - (4 - 3)]; + }, 488 => null, 489 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 490 => function ($stackPos) { - $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 1)]; }, 491 => function ($stackPos) { - $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\ClosureUse($this->semStack[$stackPos - (2 - 2)], $this->semStack[$stackPos - (2 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 492 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 493 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 494 => function ($stackPos) { - $attrs = $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes; - $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; - foreach ($this->semStack[$stackPos - (3 - 2)] as $s) { - if ($s instanceof Node\Scalar\EncapsedStringPart) { - $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', \true); - } - } - $this->semValue = new Scalar\Encapsed($this->semStack[$stackPos - (3 - 2)], $attrs); + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 495 => function ($stackPos) { - $this->semValue = $this->parseDocString($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes, $this->startAttributeStack[$stackPos - (3 - 3)] + $this->endAttributeStack[$stackPos - (3 - 3)], \true); + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 496 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = new Expr\StaticCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 497 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 498 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 499 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 498 => null, 499 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 500 => function ($stackPos) { - $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; - $this->semValue = $this->semStack[$stackPos - (3 - 1)]; + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 501 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + $this->semValue = new Name\FullyQualified(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 502 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (3 - 3)], $this->semStack[$stackPos - (3 - 1)], \false, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 503 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 504 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 505 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Name\Relative(\substr($this->semStack[$stackPos - (1 - 1)], 10), $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 503 => null, 504 => null, 505 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; }, 506 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 507 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 508 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 5)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes); - }, 509 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Error($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + $this->errorState = 2; + }, 507 => null, 508 => null, 509 => function ($stackPos) { + $this->semValue = null; }, 510 => function ($stackPos) { - $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; }, 511 => function ($stackPos) { - $this->semValue = new Expr\MethodCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = array(); }, 512 => function ($stackPos) { - $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + foreach ($this->semValue as $s) { + if ($s instanceof Node\InterpolatedStringPart) { + $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $this->phpVersion->supportsUnicodeEscapes()); + } + } }, 513 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 514 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 515 => function ($stackPos) { + foreach ($this->semStack[$stackPos - (1 - 1)] as $s) { + if ($s instanceof Node\InterpolatedStringPart) { + $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $this->phpVersion->supportsUnicodeEscapes()); + } + } $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 516 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + }, 514 => function ($stackPos) { + $this->semValue = array(); + }, 515 => null, 516 => function ($stackPos) { + $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 517 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Scalar\MagicConst\Line($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 518 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Scalar\MagicConst\File($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 519 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Scalar\MagicConst\Dir($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 520 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Scalar\MagicConst\Class_($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 521 => function ($stackPos) { - $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Scalar\MagicConst\Trait_($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 522 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Scalar\MagicConst\Method($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 523 => function ($stackPos) { - $var = \substr($this->semStack[$stackPos - (1 - 1)], 1); - $this->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes) : $var; + $this->semValue = new Scalar\MagicConst\Function_($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 524 => function ($stackPos) { - $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Scalar\MagicConst\Namespace_($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 525 => function ($stackPos) { - $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (6 - 1)], $this->semStack[$stackPos - (6 - 5)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes); + $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 526 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos - (5 - 1)], $this->semStack[$stackPos - (5 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 527 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos - (3 - 1)], new Expr\Error($this->getAttributes($this->tokenStartStack[$stackPos - (3 - 3)], $this->tokenEndStack[$stackPos - (3 - 3)])), $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + $this->errorState = 2; }, 528 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $attrs = $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos]); + $attrs['kind'] = Expr\Array_::KIND_SHORT; + $this->semValue = new Expr\Array_($this->semStack[$stackPos - (3 - 2)], $attrs); }, 529 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $attrs = $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos]); + $attrs['kind'] = Expr\Array_::KIND_LONG; + $this->semValue = new Expr\Array_($this->semStack[$stackPos - (4 - 3)], $attrs); + $this->createdArrays->attach($this->semValue); }, 530 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->createdArrays->attach($this->semValue); }, 531 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = Scalar\String_::fromString($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos]), $this->phpVersion->supportsUnicodeEscapes()); }, 532 => function ($stackPos) { - $this->semValue = null; + $attrs = $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos]); + $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; + foreach ($this->semStack[$stackPos - (3 - 2)] as $s) { + if ($s instanceof Node\InterpolatedStringPart) { + $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', $this->phpVersion->supportsUnicodeEscapes()); + } + } + $this->semValue = new Scalar\InterpolatedString($this->semStack[$stackPos - (3 - 2)], $attrs); }, 533 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = $this->parseLNumber($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos]), $this->phpVersion->allowsInvalidOctals()); }, 534 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 535 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; - }, 536 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 537 => function ($stackPos) { - $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - $this->errorState = 2; - }, 538 => function ($stackPos) { - $this->semValue = new Expr\List_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = Scalar\Float_::fromString($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 535 => null, 536 => null, 537 => null, 538 => function ($stackPos) { + $this->semValue = $this->parseDocString($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos]), $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 3)], $this->tokenEndStack[$stackPos - (3 - 3)]), \true); }, 539 => function ($stackPos) { - $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; - $this->semValue = $this->semStack[$stackPos - (3 - 1)]; + $this->semValue = $this->parseDocString($this->semStack[$stackPos - (2 - 1)], '', $this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos]), $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 2)], $this->tokenEndStack[$stackPos - (2 - 2)]), \true); }, 540 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + $this->semValue = $this->parseDocString($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos]), $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 3)], $this->tokenEndStack[$stackPos - (3 - 3)]), \true); }, 541 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 542 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 543 => function ($stackPos) { $this->semValue = null; - }, 544 => function ($stackPos) { - $this->semValue = array(); - }, 545 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 546 => function ($stackPos) { + }, 542 => null, 543 => null, 544 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + }, 545 => null, 546 => null, 547 => null, 548 => null, 549 => null, 550 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + }, 551 => null, 552 => null, 553 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 554 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 555 => null, 556 => function ($stackPos) { + $this->semValue = new Expr\MethodCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 557 => function ($stackPos) { + $this->semValue = new Expr\NullsafeMethodCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 558 => function ($stackPos) { + $this->semValue = null; + }, 559 => null, 560 => null, 561 => null, 562 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 563 => function ($stackPos) { + $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 564 => null, 565 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 566 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); + }, 567 => function ($stackPos) { + $this->semValue = new Expr\Variable(new Expr\Error($this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])), $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); + $this->errorState = 2; + }, 568 => function ($stackPos) { + $var = $this->semStack[$stackPos - (1 - 1)]->name; + $this->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])) : $var; + }, 569 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 570 => null, 571 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 572 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 573 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 574 => function ($stackPos) { + $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 575 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 576 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 577 => null, 578 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + }, 579 => null, 580 => null, 581 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + }, 582 => null, 583 => function ($stackPos) { + $this->semValue = new Expr\Error($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + $this->errorState = 2; + }, 584 => function ($stackPos) { + $this->semValue = new Expr\List_($this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + $this->semValue->setAttribute('kind', Expr\List_::KIND_LIST); + $this->postprocessList($this->semValue); + }, 585 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $end = \count($this->semValue) - 1; + if ($this->semValue[$end]->value instanceof Expr\Error) { + \array_pop($this->semValue); + } + }, 586 => null, 587 => function ($stackPos) { + /* do nothing -- prevent default action of $$=$this->semStack[$1]. See $551. */ + }, 588 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 547 => function ($stackPos) { + }, 589 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 548 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (3 - 3)], $this->semStack[$stackPos - (3 - 1)], \false, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 549 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 550 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (4 - 4)], $this->semStack[$stackPos - (4 - 1)], \true, $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 551 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (2 - 2)], null, \true, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 552 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (2 - 2)], null, \false, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes, \true, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 553 => function ($stackPos) { + }, 590 => function ($stackPos) { + $this->semValue = new Node\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 591 => function ($stackPos) { + $this->semValue = new Node\ArrayItem($this->semStack[$stackPos - (2 - 2)], null, \true, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); + }, 592 => function ($stackPos) { + $this->semValue = new Node\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 593 => function ($stackPos) { + $this->semValue = new Node\ArrayItem($this->semStack[$stackPos - (3 - 3)], $this->semStack[$stackPos - (3 - 1)], \false, $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 594 => function ($stackPos) { + $this->semValue = new Node\ArrayItem($this->semStack[$stackPos - (4 - 4)], $this->semStack[$stackPos - (4 - 1)], \true, $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 595 => function ($stackPos) { + $this->semValue = new Node\ArrayItem($this->semStack[$stackPos - (3 - 3)], $this->semStack[$stackPos - (3 - 1)], \false, $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 596 => function ($stackPos) { + $this->semValue = new Node\ArrayItem($this->semStack[$stackPos - (2 - 2)], null, \false, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos]), \true); + }, 597 => function ($stackPos) { + /* Create an Error node now to remember the position. We'll later either report an error, + or convert this into a null element, depending on whether this is a creation or destructuring context. */ + $attrs = $this->createEmptyElemAttributes($this->tokenPos); + $this->semValue = new Node\ArrayItem(new Expr\Error($attrs), null, \false, $attrs); + }, 598 => function ($stackPos) { $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 554 => function ($stackPos) { + }, 599 => function ($stackPos) { $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 555 => function ($stackPos) { + }, 600 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 556 => function ($stackPos) { + }, 601 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)]); - }, 557 => function ($stackPos) { - $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 558 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 559 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 560 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 561 => function ($stackPos) { - $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 562 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 563 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 564 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 4)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes); - }, 565 => function ($stackPos) { + }, 602 => function ($stackPos) { + $attrs = $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos]); + $attrs['rawValue'] = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Node\InterpolatedStringPart($this->semStack[$stackPos - (1 - 1)], $attrs); + }, 603 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 604 => null, 605 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 606 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 607 => function ($stackPos) { + $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 608 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 609 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 610 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos])); + }, 611 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (3 - 2)]; - }, 566 => function ($stackPos) { - $this->semValue = new Scalar\String_($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 567 => function ($stackPos) { - $this->semValue = $this->parseNumString($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 568 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }]; + }, 612 => function ($stackPos) { + $this->semValue = new Scalar\String_($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 613 => function ($stackPos) { + $this->semValue = $this->parseNumString($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 614 => function ($stackPos) { + $this->semValue = $this->parseNumString('-' . $this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); + }, 615 => null]; } } '", "T_IS_GREATER_OR_EQUAL", "T_SL", "T_SR", "'+'", "'-'", "'.'", "'*'", "'/'", "'%'", "'!'", "T_INSTANCEOF", "'~'", "T_INC", "T_DEC", "T_INT_CAST", "T_DOUBLE_CAST", "T_STRING_CAST", "T_ARRAY_CAST", "T_OBJECT_CAST", "T_BOOL_CAST", "T_UNSET_CAST", "'@'", "T_POW", "'['", "T_NEW", "T_CLONE", "T_EXIT", "T_IF", "T_ELSEIF", "T_ELSE", "T_ENDIF", "T_LNUMBER", "T_DNUMBER", "T_STRING", "T_STRING_VARNAME", "T_VARIABLE", "T_NUM_STRING", "T_INLINE_HTML", "T_ENCAPSED_AND_WHITESPACE", "T_CONSTANT_ENCAPSED_STRING", "T_ECHO", "T_DO", "T_WHILE", "T_ENDWHILE", "T_FOR", "T_ENDFOR", "T_FOREACH", "T_ENDFOREACH", "T_DECLARE", "T_ENDDECLARE", "T_AS", "T_SWITCH", "T_MATCH", "T_ENDSWITCH", "T_CASE", "T_DEFAULT", "T_BREAK", "T_CONTINUE", "T_GOTO", "T_FUNCTION", "T_FN", "T_CONST", "T_RETURN", "T_TRY", "T_CATCH", "T_FINALLY", "T_USE", "T_INSTEADOF", "T_GLOBAL", "T_STATIC", "T_ABSTRACT", "T_FINAL", "T_PRIVATE", "T_PROTECTED", "T_PUBLIC", "T_READONLY", "T_VAR", "T_UNSET", "T_ISSET", "T_EMPTY", "T_HALT_COMPILER", "T_CLASS", "T_TRAIT", "T_INTERFACE", "T_ENUM", "T_EXTENDS", "T_IMPLEMENTS", "T_OBJECT_OPERATOR", "T_NULLSAFE_OBJECT_OPERATOR", "T_LIST", "T_ARRAY", "T_CALLABLE", "T_CLASS_C", "T_TRAIT_C", "T_METHOD_C", "T_FUNC_C", "T_LINE", "T_FILE", "T_START_HEREDOC", "T_END_HEREDOC", "T_DOLLAR_OPEN_CURLY_BRACES", "T_CURLY_OPEN", "T_PAAMAYIM_NEKUDOTAYIM", "T_NAMESPACE", "T_NS_C", "T_DIR", "T_NS_SEPARATOR", "T_ELLIPSIS", "T_NAME_FULLY_QUALIFIED", "T_NAME_QUALIFIED", "T_NAME_RELATIVE", "T_ATTRIBUTE", "';'", "']'", "'{'", "'}'", "'('", "')'", "'`'", "'\"'", "'\$'"); - protected $tokenToSymbol = array(0, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 56, 166, 168, 167, 55, 168, 168, 163, 164, 53, 50, 8, 51, 52, 54, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 31, 159, 44, 16, 46, 30, 68, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 70, 168, 160, 36, 168, 165, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 161, 35, 162, 58, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43, 45, 47, 48, 49, 57, 59, 60, 61, 62, 63, 64, 65, 66, 67, 69, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158); - protected $action = array(132, 133, 134, 575, 135, 136, 0, 738, 739, 740, 137, 37, 850, 825, 851, 476, -32766, -32766, -32766, -32767, -32767, -32767, -32767, 101, 102, 103, 104, 105, 1097, 1098, 1099, 1096, 1095, 1094, 1100, 732, 731, -32766, 1289, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32767, -32767, -32767, -32767, -32767, 1022, 377, 376, 2, 741, -32766, -32766, -32766, -32766, -32766, 822, 417, -32766, -32766, -32766, -32766, -32766, -32766, 267, 138, 399, 745, 746, 747, 748, 287, -32766, 423, -32766, -32766, -32766, -32766, -32766, -32766, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 779, 576, 780, 781, 782, 783, 771, 772, 340, 341, 774, 775, 760, 761, 762, 764, 765, 766, 351, 806, 807, 808, 809, 810, 577, 767, 768, 578, 579, 800, 791, 789, 790, 803, 786, 787, -327, 423, 580, 581, 785, 582, 583, 584, 585, 586, 587, 605, -590, 477, -86, 814, 788, 588, 589, -590, 139, -32766, -32766, -32766, 132, 133, 134, 575, 135, 136, 1046, 738, 739, 740, 137, 37, 323, 1013, 823, 824, 1334, 1324, -32766, 1335, -32766, -32766, -32766, -32766, -32766, -32766, -32766, 1097, 1098, 1099, 1096, 1095, 1094, 1100, -587, 732, 731, -32766, -32766, -32766, 12, -587, 81, -32766, -32766, -32766, 945, 946, 322, 927, 34, 947, 1224, 1223, 1225, 741, -86, 942, -32766, 1075, -32766, -32766, -32766, -32766, -32766, 239, -32766, -32766, -32766, 267, 138, 399, 745, 746, 747, 748, 461, 462, 423, 35, 247, 103, 104, 105, 128, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 779, 576, 780, 781, 782, 783, 771, 772, 340, 341, 774, 775, 760, 761, 762, 764, 765, 766, 351, 806, 807, 808, 809, 810, 577, 767, 768, 578, 579, 800, 791, 789, 790, 803, 786, 787, -327, 144, 580, 581, 785, 582, 583, 584, 585, 586, 587, 1222, 82, 83, 84, -590, 788, 588, 589, -590, 148, 763, 733, 734, 735, 736, 737, 1309, 738, 739, 740, 776, 777, 36, 1308, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 288, 271, -587, -193, 375, 376, -587, 976, -32766, 1021, 453, 454, 455, 109, 417, 945, 946, 741, 712, 819, 947, -32766, -32766, -32766, -271, 1073, 941, 1224, 1223, 1225, 288, 742, 743, 744, 745, 746, 747, 748, -192, -365, 812, -365, -32766, 599, -32766, -32766, 549, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 779, 802, 780, 781, 782, 783, 771, 772, 773, 801, 774, 775, 760, 761, 762, 764, 765, 766, 805, 806, 807, 808, 809, 810, 811, 767, 768, 769, 770, 800, 791, 789, 790, 803, 786, 787, 251, 820, 778, 784, 785, 792, 793, 795, 794, 796, 797, 732, 731, 1261, 1022, 1019, 788, 799, 798, 49, 50, 51, 507, 52, 53, 1009, 1008, 1007, 1010, 54, 55, -111, 56, 816, 1045, 14, -111, 1022, -111, 287, 1305, 977, 306, 302, 1022, 238, -111, -111, -111, -111, -111, -111, -111, -111, 106, 107, 108, 1089, 271, -32766, -32766, -32766, 280, 284, 126, -193, 929, 57, 58, 287, 109, 1019, -541, 59, 308, 60, 244, 245, 61, 62, 63, 64, 65, 66, 67, 68, 1229, 27, 269, 69, 439, 508, -341, 1022, 929, 1255, 1256, 509, 907, 823, -192, 150, 907, 1253, 41, 24, 510, 352, 511, 818, 512, 386, 513, 11, 699, 514, 515, 648, 25, 814, 43, 44, 440, 372, 371, 907, 45, 516, 702, 1220, 667, 668, 363, 334, -540, 357, -541, -541, 320, 1215, 1249, 518, 519, 520, -581, 1074, 335, 724, -581, 1019, -32766, -541, 336, 521, 522, 703, 1243, 1244, 1245, 1246, 1240, 1241, 294, -541, 850, -547, 851, 823, 1247, 1242, 365, 1022, 1224, 1223, 1225, 295, -153, -153, -153, 369, 70, 897, 318, 319, 322, 897, 384, 149, 402, 373, 374, -153, 435, -153, 436, -153, 280, -153, -540, -540, 141, 1220, 378, 379, 639, 640, 322, 370, 897, 907, 437, 438, 829, -540, -88, 151, 732, 731, 945, 946, 153, 823, -32766, 517, -51, -540, 154, -546, 883, 941, -111, -111, -111, 31, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 155, 74, 27, 157, 32, 322, -85, 123, 124, 909, 129, 697, 130, 909, 823, 697, -153, 143, 1253, 158, -32766, -544, 1229, -542, 159, 160, 1222, 161, -79, 1134, 1136, -75, 285, -32766, -32766, -32766, 909, -32766, 697, -32766, -539, -32766, -301, -73, -32766, 897, -72, -71, 1220, -32766, -32766, -32766, -16, 140, 1215, -32766, -32766, 732, 731, 322, -70, -32766, 414, -69, -4, 907, -68, -67, 521, 522, -32766, 1243, 1244, 1245, 1246, 1240, 1241, -66, -47, -18, 147, 270, 281, 1247, 1242, -544, -544, -542, -542, 732, 731, 713, 716, 906, -32766, 72, 146, 907, 319, 322, 1222, -297, -542, 823, -539, -539, 276, -32766, -32766, -32766, 277, -32766, -544, -32766, -542, -32766, 282, 283, -32766, -539, 909, 328, 697, -32766, -32766, -32766, -32766, 704, 286, -32766, -32766, -539, 1222, 923, 289, -32766, 414, 1220, 290, -32766, -32766, -32766, 271, -32766, -32766, -32766, 47, -32766, 897, -111, -32766, 677, 109, 814, 145, -32766, -32766, -32766, -32766, 823, 131, -32766, -32766, 1336, -32766, 654, 670, -32766, 414, 1104, 370, 637, 430, 551, 73, 13, -32766, 293, 555, 295, 897, 945, 946, 649, 74, 434, 517, 458, 322, 487, 690, 842, 941, -111, -111, -111, 301, 1022, 561, 655, 671, 1260, 300, -32766, -539, -32766, 907, 603, 303, 1222, 296, 297, 39, 1262, 9, 40, -32766, -32766, -32766, 0, -32766, 907, -32766, 909, -32766, 697, -4, -32766, 0, 1229, 907, 0, -32766, -32766, -32766, -32766, 307, 125, -32766, -32766, 0, 1222, 907, 0, -32766, 414, 0, 0, -32766, -32766, -32766, 707, -32766, -32766, -32766, 962, -32766, 697, -505, -32766, 714, -495, 7, 482, -32766, -32766, -32766, -32766, -539, -539, -32766, -32766, 16, 1222, 567, 367, -32766, 414, 925, 295, -32766, -32766, -32766, -539, -32766, -32766, -32766, 822, -32766, 897, 721, -32766, 722, -575, 888, -539, -32766, -32766, -32766, 986, 963, 970, -32766, -32766, 897, -249, -249, -249, -32766, 414, 823, 370, 960, 897, 971, 886, 958, -32766, 1078, 1081, 718, 1082, 945, 946, 1079, 897, 1080, 517, 1086, 33, 1250, 834, 883, 941, -111, -111, -111, 27, 1275, 1293, 1327, -248, -248, -248, 1220, 642, 884, 370, 317, 823, 366, 698, 701, 1253, 1331, 705, -111, 706, 945, 946, 708, 709, 710, 517, 909, -32766, 697, -249, 883, 941, -111, -111, -111, 711, 715, 700, -509, 1333, 845, 909, 48, 697, -573, 1220, 844, 853, 295, 935, 909, 1215, 697, 74, 978, 852, 1332, 322, 934, 932, 933, 936, 909, 1206, 697, -248, 522, 916, 1243, 1244, 1245, 1246, 1240, 1241, 926, 914, 968, 969, 1330, 1287, 1247, 1242, 1276, 1294, -32766, 1300, 1303, 1191, -547, -546, 1222, -545, 72, -489, 1, 319, 322, -32766, -32766, -32766, 28, -32766, 29, -32766, 38, -32766, 298, 299, -32766, 42, 46, 71, 75, -32766, -32766, -32766, 76, 77, 78, -32766, -32766, 368, 79, 80, 142, -32766, 414, 152, 156, 243, 324, 352, 353, 127, -32766, -274, 354, 355, 356, 357, 358, 359, 360, 361, 362, 364, 431, 0, -272, -271, 18, 19, 20, 21, 23, 401, 478, 479, 486, 489, 490, 491, 492, 496, 497, 498, 505, 684, 1233, 1174, 1251, 1048, 1047, 1028, 0, 1210, 1024, -276, -103, 17, 22, 26, 292, 400, 596, 600, 628, 689, 1178, 1228, 1175, 1306, 0, 0, 1254, 0, 322); - protected $actionCheck = array(2, 3, 4, 5, 6, 7, 0, 9, 10, 11, 12, 13, 106, 1, 108, 31, 9, 10, 11, 44, 45, 46, 47, 48, 49, 50, 51, 52, 116, 117, 118, 119, 120, 121, 122, 37, 38, 30, 1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 138, 106, 107, 8, 57, 9, 10, 11, 9, 10, 155, 116, 9, 10, 11, 9, 10, 11, 71, 72, 73, 74, 75, 76, 77, 163, 30, 80, 32, 33, 34, 35, 36, 30, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 8, 80, 136, 137, 138, 139, 140, 141, 142, 143, 144, 51, 1, 161, 31, 80, 150, 151, 152, 8, 154, 9, 10, 11, 2, 3, 4, 5, 6, 7, 164, 9, 10, 11, 12, 13, 70, 1, 82, 159, 80, 85, 30, 83, 32, 33, 34, 35, 36, 37, 38, 116, 117, 118, 119, 120, 121, 122, 1, 37, 38, 9, 10, 11, 8, 8, 161, 9, 10, 11, 117, 118, 167, 1, 8, 122, 155, 156, 157, 57, 97, 128, 30, 162, 32, 33, 34, 35, 30, 14, 32, 33, 34, 71, 72, 73, 74, 75, 76, 77, 134, 135, 80, 147, 148, 50, 51, 52, 8, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 164, 8, 136, 137, 138, 139, 140, 141, 142, 143, 144, 80, 9, 10, 11, 160, 150, 151, 152, 164, 154, 2, 3, 4, 5, 6, 7, 1, 9, 10, 11, 12, 13, 30, 8, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 30, 57, 160, 8, 106, 107, 164, 31, 9, 137, 129, 130, 131, 69, 116, 117, 118, 57, 161, 80, 122, 9, 10, 11, 164, 1, 128, 155, 156, 157, 30, 71, 72, 73, 74, 75, 76, 77, 8, 106, 80, 108, 30, 1, 32, 33, 85, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 8, 156, 136, 137, 138, 139, 140, 141, 142, 143, 144, 37, 38, 146, 138, 116, 150, 151, 152, 2, 3, 4, 5, 6, 7, 119, 120, 121, 122, 12, 13, 101, 15, 80, 1, 101, 106, 138, 108, 163, 1, 159, 8, 113, 138, 97, 116, 117, 118, 119, 120, 121, 122, 123, 53, 54, 55, 123, 57, 9, 10, 11, 163, 30, 14, 164, 122, 50, 51, 163, 69, 116, 70, 56, 8, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 1, 70, 71, 72, 73, 74, 162, 138, 122, 78, 79, 80, 1, 82, 164, 14, 1, 86, 87, 88, 89, 163, 91, 156, 93, 106, 95, 108, 161, 98, 99, 75, 76, 80, 103, 104, 105, 106, 107, 1, 109, 110, 31, 116, 75, 76, 115, 116, 70, 163, 134, 135, 8, 122, 1, 124, 125, 126, 160, 159, 8, 161, 164, 116, 137, 149, 8, 136, 137, 31, 139, 140, 141, 142, 143, 144, 145, 161, 106, 163, 108, 82, 151, 152, 8, 138, 155, 156, 157, 158, 75, 76, 77, 8, 163, 84, 165, 166, 167, 84, 8, 101, 102, 106, 107, 90, 8, 92, 8, 94, 163, 96, 134, 135, 161, 116, 106, 107, 111, 112, 167, 106, 84, 1, 8, 8, 8, 149, 31, 14, 37, 38, 117, 118, 14, 82, 137, 122, 31, 161, 14, 163, 127, 128, 129, 130, 131, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 14, 163, 70, 14, 14, 167, 31, 16, 16, 159, 16, 161, 16, 159, 82, 161, 162, 16, 86, 16, 74, 70, 1, 70, 16, 16, 80, 16, 31, 59, 60, 31, 37, 87, 88, 89, 159, 91, 161, 93, 70, 95, 35, 31, 98, 84, 31, 31, 116, 103, 104, 105, 31, 161, 122, 109, 110, 37, 38, 167, 31, 115, 116, 31, 0, 1, 31, 31, 136, 137, 124, 139, 140, 141, 142, 143, 144, 31, 31, 31, 31, 31, 31, 151, 152, 134, 135, 134, 135, 37, 38, 31, 31, 31, 74, 163, 31, 1, 166, 167, 80, 35, 149, 82, 134, 135, 35, 87, 88, 89, 35, 91, 161, 93, 161, 95, 35, 35, 98, 149, 159, 35, 161, 103, 104, 105, 74, 31, 37, 109, 110, 161, 80, 38, 37, 115, 116, 116, 37, 87, 88, 89, 57, 91, 124, 93, 70, 95, 84, 128, 98, 77, 69, 80, 70, 103, 104, 105, 137, 82, 31, 109, 110, 83, 85, 96, 94, 115, 116, 82, 106, 113, 108, 85, 154, 97, 124, 113, 89, 158, 84, 117, 118, 90, 163, 128, 122, 97, 167, 97, 92, 127, 128, 129, 130, 131, 133, 138, 153, 100, 100, 146, 132, 74, 70, 137, 1, 153, 114, 80, 134, 135, 159, 146, 150, 159, 87, 88, 89, -1, 91, 1, 93, 159, 95, 161, 162, 98, -1, 1, 1, -1, 103, 104, 105, 74, 132, 161, 109, 110, -1, 80, 1, -1, 115, 116, -1, -1, 87, 88, 89, 31, 91, 124, 93, 159, 95, 161, 149, 98, 31, 149, 149, 102, 103, 104, 105, 74, 134, 135, 109, 110, 149, 80, 81, 149, 115, 116, 154, 158, 87, 88, 89, 149, 91, 124, 93, 155, 95, 84, 159, 98, 159, 163, 159, 161, 103, 104, 105, 159, 159, 159, 109, 110, 84, 100, 101, 102, 115, 116, 82, 106, 159, 84, 159, 159, 159, 124, 159, 159, 162, 159, 117, 118, 159, 84, 159, 122, 159, 161, 160, 160, 127, 128, 129, 130, 131, 70, 160, 160, 160, 100, 101, 102, 116, 160, 162, 106, 161, 82, 161, 161, 161, 86, 162, 161, 128, 161, 117, 118, 161, 161, 161, 122, 159, 137, 161, 162, 127, 128, 129, 130, 131, 161, 161, 161, 165, 162, 162, 159, 70, 161, 163, 116, 162, 162, 158, 162, 159, 122, 161, 163, 162, 162, 162, 167, 162, 162, 162, 162, 159, 162, 161, 162, 137, 162, 139, 140, 141, 142, 143, 144, 162, 162, 162, 162, 162, 162, 151, 152, 162, 162, 74, 162, 162, 165, 163, 163, 80, 163, 163, 163, 163, 166, 167, 87, 88, 89, 163, 91, 163, 93, 163, 95, 134, 135, 98, 163, 163, 163, 163, 103, 104, 105, 163, 163, 163, 109, 110, 149, 163, 163, 163, 115, 116, 163, 163, 163, 163, 163, 163, 161, 124, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -1, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -1, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -1, -1, 166, -1, 167); - protected $actionBase = array(0, -2, 154, 542, 752, 893, 929, 580, 53, 394, 855, 307, 307, 67, 307, 307, 307, 565, 908, 908, 917, 908, 538, 784, 649, 649, 649, 708, 708, 708, 708, 740, 740, 849, 849, 881, 817, 634, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 12, 323, 389, 678, 1044, 1050, 1046, 1051, 1042, 1041, 1045, 1047, 1052, 942, 943, 753, 946, 947, 949, 950, 1048, 873, 1043, 1049, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 346, 491, 50, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 54, 54, 54, 620, 620, 359, 190, 184, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 658, 47, 144, 144, 7, 7, 7, 7, 7, 371, -25, -25, -25, -25, 709, 347, 916, 474, 526, 375, 280, 317, 245, 340, 340, 187, 187, 396, 396, -87, -87, 396, 396, 396, 747, 747, 747, 747, 443, 505, -94, 308, 454, 480, 480, 480, 480, 454, 454, 454, 454, 755, 1054, 454, 454, 454, 641, 822, 822, 998, 442, 442, 442, 822, 499, 776, 88, 499, 88, 37, 92, 756, 85, -54, 425, 756, 639, 764, 189, 143, 820, 524, 820, 1040, 385, 767, 413, 735, 688, 857, 902, 1053, 787, 940, 788, 941, 228, 98, 685, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1055, 415, 1040, 286, 1055, 1055, 1055, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 534, 286, 483, 496, 286, 774, 415, 12, 800, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 736, -16, 12, 323, 204, 204, 427, 168, 204, 204, 204, 204, 12, 12, 12, 524, 773, 733, 537, 742, 377, 773, 773, 773, 115, 124, 207, 342, 695, 754, 446, 761, 761, 775, 957, 957, 761, 765, 761, 775, 973, 761, 761, 957, 957, 809, 232, 625, 579, 612, 627, 957, 475, 761, 761, 761, 761, 792, 643, 761, 433, 281, 761, 761, 792, 758, 739, 46, 751, 957, 957, 957, 792, 603, 751, 751, 751, 819, 821, 746, 738, 571, 507, 645, 198, 783, 738, 738, 761, 619, 746, 738, 746, 738, 812, 738, 738, 738, 746, 738, 765, 585, 738, 691, 644, 188, 738, 6, 974, 975, 624, 979, 967, 980, 1009, 981, 985, 878, 956, 992, 972, 986, 965, 963, 750, 679, 680, 801, 797, 954, 771, 771, 771, 951, 771, 771, 771, 771, 771, 771, 771, 771, 679, 858, 814, 745, 777, 995, 682, 684, 743, 872, 899, 948, 994, 1030, 987, 741, 689, 1016, 999, 846, 875, 1000, 1001, 1017, 1031, 1032, 880, 772, 903, 904, 859, 1003, 879, 771, 974, 985, 663, 972, 986, 965, 963, 734, 724, 720, 723, 717, 704, 700, 703, 737, 1033, 907, 818, 866, 1002, 952, 679, 867, 1012, 856, 1018, 1019, 877, 778, 768, 868, 910, 1004, 1005, 1006, 882, 1034, 884, 744, 1013, 997, 1020, 780, 911, 1021, 1022, 1023, 1024, 887, 913, 888, 889, 823, 781, 1010, 757, 918, 528, 769, 770, 789, 1008, 642, 993, 900, 919, 920, 1025, 1026, 1027, 922, 923, 990, 828, 1014, 760, 1015, 1011, 829, 830, 647, 785, 1035, 759, 763, 779, 653, 674, 924, 925, 927, 991, 748, 762, 841, 843, 1037, 683, 1038, 931, 677, 844, 696, 938, 1029, 697, 699, 786, 901, 811, 782, 766, 1007, 749, 845, 939, 847, 848, 850, 1028, 853, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 458, 458, 458, 458, 458, 458, 307, 307, 307, 307, 0, 0, 307, 0, 0, 0, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 219, 219, 291, 291, 291, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 291, 291, 291, 291, 291, 291, 291, 291, 809, 442, 442, 442, 442, 219, 219, 219, 219, 219, -88, -88, 219, 809, 219, 219, 442, 442, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 286, 88, 219, 765, 765, 765, 765, 219, 219, 219, 219, 88, 88, 219, 219, 219, 0, 0, 0, 0, 0, 0, 0, 0, 286, 88, 0, 286, 0, 765, 765, 219, 0, 809, 314, 219, 0, 0, 0, 0, 286, 765, 286, 415, 761, 88, 761, 415, 415, 204, 12, 314, 527, 527, 527, 527, 0, 0, 524, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 765, 0, 809, 0, 765, 765, 765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 765, 0, 0, 957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 973, 0, 0, 0, 0, 0, 0, 765, 0, 0, 0, 0, 0, 0, 0, 0, 771, 778, 0, 778, 0, 771, 771, 771, 0, 0, 0, 0, 785, 683); - protected $actionDefault = array(3, 32767, 103, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 101, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 593, 593, 593, 593, 32767, 32767, 253, 103, 32767, 32767, 467, 385, 385, 385, 32767, 32767, 537, 537, 537, 537, 537, 537, 32767, 32767, 32767, 32767, 32767, 32767, 467, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 101, 32767, 32767, 32767, 37, 7, 8, 10, 11, 50, 17, 323, 32767, 32767, 32767, 32767, 103, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 586, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 471, 450, 451, 453, 454, 384, 538, 592, 326, 589, 383, 146, 338, 328, 241, 329, 257, 472, 258, 473, 476, 477, 214, 286, 380, 150, 414, 468, 416, 466, 470, 415, 390, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 388, 389, 469, 447, 446, 445, 32767, 32767, 412, 413, 417, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 103, 32767, 387, 420, 418, 419, 436, 437, 434, 435, 438, 32767, 439, 440, 441, 442, 32767, 315, 32767, 32767, 32767, 364, 362, 315, 112, 32767, 32767, 427, 428, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 531, 444, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 103, 32767, 101, 533, 409, 411, 501, 422, 423, 421, 391, 32767, 508, 32767, 103, 510, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 532, 32767, 539, 539, 32767, 494, 101, 194, 32767, 32767, 32767, 194, 194, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 600, 494, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 32767, 194, 111, 32767, 32767, 32767, 101, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 189, 32767, 267, 269, 103, 554, 194, 32767, 513, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 506, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 494, 432, 139, 32767, 139, 539, 424, 425, 426, 496, 539, 539, 539, 311, 288, 32767, 32767, 32767, 32767, 511, 511, 101, 101, 101, 101, 506, 32767, 32767, 32767, 32767, 112, 100, 100, 100, 100, 100, 104, 102, 32767, 32767, 32767, 32767, 222, 100, 32767, 102, 102, 32767, 32767, 222, 224, 211, 102, 226, 32767, 558, 559, 222, 102, 226, 226, 226, 246, 246, 483, 317, 102, 100, 102, 102, 196, 317, 317, 32767, 102, 483, 317, 483, 317, 198, 317, 317, 317, 483, 317, 32767, 102, 317, 213, 100, 100, 317, 32767, 32767, 32767, 496, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 221, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 526, 32767, 543, 556, 430, 431, 433, 541, 455, 456, 457, 458, 459, 460, 461, 463, 588, 32767, 500, 32767, 32767, 32767, 32767, 337, 598, 32767, 598, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 599, 32767, 539, 32767, 32767, 32767, 32767, 429, 9, 76, 489, 43, 44, 52, 58, 517, 518, 519, 520, 514, 515, 521, 516, 32767, 32767, 522, 564, 32767, 32767, 540, 591, 32767, 32767, 32767, 32767, 32767, 32767, 139, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 526, 32767, 137, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 539, 32767, 32767, 32767, 32767, 313, 310, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 539, 32767, 32767, 32767, 32767, 32767, 290, 32767, 307, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 285, 32767, 32767, 379, 32767, 32767, 32767, 32767, 358, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 152, 152, 3, 3, 340, 152, 152, 152, 340, 340, 152, 340, 340, 340, 152, 152, 152, 152, 152, 152, 279, 184, 261, 264, 246, 246, 152, 350, 152); - protected $goto = array(194, 194, 685, 425, 653, 346, 614, 650, 419, 310, 311, 331, 569, 316, 424, 332, 426, 630, 1200, 930, 693, 1051, 1201, 1204, 931, 1205, 165, 165, 165, 165, 218, 195, 191, 191, 175, 177, 213, 191, 191, 191, 191, 191, 192, 192, 192, 192, 192, 192, 186, 187, 188, 189, 190, 215, 213, 216, 529, 530, 415, 531, 533, 534, 535, 536, 537, 538, 539, 540, 1120, 166, 167, 168, 193, 169, 170, 171, 164, 172, 173, 174, 176, 212, 214, 217, 235, 240, 241, 242, 254, 255, 256, 257, 258, 259, 260, 261, 263, 264, 265, 266, 278, 279, 313, 314, 315, 420, 421, 422, 574, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 178, 234, 179, 196, 197, 198, 236, 186, 187, 188, 189, 190, 215, 1120, 199, 180, 181, 182, 200, 196, 183, 237, 201, 199, 163, 202, 203, 184, 204, 205, 206, 185, 207, 208, 209, 210, 211, 275, 275, 275, 275, 843, 593, 646, 647, 560, 664, 665, 666, 720, 629, 631, 840, 418, 651, 604, 841, 350, 675, 679, 996, 683, 691, 992, 616, 616, 817, 350, 350, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1092, 1093, 350, 350, 874, 350, 848, 1337, 896, 891, 892, 905, 849, 893, 846, 894, 895, 847, 548, 900, 899, 901, 350, 391, 394, 554, 594, 598, 1270, 1270, 1072, 1068, 1069, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1268, 1268, 815, 347, 348, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1221, 1020, 1221, 1020, 1221, 836, 5, 1020, 6, 1020, 1020, 1281, 961, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 349, 349, 349, 349, 1221, 460, 460, 566, 678, 1221, 1221, 1221, 1221, 344, 460, 1221, 1221, 1221, 1302, 1302, 1302, 1302, 602, 617, 620, 621, 622, 623, 643, 644, 645, 695, 836, 912, 553, 546, 1310, 913, 548, 532, 532, 821, 856, 982, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 543, 473, 543, 868, 543, 928, 855, 928, 389, 475, 337, 546, 553, 562, 563, 339, 572, 595, 609, 610, 1320, 1320, 249, 249, 1026, 1025, 15, 821, 450, 821, 494, 565, 495, 955, 955, 955, 955, 1320, 501, 450, 949, 956, 839, 652, 1321, 1321, 1169, 1214, 246, 246, 246, 246, 248, 250, 1323, 985, 959, 959, 957, 959, 719, 1321, 545, 994, 989, 470, 1295, 1296, 953, 405, 692, 917, 1108, 432, 541, 541, 541, 541, 612, 597, 452, 444, 1029, 1030, 1001, 658, 444, 1292, 444, 1292, 674, 1292, 860, 833, 656, 980, 836, 861, 547, 557, 854, 321, 305, 547, 333, 557, 1297, 1298, 392, 456, 570, 607, 1211, 944, 398, 858, 1304, 1304, 1304, 1304, 463, 573, 464, 465, 608, 1004, 866, 403, 404, 1328, 1329, 1057, 662, 1212, 663, 471, 407, 408, 409, 723, 676, 870, 1288, 410, 624, 626, 627, 342, 427, 1216, 869, 857, 1056, 1060, 427, 864, 1061, 1103, 966, 0, 0, 964, 1027, 1027, 0, 0, 0, 657, 1038, 1034, 1035, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 0, 1059, 444, 954, 0, 1290, 1290, 1059, 592, 1085, 0, 696, 682, 682, 0, 502, 688, 1083, 0, 0, 0, 1217, 1218, 272, 428, 1101, 873, 0, 544, 831, 544, 0, 0, 0, 673, 938, 0, 0, 1015, 1031, 1032, 0, 0, 0, 0, 0, 0, 1219, 1278, 1279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 999, 999); - protected $gotoCheck = array(42, 42, 72, 65, 65, 96, 55, 55, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 78, 78, 9, 126, 78, 78, 78, 78, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 23, 23, 23, 23, 15, 129, 85, 85, 48, 85, 85, 85, 48, 48, 48, 26, 13, 48, 13, 27, 14, 48, 48, 48, 48, 48, 48, 107, 107, 7, 14, 14, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 143, 143, 14, 14, 45, 14, 15, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 64, 15, 64, 14, 58, 58, 58, 58, 58, 168, 168, 15, 15, 15, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 169, 169, 6, 96, 96, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 72, 72, 72, 72, 72, 22, 46, 72, 46, 72, 72, 14, 49, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 24, 24, 24, 24, 72, 148, 148, 170, 14, 72, 72, 72, 72, 177, 148, 72, 72, 72, 9, 9, 9, 9, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 22, 72, 75, 75, 179, 72, 14, 171, 171, 12, 35, 102, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 19, 83, 19, 35, 19, 9, 35, 9, 61, 83, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 180, 180, 5, 5, 117, 117, 75, 12, 19, 12, 154, 103, 154, 19, 19, 19, 19, 180, 154, 19, 19, 19, 25, 63, 181, 181, 150, 14, 5, 5, 5, 5, 5, 5, 180, 25, 25, 25, 25, 25, 25, 181, 25, 25, 25, 174, 174, 174, 92, 92, 92, 17, 17, 112, 106, 106, 106, 106, 17, 106, 82, 23, 118, 118, 17, 119, 23, 129, 23, 129, 115, 129, 17, 18, 17, 17, 22, 39, 9, 9, 17, 167, 167, 9, 29, 9, 176, 176, 9, 9, 2, 2, 17, 91, 28, 37, 129, 129, 129, 129, 9, 9, 9, 9, 79, 109, 9, 81, 81, 9, 9, 128, 81, 159, 81, 156, 81, 81, 81, 98, 81, 41, 129, 81, 84, 84, 84, 81, 116, 20, 16, 16, 16, 16, 116, 9, 131, 146, 95, -1, -1, 16, 116, 116, -1, -1, -1, 116, 116, 116, 116, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, -1, 129, 23, 16, -1, 129, 129, 129, 8, 8, -1, 8, 8, 8, -1, 8, 8, 8, -1, -1, -1, 20, 20, 24, 88, 16, 16, -1, 24, 20, 24, -1, -1, -1, 88, 88, -1, -1, 88, 88, 88, -1, -1, -1, -1, -1, -1, 20, 20, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 106, 106); - protected $gotoBase = array(0, 0, -250, 0, 0, 360, 235, 181, 522, 7, 0, 0, 33, -156, -113, -178, 43, -49, 126, 72, 100, 0, -9, 158, 282, 377, 172, 176, 120, 150, 0, 0, 0, 0, 0, -39, 0, 119, 0, 116, 0, 45, -1, 0, 0, 195, -456, 0, -529, 250, 0, 0, 0, 0, 0, -33, 0, 0, 182, 0, 0, 306, 0, 143, 203, -235, 0, 0, 0, 0, 0, 0, -6, 0, 0, -21, 0, 0, -385, 124, -46, -19, 144, -123, 10, -538, 0, 0, 275, 0, 0, 127, 106, 0, 0, 60, -472, 0, 76, 0, 0, 0, 294, 328, 0, 0, 386, -50, 0, 99, 0, 0, 138, 0, 0, 149, 219, 87, 139, 137, 0, 0, 0, 0, 0, 0, 19, 0, 101, 159, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -69, 0, 0, 58, 0, 257, 0, 114, 0, 0, 0, -120, 0, 40, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 122, -7, 8, 264, 86, 0, 0, 107, 0, 78, 269, 0, 291, 55, 79, 0, 0); - protected $gotoDefault = array(-32768, 506, 727, 4, 728, 921, 804, 813, 590, 523, 694, 343, 618, 416, 1286, 898, 1107, 571, 832, 1230, 1238, 451, 835, 326, 717, 880, 881, 882, 395, 381, 387, 393, 641, 619, 488, 867, 447, 859, 480, 862, 446, 871, 162, 413, 504, 875, 3, 877, 550, 908, 382, 885, 383, 669, 887, 556, 889, 890, 390, 396, 397, 1112, 564, 615, 902, 253, 558, 903, 380, 904, 911, 385, 388, 680, 459, 499, 493, 406, 1087, 559, 601, 638, 441, 467, 613, 625, 611, 474, 1023, 411, 325, 943, 951, 481, 457, 965, 345, 973, 725, 1119, 632, 483, 981, 633, 988, 991, 524, 525, 472, 1003, 268, 1006, 484, 1044, 659, 1017, 1018, 660, 634, 1040, 635, 661, 636, 1042, 466, 591, 1050, 448, 1058, 1274, 449, 1062, 262, 1065, 274, 412, 429, 1070, 1071, 8, 1077, 686, 687, 10, 273, 503, 1102, 681, 445, 1118, 433, 1188, 1190, 552, 485, 1208, 1207, 672, 500, 1213, 442, 1277, 443, 526, 468, 312, 527, 304, 329, 309, 542, 291, 330, 528, 469, 1283, 1291, 327, 30, 1311, 1322, 338, 568, 606); - protected $ruleToNonTerminal = array(0, 1, 3, 3, 2, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 9, 10, 11, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18, 21, 21, 22, 23, 23, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 29, 30, 30, 32, 34, 34, 28, 36, 36, 33, 38, 38, 35, 35, 37, 37, 39, 39, 31, 40, 40, 41, 43, 44, 44, 45, 46, 46, 48, 47, 47, 47, 47, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 25, 25, 68, 68, 71, 71, 70, 69, 69, 62, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 26, 26, 27, 27, 27, 27, 27, 87, 87, 89, 89, 82, 82, 90, 90, 91, 91, 91, 83, 83, 86, 86, 84, 84, 92, 93, 93, 56, 56, 64, 64, 67, 67, 67, 66, 94, 94, 95, 57, 57, 57, 57, 96, 96, 97, 97, 98, 98, 99, 100, 100, 101, 101, 102, 102, 54, 54, 50, 50, 104, 52, 52, 105, 51, 51, 53, 53, 63, 63, 63, 63, 80, 80, 108, 108, 110, 110, 111, 111, 111, 111, 109, 109, 109, 113, 113, 113, 113, 88, 88, 116, 116, 116, 117, 117, 114, 114, 118, 118, 120, 120, 121, 121, 115, 122, 122, 119, 123, 123, 123, 123, 112, 112, 81, 81, 81, 20, 20, 20, 125, 124, 124, 126, 126, 126, 126, 59, 127, 127, 128, 60, 130, 130, 131, 131, 132, 132, 85, 133, 133, 133, 133, 133, 133, 138, 138, 139, 139, 140, 140, 140, 140, 140, 141, 142, 142, 137, 137, 134, 134, 136, 136, 144, 144, 143, 143, 143, 143, 143, 143, 143, 135, 145, 145, 147, 146, 146, 61, 103, 148, 148, 55, 55, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 155, 149, 149, 154, 154, 157, 158, 158, 159, 160, 161, 161, 161, 161, 19, 19, 72, 72, 72, 72, 150, 150, 150, 150, 163, 163, 151, 151, 153, 153, 153, 156, 156, 168, 168, 168, 168, 168, 168, 168, 168, 168, 169, 169, 107, 171, 171, 171, 171, 152, 152, 152, 152, 152, 152, 152, 152, 58, 58, 166, 166, 166, 166, 172, 172, 162, 162, 162, 173, 173, 173, 173, 173, 173, 73, 73, 65, 65, 65, 65, 129, 129, 129, 129, 176, 175, 165, 165, 165, 165, 165, 165, 165, 164, 164, 164, 174, 174, 174, 174, 106, 170, 178, 178, 177, 177, 179, 179, 179, 179, 179, 179, 179, 179, 167, 167, 167, 167, 181, 182, 180, 180, 180, 180, 180, 180, 180, 180, 183, 183, 183, 183); - protected $ruleToLength = array(1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 2, 1, 3, 4, 1, 2, 0, 1, 1, 1, 1, 1, 3, 5, 4, 3, 4, 2, 3, 1, 1, 7, 6, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 3, 1, 3, 1, 2, 2, 3, 1, 3, 2, 3, 1, 3, 2, 0, 1, 1, 1, 1, 1, 3, 7, 10, 5, 7, 9, 5, 3, 3, 3, 3, 3, 3, 1, 2, 5, 7, 9, 6, 5, 6, 3, 2, 1, 1, 1, 0, 2, 1, 3, 8, 0, 4, 2, 1, 3, 0, 1, 0, 1, 0, 1, 3, 1, 1, 1, 8, 9, 7, 8, 7, 6, 8, 0, 2, 0, 2, 1, 2, 1, 2, 1, 1, 1, 0, 2, 0, 2, 0, 2, 2, 1, 3, 1, 4, 1, 4, 1, 1, 4, 2, 1, 3, 3, 3, 4, 4, 5, 0, 2, 4, 3, 1, 1, 7, 0, 2, 1, 3, 3, 4, 1, 4, 0, 2, 5, 0, 2, 6, 0, 2, 0, 3, 1, 2, 1, 1, 2, 0, 1, 3, 0, 2, 1, 1, 1, 1, 6, 8, 6, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 3, 1, 1, 2, 1, 1, 0, 1, 0, 2, 2, 2, 4, 3, 1, 1, 3, 1, 2, 2, 3, 2, 3, 1, 1, 2, 3, 1, 1, 3, 2, 0, 1, 5, 5, 10, 3, 5, 1, 1, 3, 0, 2, 4, 5, 4, 4, 4, 3, 1, 1, 1, 1, 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, 1, 1, 3, 2, 2, 3, 1, 0, 1, 1, 3, 3, 3, 4, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 3, 4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 2, 1, 2, 4, 2, 2, 8, 9, 8, 9, 9, 10, 9, 10, 8, 3, 2, 0, 4, 2, 1, 3, 2, 1, 2, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 0, 3, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 4, 1, 1, 3, 1, 1, 1, 1, 1, 3, 2, 3, 0, 1, 1, 3, 1, 1, 1, 1, 1, 3, 1, 1, 4, 4, 1, 4, 4, 0, 1, 1, 1, 3, 3, 1, 4, 2, 2, 1, 3, 1, 4, 4, 3, 3, 3, 3, 1, 3, 1, 1, 3, 1, 1, 4, 1, 1, 1, 3, 1, 1, 2, 1, 3, 4, 3, 2, 0, 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, 3, 3, 6, 3, 1, 1, 2, 1); - protected function initReduceCallbacks() - { - $this->reduceCallbacks = [0 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 1 => function ($stackPos) { +class Php8 extends \PHPUnit\PhpParser\ParserAbstract +{ + public const YYERRTOK = 256; + public const T_THROW = 257; + public const T_INCLUDE = 258; + public const T_INCLUDE_ONCE = 259; + public const T_EVAL = 260; + public const T_REQUIRE = 261; + public const T_REQUIRE_ONCE = 262; + public const T_LOGICAL_OR = 263; + public const T_LOGICAL_XOR = 264; + public const T_LOGICAL_AND = 265; + public const T_PRINT = 266; + public const T_YIELD = 267; + public const T_DOUBLE_ARROW = 268; + public const T_YIELD_FROM = 269; + public const T_PLUS_EQUAL = 270; + public const T_MINUS_EQUAL = 271; + public const T_MUL_EQUAL = 272; + public const T_DIV_EQUAL = 273; + public const T_CONCAT_EQUAL = 274; + public const T_MOD_EQUAL = 275; + public const T_AND_EQUAL = 276; + public const T_OR_EQUAL = 277; + public const T_XOR_EQUAL = 278; + public const T_SL_EQUAL = 279; + public const T_SR_EQUAL = 280; + public const T_POW_EQUAL = 281; + public const T_COALESCE_EQUAL = 282; + public const T_COALESCE = 283; + public const T_BOOLEAN_OR = 284; + public const T_BOOLEAN_AND = 285; + public const T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG = 286; + public const T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG = 287; + public const T_IS_EQUAL = 288; + public const T_IS_NOT_EQUAL = 289; + public const T_IS_IDENTICAL = 290; + public const T_IS_NOT_IDENTICAL = 291; + public const T_SPACESHIP = 292; + public const T_IS_SMALLER_OR_EQUAL = 293; + public const T_IS_GREATER_OR_EQUAL = 294; + public const T_SL = 295; + public const T_SR = 296; + public const T_INSTANCEOF = 297; + public const T_INC = 298; + public const T_DEC = 299; + public const T_INT_CAST = 300; + public const T_DOUBLE_CAST = 301; + public const T_STRING_CAST = 302; + public const T_ARRAY_CAST = 303; + public const T_OBJECT_CAST = 304; + public const T_BOOL_CAST = 305; + public const T_UNSET_CAST = 306; + public const T_POW = 307; + public const T_NEW = 308; + public const T_CLONE = 309; + public const T_EXIT = 310; + public const T_IF = 311; + public const T_ELSEIF = 312; + public const T_ELSE = 313; + public const T_ENDIF = 314; + public const T_LNUMBER = 315; + public const T_DNUMBER = 316; + public const T_STRING = 317; + public const T_STRING_VARNAME = 318; + public const T_VARIABLE = 319; + public const T_NUM_STRING = 320; + public const T_INLINE_HTML = 321; + public const T_ENCAPSED_AND_WHITESPACE = 322; + public const T_CONSTANT_ENCAPSED_STRING = 323; + public const T_ECHO = 324; + public const T_DO = 325; + public const T_WHILE = 326; + public const T_ENDWHILE = 327; + public const T_FOR = 328; + public const T_ENDFOR = 329; + public const T_FOREACH = 330; + public const T_ENDFOREACH = 331; + public const T_DECLARE = 332; + public const T_ENDDECLARE = 333; + public const T_AS = 334; + public const T_SWITCH = 335; + public const T_MATCH = 336; + public const T_ENDSWITCH = 337; + public const T_CASE = 338; + public const T_DEFAULT = 339; + public const T_BREAK = 340; + public const T_CONTINUE = 341; + public const T_GOTO = 342; + public const T_FUNCTION = 343; + public const T_FN = 344; + public const T_CONST = 345; + public const T_RETURN = 346; + public const T_TRY = 347; + public const T_CATCH = 348; + public const T_FINALLY = 349; + public const T_USE = 350; + public const T_INSTEADOF = 351; + public const T_GLOBAL = 352; + public const T_STATIC = 353; + public const T_ABSTRACT = 354; + public const T_FINAL = 355; + public const T_PRIVATE = 356; + public const T_PROTECTED = 357; + public const T_PUBLIC = 358; + public const T_READONLY = 359; + public const T_VAR = 360; + public const T_UNSET = 361; + public const T_ISSET = 362; + public const T_EMPTY = 363; + public const T_HALT_COMPILER = 364; + public const T_CLASS = 365; + public const T_TRAIT = 366; + public const T_INTERFACE = 367; + public const T_ENUM = 368; + public const T_EXTENDS = 369; + public const T_IMPLEMENTS = 370; + public const T_OBJECT_OPERATOR = 371; + public const T_NULLSAFE_OBJECT_OPERATOR = 372; + public const T_LIST = 373; + public const T_ARRAY = 374; + public const T_CALLABLE = 375; + public const T_CLASS_C = 376; + public const T_TRAIT_C = 377; + public const T_METHOD_C = 378; + public const T_FUNC_C = 379; + public const T_LINE = 380; + public const T_FILE = 381; + public const T_START_HEREDOC = 382; + public const T_END_HEREDOC = 383; + public const T_DOLLAR_OPEN_CURLY_BRACES = 384; + public const T_CURLY_OPEN = 385; + public const T_PAAMAYIM_NEKUDOTAYIM = 386; + public const T_NAMESPACE = 387; + public const T_NS_C = 388; + public const T_DIR = 389; + public const T_NS_SEPARATOR = 390; + public const T_ELLIPSIS = 391; + public const T_NAME_FULLY_QUALIFIED = 392; + public const T_NAME_QUALIFIED = 393; + public const T_NAME_RELATIVE = 394; + public const T_ATTRIBUTE = 395; + protected int $tokenToSymbolMapSize = 396; + protected int $actionTableSize = 1257; + protected int $gotoTableSize = 657; + protected int $invalidSymbol = 168; + protected int $errorSymbol = 1; + protected int $defaultAction = -32766; + protected int $unexpectedTokenRule = 32767; + protected int $YY2TBLSTATE = 435; + protected int $numNonLeafStates = 739; + protected array $symbolToName = array("EOF", "error", "T_THROW", "T_INCLUDE", "T_INCLUDE_ONCE", "T_EVAL", "T_REQUIRE", "T_REQUIRE_ONCE", "','", "T_LOGICAL_OR", "T_LOGICAL_XOR", "T_LOGICAL_AND", "T_PRINT", "T_YIELD", "T_DOUBLE_ARROW", "T_YIELD_FROM", "'='", "T_PLUS_EQUAL", "T_MINUS_EQUAL", "T_MUL_EQUAL", "T_DIV_EQUAL", "T_CONCAT_EQUAL", "T_MOD_EQUAL", "T_AND_EQUAL", "T_OR_EQUAL", "T_XOR_EQUAL", "T_SL_EQUAL", "T_SR_EQUAL", "T_POW_EQUAL", "T_COALESCE_EQUAL", "'?'", "':'", "T_COALESCE", "T_BOOLEAN_OR", "T_BOOLEAN_AND", "'|'", "'^'", "T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG", "T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG", "T_IS_EQUAL", "T_IS_NOT_EQUAL", "T_IS_IDENTICAL", "T_IS_NOT_IDENTICAL", "T_SPACESHIP", "'<'", "T_IS_SMALLER_OR_EQUAL", "'>'", "T_IS_GREATER_OR_EQUAL", "'.'", "T_SL", "T_SR", "'+'", "'-'", "'*'", "'/'", "'%'", "'!'", "T_INSTANCEOF", "'~'", "T_INC", "T_DEC", "T_INT_CAST", "T_DOUBLE_CAST", "T_STRING_CAST", "T_ARRAY_CAST", "T_OBJECT_CAST", "T_BOOL_CAST", "T_UNSET_CAST", "'@'", "T_POW", "'['", "T_NEW", "T_CLONE", "T_EXIT", "T_IF", "T_ELSEIF", "T_ELSE", "T_ENDIF", "T_LNUMBER", "T_DNUMBER", "T_STRING", "T_STRING_VARNAME", "T_VARIABLE", "T_NUM_STRING", "T_INLINE_HTML", "T_ENCAPSED_AND_WHITESPACE", "T_CONSTANT_ENCAPSED_STRING", "T_ECHO", "T_DO", "T_WHILE", "T_ENDWHILE", "T_FOR", "T_ENDFOR", "T_FOREACH", "T_ENDFOREACH", "T_DECLARE", "T_ENDDECLARE", "T_AS", "T_SWITCH", "T_MATCH", "T_ENDSWITCH", "T_CASE", "T_DEFAULT", "T_BREAK", "T_CONTINUE", "T_GOTO", "T_FUNCTION", "T_FN", "T_CONST", "T_RETURN", "T_TRY", "T_CATCH", "T_FINALLY", "T_USE", "T_INSTEADOF", "T_GLOBAL", "T_STATIC", "T_ABSTRACT", "T_FINAL", "T_PRIVATE", "T_PROTECTED", "T_PUBLIC", "T_READONLY", "T_VAR", "T_UNSET", "T_ISSET", "T_EMPTY", "T_HALT_COMPILER", "T_CLASS", "T_TRAIT", "T_INTERFACE", "T_ENUM", "T_EXTENDS", "T_IMPLEMENTS", "T_OBJECT_OPERATOR", "T_NULLSAFE_OBJECT_OPERATOR", "T_LIST", "T_ARRAY", "T_CALLABLE", "T_CLASS_C", "T_TRAIT_C", "T_METHOD_C", "T_FUNC_C", "T_LINE", "T_FILE", "T_START_HEREDOC", "T_END_HEREDOC", "T_DOLLAR_OPEN_CURLY_BRACES", "T_CURLY_OPEN", "T_PAAMAYIM_NEKUDOTAYIM", "T_NAMESPACE", "T_NS_C", "T_DIR", "T_NS_SEPARATOR", "T_ELLIPSIS", "T_NAME_FULLY_QUALIFIED", "T_NAME_QUALIFIED", "T_NAME_RELATIVE", "T_ATTRIBUTE", "';'", "']'", "'('", "')'", "'{'", "'}'", "'`'", "'\"'", "'\$'"); + protected array $tokenToSymbol = array(0, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 56, 166, 168, 167, 55, 168, 168, 161, 162, 53, 51, 8, 52, 48, 54, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 31, 159, 44, 16, 46, 30, 68, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 70, 168, 160, 36, 168, 165, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 163, 35, 164, 58, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43, 45, 47, 49, 50, 57, 59, 60, 61, 62, 63, 64, 65, 66, 67, 69, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158); + protected array $action = array(133, 134, 135, 582, 136, 137, 0, 751, 752, 753, 138, 38, 327, -32766, -32766, -32766, -32766, -32766, -32766, 837, 826, -32767, -32767, -32767, -32767, 102, 103, 104, 1112, 1113, 1114, 1111, 1110, 1109, 1115, 745, 744, -32766, 1027, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32767, -32767, -32767, -32767, -32767, 1245, -32766, -32766, 1322, 754, 1112, 1113, 1114, 1111, 1110, 1109, 1115, 459, 460, 461, 2, 990, 1306, 265, 139, 404, 758, 759, 760, 761, 467, 468, 429, 835, 606, -16, 1341, 23, 292, 815, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 791, 583, 792, 793, 794, 795, 783, 784, 345, 346, 786, 787, 772, 773, 774, 776, 777, 778, 356, 818, 819, 820, 821, 822, 584, 779, 780, 585, 586, 941, 803, 801, 802, 814, 798, 799, 835, 826, 587, 588, 797, 589, 590, 591, 592, 593, 594, -328, 36, 251, 35, -194, 800, 595, 596, -193, 140, -85, 133, 134, 135, 582, 136, 137, 1060, 751, 752, 753, 138, 38, 129, -110, -110, -585, -32766, -585, -110, -32766, -32766, -32766, 241, 836, -110, 145, 959, 960, -32766, -32766, -32766, 961, -594, -32766, 482, 745, 744, 955, 1036, -594, -32766, 991, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, 299, 754, 831, 75, -32766, -32766, -32766, 291, 142, 326, 242, -85, 326, 382, 381, 265, 139, 404, 758, 759, 760, 761, 82, 423, 429, -32766, 326, -32766, -32766, -32766, -32766, 815, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 791, 583, 792, 793, 794, 795, 783, 784, 345, 346, 786, 787, 772, 773, 774, 776, 777, 778, 356, 818, 819, 820, 821, 822, 584, 779, 780, 585, 586, 254, 803, 801, 802, 814, 798, 799, 832, 725, 587, 588, 797, 589, 590, 591, 592, 593, 594, -328, 83, 84, 85, -194, 800, 595, 596, -193, 149, 775, 746, 747, 748, 749, 750, 151, 751, 752, 753, 788, 789, 37, 483, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, -594, 274, -594, -32766, -32766, -32766, -32766, -32766, -32766, 310, 1089, 127, 312, 110, 737, 1326, 21, 754, -32766, -32766, -32766, -272, 1325, -32766, -32766, 1088, -32766, -32766, -32766, -32766, -32766, 755, 756, 757, 758, 759, 760, 761, 1104, -32766, 824, -32766, -32766, -545, 429, 1036, 323, 815, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 791, 813, 792, 793, 794, 795, 783, 784, 785, 812, 786, 787, 772, 773, 774, 776, 777, 778, 817, 818, 819, 820, 821, 822, 823, 779, 780, 781, 782, 1033, 803, 801, 802, 814, 798, 799, 745, 744, 790, 796, 797, 804, 805, 807, 806, 808, 809, 152, -32766, -545, -545, 1036, 800, 811, 810, 50, 51, 52, 513, 53, 54, 1240, 1239, 1241, -545, 55, 56, -110, 57, -32766, 1090, 920, -110, 556, -110, 292, -551, 339, -545, 306, 103, 104, -110, -110, -110, -110, -110, -110, -110, -110, 105, 106, 107, 108, 109, 1245, 274, 380, 381, -591, -367, 715, -367, 340, 58, 59, -591, 423, 110, 60, 370, 61, 248, 249, 62, 63, 64, 65, 66, 67, 68, 69, -544, 28, 267, 70, 445, 514, -32766, 374, -342, 1272, 1273, 515, 1278, 835, 862, 389, 863, 1270, 42, 25, 516, 943, 517, 943, 518, 920, 519, 299, 1036, 520, 521, 1266, 910, 441, 44, 45, 446, 377, 376, -32766, 46, 522, 1023, 1022, 1021, 1024, 368, 338, 391, 1238, 7, 291, 442, 1231, 835, 524, 525, 526, 443, 1245, 357, 1036, 362, 834, -544, -544, 154, 528, 529, 444, 1259, 1260, 1261, 1262, 1256, 1257, 298, -32766, -32766, -544, -548, 1059, 1263, 1258, 291, 1236, 1240, 1239, 1241, 299, 841, -550, 71, -544, 656, 26, 321, 322, 326, -153, -153, -153, 920, 612, 675, 676, 1035, 922, 910, -32766, 286, 710, 835, 155, -153, 828, -153, 862, -153, 863, -153, 150, 407, 156, 1240, 1239, 1241, -32766, -32766, -32766, 375, 1351, 716, 75, 1352, 158, -591, 33, -591, 326, 835, 959, 960, -78, -548, -548, 523, 920, -32766, 378, 379, 896, 955, -110, -110, -110, 32, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 745, 744, -58, -548, -57, -110, -110, 717, 745, 744, -110, 383, 384, 922, 1033, 910, -110, 710, -153, 647, 648, 830, 124, 141, 125, -32766, 1033, 326, 712, 1150, 1152, 48, 130, 131, 144, 159, 1036, -32766, 160, 161, -543, 28, 162, 1238, 920, 163, 299, 920, 1036, 75, -32766, -32766, -32766, 835, -32766, 326, -32766, 1270, -32766, 282, 910, -32766, -87, -84, -78, -73, -32766, -32766, -32766, -4, 920, 282, -32766, -32766, 720, -72, -71, 727, -32766, 420, -70, -69, -68, -67, -66, 287, 286, -32766, -65, -46, 922, 745, 744, 1231, 710, 300, 301, -546, -18, 148, -302, 273, 283, 726, -543, -543, 729, 528, 529, 920, 1259, 1260, 1261, 1262, 1256, 1257, 919, 74, 147, -543, 288, 293, 1263, 1258, 126, -298, 280, 910, -32766, 281, 910, 284, 73, -543, 1238, 976, 690, 322, 326, 710, 285, -32766, -32766, -32766, 332, -32766, 274, -32766, 294, -32766, 937, 110, -32766, 910, 685, 835, -543, -32766, -32766, -32766, 826, -546, -546, -32766, -32766, 146, -32766, -50, 701, -32766, 420, 703, 691, 20, 1119, 375, -546, 436, -32766, 645, 1353, 1277, 297, 657, -32766, 1279, 959, 960, 561, 956, -546, 523, 910, 692, 693, 678, 527, 955, -110, -110, -110, 132, 922, 662, 663, 922, 710, 464, -508, 710, -32766, 1240, 1239, 1241, 493, 679, 1238, 282, 939, 10, -543, -543, 40, -32766, -32766, -32766, 731, -32766, 922, -32766, 307, -32766, 710, -4, -32766, -543, 305, 41, 304, -32766, -32766, -32766, 0, 0, -32766, -32766, -32766, 920, 0, -543, 1238, -32766, 420, 311, 0, 567, 299, -32766, -32766, -32766, -32766, -32766, -498, -32766, 897, -32766, 0, 922, -32766, 8, 0, 710, 24, -32766, -32766, -32766, -32766, 372, 610, -32766, -32766, 834, 1238, 734, -275, -32766, 420, 920, 735, -32766, -32766, -32766, 854, -32766, -32766, -32766, 901, -32766, 1000, 977, -32766, 49, 984, 974, 488, -32766, -32766, -32766, -32766, 985, 899, -32766, -32766, 972, 1238, 574, 1093, -32766, 420, 1096, 1097, -32766, -32766, -32766, 1094, -32766, -32766, -32766, 1095, -32766, 910, 1101, -32766, 1267, 846, 1292, 1310, -32766, -32766, -32766, 1344, 650, 34, -32766, -32766, -579, -250, -250, -250, -32766, 420, -578, 375, -577, -551, 28, 267, -550, -32766, -549, -492, 1, 29, 959, 960, 302, 303, 835, 523, 30, 910, 1270, 39, 896, 955, -110, -110, -110, 43, 47, 373, 72, 76, 77, 78, 79, -249, -249, -249, 80, 81, 143, 375, 153, 128, -273, 157, 247, 328, 357, 358, 359, 360, 959, 960, 922, 361, 1231, 523, 710, -250, 362, 363, 896, 955, -110, -110, -110, 364, 365, 366, 367, 529, 28, 1259, 1260, 1261, 1262, 1256, 1257, 369, 437, 555, 1207, -272, 835, 1263, 1258, 13, 1270, 14, -32766, 15, 16, 18, 922, 73, 1238, 1348, 710, -249, 322, 326, 406, -32766, -32766, -32766, 484, -32766, 485, -32766, 492, -32766, 495, 496, -32766, 497, 498, 502, 503, -32766, -32766, -32766, 504, 511, 1231, -32766, -32766, 572, 696, 1249, 1190, -32766, 420, 1268, 1062, 1061, 1042, 1226, 1038, 529, -32766, 1259, 1260, 1261, 1262, 1256, 1257, -277, -102, 12, 17, 27, 296, 1263, 1258, 405, 603, 607, 636, 702, 1194, 1244, 1191, 73, 320, 1323, 0, 371, 322, 326, 711, 714, 718, 719, 721, 722, 723, 724, 728, 0, 713, 0, 1350, 857, 856, 865, 949, 992, 864, 1349, 948, 946, 947, 950, 1222, 930, 940, 928, 982, 983, 634, 1347, 1304, 1293, 1311, 1320, 0, 0, 1271, 0, 326); + protected array $actionCheck = array(2, 3, 4, 5, 6, 7, 0, 9, 10, 11, 12, 13, 70, 9, 10, 11, 9, 10, 11, 1, 80, 44, 45, 46, 47, 48, 49, 50, 116, 117, 118, 119, 120, 121, 122, 37, 38, 30, 1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 1, 9, 10, 1, 57, 116, 117, 118, 119, 120, 121, 122, 129, 130, 131, 8, 31, 1, 71, 72, 73, 74, 75, 76, 77, 134, 135, 80, 82, 1, 31, 85, 8, 30, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 1, 128, 129, 130, 131, 132, 133, 82, 80, 136, 137, 138, 139, 140, 141, 142, 143, 144, 8, 147, 148, 8, 8, 150, 151, 152, 8, 154, 31, 2, 3, 4, 5, 6, 7, 162, 9, 10, 11, 12, 13, 8, 117, 118, 160, 116, 162, 122, 9, 10, 11, 97, 159, 128, 8, 117, 118, 9, 10, 11, 122, 1, 137, 31, 37, 38, 128, 138, 8, 30, 159, 32, 33, 34, 35, 36, 37, 38, 30, 9, 32, 33, 34, 158, 57, 80, 161, 9, 10, 11, 161, 163, 167, 14, 97, 167, 106, 107, 71, 72, 73, 74, 75, 76, 77, 163, 116, 80, 30, 167, 32, 33, 34, 35, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 8, 128, 129, 130, 131, 132, 133, 156, 163, 136, 137, 138, 139, 140, 141, 142, 143, 144, 162, 9, 10, 11, 162, 150, 151, 152, 162, 154, 2, 3, 4, 5, 6, 7, 14, 9, 10, 11, 12, 13, 30, 163, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 160, 57, 162, 9, 10, 11, 9, 10, 11, 8, 159, 14, 8, 69, 163, 1, 101, 57, 9, 10, 11, 162, 8, 116, 30, 1, 32, 33, 34, 35, 36, 71, 72, 73, 74, 75, 76, 77, 123, 30, 80, 32, 33, 70, 80, 138, 8, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 116, 128, 129, 130, 131, 132, 133, 37, 38, 136, 137, 138, 139, 140, 141, 142, 143, 144, 14, 116, 134, 135, 138, 150, 151, 152, 2, 3, 4, 5, 6, 7, 155, 156, 157, 149, 12, 13, 101, 15, 137, 164, 1, 106, 85, 108, 30, 161, 8, 163, 113, 49, 50, 116, 117, 118, 119, 120, 121, 122, 123, 51, 52, 53, 54, 55, 1, 57, 106, 107, 1, 106, 31, 108, 8, 51, 52, 8, 116, 69, 56, 8, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 70, 71, 72, 73, 74, 116, 8, 164, 78, 79, 80, 146, 82, 106, 8, 108, 86, 87, 88, 89, 122, 91, 122, 93, 1, 95, 158, 138, 98, 99, 1, 84, 8, 103, 104, 105, 106, 107, 116, 109, 110, 119, 120, 121, 122, 115, 116, 106, 80, 108, 161, 8, 122, 82, 124, 125, 126, 8, 1, 161, 138, 161, 155, 134, 135, 14, 136, 137, 8, 139, 140, 141, 142, 143, 144, 145, 51, 52, 149, 70, 1, 151, 152, 161, 116, 155, 156, 157, 158, 8, 161, 161, 163, 75, 76, 165, 166, 167, 75, 76, 77, 1, 52, 75, 76, 137, 159, 84, 137, 30, 163, 82, 14, 90, 80, 92, 106, 94, 108, 96, 101, 102, 14, 155, 156, 157, 9, 10, 11, 106, 80, 31, 161, 83, 14, 160, 14, 162, 167, 82, 117, 118, 16, 134, 135, 122, 1, 30, 106, 107, 127, 128, 129, 130, 131, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 37, 38, 16, 163, 16, 117, 118, 31, 37, 38, 122, 106, 107, 159, 116, 84, 128, 163, 164, 111, 112, 156, 16, 163, 16, 137, 116, 167, 163, 59, 60, 70, 16, 16, 16, 16, 138, 74, 16, 16, 70, 70, 16, 80, 1, 16, 158, 1, 138, 161, 87, 88, 89, 82, 91, 167, 93, 86, 95, 161, 84, 98, 31, 31, 31, 31, 103, 104, 105, 0, 1, 161, 109, 110, 31, 31, 31, 31, 115, 116, 31, 31, 31, 31, 31, 37, 30, 124, 31, 31, 159, 37, 38, 122, 163, 134, 135, 70, 31, 31, 35, 31, 31, 31, 134, 135, 31, 136, 137, 1, 139, 140, 141, 142, 143, 144, 31, 154, 31, 149, 37, 37, 151, 152, 163, 35, 35, 84, 74, 35, 84, 35, 161, 163, 80, 159, 80, 166, 167, 163, 35, 87, 88, 89, 35, 91, 57, 93, 37, 95, 38, 69, 98, 84, 77, 82, 70, 103, 104, 105, 80, 134, 135, 109, 110, 70, 85, 31, 80, 115, 116, 92, 116, 97, 82, 106, 149, 108, 124, 113, 83, 146, 113, 90, 137, 146, 117, 118, 89, 128, 163, 122, 84, 137, 138, 94, 127, 128, 129, 130, 131, 31, 159, 96, 100, 159, 163, 97, 149, 163, 74, 155, 156, 157, 97, 100, 80, 161, 154, 150, 134, 135, 159, 87, 88, 89, 164, 91, 159, 93, 114, 95, 163, 164, 98, 149, 133, 159, 132, 103, 104, 105, -1, -1, 74, 109, 110, 1, -1, 163, 80, 115, 116, 132, -1, 153, 158, 87, 88, 89, 124, 91, 149, 93, 164, 95, -1, 159, 98, 149, -1, 163, 149, 103, 104, 105, 74, 149, 153, 109, 110, 155, 80, 159, 162, 115, 116, 1, 159, 87, 88, 89, 159, 91, 124, 93, 159, 95, 159, 159, 98, 70, 159, 159, 102, 103, 104, 105, 74, 159, 159, 109, 110, 159, 80, 81, 159, 115, 116, 159, 159, 87, 88, 89, 159, 91, 124, 93, 159, 95, 84, 159, 98, 160, 160, 160, 160, 103, 104, 105, 160, 160, 163, 109, 110, 161, 100, 101, 102, 115, 116, 161, 106, 161, 161, 70, 71, 161, 124, 161, 161, 161, 161, 117, 118, 134, 135, 82, 122, 161, 84, 86, 161, 127, 128, 129, 130, 131, 161, 161, 149, 161, 161, 161, 161, 161, 100, 101, 102, 161, 161, 161, 106, 161, 163, 162, 161, 161, 161, 161, 161, 161, 161, 117, 118, 159, 161, 122, 122, 163, 164, 161, 161, 127, 128, 129, 130, 131, 161, 161, 161, 161, 137, 70, 139, 140, 141, 142, 143, 144, 161, 161, 161, 165, 162, 82, 151, 152, 162, 86, 162, 74, 162, 162, 162, 159, 161, 80, 164, 163, 164, 166, 167, 162, 87, 88, 89, 162, 91, 162, 93, 162, 95, 162, 162, 98, 162, 162, 162, 162, 103, 104, 105, 162, 162, 122, 109, 110, 162, 162, 162, 162, 115, 116, 162, 162, 162, 162, 162, 162, 137, 124, 139, 140, 141, 142, 143, 144, 162, 162, 162, 162, 162, 162, 151, 152, 162, 162, 162, 162, 162, 162, 162, 162, 161, 163, 162, -1, 163, 166, 167, 163, 163, 163, 163, 163, 163, 163, 163, 163, -1, 163, -1, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -1, -1, 166, -1, 167); + protected array $actionBase = array(0, -2, 152, 549, 764, 941, 981, 751, 555, 309, 560, 864, 626, 738, 738, 741, 738, 473, 671, 783, -60, 305, 305, 783, 305, 803, 803, 803, 658, 658, 658, 658, 749, 749, 897, 897, 929, 865, 831, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 18, 36, 79, 648, 1036, 1044, 1040, 1045, 1034, 1033, 1039, 1041, 1046, 1083, 1084, 782, 1085, 1086, 1082, 1087, 1042, 876, 1035, 1043, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 195, 342, 43, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 643, 643, 643, 666, 666, 354, 173, 980, 203, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 665, 339, 164, 164, 7, 7, 7, 7, 7, 50, 369, 583, -23, -23, -23, -23, 448, 605, 497, 260, 397, 434, 54, 394, 593, 593, 316, 316, 415, 415, 316, 316, 316, 442, 442, 252, 252, 252, 252, 318, 455, 433, 391, 742, 53, 53, 53, 53, 742, 742, 742, 742, 734, 1088, 742, 742, 742, 722, 781, 781, 926, 551, 551, 781, 536, -3, -3, 536, 63, -3, 67, 576, 335, 756, 115, 9, 335, 535, 656, 501, 185, 821, 568, 821, 1032, 424, 776, 776, 426, 753, 729, 867, 1063, 1049, 799, 1080, 810, 1081, -66, -58, 728, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1089, 402, 1032, 130, 1089, 1089, 1089, 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, 603, 130, 544, 554, 130, 804, 402, 18, 808, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 762, 157, 18, 36, 124, 124, 196, 37, 124, 124, 124, 124, 18, 18, 18, 18, 568, 784, 797, 600, 820, 143, 784, 784, 784, 122, 135, 204, 139, 760, 785, 467, 775, 775, 787, 895, 895, 775, 768, 775, 787, 913, 775, 775, 895, 895, 793, 158, 550, 472, 524, 569, 895, 346, 775, 775, 775, 775, 816, 575, 775, 271, 171, 775, 775, 816, 801, 766, 58, 798, 895, 895, 895, 816, 505, 798, 798, 798, 819, 824, 761, 765, 383, 349, 607, 138, 807, 765, 765, 775, 532, 761, 765, 761, 765, 759, 765, 765, 765, 761, 765, 768, 498, 765, 714, 586, 75, 765, 6, 915, 916, 726, 917, 906, 918, 965, 919, 923, 1053, 894, 931, 912, 924, 966, 903, 896, 780, 701, 703, 815, 754, 893, 777, 777, 777, 888, 777, 777, 777, 777, 777, 777, 777, 777, 701, 868, 823, 794, 934, 711, 712, 1011, 730, 795, 963, 933, 1013, 925, 758, 713, 977, 935, 757, 1047, 936, 940, 986, 1014, 828, 1017, 979, 790, 1064, 1065, 869, 946, 1054, 777, 915, 923, 727, 912, 924, 903, 896, 752, 748, 746, 747, 745, 744, 739, 740, 763, 1018, 887, 879, 870, 945, 891, 701, 871, 971, 874, 990, 992, 1050, 805, 792, 875, 1066, 952, 953, 954, 1055, 1019, 1056, 773, 973, 817, 994, 812, 1067, 996, 997, 999, 1000, 1057, 1068, 1058, 885, 1059, 832, 788, 928, 802, 1069, 299, 791, 800, 806, 964, 436, 932, 1060, 1070, 1071, 1001, 1002, 1006, 1072, 1073, 927, 834, 975, 796, 976, 967, 835, 838, 577, 779, 1020, 786, 789, 778, 624, 634, 1074, 1075, 1076, 930, 767, 772, 839, 845, 1021, 743, 1022, 1077, 646, 846, 717, 1078, 1012, 718, 721, 652, 683, 681, 724, 774, 1061, 818, 811, 771, 955, 721, 770, 849, 1079, 852, 855, 856, 1007, 860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 456, 456, 456, 456, 456, 456, 305, 305, 305, 305, 305, 456, 456, 456, 456, 456, 456, 456, 305, 305, 0, 0, 305, 0, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 494, 494, 289, 289, 494, 289, 494, 494, 494, 494, 494, 494, 494, 494, 494, 0, 289, 289, 289, 289, 289, 289, 289, 289, 494, 793, 494, 442, 442, 442, 442, 494, 494, 494, -88, -88, 442, 494, 63, 494, 494, 494, 494, 494, 494, 494, 494, 494, 0, 0, 494, 494, 494, 494, 0, 0, 130, -3, 494, 768, 768, 768, 768, 494, 494, 494, 494, -3, -3, 494, 494, 494, 0, 0, 0, 0, 442, 442, 0, 130, 0, 0, 130, 0, 0, 768, 768, 494, 63, 793, 359, 494, 0, 0, 0, 0, 130, 768, 130, 402, 775, -3, -3, 775, 402, 402, 124, 18, 359, 545, 545, 545, 545, 0, 0, 568, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 768, 0, 793, 0, 768, 768, 768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 768, 0, 0, 895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 913, 0, 0, 0, 0, 0, 0, 768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 777, 805, 0, 805, 0, 777, 777, 777, 0, 0, 0, 0, 779, 743); + protected array $actionDefault = array(3, 32767, 102, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 100, 32767, 32767, 32767, 32767, 597, 597, 597, 597, 32767, 32767, 254, 102, 32767, 32767, 470, 387, 387, 387, 32767, 32767, 541, 541, 541, 541, 541, 541, 32767, 32767, 32767, 32767, 32767, 32767, 470, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 100, 32767, 32767, 32767, 36, 7, 8, 10, 11, 49, 17, 324, 32767, 32767, 32767, 32767, 102, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 590, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 474, 453, 454, 456, 457, 386, 542, 596, 327, 593, 385, 145, 339, 329, 242, 330, 258, 475, 259, 476, 479, 480, 215, 287, 382, 149, 150, 417, 471, 419, 469, 473, 418, 392, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 390, 391, 472, 450, 449, 448, 32767, 32767, 415, 416, 32767, 420, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 102, 32767, 389, 423, 421, 422, 439, 440, 437, 438, 441, 32767, 32767, 32767, 442, 443, 444, 445, 316, 32767, 32767, 366, 364, 424, 316, 111, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 430, 431, 32767, 32767, 32767, 32767, 535, 447, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 102, 32767, 100, 537, 412, 414, 504, 425, 426, 393, 32767, 511, 32767, 102, 32767, 513, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 536, 32767, 543, 543, 32767, 497, 100, 195, 32767, 32767, 512, 32767, 195, 195, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 604, 497, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 32767, 195, 110, 32767, 32767, 32767, 100, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 190, 32767, 268, 270, 102, 558, 195, 32767, 516, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 509, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 497, 435, 138, 32767, 138, 543, 427, 428, 429, 499, 543, 543, 543, 312, 289, 32767, 32767, 32767, 32767, 514, 514, 100, 100, 100, 100, 509, 32767, 32767, 32767, 32767, 111, 99, 99, 99, 99, 99, 103, 101, 32767, 32767, 32767, 32767, 223, 99, 32767, 101, 101, 32767, 32767, 223, 225, 212, 101, 227, 32767, 562, 563, 223, 101, 227, 227, 227, 247, 247, 486, 318, 101, 99, 101, 101, 197, 318, 318, 32767, 101, 486, 318, 486, 318, 199, 318, 318, 318, 486, 318, 32767, 101, 318, 214, 99, 99, 318, 32767, 32767, 32767, 499, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 222, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 530, 32767, 547, 560, 433, 434, 436, 545, 458, 459, 460, 461, 462, 463, 464, 466, 592, 32767, 503, 32767, 32767, 32767, 338, 32767, 602, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 603, 32767, 543, 32767, 32767, 32767, 32767, 432, 9, 74, 492, 42, 43, 51, 57, 520, 521, 522, 523, 517, 518, 524, 519, 32767, 32767, 525, 568, 32767, 32767, 544, 595, 32767, 32767, 32767, 32767, 32767, 32767, 138, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 530, 32767, 136, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 526, 32767, 32767, 32767, 543, 32767, 32767, 32767, 32767, 314, 311, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 543, 32767, 32767, 32767, 32767, 32767, 291, 32767, 308, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 286, 32767, 32767, 381, 499, 294, 296, 297, 32767, 32767, 32767, 32767, 360, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 152, 152, 3, 3, 341, 152, 152, 152, 341, 341, 152, 341, 341, 341, 152, 152, 152, 152, 152, 152, 280, 185, 262, 265, 247, 247, 152, 352, 152); + protected array $goto = array(196, 196, 1034, 1065, 697, 431, 661, 621, 658, 319, 706, 425, 314, 315, 335, 576, 430, 336, 432, 638, 654, 655, 852, 672, 673, 674, 853, 167, 167, 167, 167, 221, 197, 193, 193, 177, 179, 216, 193, 193, 193, 193, 193, 194, 194, 194, 194, 194, 194, 188, 189, 190, 191, 192, 218, 216, 219, 536, 537, 421, 538, 540, 541, 542, 543, 544, 545, 546, 547, 1136, 168, 169, 170, 195, 171, 172, 173, 166, 174, 175, 176, 178, 215, 217, 220, 238, 243, 244, 246, 257, 258, 259, 260, 261, 262, 263, 264, 268, 269, 270, 271, 277, 289, 290, 317, 318, 426, 427, 428, 581, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 180, 237, 181, 198, 199, 200, 239, 188, 189, 190, 191, 192, 218, 1136, 201, 182, 183, 184, 202, 198, 185, 240, 203, 201, 165, 204, 205, 186, 206, 207, 208, 187, 209, 210, 211, 212, 213, 214, 855, 1232, 975, 279, 279, 279, 279, 623, 623, 419, 351, 1269, 600, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1287, 1287, 599, 1100, 1287, 709, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 508, 700, 827, 1098, 458, 559, 552, 860, 833, 909, 904, 905, 918, 861, 906, 858, 907, 908, 859, 1233, 1234, 912, 500, 886, 501, 252, 252, 843, 1107, 1108, 507, 1087, 1082, 1083, 1084, 341, 552, 559, 568, 569, 344, 579, 602, 616, 617, 1235, 1295, 1296, 833, 440, 833, 22, 250, 250, 250, 250, 245, 253, 694, 573, 1237, 829, 1237, 893, 851, 893, 893, 1034, 1034, 1237, 694, 349, 342, 1034, 694, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 848, 1327, 1034, 1034, 1034, 1034, 1319, 1319, 1319, 1319, 1237, 343, 342, 1040, 1039, 1237, 1237, 1237, 1237, 868, 996, 1237, 1237, 1237, 913, 355, 914, 354, 354, 354, 354, 466, 466, 479, 880, 355, 355, 867, 394, 926, 466, 481, 571, 927, 967, 410, 705, 942, 355, 355, 942, 848, 355, 660, 1354, 609, 624, 627, 628, 629, 630, 651, 652, 653, 708, 554, 1133, 1285, 1285, 355, 355, 1285, 1058, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 539, 539, 1185, 424, 539, 611, 539, 539, 539, 539, 539, 539, 539, 539, 539, 566, 682, 1337, 1337, 733, 637, 639, 1043, 1044, 659, 476, 1312, 1313, 683, 687, 1010, 695, 704, 1006, 1337, 1298, 438, 408, 409, 631, 633, 635, 670, 5, 671, 6, 412, 413, 414, 337, 684, 1340, 1340, 415, 325, 309, 686, 347, 352, 353, 553, 563, 450, 450, 450, 553, 1309, 563, 1309, 666, 397, 462, 845, 1314, 1315, 1309, 548, 548, 548, 548, 873, 604, 469, 580, 470, 471, 403, 554, 878, 848, 958, 1345, 1346, 577, 614, 870, 550, 615, 550, 255, 255, 1321, 1321, 1321, 1321, 550, 999, 1018, 477, 971, 1228, 732, 736, 881, 869, 1070, 1074, 876, 882, 551, 1008, 1003, 1071, 1075, 978, 980, 0, 1305, 1118, 0, 456, 0, 0, 0, 0, 969, 969, 969, 969, 0, 0, 456, 963, 970, 0, 0, 0, 0, 968, 0, 1230, 0, 0, 0, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 931, 1123, 450, 0, 1073, 1116, 885, 619, 1307, 1307, 1073, 1216, 944, 1015, 433, 1217, 1220, 945, 1221, 0, 433, 872, 0, 664, 994, 0, 1041, 1041, 0, 866, 0, 0, 0, 665, 1052, 1048, 1049, 0, 0, 0, 0, 1227, 324, 275, 324, 1037, 1037, 681, 952, 0, 0, 1029, 1045, 1046, 396, 399, 560, 601, 605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1013, 1013); + protected array $gotoCheck = array(42, 42, 73, 127, 73, 66, 66, 56, 56, 66, 9, 66, 66, 66, 66, 66, 66, 66, 66, 66, 86, 86, 26, 86, 86, 86, 27, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 15, 20, 49, 23, 23, 23, 23, 108, 108, 43, 97, 108, 130, 108, 108, 108, 108, 108, 108, 108, 108, 108, 170, 170, 8, 8, 170, 8, 170, 170, 170, 170, 170, 170, 170, 170, 170, 8, 8, 6, 8, 83, 76, 76, 15, 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 20, 20, 15, 155, 45, 155, 5, 5, 20, 144, 144, 155, 15, 15, 15, 15, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 20, 20, 20, 12, 83, 12, 76, 5, 5, 5, 5, 5, 5, 7, 172, 73, 7, 73, 25, 25, 25, 25, 73, 73, 73, 7, 179, 168, 73, 7, 73, 73, 73, 73, 73, 73, 73, 73, 73, 22, 181, 73, 73, 73, 73, 9, 9, 9, 9, 73, 168, 168, 118, 118, 73, 73, 73, 73, 35, 103, 73, 73, 73, 65, 14, 65, 24, 24, 24, 24, 149, 149, 84, 35, 14, 14, 35, 62, 73, 149, 84, 104, 73, 93, 93, 93, 9, 14, 14, 9, 22, 14, 64, 14, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 14, 150, 171, 171, 14, 14, 171, 114, 171, 171, 171, 171, 171, 171, 171, 171, 171, 173, 173, 151, 13, 173, 13, 173, 173, 173, 173, 173, 173, 173, 173, 173, 48, 116, 182, 182, 48, 48, 48, 119, 119, 48, 176, 176, 176, 48, 48, 48, 48, 48, 48, 182, 14, 113, 82, 82, 85, 85, 85, 82, 46, 82, 46, 82, 82, 82, 29, 82, 182, 182, 82, 169, 169, 14, 82, 97, 97, 9, 9, 23, 23, 23, 9, 130, 9, 130, 120, 9, 9, 18, 178, 178, 130, 107, 107, 107, 107, 39, 107, 9, 9, 9, 9, 28, 14, 9, 22, 92, 9, 9, 2, 2, 37, 19, 80, 19, 5, 5, 130, 130, 130, 130, 19, 50, 110, 157, 50, 160, 50, 99, 16, 16, 16, 16, 9, 41, 50, 50, 50, 129, 132, 16, 96, -1, 130, 147, -1, 19, -1, -1, -1, -1, 19, 19, 19, 19, -1, -1, 19, 19, 19, -1, -1, -1, -1, 16, -1, 14, -1, -1, -1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 17, 17, 23, -1, 130, 16, 16, 17, 130, 130, 130, 79, 79, 17, 117, 79, 79, 79, 79, -1, 117, 17, -1, 17, 17, -1, 117, 117, -1, 17, -1, -1, -1, 117, 117, 117, 117, -1, -1, -1, -1, 17, 24, 24, 24, 89, 89, 89, 89, -1, -1, 89, 89, 89, 59, 59, 59, 59, 59, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 107, 107); + protected array $gotoBase = array(0, 0, -253, 0, 0, 224, 182, 251, 179, -10, 0, 0, -89, 32, 11, -185, 27, 66, 128, 197, -229, 0, 5, 163, 308, 260, 18, 22, 115, 118, 0, 0, 0, 0, 0, -68, 0, 122, 0, 123, 0, 43, -1, 153, 0, 200, -327, 0, -330, 147, 460, 0, 0, 0, 0, 0, -33, 0, 0, 540, 0, 0, 280, 0, 95, 294, -236, 0, 0, 0, 0, 0, 0, -5, 0, 0, -140, 0, 0, 134, 119, -19, -88, -75, -152, -74, -698, 0, 0, 296, 0, 0, 127, 23, 0, 0, 48, -310, 0, 71, 0, 0, 0, 269, 283, 0, 0, 414, -71, 0, 103, 0, 0, 124, 83, 0, 100, 273, 17, 104, 144, 0, 0, 0, 0, 0, 0, 1, 0, 114, 167, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -47, 0, 0, 50, 0, 281, 105, 94, 0, 0, 0, -273, 0, 34, 0, 0, 107, 0, 0, 0, 0, 0, 0, 0, -26, 99, -56, 110, 230, 125, 0, 0, 90, 0, 67, 241, 0, 254, 75, 0, 0); + protected array $gotoDefault = array(-32768, 512, 740, 4, 741, 935, 816, 825, 597, 530, 707, 348, 625, 422, 1303, 911, 1122, 578, 844, 1246, 1254, 457, 847, 330, 730, 923, 894, 895, 400, 386, 392, 398, 649, 626, 494, 879, 453, 871, 486, 874, 452, 883, 164, 418, 510, 887, 3, 890, 557, 921, 973, 387, 898, 388, 677, 900, 562, 902, 903, 395, 401, 402, 1127, 570, 622, 915, 256, 564, 916, 385, 917, 925, 390, 393, 688, 465, 505, 499, 411, 1102, 565, 608, 646, 447, 473, 620, 632, 618, 480, 434, 416, 329, 957, 965, 487, 463, 979, 350, 987, 738, 1135, 640, 489, 995, 641, 1002, 1005, 531, 532, 478, 1017, 272, 1020, 490, 19, 667, 1031, 1032, 668, 642, 1054, 643, 669, 644, 1056, 472, 598, 1064, 454, 1072, 1291, 455, 1076, 266, 1079, 278, 417, 435, 1085, 1086, 9, 1092, 698, 699, 11, 276, 509, 1117, 689, 451, 1134, 439, 1204, 1206, 558, 491, 1224, 1223, 680, 506, 1229, 448, 1294, 449, 533, 474, 316, 534, 1338, 308, 333, 313, 549, 295, 334, 535, 475, 1300, 1308, 331, 31, 1328, 1339, 575, 613); + protected array $ruleToNonTerminal = array(0, 1, 3, 3, 2, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 9, 10, 11, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18, 21, 21, 22, 23, 23, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 29, 30, 30, 32, 34, 34, 28, 36, 36, 33, 38, 38, 35, 35, 37, 37, 39, 39, 31, 40, 40, 41, 43, 44, 44, 45, 45, 46, 46, 48, 47, 47, 47, 47, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 25, 25, 50, 69, 69, 72, 72, 71, 70, 70, 63, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 26, 26, 27, 27, 27, 27, 27, 88, 88, 90, 90, 83, 83, 91, 91, 92, 92, 92, 84, 84, 87, 87, 85, 85, 93, 94, 94, 57, 57, 65, 65, 68, 68, 68, 67, 95, 95, 96, 58, 58, 58, 58, 97, 97, 98, 98, 99, 99, 100, 101, 101, 102, 102, 103, 103, 55, 55, 51, 51, 105, 53, 53, 106, 52, 52, 54, 54, 64, 64, 64, 64, 81, 81, 109, 109, 111, 111, 112, 112, 112, 112, 110, 110, 110, 114, 114, 114, 114, 89, 89, 117, 117, 117, 118, 118, 115, 115, 119, 119, 121, 121, 122, 122, 116, 123, 123, 120, 124, 124, 124, 124, 113, 113, 82, 82, 82, 20, 20, 20, 126, 125, 125, 127, 127, 127, 127, 60, 128, 128, 129, 61, 131, 131, 132, 132, 133, 133, 86, 134, 134, 134, 134, 134, 134, 134, 139, 139, 140, 140, 141, 141, 141, 141, 141, 142, 143, 143, 138, 138, 135, 135, 137, 137, 145, 145, 144, 144, 144, 144, 144, 144, 144, 136, 146, 146, 148, 147, 147, 62, 104, 149, 149, 56, 56, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 156, 150, 150, 155, 155, 158, 159, 159, 160, 161, 162, 162, 162, 162, 19, 19, 73, 73, 73, 73, 151, 151, 151, 151, 164, 164, 152, 152, 154, 154, 154, 157, 157, 170, 170, 170, 170, 170, 170, 170, 170, 170, 171, 171, 171, 108, 173, 173, 173, 173, 153, 153, 153, 153, 153, 153, 153, 153, 59, 59, 167, 167, 167, 167, 174, 174, 163, 163, 163, 175, 175, 175, 175, 175, 175, 74, 74, 66, 66, 66, 66, 130, 130, 130, 130, 178, 177, 166, 166, 166, 166, 166, 166, 166, 165, 165, 165, 176, 176, 176, 176, 107, 172, 180, 180, 179, 179, 181, 181, 181, 181, 181, 181, 181, 181, 169, 169, 169, 169, 168, 183, 182, 182, 182, 182, 182, 182, 182, 182, 184, 184, 184, 184); + protected array $ruleToLength = array(1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 2, 1, 3, 4, 1, 2, 0, 1, 1, 1, 1, 4, 3, 5, 4, 3, 4, 2, 3, 1, 1, 7, 6, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 3, 1, 3, 1, 2, 2, 3, 1, 3, 2, 3, 1, 3, 3, 2, 0, 1, 1, 1, 1, 1, 3, 7, 10, 5, 7, 9, 5, 3, 3, 3, 3, 3, 3, 1, 2, 5, 7, 9, 6, 5, 6, 3, 2, 1, 1, 1, 1, 0, 2, 1, 3, 8, 0, 4, 2, 1, 3, 0, 1, 0, 1, 0, 1, 3, 1, 1, 1, 8, 9, 7, 8, 7, 6, 8, 0, 2, 0, 2, 1, 2, 1, 2, 1, 1, 1, 0, 2, 0, 2, 0, 2, 2, 1, 3, 1, 4, 1, 4, 1, 1, 4, 2, 1, 3, 3, 3, 4, 4, 5, 0, 2, 4, 3, 1, 1, 7, 0, 2, 1, 3, 3, 4, 1, 4, 0, 2, 5, 0, 2, 6, 0, 2, 0, 3, 1, 2, 1, 1, 2, 0, 1, 3, 0, 2, 1, 1, 1, 1, 6, 8, 6, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 3, 1, 1, 2, 1, 1, 0, 1, 0, 2, 2, 2, 4, 3, 1, 1, 3, 1, 2, 2, 3, 2, 3, 1, 1, 2, 3, 1, 1, 3, 2, 0, 1, 5, 5, 6, 10, 3, 5, 1, 1, 3, 0, 2, 4, 5, 4, 4, 4, 3, 1, 1, 1, 1, 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, 1, 1, 3, 2, 2, 3, 1, 0, 1, 1, 3, 3, 3, 4, 4, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 3, 4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 2, 1, 2, 4, 2, 2, 8, 9, 8, 9, 9, 10, 9, 10, 8, 3, 2, 0, 4, 2, 1, 3, 2, 1, 2, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 0, 3, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 5, 3, 3, 4, 1, 1, 3, 1, 1, 1, 1, 1, 3, 2, 3, 0, 1, 1, 3, 1, 1, 1, 1, 1, 3, 1, 1, 4, 4, 1, 4, 4, 0, 1, 1, 1, 3, 3, 1, 4, 2, 2, 1, 3, 1, 4, 4, 3, 3, 3, 3, 1, 3, 1, 1, 3, 1, 1, 4, 1, 1, 1, 3, 1, 1, 2, 1, 3, 4, 3, 2, 0, 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, 3, 3, 6, 3, 1, 1, 2, 1); + protected function initReduceCallbacks() : void + { + $this->reduceCallbacks = [0 => null, 1 => function ($stackPos) { $this->semValue = $this->handleNamespaces($this->semStack[$stackPos - (1 - 1)]); }, 2 => function ($stackPos) { - if (\is_array($this->semStack[$stackPos - (2 - 2)])) { - $this->semValue = \array_merge($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)]); - } else { + if ($this->semStack[$stackPos - (2 - 2)] !== null) { $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; } + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; }, 3 => function ($stackPos) { $this->semValue = array(); }, 4 => function ($stackPos) { - $startAttributes = $this->lookaheadStartAttributes; - if (isset($startAttributes['comments'])) { - $nop = new Stmt\Nop($this->createCommentNopAttributes($startAttributes['comments'])); - } else { - $nop = null; - } + $nop = $this->maybeCreateZeroLengthNop($this->tokenPos); if ($nop !== null) { $this->semStack[$stackPos - (1 - 1)][] = $nop; } $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 5 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 6 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 7 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 8 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 9 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 10 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 11 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 12 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 13 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 14 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 15 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 16 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 17 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 18 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 19 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 20 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 21 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 22 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 23 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 24 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 25 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 26 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 27 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 28 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 29 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 30 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 31 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 32 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 33 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 34 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 35 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 36 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 37 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 38 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 39 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 40 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 41 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 42 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 43 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 44 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 45 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 46 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 47 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 48 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 49 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 50 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 51 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 52 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 53 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 54 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 55 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 56 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 57 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 58 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 59 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 60 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 61 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 62 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 63 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 64 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 65 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 66 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 67 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 68 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 69 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 70 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 71 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 72 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 73 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 74 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 75 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 76 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 77 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 78 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 79 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 80 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 81 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 82 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 83 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 84 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 85 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; + }, 5 => null, 6 => null, 7 => null, 8 => null, 9 => null, 10 => null, 11 => null, 12 => null, 13 => null, 14 => null, 15 => null, 16 => null, 17 => null, 18 => null, 19 => null, 20 => null, 21 => null, 22 => null, 23 => null, 24 => null, 25 => null, 26 => null, 27 => null, 28 => null, 29 => null, 30 => null, 31 => null, 32 => null, 33 => null, 34 => null, 35 => null, 36 => null, 37 => null, 38 => null, 39 => null, 40 => null, 41 => null, 42 => null, 43 => null, 44 => null, 45 => null, 46 => null, 47 => null, 48 => null, 49 => null, 50 => null, 51 => null, 52 => null, 53 => null, 54 => null, 55 => null, 56 => null, 57 => null, 58 => null, 59 => null, 60 => null, 61 => null, 62 => null, 63 => null, 64 => null, 65 => null, 66 => null, 67 => null, 68 => null, 69 => null, 70 => null, 71 => null, 72 => null, 73 => null, 74 => null, 75 => null, 76 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + if ($this->semValue === "emitError(new Error('Cannot use "getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos]))); + } + }, 77 => null, 78 => null, 79 => null, 80 => null, 81 => null, 82 => null, 83 => null, 84 => null, 85 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 86 => function ($stackPos) { - $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 87 => function ($stackPos) { - $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 88 => function ($stackPos) { - $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 89 => function ($stackPos) { - $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 90 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 91 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 92 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 93 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 94 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 95 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 94 => null, 95 => function ($stackPos) { + $this->semValue = new Name(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 96 => function ($stackPos) { - $this->semValue = new Name(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Variable(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 97 => function ($stackPos) { - $this->semValue = new Expr\Variable(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + /* nothing */ }, 98 => function ($stackPos) { /* nothing */ }, 99 => function ($stackPos) { /* nothing */ }, 100 => function ($stackPos) { - /* nothing */ - }, 101 => function ($stackPos) { - $this->emitError(new Error('A trailing comma is not allowed here', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes)); - }, 102 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 103 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; + $this->emitError(new Error('A trailing comma is not allowed here', $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos]))); + }, 101 => null, 102 => null, 103 => function ($stackPos) { + $this->semValue = new Node\Attribute($this->semStack[$stackPos - (1 - 1)], [], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 104 => function ($stackPos) { - $this->semValue = new Node\Attribute($this->semStack[$stackPos - (1 - 1)], [], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Node\Attribute($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 105 => function ($stackPos) { - $this->semValue = new Node\Attribute($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 106 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 107 => function ($stackPos) { + }, 106 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; + }, 107 => function ($stackPos) { + $this->semValue = new Node\AttributeGroup($this->semStack[$stackPos - (4 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 108 => function ($stackPos) { - $this->semValue = new Node\AttributeGroup($this->semStack[$stackPos - (4 - 2)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 109 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 110 => function ($stackPos) { + }, 109 => function ($stackPos) { $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 111 => function ($stackPos) { + }, 110 => function ($stackPos) { $this->semValue = []; - }, 112 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 113 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 114 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 115 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + }, 111 => null, 112 => null, 113 => null, 114 => null, 115 => function ($stackPos) { + $this->semValue = new Stmt\HaltCompiler($this->handleHaltCompiler(), $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 116 => function ($stackPos) { - $this->semValue = new Stmt\HaltCompiler($this->lexer->handleHaltCompiler(), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 117 => function ($stackPos) { - $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos - (3 - 2)], null, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos - (3 - 2)], null, $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); $this->checkNamespace($this->semValue); - }, 118 => function ($stackPos) { - $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos - (5 - 2)], $this->semStack[$stackPos - (5 - 4)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); + }, 117 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos - (5 - 2)], $this->semStack[$stackPos - (5 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); $this->checkNamespace($this->semValue); - }, 119 => function ($stackPos) { - $this->semValue = new Stmt\Namespace_(null, $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + }, 118 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_(null, $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); $this->checkNamespace($this->semValue); + }, 119 => function ($stackPos) { + $this->semValue = new Stmt\Use_($this->semStack[$stackPos - (3 - 2)], Stmt\Use_::TYPE_NORMAL, $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 120 => function ($stackPos) { - $this->semValue = new Stmt\Use_($this->semStack[$stackPos - (3 - 2)], Stmt\Use_::TYPE_NORMAL, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 121 => function ($stackPos) { - $this->semValue = new Stmt\Use_($this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 2)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 122 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + $this->semValue = new Stmt\Use_($this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 121 => null, 122 => function ($stackPos) { + $this->semValue = new Stmt\Const_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 123 => function ($stackPos) { - $this->semValue = new Stmt\Const_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 124 => function ($stackPos) { $this->semValue = Stmt\Use_::TYPE_FUNCTION; - }, 125 => function ($stackPos) { + }, 124 => function ($stackPos) { $this->semValue = Stmt\Use_::TYPE_CONSTANT; + }, 125 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 6)], $this->semStack[$stackPos - (7 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (7 - 1)], $this->tokenEndStack[$stackPos])); }, 126 => function ($stackPos) { - $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 6)], $this->semStack[$stackPos - (7 - 2)], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes); - }, 127 => function ($stackPos) { - $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes); - }, 128 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 129 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 5)], Stmt\Use_::TYPE_UNKNOWN, $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos])); + }, 127 => null, 128 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 130 => function ($stackPos) { + }, 129 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 131 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 132 => function ($stackPos) { + }, 130 => null, 131 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 133 => function ($stackPos) { + }, 132 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 134 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 135 => function ($stackPos) { + }, 133 => null, 134 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 136 => function ($stackPos) { + }, 135 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 137 => function ($stackPos) { - $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + }, 136 => function ($stackPos) { + $this->semValue = new Node\UseItem($this->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); $this->checkUseUse($this->semValue, $stackPos - (1 - 1)); - }, 138 => function ($stackPos) { - $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + }, 137 => function ($stackPos) { + $this->semValue = new Node\UseItem($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); $this->checkUseUse($this->semValue, $stackPos - (3 - 3)); - }, 139 => function ($stackPos) { - $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + }, 138 => function ($stackPos) { + $this->semValue = new Node\UseItem($this->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); $this->checkUseUse($this->semValue, $stackPos - (1 - 1)); - }, 140 => function ($stackPos) { - $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + }, 139 => function ($stackPos) { + $this->semValue = new Node\UseItem($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); $this->checkUseUse($this->semValue, $stackPos - (3 - 3)); - }, 141 => function ($stackPos) { + }, 140 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (1 - 1)]; $this->semValue->type = Stmt\Use_::TYPE_NORMAL; - }, 142 => function ($stackPos) { + }, 141 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (2 - 2)]; $this->semValue->type = $this->semStack[$stackPos - (2 - 1)]; - }, 143 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 144 => function ($stackPos) { + }, 142 => null, 143 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 145 => function ($stackPos) { + }, 144 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 146 => function ($stackPos) { - $this->semValue = new Node\Const_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 147 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 148 => function ($stackPos) { + }, 145 => function ($stackPos) { + $this->semValue = new Node\Const_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 146 => null, 147 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 149 => function ($stackPos) { + }, 148 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + }, 149 => function ($stackPos) { + $this->semValue = new Node\Const_(new Node\Identifier($this->semStack[$stackPos - (3 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos - (3 - 1)])), $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 150 => function ($stackPos) { - $this->semValue = new Node\Const_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\Const_(new Node\Identifier($this->semStack[$stackPos - (3 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos - (3 - 1)])), $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 151 => function ($stackPos) { - if (\is_array($this->semStack[$stackPos - (2 - 2)])) { - $this->semValue = \array_merge($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)]); - } else { + if ($this->semStack[$stackPos - (2 - 2)] !== null) { $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; } + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; }, 152 => function ($stackPos) { $this->semValue = array(); }, 153 => function ($stackPos) { - $startAttributes = $this->lookaheadStartAttributes; - if (isset($startAttributes['comments'])) { - $nop = new Stmt\Nop($this->createCommentNopAttributes($startAttributes['comments'])); - } else { - $nop = null; - } + $nop = $this->maybeCreateZeroLengthNop($this->tokenPos); if ($nop !== null) { $this->semStack[$stackPos - (1 - 1)][] = $nop; } $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 154 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 155 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 156 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 157 => function ($stackPos) { - throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + }, 154 => null, 155 => null, 156 => null, 157 => function ($stackPos) { + throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 158 => function ($stackPos) { - if ($this->semStack[$stackPos - (3 - 2)]) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; - $attrs = $this->startAttributeStack[$stackPos - (3 - 1)]; - $stmts = $this->semValue; - if (!empty($attrs['comments'])) { - $stmts[0]->setAttribute('comments', \array_merge($attrs['comments'], $stmts[0]->getAttribute('comments', []))); - } - } else { - $startAttributes = $this->startAttributeStack[$stackPos - (3 - 1)]; - if (isset($startAttributes['comments'])) { - $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes); - } else { - $this->semValue = null; - } - if (null === $this->semValue) { - $this->semValue = array(); - } - } + $this->semValue = new Stmt\Block($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 159 => function ($stackPos) { - $this->semValue = new Stmt\If_($this->semStack[$stackPos - (7 - 3)], ['stmts' => \is_array($this->semStack[$stackPos - (7 - 5)]) ? $this->semStack[$stackPos - (7 - 5)] : array($this->semStack[$stackPos - (7 - 5)]), 'elseifs' => $this->semStack[$stackPos - (7 - 6)], 'else' => $this->semStack[$stackPos - (7 - 7)]], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\If_($this->semStack[$stackPos - (7 - 3)], ['stmts' => $this->semStack[$stackPos - (7 - 5)], 'elseifs' => $this->semStack[$stackPos - (7 - 6)], 'else' => $this->semStack[$stackPos - (7 - 7)]], $this->getAttributes($this->tokenStartStack[$stackPos - (7 - 1)], $this->tokenEndStack[$stackPos])); }, 160 => function ($stackPos) { - $this->semValue = new Stmt\If_($this->semStack[$stackPos - (10 - 3)], ['stmts' => $this->semStack[$stackPos - (10 - 6)], 'elseifs' => $this->semStack[$stackPos - (10 - 7)], 'else' => $this->semStack[$stackPos - (10 - 8)]], $this->startAttributeStack[$stackPos - (10 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\If_($this->semStack[$stackPos - (10 - 3)], ['stmts' => $this->semStack[$stackPos - (10 - 6)], 'elseifs' => $this->semStack[$stackPos - (10 - 7)], 'else' => $this->semStack[$stackPos - (10 - 8)]], $this->getAttributes($this->tokenStartStack[$stackPos - (10 - 1)], $this->tokenEndStack[$stackPos])); }, 161 => function ($stackPos) { - $this->semValue = new Stmt\While_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\While_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 162 => function ($stackPos) { - $this->semValue = new Stmt\Do_($this->semStack[$stackPos - (7 - 5)], \is_array($this->semStack[$stackPos - (7 - 2)]) ? $this->semStack[$stackPos - (7 - 2)] : array($this->semStack[$stackPos - (7 - 2)]), $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Do_($this->semStack[$stackPos - (7 - 5)], $this->semStack[$stackPos - (7 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (7 - 1)], $this->tokenEndStack[$stackPos])); }, 163 => function ($stackPos) { - $this->semValue = new Stmt\For_(['init' => $this->semStack[$stackPos - (9 - 3)], 'cond' => $this->semStack[$stackPos - (9 - 5)], 'loop' => $this->semStack[$stackPos - (9 - 7)], 'stmts' => $this->semStack[$stackPos - (9 - 9)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\For_(['init' => $this->semStack[$stackPos - (9 - 3)], 'cond' => $this->semStack[$stackPos - (9 - 5)], 'loop' => $this->semStack[$stackPos - (9 - 7)], 'stmts' => $this->semStack[$stackPos - (9 - 9)]], $this->getAttributes($this->tokenStartStack[$stackPos - (9 - 1)], $this->tokenEndStack[$stackPos])); }, 164 => function ($stackPos) { - $this->semValue = new Stmt\Switch_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Switch_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 165 => function ($stackPos) { - $this->semValue = new Stmt\Break_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Break_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 166 => function ($stackPos) { - $this->semValue = new Stmt\Continue_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Continue_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 167 => function ($stackPos) { - $this->semValue = new Stmt\Return_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Return_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 168 => function ($stackPos) { - $this->semValue = new Stmt\Global_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Global_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 169 => function ($stackPos) { - $this->semValue = new Stmt\Static_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Static_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 170 => function ($stackPos) { - $this->semValue = new Stmt\Echo_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Echo_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 171 => function ($stackPos) { - $this->semValue = new Stmt\InlineHTML($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\InlineHTML($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + $this->semValue->setAttribute('hasLeadingNewline', $this->inlineHtmlHasLeadingNewline($stackPos - (1 - 1))); }, 172 => function ($stackPos) { - $e = $this->semStack[$stackPos - (2 - 1)]; - if ($e instanceof Expr\Throw_) { - // For backwards-compatibility reasons, convert throw in statement position into - // Stmt\Throw_ rather than Stmt\Expression(Expr\Throw_). - $this->semValue = new Stmt\Throw_($e->expr, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - } else { - $this->semValue = new Stmt\Expression($e, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - } + $this->semValue = new Stmt\Expression($this->semStack[$stackPos - (2 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 173 => function ($stackPos) { - $this->semValue = new Stmt\Unset_($this->semStack[$stackPos - (5 - 3)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Unset_($this->semStack[$stackPos - (5 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 174 => function ($stackPos) { - $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$stackPos - (7 - 5)][1], 'stmts' => $this->semStack[$stackPos - (7 - 7)]], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$stackPos - (7 - 5)][1], 'stmts' => $this->semStack[$stackPos - (7 - 7)]], $this->getAttributes($this->tokenStartStack[$stackPos - (7 - 1)], $this->tokenEndStack[$stackPos])); }, 175 => function ($stackPos) { - $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (9 - 3)], $this->semStack[$stackPos - (9 - 7)][0], ['keyVar' => $this->semStack[$stackPos - (9 - 5)], 'byRef' => $this->semStack[$stackPos - (9 - 7)][1], 'stmts' => $this->semStack[$stackPos - (9 - 9)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (9 - 3)], $this->semStack[$stackPos - (9 - 7)][0], ['keyVar' => $this->semStack[$stackPos - (9 - 5)], 'byRef' => $this->semStack[$stackPos - (9 - 7)][1], 'stmts' => $this->semStack[$stackPos - (9 - 9)]], $this->getAttributes($this->tokenStartStack[$stackPos - (9 - 1)], $this->tokenEndStack[$stackPos])); }, 176 => function ($stackPos) { - $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (6 - 3)], new Expr\Error($this->startAttributeStack[$stackPos - (6 - 4)] + $this->endAttributeStack[$stackPos - (6 - 4)]), ['stmts' => $this->semStack[$stackPos - (6 - 6)]], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (6 - 3)], new Expr\Error($this->getAttributes($this->tokenStartStack[$stackPos - (6 - 4)], $this->tokenEndStack[$stackPos - (6 - 4)])), ['stmts' => $this->semStack[$stackPos - (6 - 6)]], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos])); }, 177 => function ($stackPos) { - $this->semValue = new Stmt\Declare_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Declare_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 178 => function ($stackPos) { - $this->semValue = new Stmt\TryCatch($this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 5)], $this->semStack[$stackPos - (6 - 6)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\TryCatch($this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 5)], $this->semStack[$stackPos - (6 - 6)], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos])); $this->checkTryCatch($this->semValue); }, 179 => function ($stackPos) { - $this->semValue = new Stmt\Goto_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Goto_($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 180 => function ($stackPos) { - $this->semValue = new Stmt\Label($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Label($this->semStack[$stackPos - (2 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 181 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = null; /* means: no statement */ - }, 182 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 183 => function ($stackPos) { - $startAttributes = $this->startAttributeStack[$stackPos - (1 - 1)]; - if (isset($startAttributes['comments'])) { - $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes); + }, 182 => null, 183 => function ($stackPos) { + $this->semValue = $this->maybeCreateNop($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos]); + }, 184 => function ($stackPos) { + if ($this->semStack[$stackPos - (1 - 1)] instanceof Stmt\Block) { + $this->semValue = $this->semStack[$stackPos - (1 - 1)]->stmts; } else { - $this->semValue = null; - } - if ($this->semValue === null) { - $this->semValue = array(); + if ($this->semStack[$stackPos - (1 - 1)] === null) { + $this->semValue = []; + } else { + $this->semValue = [$this->semStack[$stackPos - (1 - 1)]]; + } } - /* means: no statement */ - }, 184 => function ($stackPos) { - $this->semValue = array(); }, 185 => function ($stackPos) { + $this->semValue = array(); + }, 186 => function ($stackPos) { $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 186 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 187 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + }, 188 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 188 => function ($stackPos) { - $this->semValue = new Stmt\Catch_($this->semStack[$stackPos - (8 - 3)], $this->semStack[$stackPos - (8 - 4)], $this->semStack[$stackPos - (8 - 7)], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes); }, 189 => function ($stackPos) { - $this->semValue = null; + $this->semValue = new Stmt\Catch_($this->semStack[$stackPos - (8 - 3)], $this->semStack[$stackPos - (8 - 4)], $this->semStack[$stackPos - (8 - 7)], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos])); }, 190 => function ($stackPos) { - $this->semValue = new Stmt\Finally_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = null; }, 191 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 192 => function ($stackPos) { + $this->semValue = new Stmt\Finally_($this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 192 => null, 193 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 193 => function ($stackPos) { + }, 194 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 194 => function ($stackPos) { - $this->semValue = \false; }, 195 => function ($stackPos) { - $this->semValue = \true; - }, 196 => function ($stackPos) { $this->semValue = \false; - }, 197 => function ($stackPos) { + }, 196 => function ($stackPos) { $this->semValue = \true; - }, 198 => function ($stackPos) { + }, 197 => function ($stackPos) { $this->semValue = \false; - }, 199 => function ($stackPos) { + }, 198 => function ($stackPos) { $this->semValue = \true; + }, 199 => function ($stackPos) { + $this->semValue = \false; }, 200 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + $this->semValue = \true; }, 201 => function ($stackPos) { - $this->semValue = []; + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; }, 202 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 203 => function ($stackPos) { - $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 204 => function ($stackPos) { - $this->semValue = new Stmt\Function_($this->semStack[$stackPos - (8 - 3)], ['byRef' => $this->semStack[$stackPos - (8 - 2)], 'params' => $this->semStack[$stackPos - (8 - 5)], 'returnType' => $this->semStack[$stackPos - (8 - 7)], 'stmts' => $this->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes); + $this->semValue = []; + }, 203 => null, 204 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 205 => function ($stackPos) { - $this->semValue = new Stmt\Function_($this->semStack[$stackPos - (9 - 4)], ['byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 6)], 'returnType' => $this->semStack[$stackPos - (9 - 8)], 'stmts' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => $this->semStack[$stackPos - (9 - 1)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Function_($this->semStack[$stackPos - (8 - 3)], ['byRef' => $this->semStack[$stackPos - (8 - 2)], 'params' => $this->semStack[$stackPos - (8 - 5)], 'returnType' => $this->semStack[$stackPos - (8 - 7)], 'stmts' => $this->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos])); }, 206 => function ($stackPos) { - $this->semValue = new Stmt\Class_($this->semStack[$stackPos - (7 - 2)], ['type' => $this->semStack[$stackPos - (7 - 1)], 'extends' => $this->semStack[$stackPos - (7 - 3)], 'implements' => $this->semStack[$stackPos - (7 - 4)], 'stmts' => $this->semStack[$stackPos - (7 - 6)], 'attrGroups' => []], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes); - $this->checkClass($this->semValue, $stackPos - (7 - 2)); + $this->semValue = new Stmt\Function_($this->semStack[$stackPos - (9 - 4)], ['byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 6)], 'returnType' => $this->semStack[$stackPos - (9 - 8)], 'stmts' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => $this->semStack[$stackPos - (9 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (9 - 1)], $this->tokenEndStack[$stackPos])); }, 207 => function ($stackPos) { - $this->semValue = new Stmt\Class_($this->semStack[$stackPos - (8 - 3)], ['type' => $this->semStack[$stackPos - (8 - 2)], 'extends' => $this->semStack[$stackPos - (8 - 4)], 'implements' => $this->semStack[$stackPos - (8 - 5)], 'stmts' => $this->semStack[$stackPos - (8 - 7)], 'attrGroups' => $this->semStack[$stackPos - (8 - 1)]], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes); - $this->checkClass($this->semValue, $stackPos - (8 - 3)); + $this->semValue = new Stmt\Class_($this->semStack[$stackPos - (7 - 2)], ['type' => $this->semStack[$stackPos - (7 - 1)], 'extends' => $this->semStack[$stackPos - (7 - 3)], 'implements' => $this->semStack[$stackPos - (7 - 4)], 'stmts' => $this->semStack[$stackPos - (7 - 6)], 'attrGroups' => []], $this->getAttributes($this->tokenStartStack[$stackPos - (7 - 1)], $this->tokenEndStack[$stackPos])); + $this->checkClass($this->semValue, $stackPos - (7 - 2)); }, 208 => function ($stackPos) { - $this->semValue = new Stmt\Interface_($this->semStack[$stackPos - (7 - 3)], ['extends' => $this->semStack[$stackPos - (7 - 4)], 'stmts' => $this->semStack[$stackPos - (7 - 6)], 'attrGroups' => $this->semStack[$stackPos - (7 - 1)]], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes); - $this->checkInterface($this->semValue, $stackPos - (7 - 3)); + $this->semValue = new Stmt\Class_($this->semStack[$stackPos - (8 - 3)], ['type' => $this->semStack[$stackPos - (8 - 2)], 'extends' => $this->semStack[$stackPos - (8 - 4)], 'implements' => $this->semStack[$stackPos - (8 - 5)], 'stmts' => $this->semStack[$stackPos - (8 - 7)], 'attrGroups' => $this->semStack[$stackPos - (8 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos])); + $this->checkClass($this->semValue, $stackPos - (8 - 3)); }, 209 => function ($stackPos) { - $this->semValue = new Stmt\Trait_($this->semStack[$stackPos - (6 - 3)], ['stmts' => $this->semStack[$stackPos - (6 - 5)], 'attrGroups' => $this->semStack[$stackPos - (6 - 1)]], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Interface_($this->semStack[$stackPos - (7 - 3)], ['extends' => $this->semStack[$stackPos - (7 - 4)], 'stmts' => $this->semStack[$stackPos - (7 - 6)], 'attrGroups' => $this->semStack[$stackPos - (7 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (7 - 1)], $this->tokenEndStack[$stackPos])); + $this->checkInterface($this->semValue, $stackPos - (7 - 3)); }, 210 => function ($stackPos) { - $this->semValue = new Stmt\Enum_($this->semStack[$stackPos - (8 - 3)], ['scalarType' => $this->semStack[$stackPos - (8 - 4)], 'implements' => $this->semStack[$stackPos - (8 - 5)], 'stmts' => $this->semStack[$stackPos - (8 - 7)], 'attrGroups' => $this->semStack[$stackPos - (8 - 1)]], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes); - $this->checkEnum($this->semValue, $stackPos - (8 - 3)); + $this->semValue = new Stmt\Trait_($this->semStack[$stackPos - (6 - 3)], ['stmts' => $this->semStack[$stackPos - (6 - 5)], 'attrGroups' => $this->semStack[$stackPos - (6 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos])); }, 211 => function ($stackPos) { - $this->semValue = null; + $this->semValue = new Stmt\Enum_($this->semStack[$stackPos - (8 - 3)], ['scalarType' => $this->semStack[$stackPos - (8 - 4)], 'implements' => $this->semStack[$stackPos - (8 - 5)], 'stmts' => $this->semStack[$stackPos - (8 - 7)], 'attrGroups' => $this->semStack[$stackPos - (8 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos])); + $this->checkEnum($this->semValue, $stackPos - (8 - 3)); }, 212 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 2)]; - }, 213 => function ($stackPos) { $this->semValue = null; - }, 214 => function ($stackPos) { + }, 213 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (2 - 2)]; + }, 214 => function ($stackPos) { + $this->semValue = null; }, 215 => function ($stackPos) { - $this->semValue = 0; + $this->semValue = $this->semStack[$stackPos - (2 - 2)]; }, 216 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 217 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 218 => function ($stackPos) { + $this->semValue = 0; + }, 217 => null, 218 => null, 219 => function ($stackPos) { $this->checkClassModifier($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2)); $this->semValue = $this->semStack[$stackPos - (2 - 1)] | $this->semStack[$stackPos - (2 - 2)]; - }, 219 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; }, 220 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_FINAL; + $this->semValue = Modifiers::ABSTRACT; }, 221 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_READONLY; + $this->semValue = Modifiers::FINAL; }, 222 => function ($stackPos) { - $this->semValue = null; + $this->semValue = Modifiers::READONLY; }, 223 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = null; }, 224 => function ($stackPos) { - $this->semValue = array(); - }, 225 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (2 - 2)]; - }, 226 => function ($stackPos) { + }, 225 => function ($stackPos) { $this->semValue = array(); - }, 227 => function ($stackPos) { + }, 226 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (2 - 2)]; + }, 227 => function ($stackPos) { + $this->semValue = array(); }, 228 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 229 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (2 - 2)]; + }, 229 => null, 230 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 230 => function ($stackPos) { + }, 231 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 231 => function ($stackPos) { - $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]); - }, 232 => function ($stackPos) { + }, 232 => null, 233 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (4 - 2)]; - }, 233 => function ($stackPos) { - $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]); - }, 234 => function ($stackPos) { + }, 234 => null, 235 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (4 - 2)]; - }, 235 => function ($stackPos) { - $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]); }, 236 => function ($stackPos) { - $this->semValue = null; + if ($this->semStack[$stackPos - (1 - 1)] instanceof Stmt\Block) { + $this->semValue = $this->semStack[$stackPos - (1 - 1)]->stmts; + } else { + if ($this->semStack[$stackPos - (1 - 1)] === null) { + $this->semValue = []; + } else { + $this->semValue = [$this->semStack[$stackPos - (1 - 1)]]; + } + } }, 237 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (4 - 2)]; + $this->semValue = null; }, 238 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 239 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (4 - 2)]; + }, 239 => null, 240 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 240 => function ($stackPos) { + }, 241 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 241 => function ($stackPos) { - $this->semValue = new Stmt\DeclareDeclare($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); }, 242 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + $this->semValue = new Node\DeclareItem($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 243 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (4 - 3)]; + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; }, 244 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (4 - 2)]; + $this->semValue = $this->semStack[$stackPos - (4 - 3)]; }, 245 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (5 - 3)]; + $this->semValue = $this->semStack[$stackPos - (4 - 2)]; }, 246 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = $this->semStack[$stackPos - (5 - 3)]; }, 247 => function ($stackPos) { + $this->semValue = array(); + }, 248 => function ($stackPos) { $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 248 => function ($stackPos) { - $this->semValue = new Stmt\Case_($this->semStack[$stackPos - (4 - 2)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); }, 249 => function ($stackPos) { - $this->semValue = new Stmt\Case_(null, $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\Case_($this->semStack[$stackPos - (4 - 2)], $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 250 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 251 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 252 => function ($stackPos) { - $this->semValue = new Expr\Match_($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 6)], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes); - }, 253 => function ($stackPos) { - $this->semValue = []; + $this->semValue = new Stmt\Case_(null, $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 251 => null, 252 => null, 253 => function ($stackPos) { + $this->semValue = new Expr\Match_($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 6)], $this->getAttributes($this->tokenStartStack[$stackPos - (7 - 1)], $this->tokenEndStack[$stackPos])); }, 254 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 255 => function ($stackPos) { + $this->semValue = []; + }, 255 => null, 256 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 256 => function ($stackPos) { + }, 257 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 257 => function ($stackPos) { - $this->semValue = new Node\MatchArm($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); }, 258 => function ($stackPos) { - $this->semValue = new Node\MatchArm(null, $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Node\MatchArm($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 259 => function ($stackPos) { - $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]); + $this->semValue = new Node\MatchArm(null, $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 260 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (4 - 2)]; + $this->semValue = $this->semStack[$stackPos - (1 - 1)]; }, 261 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = $this->semStack[$stackPos - (4 - 2)]; }, 262 => function ($stackPos) { + $this->semValue = array(); + }, 263 => function ($stackPos) { $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 263 => function ($stackPos) { - $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos - (5 - 3)], \is_array($this->semStack[$stackPos - (5 - 5)]) ? $this->semStack[$stackPos - (5 - 5)] : array($this->semStack[$stackPos - (5 - 5)]), $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); }, 264 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 265 => function ($stackPos) { + $this->semValue = array(); + }, 266 => function ($stackPos) { $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 266 => function ($stackPos) { - $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 6)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes); - $this->fixupAlternativeElse($this->semValue); }, 267 => function ($stackPos) { - $this->semValue = null; + $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 6)], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos])); + $this->fixupAlternativeElse($this->semValue); }, 268 => function ($stackPos) { - $this->semValue = new Stmt\Else_(\is_array($this->semStack[$stackPos - (2 - 2)]) ? $this->semStack[$stackPos - (2 - 2)] : array($this->semStack[$stackPos - (2 - 2)]), $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 269 => function ($stackPos) { $this->semValue = null; + }, 269 => function ($stackPos) { + $this->semValue = new Stmt\Else_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 270 => function ($stackPos) { - $this->semValue = new Stmt\Else_($this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - $this->fixupAlternativeElse($this->semValue); + $this->semValue = null; }, 271 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)], \false); + $this->semValue = new Stmt\Else_($this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + $this->fixupAlternativeElse($this->semValue); }, 272 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (2 - 2)], \true); - }, 273 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)], \false); + }, 273 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (2 - 2)], \true); }, 274 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)], \false); }, 275 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 276 => function ($stackPos) { + $this->semValue = array($this->fixupArrayDestructuring($this->semStack[$stackPos - (1 - 1)]), \false); + }, 276 => null, 277 => function ($stackPos) { $this->semValue = array(); - }, 277 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 278 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + }, 279 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 279 => function ($stackPos) { - $this->semValue = 0; }, 280 => function ($stackPos) { + $this->semValue = 0; + }, 281 => function ($stackPos) { $this->checkModifier($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2)); $this->semValue = $this->semStack[$stackPos - (2 - 1)] | $this->semStack[$stackPos - (2 - 2)]; - }, 281 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; }, 282 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; + $this->semValue = Modifiers::PUBLIC; }, 283 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; + $this->semValue = Modifiers::PROTECTED; }, 284 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_READONLY; + $this->semValue = Modifiers::PRIVATE; }, 285 => function ($stackPos) { - $this->semValue = new Node\Param($this->semStack[$stackPos - (6 - 6)], null, $this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 4)], $this->semStack[$stackPos - (6 - 5)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes, $this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 1)]); - $this->checkParam($this->semValue); + $this->semValue = Modifiers::READONLY; }, 286 => function ($stackPos) { - $this->semValue = new Node\Param($this->semStack[$stackPos - (8 - 6)], $this->semStack[$stackPos - (8 - 8)], $this->semStack[$stackPos - (8 - 3)], $this->semStack[$stackPos - (8 - 4)], $this->semStack[$stackPos - (8 - 5)], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes, $this->semStack[$stackPos - (8 - 2)], $this->semStack[$stackPos - (8 - 1)]); + $this->semValue = new Node\Param($this->semStack[$stackPos - (6 - 6)], null, $this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 4)], $this->semStack[$stackPos - (6 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos]), $this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 1)]); $this->checkParam($this->semValue); }, 287 => function ($stackPos) { - $this->semValue = new Node\Param(new Expr\Error($this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes), null, $this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 4)], $this->semStack[$stackPos - (6 - 5)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes, $this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 1)]); + $this->semValue = new Node\Param($this->semStack[$stackPos - (8 - 6)], $this->semStack[$stackPos - (8 - 8)], $this->semStack[$stackPos - (8 - 3)], $this->semStack[$stackPos - (8 - 4)], $this->semStack[$stackPos - (8 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos]), $this->semStack[$stackPos - (8 - 2)], $this->semStack[$stackPos - (8 - 1)]); + $this->checkParam($this->semValue); }, 288 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 289 => function ($stackPos) { - $this->semValue = new Node\NullableType($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 290 => function ($stackPos) { - $this->semValue = new Node\UnionType($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Node\Param(new Expr\Error($this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos])), null, $this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 4)], $this->semStack[$stackPos - (6 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos]), $this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 1)]); + }, 289 => null, 290 => function ($stackPos) { + $this->semValue = new Node\NullableType($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 291 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 292 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 293 => function ($stackPos) { - $this->semValue = new Node\Name('static', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 294 => function ($stackPos) { - $this->semValue = $this->handleBuiltinTypes($this->semStack[$stackPos - (1 - 1)]); + $this->semValue = new Node\UnionType($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 292 => null, 293 => null, 294 => function ($stackPos) { + $this->semValue = new Node\Name('static', $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 295 => function ($stackPos) { - $this->semValue = new Node\Identifier('array', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = $this->handleBuiltinTypes($this->semStack[$stackPos - (1 - 1)]); }, 296 => function ($stackPos) { - $this->semValue = new Node\Identifier('callable', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Node\Identifier('array', $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 297 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 298 => function ($stackPos) { + $this->semValue = new Node\Identifier('callable', $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 298 => null, 299 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (3 - 2)]; - }, 299 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); }, 300 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); + }, 301 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 301 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 302 => function ($stackPos) { + }, 302 => null, 303 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (3 - 2)]; - }, 303 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); }, 304 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); + }, 305 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 305 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); }, 306 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); + }, 307 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 307 => function ($stackPos) { - $this->semValue = new Node\IntersectionType($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); }, 308 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); + $this->semValue = new Node\IntersectionType($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 309 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); + }, 310 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 310 => function ($stackPos) { - $this->semValue = new Node\IntersectionType($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); }, 311 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 312 => function ($stackPos) { - $this->semValue = new Node\NullableType($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 313 => function ($stackPos) { - $this->semValue = new Node\UnionType($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Node\IntersectionType($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 312 => null, 313 => function ($stackPos) { + $this->semValue = new Node\NullableType($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 314 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 315 => function ($stackPos) { + $this->semValue = new Node\UnionType($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 315 => null, 316 => function ($stackPos) { $this->semValue = null; - }, 316 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 317 => function ($stackPos) { + }, 317 => null, 318 => function ($stackPos) { $this->semValue = null; - }, 318 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 2)]; }, 319 => function ($stackPos) { - $this->semValue = null; + $this->semValue = $this->semStack[$stackPos - (2 - 2)]; }, 320 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = null; }, 321 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (4 - 2)]; + $this->semValue = array(); }, 322 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (3 - 2)]); + $this->semValue = $this->semStack[$stackPos - (4 - 2)]; }, 323 => function ($stackPos) { - $this->semValue = new Node\VariadicPlaceholder($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (3 - 2)]); }, 324 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + $this->semValue = new Node\VariadicPlaceholder($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 325 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + }, 326 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 326 => function ($stackPos) { - $this->semValue = new Node\Arg($this->semStack[$stackPos - (1 - 1)], \false, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); }, 327 => function ($stackPos) { - $this->semValue = new Node\Arg($this->semStack[$stackPos - (2 - 2)], \true, \false, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Node\Arg($this->semStack[$stackPos - (1 - 1)], \false, \false, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 328 => function ($stackPos) { - $this->semValue = new Node\Arg($this->semStack[$stackPos - (2 - 2)], \false, \true, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Node\Arg($this->semStack[$stackPos - (2 - 2)], \true, \false, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 329 => function ($stackPos) { - $this->semValue = new Node\Arg($this->semStack[$stackPos - (3 - 3)], \false, \false, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes, $this->semStack[$stackPos - (3 - 1)]); + $this->semValue = new Node\Arg($this->semStack[$stackPos - (2 - 2)], \false, \true, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 330 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 331 => function ($stackPos) { + $this->semValue = new Node\Arg($this->semStack[$stackPos - (3 - 3)], \false, \false, $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos]), $this->semStack[$stackPos - (3 - 1)]); + }, 331 => null, 332 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 332 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 333 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 334 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 335 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + }, 334 => null, 335 => null, 336 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 336 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 337 => function ($stackPos) { - $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos - (1 - 1)], null, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 338 => function ($stackPos) { - $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\StaticVar($this->semStack[$stackPos - (1 - 1)], null, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 339 => function ($stackPos) { + $this->semValue = new Node\StaticVar($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 340 => function ($stackPos) { if ($this->semStack[$stackPos - (2 - 2)] !== null) { $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - } - }, 340 => function ($stackPos) { - $this->semValue = array(); - }, 341 => function ($stackPos) { - $startAttributes = $this->lookaheadStartAttributes; - if (isset($startAttributes['comments'])) { - $nop = new Stmt\Nop($this->createCommentNopAttributes($startAttributes['comments'])); } else { - $nop = null; + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; } + }, 341 => function ($stackPos) { + $this->semValue = array(); + }, 342 => function ($stackPos) { + $nop = $this->maybeCreateZeroLengthNop($this->tokenPos); if ($nop !== null) { $this->semStack[$stackPos - (1 - 1)][] = $nop; } $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 342 => function ($stackPos) { - $this->semValue = new Stmt\Property($this->semStack[$stackPos - (5 - 2)], $this->semStack[$stackPos - (5 - 4)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes, $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 1)]); - $this->checkProperty($this->semValue, $stackPos - (5 - 2)); }, 343 => function ($stackPos) { - $this->semValue = new Stmt\ClassConst($this->semStack[$stackPos - (5 - 4)], $this->semStack[$stackPos - (5 - 2)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes, $this->semStack[$stackPos - (5 - 1)]); - $this->checkClassConst($this->semValue, $stackPos - (5 - 2)); + $this->semValue = new Stmt\Property($this->semStack[$stackPos - (5 - 2)], $this->semStack[$stackPos - (5 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos]), $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 1)]); + $this->checkProperty($this->semValue, $stackPos - (5 - 2)); }, 344 => function ($stackPos) { - $this->semValue = new Stmt\ClassMethod($this->semStack[$stackPos - (10 - 5)], ['type' => $this->semStack[$stackPos - (10 - 2)], 'byRef' => $this->semStack[$stackPos - (10 - 4)], 'params' => $this->semStack[$stackPos - (10 - 7)], 'returnType' => $this->semStack[$stackPos - (10 - 9)], 'stmts' => $this->semStack[$stackPos - (10 - 10)], 'attrGroups' => $this->semStack[$stackPos - (10 - 1)]], $this->startAttributeStack[$stackPos - (10 - 1)] + $this->endAttributes); - $this->checkClassMethod($this->semValue, $stackPos - (10 - 2)); + $this->semValue = new Stmt\ClassConst($this->semStack[$stackPos - (5 - 4)], $this->semStack[$stackPos - (5 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos]), $this->semStack[$stackPos - (5 - 1)]); + $this->checkClassConst($this->semValue, $stackPos - (5 - 2)); }, 345 => function ($stackPos) { - $this->semValue = new Stmt\TraitUse($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\ClassConst($this->semStack[$stackPos - (6 - 5)], $this->semStack[$stackPos - (6 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos]), $this->semStack[$stackPos - (6 - 1)], $this->semStack[$stackPos - (6 - 4)]); + $this->checkClassConst($this->semValue, $stackPos - (6 - 2)); }, 346 => function ($stackPos) { - $this->semValue = new Stmt\EnumCase($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 4)], $this->semStack[$stackPos - (5 - 1)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\ClassMethod($this->semStack[$stackPos - (10 - 5)], ['type' => $this->semStack[$stackPos - (10 - 2)], 'byRef' => $this->semStack[$stackPos - (10 - 4)], 'params' => $this->semStack[$stackPos - (10 - 7)], 'returnType' => $this->semStack[$stackPos - (10 - 9)], 'stmts' => $this->semStack[$stackPos - (10 - 10)], 'attrGroups' => $this->semStack[$stackPos - (10 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (10 - 1)], $this->tokenEndStack[$stackPos])); + $this->checkClassMethod($this->semValue, $stackPos - (10 - 2)); }, 347 => function ($stackPos) { - $this->semValue = null; - /* will be skipped */ + $this->semValue = new Stmt\TraitUse($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 348 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = new Stmt\EnumCase($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 4)], $this->semStack[$stackPos - (5 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 349 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + $this->semValue = null; + /* will be skipped */ }, 350 => function ($stackPos) { $this->semValue = array(); }, 351 => function ($stackPos) { - $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; }, 352 => function ($stackPos) { - $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = array(); }, 353 => function ($stackPos) { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (5 - 1)][0], $this->semStack[$stackPos - (5 - 1)][1], $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 4)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); + $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; }, 354 => function ($stackPos) { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], $this->semStack[$stackPos - (4 - 3)], null, $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 355 => function ($stackPos) { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], null, $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (5 - 1)][0], $this->semStack[$stackPos - (5 - 1)][1], $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 356 => function ($stackPos) { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], null, $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], $this->semStack[$stackPos - (4 - 3)], null, $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 357 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], null, $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 358 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], null, $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 359 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]); + }, 360 => null, 361 => function ($stackPos) { $this->semValue = array(null, $this->semStack[$stackPos - (1 - 1)]); - }, 360 => function ($stackPos) { - $this->semValue = null; - }, 361 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; }, 362 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 363 => function ($stackPos) { - $this->semValue = 0; - }, 364 => function ($stackPos) { + $this->semValue = null; + }, 363 => null, 364 => null, 365 => function ($stackPos) { $this->semValue = 0; - }, 365 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; }, 366 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 367 => function ($stackPos) { + $this->semValue = 0; + }, 367 => null, 368 => null, 369 => function ($stackPos) { $this->checkModifier($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2)); $this->semValue = $this->semStack[$stackPos - (2 - 1)] | $this->semStack[$stackPos - (2 - 2)]; - }, 368 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; - }, 369 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; }, 370 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; + $this->semValue = Modifiers::PUBLIC; }, 371 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_STATIC; + $this->semValue = Modifiers::PROTECTED; }, 372 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + $this->semValue = Modifiers::PRIVATE; }, 373 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_FINAL; + $this->semValue = Modifiers::STATIC; }, 374 => function ($stackPos) { - $this->semValue = Stmt\Class_::MODIFIER_READONLY; + $this->semValue = Modifiers::ABSTRACT; }, 375 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + $this->semValue = Modifiers::FINAL; }, 376 => function ($stackPos) { + $this->semValue = Modifiers::READONLY; + }, 377 => null, 378 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 377 => function ($stackPos) { + }, 379 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 378 => function ($stackPos) { - $this->semValue = new Node\VarLikeIdentifier(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 379 => function ($stackPos) { - $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos - (1 - 1)], null, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); }, 380 => function ($stackPos) { - $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\VarLikeIdentifier(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 381 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + $this->semValue = new Node\PropertyItem($this->semStack[$stackPos - (1 - 1)], null, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 382 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; - }, 383 => function ($stackPos) { + $this->semValue = new Node\PropertyItem($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 383 => null, 384 => null, 385 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 384 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 385 => function ($stackPos) { - $this->semValue = array(); }, 386 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 387 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 388 => function ($stackPos) { - $this->semValue = new Expr\Assign($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 389 => function ($stackPos) { - $this->semValue = new Expr\Assign($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 390 => function ($stackPos) { - $this->semValue = new Expr\Assign($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = array(); + }, 388 => null, 389 => null, 390 => function ($stackPos) { + $this->semValue = new Expr\Assign($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 391 => function ($stackPos) { - $this->semValue = new Expr\AssignRef($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Assign($this->fixupArrayDestructuring($this->semStack[$stackPos - (3 - 1)]), $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 392 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\Assign($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 393 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\AssignRef($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 394 => function ($stackPos) { - $this->semValue = new Expr\Clone_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 395 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Plus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 396 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Minus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 397 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Mul($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignRef($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + if (!$this->phpVersion->allowsAssignNewByReference()) { + $this->emitError(new Error('Cannot assign new by reference', $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos]))); + } + }, 395 => null, 396 => null, 397 => function ($stackPos) { + $this->semValue = new Expr\Clone_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 398 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Div($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\Plus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 399 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Concat($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\Minus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 400 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Mod($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\Mul($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 401 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\Div($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 402 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\Concat($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 403 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\Mod($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 404 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 405 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 406 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Pow($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 407 => function ($stackPos) { - $this->semValue = new Expr\AssignOp\Coalesce($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 408 => function ($stackPos) { - $this->semValue = new Expr\PostInc($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 409 => function ($stackPos) { - $this->semValue = new Expr\PreInc($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\Pow($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 410 => function ($stackPos) { - $this->semValue = new Expr\PostDec($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\AssignOp\Coalesce($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 411 => function ($stackPos) { - $this->semValue = new Expr\PreDec($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\PostInc($this->semStack[$stackPos - (2 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 412 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\PreInc($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 413 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\PostDec($this->semStack[$stackPos - (2 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 414 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\PreDec($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 415 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 416 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 417 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 418 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 419 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 420 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 421 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 422 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 423 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 424 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 425 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 426 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 427 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 428 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 429 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 430 => function ($stackPos) { - $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 431 => function ($stackPos) { - $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 432 => function ($stackPos) { - $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 433 => function ($stackPos) { - $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 434 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 435 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 436 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 437 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 438 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 439 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 440 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 441 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 442 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 443 => function ($stackPos) { - $this->semValue = new Expr\Instanceof_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 444 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 445 => function ($stackPos) { - $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (5 - 1)], $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 446 => function ($stackPos) { - $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (4 - 1)], null, $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Instanceof_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 447 => function ($stackPos) { - $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; }, 448 => function ($stackPos) { - $this->semValue = new Expr\Isset_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (5 - 1)], $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); }, 449 => function ($stackPos) { - $this->semValue = new Expr\Empty_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (4 - 1)], null, $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 450 => function ($stackPos) { - $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 451 => function ($stackPos) { - $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Isset_($this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 452 => function ($stackPos) { - $this->semValue = new Expr\Eval_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Empty_($this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 453 => function ($stackPos) { - $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 454 => function ($stackPos) { - $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 455 => function ($stackPos) { - $this->semValue = new Expr\Cast\Int_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Eval_($this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 456 => function ($stackPos) { - $attrs = $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes; - $attrs['kind'] = $this->getFloatCastKind($this->semStack[$stackPos - (2 - 1)]); - $this->semValue = new Expr\Cast\Double($this->semStack[$stackPos - (2 - 2)], $attrs); + $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 457 => function ($stackPos) { - $this->semValue = new Expr\Cast\String_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 458 => function ($stackPos) { - $this->semValue = new Expr\Cast\Array_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Cast\Int_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 459 => function ($stackPos) { - $this->semValue = new Expr\Cast\Object_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $attrs = $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos]); + $attrs['kind'] = $this->getFloatCastKind($this->semStack[$stackPos - (2 - 1)]); + $this->semValue = new Expr\Cast\Double($this->semStack[$stackPos - (2 - 2)], $attrs); }, 460 => function ($stackPos) { - $this->semValue = new Expr\Cast\Bool_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Cast\String_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 461 => function ($stackPos) { - $this->semValue = new Expr\Cast\Unset_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Cast\Array_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 462 => function ($stackPos) { - $attrs = $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes; - $attrs['kind'] = \strtolower($this->semStack[$stackPos - (2 - 1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; - $this->semValue = new Expr\Exit_($this->semStack[$stackPos - (2 - 2)], $attrs); + $this->semValue = new Expr\Cast\Object_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 463 => function ($stackPos) { - $this->semValue = new Expr\ErrorSuppress($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Cast\Bool_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 464 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\Cast\Unset_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 465 => function ($stackPos) { - $this->semValue = new Expr\ShellExec($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $attrs = $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos]); + $attrs['kind'] = \strtolower($this->semStack[$stackPos - (2 - 1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; + $this->semValue = new Expr\Exit_($this->semStack[$stackPos - (2 - 2)], $attrs); }, 466 => function ($stackPos) { - $this->semValue = new Expr\Print_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 467 => function ($stackPos) { - $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 468 => function ($stackPos) { - $this->semValue = new Expr\Yield_($this->semStack[$stackPos - (2 - 2)], null, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\ErrorSuppress($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); + }, 467 => null, 468 => function ($stackPos) { + $this->semValue = new Expr\ShellExec($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 469 => function ($stackPos) { - $this->semValue = new Expr\Yield_($this->semStack[$stackPos - (4 - 4)], $this->semStack[$stackPos - (4 - 2)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Print_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 470 => function ($stackPos) { - $this->semValue = new Expr\YieldFrom($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Yield_(null, null, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 471 => function ($stackPos) { - $this->semValue = new Expr\Throw_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Yield_($this->semStack[$stackPos - (2 - 2)], null, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 472 => function ($stackPos) { - $this->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $this->semStack[$stackPos - (8 - 2)], 'params' => $this->semStack[$stackPos - (8 - 4)], 'returnType' => $this->semStack[$stackPos - (8 - 6)], 'expr' => $this->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Yield_($this->semStack[$stackPos - (4 - 4)], $this->semStack[$stackPos - (4 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 473 => function ($stackPos) { - $this->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'returnType' => $this->semStack[$stackPos - (9 - 7)], 'expr' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes); + $this->semValue = new Expr\YieldFrom($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 474 => function ($stackPos) { - $this->semValue = new Expr\Closure(['static' => \false, 'byRef' => $this->semStack[$stackPos - (8 - 2)], 'params' => $this->semStack[$stackPos - (8 - 4)], 'uses' => $this->semStack[$stackPos - (8 - 6)], 'returnType' => $this->semStack[$stackPos - (8 - 7)], 'stmts' => $this->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Throw_($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 475 => function ($stackPos) { - $this->semValue = new Expr\Closure(['static' => \true, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'uses' => $this->semStack[$stackPos - (9 - 7)], 'returnType' => $this->semStack[$stackPos - (9 - 8)], 'stmts' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes); + $this->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $this->semStack[$stackPos - (8 - 2)], 'params' => $this->semStack[$stackPos - (8 - 4)], 'returnType' => $this->semStack[$stackPos - (8 - 6)], 'expr' => $this->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos])); }, 476 => function ($stackPos) { - $this->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'returnType' => $this->semStack[$stackPos - (9 - 7)], 'expr' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => $this->semStack[$stackPos - (9 - 1)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes); + $this->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'returnType' => $this->semStack[$stackPos - (9 - 7)], 'expr' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $this->getAttributes($this->tokenStartStack[$stackPos - (9 - 1)], $this->tokenEndStack[$stackPos])); }, 477 => function ($stackPos) { - $this->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $this->semStack[$stackPos - (10 - 4)], 'params' => $this->semStack[$stackPos - (10 - 6)], 'returnType' => $this->semStack[$stackPos - (10 - 8)], 'expr' => $this->semStack[$stackPos - (10 - 10)], 'attrGroups' => $this->semStack[$stackPos - (10 - 1)]], $this->startAttributeStack[$stackPos - (10 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Closure(['static' => \false, 'byRef' => $this->semStack[$stackPos - (8 - 2)], 'params' => $this->semStack[$stackPos - (8 - 4)], 'uses' => $this->semStack[$stackPos - (8 - 6)], 'returnType' => $this->semStack[$stackPos - (8 - 7)], 'stmts' => $this->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos])); }, 478 => function ($stackPos) { - $this->semValue = new Expr\Closure(['static' => \false, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'uses' => $this->semStack[$stackPos - (9 - 7)], 'returnType' => $this->semStack[$stackPos - (9 - 8)], 'stmts' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => $this->semStack[$stackPos - (9 - 1)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Closure(['static' => \true, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'uses' => $this->semStack[$stackPos - (9 - 7)], 'returnType' => $this->semStack[$stackPos - (9 - 8)], 'stmts' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $this->getAttributes($this->tokenStartStack[$stackPos - (9 - 1)], $this->tokenEndStack[$stackPos])); }, 479 => function ($stackPos) { - $this->semValue = new Expr\Closure(['static' => \true, 'byRef' => $this->semStack[$stackPos - (10 - 4)], 'params' => $this->semStack[$stackPos - (10 - 6)], 'uses' => $this->semStack[$stackPos - (10 - 8)], 'returnType' => $this->semStack[$stackPos - (10 - 9)], 'stmts' => $this->semStack[$stackPos - (10 - 10)], 'attrGroups' => $this->semStack[$stackPos - (10 - 1)]], $this->startAttributeStack[$stackPos - (10 - 1)] + $this->endAttributes); + $this->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'returnType' => $this->semStack[$stackPos - (9 - 7)], 'expr' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => $this->semStack[$stackPos - (9 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (9 - 1)], $this->tokenEndStack[$stackPos])); }, 480 => function ($stackPos) { - $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$stackPos - (8 - 4)], 'implements' => $this->semStack[$stackPos - (8 - 5)], 'stmts' => $this->semStack[$stackPos - (8 - 7)], 'attrGroups' => $this->semStack[$stackPos - (8 - 1)]], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes), $this->semStack[$stackPos - (8 - 3)]); - $this->checkClass($this->semValue[0], -1); + $this->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $this->semStack[$stackPos - (10 - 4)], 'params' => $this->semStack[$stackPos - (10 - 6)], 'returnType' => $this->semStack[$stackPos - (10 - 8)], 'expr' => $this->semStack[$stackPos - (10 - 10)], 'attrGroups' => $this->semStack[$stackPos - (10 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (10 - 1)], $this->tokenEndStack[$stackPos])); }, 481 => function ($stackPos) { - $this->semValue = new Expr\New_($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Closure(['static' => \false, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'uses' => $this->semStack[$stackPos - (9 - 7)], 'returnType' => $this->semStack[$stackPos - (9 - 8)], 'stmts' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => $this->semStack[$stackPos - (9 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (9 - 1)], $this->tokenEndStack[$stackPos])); }, 482 => function ($stackPos) { - list($class, $ctorArgs) = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Closure(['static' => \true, 'byRef' => $this->semStack[$stackPos - (10 - 4)], 'params' => $this->semStack[$stackPos - (10 - 6)], 'uses' => $this->semStack[$stackPos - (10 - 8)], 'returnType' => $this->semStack[$stackPos - (10 - 9)], 'stmts' => $this->semStack[$stackPos - (10 - 10)], 'attrGroups' => $this->semStack[$stackPos - (10 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (10 - 1)], $this->tokenEndStack[$stackPos])); }, 483 => function ($stackPos) { - $this->semValue = array(); + $this->semValue = array(new Stmt\Class_(null, ['type' => $this->semStack[$stackPos - (8 - 2)], 'extends' => $this->semStack[$stackPos - (8 - 4)], 'implements' => $this->semStack[$stackPos - (8 - 5)], 'stmts' => $this->semStack[$stackPos - (8 - 7)], 'attrGroups' => $this->semStack[$stackPos - (8 - 1)]], $this->getAttributes($this->tokenStartStack[$stackPos - (8 - 1)], $this->tokenEndStack[$stackPos])), $this->semStack[$stackPos - (8 - 3)]); + $this->checkClass($this->semValue[0], -1); }, 484 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (4 - 3)]; + $this->semValue = new Expr\New_($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 485 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + list($class, $ctorArgs) = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = new Expr\New_($class, $ctorArgs, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 486 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + $this->semValue = array(); }, 487 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (4 - 3)]; + }, 488 => null, 489 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + }, 490 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 488 => function ($stackPos) { - $this->semValue = new Expr\ClosureUse($this->semStack[$stackPos - (2 - 2)], $this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 489 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 490 => function ($stackPos) { - $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); }, 491 => function ($stackPos) { - $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Node\ClosureUse($this->semStack[$stackPos - (2 - 2)], $this->semStack[$stackPos - (2 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 492 => function ($stackPos) { - $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 493 => function ($stackPos) { - $this->semValue = new Expr\StaticCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 494 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 495 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 496 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\StaticCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 497 => function ($stackPos) { - $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 498 => function ($stackPos) { - $this->semValue = new Name\FullyQualified(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 499 => function ($stackPos) { - $this->semValue = new Name\Relative(\substr($this->semStack[$stackPos - (1 - 1)], 10), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 498 => null, 499 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 500 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 501 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Name\FullyQualified(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 502 => function ($stackPos) { + $this->semValue = new Name\Relative(\substr($this->semStack[$stackPos - (1 - 1)], 10), $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 503 => null, 504 => null, 505 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (3 - 2)]; - }, 503 => function ($stackPos) { - $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - $this->errorState = 2; - }, 504 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 505 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; }, 506 => function ($stackPos) { + $this->semValue = new Expr\Error($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + $this->errorState = 2; + }, 507 => null, 508 => null, 509 => function ($stackPos) { $this->semValue = null; - }, 507 => function ($stackPos) { + }, 510 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (3 - 2)]; - }, 508 => function ($stackPos) { + }, 511 => function ($stackPos) { $this->semValue = array(); - }, 509 => function ($stackPos) { - $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$stackPos - (1 - 1)], '`'), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes)); - }, 510 => function ($stackPos) { + }, 512 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + foreach ($this->semValue as $s) { + if ($s instanceof Node\InterpolatedStringPart) { + $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $this->phpVersion->supportsUnicodeEscapes()); + } + } + }, 513 => function ($stackPos) { foreach ($this->semStack[$stackPos - (1 - 1)] as $s) { - if ($s instanceof Node\Scalar\EncapsedStringPart) { - $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', \true); + if ($s instanceof Node\InterpolatedStringPart) { + $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $this->phpVersion->supportsUnicodeEscapes()); } } $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 511 => function ($stackPos) { - $this->semValue = array(); - }, 512 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 513 => function ($stackPos) { - $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); }, 514 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 515 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 516 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = array(); + }, 515 => null, 516 => function ($stackPos) { + $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 517 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Scalar\MagicConst\Line($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 518 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Scalar\MagicConst\File($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 519 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Scalar\MagicConst\Dir($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 520 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Scalar\MagicConst\Class_($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 521 => function ($stackPos) { - $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Scalar\MagicConst\Trait_($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 522 => function ($stackPos) { - $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Scalar\MagicConst\Method($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 523 => function ($stackPos) { - $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos - (3 - 1)], new Expr\Error($this->startAttributeStack[$stackPos - (3 - 3)] + $this->endAttributeStack[$stackPos - (3 - 3)]), $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - $this->errorState = 2; + $this->semValue = new Scalar\MagicConst\Function_($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 524 => function ($stackPos) { - $attrs = $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes; + $this->semValue = new Scalar\MagicConst\Namespace_($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 525 => function ($stackPos) { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 526 => function ($stackPos) { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos - (5 - 1)], $this->semStack[$stackPos - (5 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (5 - 1)], $this->tokenEndStack[$stackPos])); + }, 527 => function ($stackPos) { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos - (3 - 1)], new Expr\Error($this->getAttributes($this->tokenStartStack[$stackPos - (3 - 3)], $this->tokenEndStack[$stackPos - (3 - 3)])), $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + $this->errorState = 2; + }, 528 => function ($stackPos) { + $attrs = $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos]); $attrs['kind'] = Expr\Array_::KIND_SHORT; $this->semValue = new Expr\Array_($this->semStack[$stackPos - (3 - 2)], $attrs); - }, 525 => function ($stackPos) { - $attrs = $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes; + }, 529 => function ($stackPos) { + $attrs = $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos]); $attrs['kind'] = Expr\Array_::KIND_LONG; $this->semValue = new Expr\Array_($this->semStack[$stackPos - (4 - 3)], $attrs); - }, 526 => function ($stackPos) { + $this->createdArrays->attach($this->semValue); + }, 530 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 527 => function ($stackPos) { - $this->semValue = Scalar\String_::fromString($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 528 => function ($stackPos) { - $attrs = $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes; + $this->createdArrays->attach($this->semValue); + }, 531 => function ($stackPos) { + $this->semValue = Scalar\String_::fromString($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos]), $this->phpVersion->supportsUnicodeEscapes()); + }, 532 => function ($stackPos) { + $attrs = $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos]); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; foreach ($this->semStack[$stackPos - (3 - 2)] as $s) { - if ($s instanceof Node\Scalar\EncapsedStringPart) { - $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', \true); + if ($s instanceof Node\InterpolatedStringPart) { + $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', $this->phpVersion->supportsUnicodeEscapes()); } } - $this->semValue = new Scalar\Encapsed($this->semStack[$stackPos - (3 - 2)], $attrs); - }, 529 => function ($stackPos) { - $this->semValue = $this->parseLNumber($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 530 => function ($stackPos) { - $this->semValue = Scalar\DNumber::fromString($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 531 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 532 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Scalar\InterpolatedString($this->semStack[$stackPos - (3 - 2)], $attrs); }, 533 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = $this->parseLNumber($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos]), $this->phpVersion->allowsInvalidOctals()); }, 534 => function ($stackPos) { - $this->semValue = $this->parseDocString($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes, $this->startAttributeStack[$stackPos - (3 - 3)] + $this->endAttributeStack[$stackPos - (3 - 3)], \true); - }, 535 => function ($stackPos) { - $this->semValue = $this->parseDocString($this->semStack[$stackPos - (2 - 1)], '', $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes, $this->startAttributeStack[$stackPos - (2 - 2)] + $this->endAttributeStack[$stackPos - (2 - 2)], \true); - }, 536 => function ($stackPos) { - $this->semValue = $this->parseDocString($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes, $this->startAttributeStack[$stackPos - (3 - 3)] + $this->endAttributeStack[$stackPos - (3 - 3)], \true); - }, 537 => function ($stackPos) { - $this->semValue = null; - }, 538 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = Scalar\Float_::fromString($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 535 => null, 536 => null, 537 => null, 538 => function ($stackPos) { + $this->semValue = $this->parseDocString($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos]), $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 3)], $this->tokenEndStack[$stackPos - (3 - 3)]), \true); }, 539 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = $this->parseDocString($this->semStack[$stackPos - (2 - 1)], '', $this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos]), $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 2)], $this->tokenEndStack[$stackPos - (2 - 2)]), \true); }, 540 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + $this->semValue = $this->parseDocString($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos]), $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 3)], $this->tokenEndStack[$stackPos - (3 - 3)]), \true); }, 541 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 542 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 543 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 544 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 545 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 546 => function ($stackPos) { + $this->semValue = null; + }, 542 => null, 543 => null, 544 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (3 - 2)]; - }, 547 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 548 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 549 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 550 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 551 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 552 => function ($stackPos) { - $this->semValue = new Expr\MethodCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 553 => function ($stackPos) { - $this->semValue = new Expr\NullsafeMethodCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + }, 545 => null, 546 => null, 547 => null, 548 => null, 549 => null, 550 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + }, 551 => null, 552 => null, 553 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 554 => function ($stackPos) { - $this->semValue = null; - }, 555 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 556 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + }, 555 => null, 556 => function ($stackPos) { + $this->semValue = new Expr\MethodCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 557 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\NullsafeMethodCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 558 => function ($stackPos) { - $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 559 => function ($stackPos) { - $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 560 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 561 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 562 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = null; + }, 559 => null, 560 => null, 561 => null, 562 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 563 => function ($stackPos) { - $this->semValue = new Expr\Variable(new Expr\Error($this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes), $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - $this->errorState = 2; - }, 564 => function ($stackPos) { - $var = $this->semStack[$stackPos - (1 - 1)]->name; - $this->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes) : $var; - }, 565 => function ($stackPos) { - $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 564 => null, 565 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 566 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\Variable($this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 567 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Variable(new Expr\Error($this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])), $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); + $this->errorState = 2; }, 568 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $var = $this->semStack[$stackPos - (1 - 1)]->name; + $this->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])) : $var; }, 569 => function ($stackPos) { - $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 570 => function ($stackPos) { - $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 571 => function ($stackPos) { - $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 570 => null, 571 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 572 => function ($stackPos) { - $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 573 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 574 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 575 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 576 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 577 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); + }, 577 => null, 578 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (3 - 2)]; - }, 578 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }, 579 => function ($stackPos) { - $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + }, 579 => null, 580 => null, 581 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + }, 582 => null, 583 => function ($stackPos) { + $this->semValue = new Expr\Error($this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); $this->errorState = 2; - }, 580 => function ($stackPos) { - $this->semValue = new Expr\List_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); - }, 581 => function ($stackPos) { + }, 584 => function ($stackPos) { + $this->semValue = new Expr\List_($this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); + $this->semValue->setAttribute('kind', Expr\List_::KIND_LIST); + $this->postprocessList($this->semValue); + }, 585 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos - (1 - 1)]; $end = \count($this->semValue) - 1; - if ($this->semValue[$end] === null) { + if ($this->semValue[$end]->value instanceof Expr\Error) { \array_pop($this->semValue); } - }, 582 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos]; - }, 583 => function ($stackPos) { + }, 586 => null, 587 => function ($stackPos) { /* do nothing -- prevent default action of $$=$this->semStack[$1]. See $551. */ - }, 584 => function ($stackPos) { + }, 588 => function ($stackPos) { $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)]; $this->semValue = $this->semStack[$stackPos - (3 - 1)]; - }, 585 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); - }, 586 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); - }, 587 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (2 - 2)], null, \true, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); - }, 588 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); }, 589 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (3 - 3)], $this->semStack[$stackPos - (3 - 1)], \false, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 590 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (4 - 4)], $this->semStack[$stackPos - (4 - 1)], \true, $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = new Node\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 591 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (3 - 3)], $this->semStack[$stackPos - (3 - 1)], \false, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Node\ArrayItem($this->semStack[$stackPos - (2 - 2)], null, \true, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); }, 592 => function ($stackPos) { - $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (2 - 2)], null, \false, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes, \true, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Node\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); }, 593 => function ($stackPos) { - $this->semValue = null; + $this->semValue = new Node\ArrayItem($this->semStack[$stackPos - (3 - 3)], $this->semStack[$stackPos - (3 - 1)], \false, $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 594 => function ($stackPos) { - $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + $this->semValue = new Node\ArrayItem($this->semStack[$stackPos - (4 - 4)], $this->semStack[$stackPos - (4 - 1)], \true, $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 595 => function ($stackPos) { - $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; - $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + $this->semValue = new Node\ArrayItem($this->semStack[$stackPos - (3 - 3)], $this->semStack[$stackPos - (3 - 1)], \false, $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 596 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); + $this->semValue = new Node\ArrayItem($this->semStack[$stackPos - (2 - 2)], null, \false, $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos]), \true); }, 597 => function ($stackPos) { - $this->semValue = array($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)]); + /* Create an Error node now to remember the position. We'll later either report an error, + or convert this into a null element, depending on whether this is a creation or destructuring context. */ + $attrs = $this->createEmptyElemAttributes($this->tokenPos); + $this->semValue = new Node\ArrayItem(new Expr\Error($attrs), null, \false, $attrs); }, 598 => function ($stackPos) { - $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; }, 599 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; }, 600 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = array($this->semStack[$stackPos - (1 - 1)]); }, 601 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes); + $this->semValue = array($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)]); }, 602 => function ($stackPos) { - $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $attrs = $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos]); + $attrs['rawValue'] = $this->semStack[$stackPos - (1 - 1)]; + $this->semValue = new Node\InterpolatedStringPart($this->semStack[$stackPos - (1 - 1)], $attrs); }, 603 => function ($stackPos) { - $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 604 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); - }, 605 => function ($stackPos) { - $this->semValue = new Expr\Variable($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Variable($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 604 => null, 605 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (4 - 1)], $this->tokenEndStack[$stackPos])); }, 606 => function ($stackPos) { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 4)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes); + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 607 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 608 => function ($stackPos) { - $this->semValue = new Scalar\String_($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Variable($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 609 => function ($stackPos) { - $this->semValue = $this->parseNumString($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes); + $this->semValue = new Expr\Variable($this->semStack[$stackPos - (3 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (3 - 1)], $this->tokenEndStack[$stackPos])); }, 610 => function ($stackPos) { - $this->semValue = $this->parseNumString('-' . $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes); + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 4)], $this->getAttributes($this->tokenStartStack[$stackPos - (6 - 1)], $this->tokenEndStack[$stackPos])); }, 611 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos - (1 - 1)]; - }]; + $this->semValue = $this->semStack[$stackPos - (3 - 2)]; + }, 612 => function ($stackPos) { + $this->semValue = new Scalar\String_($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 613 => function ($stackPos) { + $this->semValue = $this->parseNumString($this->semStack[$stackPos - (1 - 1)], $this->getAttributes($this->tokenStartStack[$stackPos - (1 - 1)], $this->tokenEndStack[$stackPos])); + }, 614 => function ($stackPos) { + $this->semValue = $this->parseNumString('-' . $this->semStack[$stackPos - (2 - 2)], $this->getAttributes($this->tokenStartStack[$stackPos - (2 - 1)], $this->tokenEndStack[$stackPos])); + }, 615 => null]; } } Map of PHP token IDs to drop */ + protected array $dropTokens; + /** @var int[] Map of external symbols (static::T_*) to internal symbols */ + protected array $tokenToSymbol; /** @var string[] Map of symbols to their names */ - protected $symbolToName; - /** @var array Names of the production rules (only necessary for debugging) */ - protected $productions; + protected array $symbolToName; + /** @var array Names of the production rules (only necessary for debugging) */ + protected array $productions; /** @var int[] Map of states to a displacement into the $action table. The corresponding action for this * state/symbol pair is $action[$actionBase[$state] + $symbol]. If $actionBase[$state] is 0, the * action is defaulted, i.e. $actionDefault[$state] should be used instead. */ - protected $actionBase; + protected array $actionBase; /** @var int[] Table of actions. Indexed according to $actionBase comment. */ - protected $action; + protected array $action; /** @var int[] Table indexed analogously to $action. If $actionCheck[$actionBase[$state] + $symbol] != $symbol * then the action is defaulted, i.e. $actionDefault[$state] should be used instead. */ - protected $actionCheck; + protected array $actionCheck; /** @var int[] Map of states to their default action */ - protected $actionDefault; + protected array $actionDefault; /** @var callable[] Semantic action callbacks */ - protected $reduceCallbacks; + protected array $reduceCallbacks; /** @var int[] Map of non-terminals to a displacement into the $goto table. The corresponding goto state for this * non-terminal/state pair is $goto[$gotoBase[$nonTerminal] + $state] (unless defaulted) */ - protected $gotoBase; + protected array $gotoBase; /** @var int[] Table of states to goto after reduction. Indexed according to $gotoBase comment. */ - protected $goto; + protected array $goto; /** @var int[] Table indexed analogously to $goto. If $gotoCheck[$gotoBase[$nonTerminal] + $state] != $nonTerminal * then the goto state is defaulted, i.e. $gotoDefault[$nonTerminal] should be used. */ - protected $gotoCheck; + protected array $gotoCheck; /** @var int[] Map of non-terminals to the default state to goto after their reduction */ - protected $gotoDefault; + protected array $gotoDefault; /** @var int[] Map of rules to the non-terminal on their left-hand side, i.e. the non-terminal to use for * determining the state to goto after reduction. */ - protected $ruleToNonTerminal; + protected array $ruleToNonTerminal; /** @var int[] Map of rules to the length of their right-hand side, which is the number of elements that have to * be popped from the stack(s) on reduction. */ - protected $ruleToLength; + protected array $ruleToLength; /* * The following members are part of the parser state: */ - /** @var Lexer Lexer that is used when parsing */ - protected $lexer; /** @var mixed Temporary value containing the result of last semantic action (reduction) */ protected $semValue; - /** @var array Semantic value stack (contains values of tokens and semantic action results) */ - protected $semStack; - /** @var array[] Start attribute stack */ - protected $startAttributeStack; - /** @var array[] End attribute stack */ - protected $endAttributeStack; - /** @var array End attributes of last *shifted* token */ - protected $endAttributes; - /** @var array Start attributes of last *read* token */ - protected $lookaheadStartAttributes; + /** @var mixed[] Semantic value stack (contains values of tokens and semantic action results) */ + protected array $semStack; + /** @var int[] Token start position stack */ + protected array $tokenStartStack; + /** @var int[] Token end position stack */ + protected array $tokenEndStack; /** @var ErrorHandler Error handler */ - protected $errorHandler; + protected ErrorHandler $errorHandler; /** @var int Error state, used to avoid error floods */ - protected $errorState; + protected int $errorState; + /** @var \SplObjectStorage|null Array nodes created during parsing, for postprocessing of empty elements. */ + protected ?\SplObjectStorage $createdArrays; + /** @var Token[] Tokens for the current parse */ + protected array $tokens; + /** @var int Current position in token array */ + protected int $tokenPos; /** * Initialize $reduceCallbacks map. */ - protected abstract function initReduceCallbacks(); + protected abstract function initReduceCallbacks() : void; /** * Creates a parser instance. * - * Options: Currently none. + * Options: + * * phpVersion: ?PhpVersion, * * @param Lexer $lexer A lexer - * @param array $options Options array. + * @param PhpVersion $phpVersion PHP version to target, defaults to latest supported. This + * option is best-effort: Even if specified, parsing will generally assume the latest + * supported version and only adjust behavior in minor ways, for example by omitting + * errors in older versions and interpreting type hints as a name or identifier depending + * on version. */ - public function __construct(Lexer $lexer, array $options = []) + public function __construct(Lexer $lexer, ?PhpVersion $phpVersion = null) { $this->lexer = $lexer; - if (isset($options['throwOnError'])) { - throw new \LogicException('"throwOnError" is no longer supported, use "errorHandler" instead'); - } + $this->phpVersion = $phpVersion ?? PhpVersion::getNewestSupported(); $this->initReduceCallbacks(); + $this->phpTokenToSymbol = $this->createTokenMap(); + $this->dropTokens = \array_fill_keys([\T_WHITESPACE, \T_OPEN_TAG, \T_COMMENT, \T_DOC_COMMENT, \T_BAD_CHARACTER], \true); } /** * Parses PHP code into a node tree. @@ -19064,32 +20387,49 @@ abstract class ParserAbstract implements Parser * @return Node\Stmt[]|null Array of statements (or null non-throwing error handler is used and * the parser was unable to recover from an error). */ - public function parse(string $code, ErrorHandler $errorHandler = null) + public function parse(string $code, ?ErrorHandler $errorHandler = null) : ?array { $this->errorHandler = $errorHandler ?: new ErrorHandler\Throwing(); - $this->lexer->startLexing($code, $this->errorHandler); + $this->createdArrays = new \SplObjectStorage(); + $this->tokens = $this->lexer->tokenize($code, $this->errorHandler); $result = $this->doParse(); + // Report errors for any empty elements used inside arrays. This is delayed until after the main parse, + // because we don't know a priori whether a given array expression will be used in a destructuring context + // or not. + foreach ($this->createdArrays as $node) { + foreach ($node->items as $item) { + if ($item->value instanceof Expr\Error) { + $this->errorHandler->handleError(new Error('Cannot use empty array elements in arrays', $item->getAttributes())); + } + } + } // Clear out some of the interior state, so we don't hold onto unnecessary // memory between uses of the parser - $this->startAttributeStack = []; - $this->endAttributeStack = []; + $this->tokenStartStack = []; + $this->tokenEndStack = []; $this->semStack = []; $this->semValue = null; + $this->createdArrays = null; + if ($result !== null) { + $traverser = new NodeTraverser(new CommentAnnotatingVisitor($this->tokens)); + $traverser->traverse($result); + } return $result; } - protected function doParse() + public function getTokens() : array + { + return $this->tokens; + } + /** @return Stmt[]|null */ + protected function doParse() : ?array { // We start off with no lookahead-token $symbol = self::SYMBOL_NONE; - // The attributes for a node are taken from the first and last token of the node. - // From the first token only the startAttributes are taken and from the last only - // the endAttributes. Both are merged using the array union operator (+). - $startAttributes = []; - $endAttributes = []; - $this->endAttributes = $endAttributes; + $tokenValue = null; + $this->tokenPos = -1; // Keep stack of start and end attributes - $this->startAttributeStack = []; - $this->endAttributeStack = [$endAttributes]; + $this->tokenStartStack = []; + $this->tokenEndStack = [0]; // Start off in the initial state and keep a stack of previous states $state = 0; $stateStack = [$state]; @@ -19104,18 +20444,16 @@ abstract class ParserAbstract implements Parser $rule = $this->actionDefault[$state]; } else { if ($symbol === self::SYMBOL_NONE) { - // Fetch the next token id from the lexer and fetch additional info by-ref. - // The end attributes are fetched into a temporary variable and only set once the token is really - // shifted (not during read). Otherwise you would sometimes get off-by-one errors, when a rule is - // reduced after a token was read but not yet shifted. - $tokenId = $this->lexer->getNextToken($tokenValue, $startAttributes, $endAttributes); - // map the lexer token id to the internally used symbols - $symbol = $tokenId >= 0 && $tokenId < $this->tokenToSymbolMapSize ? $this->tokenToSymbol[$tokenId] : $this->invalidSymbol; - if ($symbol === $this->invalidSymbol) { + do { + $token = $this->tokens[++$this->tokenPos]; + $tokenId = $token->id; + } while (isset($this->dropTokens[$tokenId])); + // Map the lexer token id to the internally used symbols. + $tokenValue = $token->text; + if (!isset($this->phpTokenToSymbol[$tokenId])) { throw new \RangeException(\sprintf('The lexer returned an invalid token (id=%d, value=%s)', $tokenId, $tokenValue)); } - // Allow productions to access the start attributes of the lookahead token. - $this->lookaheadStartAttributes = $startAttributes; + $symbol = $this->phpTokenToSymbol[$tokenId]; //$this->traceRead($symbol); } $idx = $this->actionBase[$state] + $symbol; @@ -19133,9 +20471,8 @@ abstract class ParserAbstract implements Parser ++$stackPos; $stateStack[$stackPos] = $state = $action; $this->semStack[$stackPos] = $tokenValue; - $this->startAttributeStack[$stackPos] = $startAttributes; - $this->endAttributeStack[$stackPos] = $endAttributes; - $this->endAttributes = $endAttributes; + $this->tokenStartStack[$stackPos] = $this->tokenPos; + $this->tokenEndStack[$stackPos] = $this->tokenPos; $symbol = self::SYMBOL_NONE; if ($this->errorState) { --$this->errorState; @@ -19157,22 +20494,28 @@ abstract class ParserAbstract implements Parser /* accept */ //$this->traceAccept(); return $this->semValue; - } elseif ($rule !== $this->unexpectedTokenRule) { + } + if ($rule !== $this->unexpectedTokenRule) { /* reduce */ //$this->traceReduce($rule); + $ruleLength = $this->ruleToLength[$rule]; try { - $this->reduceCallbacks[$rule]($stackPos); + $callback = $this->reduceCallbacks[$rule]; + if ($callback !== null) { + $callback($stackPos); + } elseif ($ruleLength > 0) { + $this->semValue = $this->semStack[$stackPos - $ruleLength + 1]; + } } catch (Error $e) { - if (-1 === $e->getStartLine() && isset($startAttributes['startLine'])) { - $e->setStartLine($startAttributes['startLine']); + if (-1 === $e->getStartLine()) { + $e->setStartLine($this->tokens[$this->tokenPos]->line); } $this->emitError($e); // Can't recover from this type of error return null; } /* Goto - shift nonterminal */ - $lastEndAttributes = $this->endAttributeStack[$stackPos]; - $ruleLength = $this->ruleToLength[$rule]; + $lastTokenEnd = $this->tokenEndStack[$stackPos]; $stackPos -= $ruleLength; $nonTerminal = $this->ruleToNonTerminal[$rule]; $idx = $this->gotoBase[$nonTerminal] + $stateStack[$stackPos]; @@ -19184,18 +20527,19 @@ abstract class ParserAbstract implements Parser ++$stackPos; $stateStack[$stackPos] = $state; $this->semStack[$stackPos] = $this->semValue; - $this->endAttributeStack[$stackPos] = $lastEndAttributes; + $this->tokenEndStack[$stackPos] = $lastTokenEnd; if ($ruleLength === 0) { // Empty productions use the start attributes of the lookahead token. - $this->startAttributeStack[$stackPos] = $this->lookaheadStartAttributes; + $this->tokenStartStack[$stackPos] = $this->tokenPos; } } else { /* error */ switch ($this->errorState) { case 0: $msg = $this->getErrorMessage($symbol, $state); - $this->emitError(new Error($msg, $startAttributes + $endAttributes)); + $this->emitError(new Error($msg, $this->getAttributesForToken($this->tokenPos))); // Break missing intentionally + // no break case 1: case 2: $this->errorState = 3; @@ -19214,9 +20558,8 @@ abstract class ParserAbstract implements Parser $stateStack[$stackPos] = $state = $action; // We treat the error symbol as being empty, so we reset the end attributes // to the end attributes of the last non-error symbol - $this->startAttributeStack[$stackPos] = $this->lookaheadStartAttributes; - $this->endAttributeStack[$stackPos] = $this->endAttributeStack[$stackPos - 1]; - $this->endAttributes = $this->endAttributeStack[$stackPos - 1]; + $this->tokenStartStack[$stackPos] = $this->tokenPos; + $this->tokenEndStack[$stackPos] = $this->tokenEndStack[$stackPos - 1]; break; case 3: if ($symbol === 0) { @@ -19237,7 +20580,7 @@ abstract class ParserAbstract implements Parser } throw new \RuntimeException('Reached end of parser loop'); } - protected function emitError(Error $error) + protected function emitError(Error $error) : void { $this->errorHandler->handleError($error); } @@ -19245,7 +20588,7 @@ abstract class ParserAbstract implements Parser * Format error message including expected tokens. * * @param int $symbol Unexpected symbol - * @param int $state State at time of error + * @param int $state State at time of error * * @return string Formatted error message */ @@ -19282,36 +20625,63 @@ abstract class ParserAbstract implements Parser } return $expected; } + /** + * Get attributes for a node with the given start and end token positions. + * + * @param int $tokenStartPos Token position the node starts at + * @param int $tokenEndPos Token position the node ends at + * @return array Attributes + */ + protected function getAttributes(int $tokenStartPos, int $tokenEndPos) : array + { + $startToken = $this->tokens[$tokenStartPos]; + $afterEndToken = $this->tokens[$tokenEndPos + 1]; + return ['startLine' => $startToken->line, 'startTokenPos' => $tokenStartPos, 'startFilePos' => $startToken->pos, 'endLine' => $afterEndToken->line, 'endTokenPos' => $tokenEndPos, 'endFilePos' => $afterEndToken->pos - 1]; + } + /** + * Get attributes for a single token at the given token position. + * + * @return array Attributes + */ + protected function getAttributesForToken(int $tokenPos) : array + { + if ($tokenPos < \count($this->tokens) - 1) { + return $this->getAttributes($tokenPos, $tokenPos); + } + // Get attributes for the sentinel token. + $token = $this->tokens[$tokenPos]; + return ['startLine' => $token->line, 'startTokenPos' => $tokenPos, 'startFilePos' => $token->pos, 'endLine' => $token->line, 'endTokenPos' => $tokenPos, 'endFilePos' => $token->pos]; + } /* * Tracing functions used for debugging the parser. */ /* - protected function traceNewState($state, $symbol) { + protected function traceNewState($state, $symbol): void { echo '% State ' . $state . ', Lookahead ' . ($symbol == self::SYMBOL_NONE ? '--none--' : $this->symbolToName[$symbol]) . "\n"; } - protected function traceRead($symbol) { + protected function traceRead($symbol): void { echo '% Reading ' . $this->symbolToName[$symbol] . "\n"; } - protected function traceShift($symbol) { + protected function traceShift($symbol): void { echo '% Shift ' . $this->symbolToName[$symbol] . "\n"; } - protected function traceAccept() { + protected function traceAccept(): void { echo "% Accepted.\n"; } - protected function traceReduce($n) { + protected function traceReduce($n): void { echo '% Reduce by (' . $n . ') ' . $this->productions[$n] . "\n"; } - protected function tracePop($state) { + protected function tracePop($state): void { echo '% Recovering, uncovered state ' . $state . "\n"; } - protected function traceDiscard($symbol) { + protected function traceDiscard($symbol): void { echo '% Discard ' . $this->symbolToName[$symbol] . "\n"; } */ @@ -19331,7 +20701,8 @@ abstract class ParserAbstract implements Parser if (null === $style) { // not namespaced, nothing to do return $stmts; - } elseif ('brace' === $style) { + } + if ('brace' === $style) { // For braced namespaces we only have to check that there are no invalid statements between the namespaces $afterFirstNamespace = \false; foreach ($stmts as $stmt) { @@ -19377,7 +20748,7 @@ abstract class ParserAbstract implements Parser return $resultStmts; } } - private function fixupNamespaceAttributes(Node\Stmt\Namespace_ $stmt) + private function fixupNamespaceAttributes(Node\Stmt\Namespace_ $stmt) : void { // We moved the statements into the namespace node, as such the end of the namespace node // needs to be extended to the end of the statements. @@ -19394,6 +20765,22 @@ abstract class ParserAbstract implements Parser } } } + /** @return array */ + private function getNamespaceErrorAttributes(Namespace_ $node) : array + { + $attrs = $node->getAttributes(); + // Adjust end attributes to only cover the "namespace" keyword, not the whole namespace. + if (isset($attrs['startLine'])) { + $attrs['endLine'] = $attrs['startLine']; + } + if (isset($attrs['startTokenPos'])) { + $attrs['endTokenPos'] = $attrs['startTokenPos']; + } + if (isset($attrs['startFilePos'])) { + $attrs['endFilePos'] = $attrs['startFilePos'] + \strlen('namespace') - 1; + } + return $attrs; + } /** * Determine namespacing style (semicolon or brace) * @@ -19401,7 +20788,7 @@ abstract class ParserAbstract implements Parser * * @return null|string One of "semicolon", "brace" or null (no namespaces) */ - private function getNamespacingStyle(array $stmts) + private function getNamespacingStyle(array $stmts) : ?string { $style = null; $hasNotAllowedStmts = \false; @@ -19411,10 +20798,10 @@ abstract class ParserAbstract implements Parser if (null === $style) { $style = $currentStyle; if ($hasNotAllowedStmts) { - $this->emitError(new Error('Namespace declaration statement has to be the very first statement in the script', $stmt->getLine())); + $this->emitError(new Error('Namespace declaration statement has to be the very first statement in the script', $this->getNamespaceErrorAttributes($stmt))); } } elseif ($style !== $currentStyle) { - $this->emitError(new Error('Cannot mix bracketed namespace declarations with unbracketed namespace declarations', $stmt->getLine())); + $this->emitError(new Error('Cannot mix bracketed namespace declarations with unbracketed namespace declarations', $this->getNamespaceErrorAttributes($stmt))); // Treat like semicolon style for namespace normalization return 'semicolon'; } @@ -19433,64 +20820,14 @@ abstract class ParserAbstract implements Parser } return $style; } - /** - * Fix up parsing of static property calls in PHP 5. - * - * In PHP 5 A::$b[c][d] and A::$b[c][d]() have very different interpretation. The former is - * interpreted as (A::$b)[c][d], while the latter is the same as A::{$b[c][d]}(). We parse the - * latter as the former initially and this method fixes the AST into the correct form when we - * encounter the "()". - * - * @param Node\Expr\StaticPropertyFetch|Node\Expr\ArrayDimFetch $prop - * @param Node\Arg[] $args - * @param array $attributes - * - * @return Expr\StaticCall - */ - protected function fixupPhp5StaticPropCall($prop, array $args, array $attributes) : Expr\StaticCall - { - if ($prop instanceof Node\Expr\StaticPropertyFetch) { - $name = $prop->name instanceof VarLikeIdentifier ? $prop->name->toString() : $prop->name; - $var = new Expr\Variable($name, $prop->name->getAttributes()); - return new Expr\StaticCall($prop->class, $var, $args, $attributes); - } elseif ($prop instanceof Node\Expr\ArrayDimFetch) { - $tmp = $prop; - while ($tmp->var instanceof Node\Expr\ArrayDimFetch) { - $tmp = $tmp->var; - } - /** @var Expr\StaticPropertyFetch $staticProp */ - $staticProp = $tmp->var; - // Set start attributes to attributes of innermost node - $tmp = $prop; - $this->fixupStartAttributes($tmp, $staticProp->name); - while ($tmp->var instanceof Node\Expr\ArrayDimFetch) { - $tmp = $tmp->var; - $this->fixupStartAttributes($tmp, $staticProp->name); - } - $name = $staticProp->name instanceof VarLikeIdentifier ? $staticProp->name->toString() : $staticProp->name; - $tmp->var = new Expr\Variable($name, $staticProp->name->getAttributes()); - return new Expr\StaticCall($staticProp->class, $prop, $args, $attributes); - } else { - throw new \Exception(); - } - } - protected function fixupStartAttributes(Node $to, Node $from) - { - $startAttributes = ['startLine', 'startFilePos', 'startTokenPos']; - foreach ($startAttributes as $startAttribute) { - if ($from->hasAttribute($startAttribute)) { - $to->setAttribute($startAttribute, $from->getAttribute($startAttribute)); - } - } - } + /** @return Name|Identifier */ protected function handleBuiltinTypes(Name $name) { - $builtinTypes = ['bool' => \true, 'int' => \true, 'float' => \true, 'string' => \true, 'iterable' => \true, 'void' => \true, 'object' => \true, 'null' => \true, 'false' => \true, 'mixed' => \true, 'never' => \true, 'true' => \true]; if (!$name->isUnqualified()) { return $name; } $lowerName = $name->toLowerString(); - if (!isset($builtinTypes[$lowerName])) { + if (!$this->phpVersion->supportsBuiltinType($lowerName)) { return $name; } return new Node\Identifier($lowerName, $name->getAttributes()); @@ -19498,13 +20835,13 @@ abstract class ParserAbstract implements Parser /** * Get combined start and end attributes at a stack location * - * @param int $pos Stack location + * @param int $stackPos Stack location * - * @return array Combined start and end attributes + * @return array Combined start and end attributes */ - protected function getAttributesAt(int $pos) : array + protected function getAttributesAt(int $stackPos) : array { - return $this->startAttributeStack[$pos] + $this->endAttributeStack[$pos]; + return $this->getAttributes($this->tokenStartStack[$stackPos], $this->tokenEndStack[$stackPos]); } protected function getFloatCastKind(string $cast) : int { @@ -19517,23 +20854,24 @@ abstract class ParserAbstract implements Parser } return Double::KIND_DOUBLE; } - protected function parseLNumber($str, $attributes, $allowInvalidOctal = \false) + /** @param array $attributes */ + protected function parseLNumber(string $str, array $attributes, bool $allowInvalidOctal = \false) : Int_ { try { - return LNumber::fromString($str, $attributes, $allowInvalidOctal); + return Int_::fromString($str, $attributes, $allowInvalidOctal); } catch (Error $error) { $this->emitError($error); // Use dummy value - return new LNumber(0, $attributes); + return new Int_(0, $attributes); } } /** * Parse a T_NUM_STRING token into either an integer or string node. * - * @param string $str Number string - * @param array $attributes Attributes + * @param string $str Number string + * @param array $attributes Attributes * - * @return LNumber|String_ Integer or string node. + * @return Int_|String_ Integer or string node. */ protected function parseNumString(string $str, array $attributes) { @@ -19544,9 +20882,10 @@ abstract class ParserAbstract implements Parser if (!\is_int($num)) { return new String_($str, $attributes); } - return new LNumber($num, $attributes); + return new Int_($num, $attributes); } - protected function stripIndentation(string $string, int $indentLen, string $indentChar, bool $newlineAtStart, bool $newlineAtEnd, array $attributes) + /** @param array $attributes */ + protected function stripIndentation(string $string, int $indentLen, string $indentChar, bool $newlineAtStart, bool $newlineAtEnd, array $attributes) : string { if ($indentLen === 0) { return $string; @@ -19564,7 +20903,12 @@ abstract class ParserAbstract implements Parser return \substr($matches[0], \strlen($prefix)); }, $string); } - protected function parseDocString(string $startToken, $contents, string $endToken, array $attributes, array $endTokenAttributes, bool $parseUnicodeEscape) + /** + * @param string|(Expr|InterpolatedStringPart)[] $contents + * @param array $attributes + * @param array $endTokenAttributes + */ + protected function parseDocString(string $startToken, $contents, string $endToken, array $attributes, array $endTokenAttributes, bool $parseUnicodeEscape) : Expr { $kind = \strpos($startToken, "'") === \false ? String_::KIND_HEREDOC : String_::KIND_NOWDOC; $regex = '/\\A[bB]?<<<[ \\t]*[\'"]?([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)[\'"]?(?:\\r\\n|\\n|\\r)\\z/'; @@ -19588,67 +20932,136 @@ abstract class ParserAbstract implements Parser $indentChar = $indentHasSpaces ? " " : "\t"; if (\is_string($contents)) { if ($contents === '') { + $attributes['rawValue'] = $contents; return new String_('', $attributes); } $contents = $this->stripIndentation($contents, $indentLen, $indentChar, \true, \true, $attributes); $contents = \preg_replace('~(\\r\\n|\\n|\\r)\\z~', '', $contents); + $attributes['rawValue'] = $contents; if ($kind === String_::KIND_HEREDOC) { $contents = String_::parseEscapeSequences($contents, null, $parseUnicodeEscape); } return new String_($contents, $attributes); } else { \assert(\count($contents) > 0); - if (!$contents[0] instanceof Node\Scalar\EncapsedStringPart) { + if (!$contents[0] instanceof Node\InterpolatedStringPart) { // If there is no leading encapsed string part, pretend there is an empty one $this->stripIndentation('', $indentLen, $indentChar, \true, \false, $contents[0]->getAttributes()); } $newContents = []; foreach ($contents as $i => $part) { - if ($part instanceof Node\Scalar\EncapsedStringPart) { + if ($part instanceof Node\InterpolatedStringPart) { $isLast = $i === \count($contents) - 1; $part->value = $this->stripIndentation($part->value, $indentLen, $indentChar, $i === 0, $isLast, $part->getAttributes()); - $part->value = String_::parseEscapeSequences($part->value, null, $parseUnicodeEscape); if ($isLast) { $part->value = \preg_replace('~(\\r\\n|\\n|\\r)\\z~', '', $part->value); } + $part->setAttribute('rawValue', $part->value); + $part->value = String_::parseEscapeSequences($part->value, null, $parseUnicodeEscape); if ('' === $part->value) { continue; } } $newContents[] = $part; } - return new Encapsed($newContents, $attributes); + return new InterpolatedString($newContents, $attributes); } } + protected function createCommentFromToken(Token $token, int $tokenPos) : Comment + { + \assert($token->id === \T_COMMENT || $token->id == \T_DOC_COMMENT); + return \T_DOC_COMMENT === $token->id ? new Comment\Doc($token->text, $token->line, $token->pos, $tokenPos, $token->getEndLine(), $token->getEndPos() - 1, $tokenPos) : new Comment($token->text, $token->line, $token->pos, $tokenPos, $token->getEndLine(), $token->getEndPos() - 1, $tokenPos); + } /** - * Create attributes for a zero-length common-capturing nop. - * - * @param Comment[] $comments - * @return array + * Get last comment before the given token position, if any */ - protected function createCommentNopAttributes(array $comments) + protected function getCommentBeforeToken(int $tokenPos) : ?Comment { - $comment = $comments[\count($comments) - 1]; + while (--$tokenPos >= 0) { + $token = $this->tokens[$tokenPos]; + if (!isset($this->dropTokens[$token->id])) { + break; + } + if ($token->id === \T_COMMENT || $token->id === \T_DOC_COMMENT) { + return $this->createCommentFromToken($token, $tokenPos); + } + } + return null; + } + /** + * Create a zero-length nop to capture preceding comments, if any. + */ + protected function maybeCreateZeroLengthNop(int $tokenPos) : ?Nop + { + $comment = $this->getCommentBeforeToken($tokenPos); + if ($comment === null) { + return null; + } $commentEndLine = $comment->getEndLine(); $commentEndFilePos = $comment->getEndFilePos(); $commentEndTokenPos = $comment->getEndTokenPos(); - $attributes = ['comments' => $comments]; - if (-1 !== $commentEndLine) { - $attributes['startLine'] = $commentEndLine; - $attributes['endLine'] = $commentEndLine; + $attributes = ['startLine' => $commentEndLine, 'endLine' => $commentEndLine, 'startFilePos' => $commentEndFilePos + 1, 'endFilePos' => $commentEndFilePos, 'startTokenPos' => $commentEndTokenPos + 1, 'endTokenPos' => $commentEndTokenPos]; + return new Nop($attributes); + } + protected function maybeCreateNop(int $tokenStartPos, int $tokenEndPos) : ?Nop + { + if ($this->getCommentBeforeToken($tokenStartPos) === null) { + return null; } - if (-1 !== $commentEndFilePos) { - $attributes['startFilePos'] = $commentEndFilePos + 1; - $attributes['endFilePos'] = $commentEndFilePos; + return new Nop($this->getAttributes($tokenStartPos, $tokenEndPos)); + } + protected function handleHaltCompiler() : string + { + // Prevent the lexer from returning any further tokens. + $nextToken = $this->tokens[$this->tokenPos + 1]; + $this->tokenPos = \count($this->tokens) - 2; + // Return text after __halt_compiler. + return $nextToken->id === \T_INLINE_HTML ? $nextToken->text : ''; + } + protected function inlineHtmlHasLeadingNewline(int $stackPos) : bool + { + $tokenPos = $this->tokenStartStack[$stackPos]; + $token = $this->tokens[$tokenPos]; + \assert($token->id == \T_INLINE_HTML); + if ($tokenPos > 0) { + $prevToken = $this->tokens[$tokenPos - 1]; + \assert($prevToken->id == \T_CLOSE_TAG); + return \false !== \strpos($prevToken->text, "\n") || \false !== \strpos($prevToken->text, "\r"); } - if (-1 !== $commentEndTokenPos) { - $attributes['startTokenPos'] = $commentEndTokenPos + 1; - $attributes['endTokenPos'] = $commentEndTokenPos; + return \true; + } + /** + * @return array + */ + protected function createEmptyElemAttributes(int $tokenPos) : array + { + return $this->getAttributesForToken($tokenPos); + } + protected function fixupArrayDestructuring(Array_ $node) : Expr\List_ + { + $this->createdArrays->detach($node); + return new Expr\List_(\array_map(function (Node\ArrayItem $item) { + if ($item->value instanceof Expr\Error) { + // We used Error as a placeholder for empty elements, which are legal for destructuring. + return null; + } + if ($item->value instanceof Array_) { + return new Node\ArrayItem($this->fixupArrayDestructuring($item->value), $item->key, $item->byRef, $item->getAttributes()); + } + return $item; + }, $node->items), ['kind' => Expr\List_::KIND_ARRAY] + $node->getAttributes()); + } + protected function postprocessList(Expr\List_ $node) : void + { + foreach ($node->items as $i => $item) { + if ($item->value instanceof Expr\Error) { + // We used Error as a placeholder for empty elements, which are legal for destructuring. + $node->items[$i] = null; + } } - return $attributes; } /** @param ElseIf_|Else_ $node */ - protected function fixupAlternativeElse($node) + protected function fixupAlternativeElse($node) : void { // Make sure a trailing nop statement carrying comments is part of the node. $numStmts = \count($node->stmts); @@ -19665,38 +21078,38 @@ abstract class ParserAbstract implements Parser } } } - protected function checkClassModifier($a, $b, $modifierPos) + protected function checkClassModifier(int $a, int $b, int $modifierPos) : void { try { - Class_::verifyClassModifier($a, $b); + Modifiers::verifyClassModifier($a, $b); } catch (Error $error) { $error->setAttributes($this->getAttributesAt($modifierPos)); $this->emitError($error); } } - protected function checkModifier($a, $b, $modifierPos) + protected function checkModifier(int $a, int $b, int $modifierPos) : void { // Jumping through some hoops here because verifyModifier() is also used elsewhere try { - Class_::verifyModifier($a, $b); + Modifiers::verifyModifier($a, $b); } catch (Error $error) { $error->setAttributes($this->getAttributesAt($modifierPos)); $this->emitError($error); } } - protected function checkParam(Param $node) + protected function checkParam(Param $node) : void { if ($node->variadic && null !== $node->default) { $this->emitError(new Error('Variadic parameter cannot have a default value', $node->default->getAttributes())); } } - protected function checkTryCatch(TryCatch $node) + protected function checkTryCatch(TryCatch $node) : void { if (empty($node->catches) && null === $node->finally) { $this->emitError(new Error('Cannot use try without catch or finally', $node->getAttributes())); } } - protected function checkNamespace(Namespace_ $node) + protected function checkNamespace(Namespace_ $node) : void { if (null !== $node->stmts) { foreach ($node->stmts as $stmt) { @@ -19706,13 +21119,14 @@ abstract class ParserAbstract implements Parser } } } - private function checkClassName($name, $namePos) + private function checkClassName(?Identifier $name, int $namePos) : void { if (null !== $name && $name->isSpecialClassName()) { $this->emitError(new Error(\sprintf('Cannot use \'%s\' as class name as it is reserved', $name), $this->getAttributesAt($namePos))); } } - private function checkImplementedInterfaces(array $interfaces) + /** @param Name[] $interfaces */ + private function checkImplementedInterfaces(array $interfaces) : void { foreach ($interfaces as $interface) { if ($interface->isSpecialClassName()) { @@ -19720,7 +21134,7 @@ abstract class ParserAbstract implements Parser } } } - protected function checkClass(Class_ $node, $namePos) + protected function checkClass(Class_ $node, int $namePos) : void { $this->checkClassName($node->name, $namePos); if ($node->extends && $node->extends->isSpecialClassName()) { @@ -19728,19 +21142,19 @@ abstract class ParserAbstract implements Parser } $this->checkImplementedInterfaces($node->implements); } - protected function checkInterface(Interface_ $node, $namePos) + protected function checkInterface(Interface_ $node, int $namePos) : void { $this->checkClassName($node->name, $namePos); $this->checkImplementedInterfaces($node->extends); } - protected function checkEnum(Enum_ $node, $namePos) + protected function checkEnum(Enum_ $node, int $namePos) : void { $this->checkClassName($node->name, $namePos); $this->checkImplementedInterfaces($node->implements); } - protected function checkClassMethod(ClassMethod $node, $modifierPos) + protected function checkClassMethod(ClassMethod $node, int $modifierPos) : void { - if ($node->flags & Class_::MODIFIER_STATIC) { + if ($node->flags & Modifiers::STATIC) { switch ($node->name->toLowerString()) { case '__construct': $this->emitError(new Error(\sprintf('Constructor %s() cannot be static', $node->name), $this->getAttributesAt($modifierPos))); @@ -19753,76 +21167,337 @@ abstract class ParserAbstract implements Parser break; } } - if ($node->flags & Class_::MODIFIER_READONLY) { + if ($node->flags & Modifiers::READONLY) { $this->emitError(new Error(\sprintf('Method %s() cannot be readonly', $node->name), $this->getAttributesAt($modifierPos))); } } - protected function checkClassConst(ClassConst $node, $modifierPos) + protected function checkClassConst(ClassConst $node, int $modifierPos) : void { - if ($node->flags & Class_::MODIFIER_STATIC) { + if ($node->flags & Modifiers::STATIC) { $this->emitError(new Error("Cannot use 'static' as constant modifier", $this->getAttributesAt($modifierPos))); } - if ($node->flags & Class_::MODIFIER_ABSTRACT) { + if ($node->flags & Modifiers::ABSTRACT) { $this->emitError(new Error("Cannot use 'abstract' as constant modifier", $this->getAttributesAt($modifierPos))); } - if ($node->flags & Class_::MODIFIER_READONLY) { + if ($node->flags & Modifiers::READONLY) { $this->emitError(new Error("Cannot use 'readonly' as constant modifier", $this->getAttributesAt($modifierPos))); } } - protected function checkProperty(Property $node, $modifierPos) + protected function checkProperty(Property $node, int $modifierPos) : void { - if ($node->flags & Class_::MODIFIER_ABSTRACT) { + if ($node->flags & Modifiers::ABSTRACT) { $this->emitError(new Error('Properties cannot be declared abstract', $this->getAttributesAt($modifierPos))); } - if ($node->flags & Class_::MODIFIER_FINAL) { + if ($node->flags & Modifiers::FINAL) { $this->emitError(new Error('Properties cannot be declared final', $this->getAttributesAt($modifierPos))); } } - protected function checkUseUse(UseUse $node, $namePos) + protected function checkUseUse(UseItem $node, int $namePos) : void { if ($node->alias && $node->alias->isSpecialClassName()) { $this->emitError(new Error(\sprintf('Cannot use %s as %s because \'%2$s\' is a special class name', $node->name, $node->alias), $this->getAttributesAt($namePos))); } } + /** + * Creates the token map. + * + * The token map maps the PHP internal token identifiers + * to the identifiers used by the Parser. Additionally it + * maps T_OPEN_TAG_WITH_ECHO to T_ECHO and T_CLOSE_TAG to ';'. + * + * @return array The token map + */ + protected function createTokenMap() : array + { + $tokenMap = []; + for ($i = 0; $i < 1000; ++$i) { + if ($i < 256) { + // Single-char tokens use an identity mapping. + $tokenMap[$i] = $i; + } elseif (\T_DOUBLE_COLON === $i) { + // T_DOUBLE_COLON is equivalent to T_PAAMAYIM_NEKUDOTAYIM + $tokenMap[$i] = static::T_PAAMAYIM_NEKUDOTAYIM; + } elseif (\T_OPEN_TAG_WITH_ECHO === $i) { + // T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO + $tokenMap[$i] = static::T_ECHO; + } elseif (\T_CLOSE_TAG === $i) { + // T_CLOSE_TAG is equivalent to ';' + $tokenMap[$i] = \ord(';'); + } elseif ('UNKNOWN' !== ($name = \token_name($i))) { + if (\defined($name = static::class . '::' . $name)) { + // Other tokens can be mapped directly + $tokenMap[$i] = \constant($name); + } + } + } + // Assign tokens for which we define compatibility constants, as token_name() does not know them. + $tokenMap[\T_FN] = static::T_FN; + $tokenMap[\T_COALESCE_EQUAL] = static::T_COALESCE_EQUAL; + $tokenMap[\T_NAME_QUALIFIED] = static::T_NAME_QUALIFIED; + $tokenMap[\T_NAME_FULLY_QUALIFIED] = static::T_NAME_FULLY_QUALIFIED; + $tokenMap[\T_NAME_RELATIVE] = static::T_NAME_RELATIVE; + $tokenMap[\T_MATCH] = static::T_MATCH; + $tokenMap[\T_NULLSAFE_OBJECT_OPERATOR] = static::T_NULLSAFE_OBJECT_OPERATOR; + $tokenMap[\T_ATTRIBUTE] = static::T_ATTRIBUTE; + $tokenMap[\T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG] = static::T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG; + $tokenMap[\T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG] = static::T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG; + $tokenMap[\T_ENUM] = static::T_ENUM; + $tokenMap[\T_READONLY] = static::T_READONLY; + // We have create a map from PHP token IDs to external symbol IDs. + // Now map them to the internal symbol ID. + $fullTokenMap = []; + foreach ($tokenMap as $phpToken => $extSymbol) { + $intSymbol = $this->tokenToSymbol[$extSymbol]; + if ($intSymbol === $this->invalidSymbol) { + continue; + } + $fullTokenMap[$phpToken] = $intSymbol; + } + return $fullTokenMap; + } } isHostVersion()) { + $lexer = new Lexer(); + } else { + $lexer = new Lexer\Emulative($version); } - switch ($kind) { - case self::PREFER_PHP7: - return new Parser\Multiple([new Parser\Php7($lexer, $parserOptions), new Parser\Php5($lexer, $parserOptions)]); - case self::PREFER_PHP5: - return new Parser\Multiple([new Parser\Php5($lexer, $parserOptions), new Parser\Php7($lexer, $parserOptions)]); - case self::ONLY_PHP7: - return new Parser\Php7($lexer, $parserOptions); - case self::ONLY_PHP5: - return new Parser\Php5($lexer, $parserOptions); - default: - throw new \LogicException('Kind must be one of ::PREFER_PHP7, ::PREFER_PHP5, ::ONLY_PHP7 or ::ONLY_PHP5'); + if ($version->id >= 80000) { + return new Php8($lexer, $version); + } + return new Php7($lexer, $version); + } + /** + * Create a parser targeting the newest version supported by this library. Code for older + * versions will be accepted if there have been no relevant backwards-compatibility breaks in + * PHP. + */ + public function createForNewestSupportedVersion() : Parser + { + return $this->createForVersion(PhpVersion::getNewestSupported()); + } + /** + * Create a parser targeting the host PHP version, that is the PHP version we're currently + * running on. This parser will not use any token emulation. + */ + public function createForHostVersion() : Parser + { + return $this->createForVersion(PhpVersion::getHostVersion()); + } +} + 50100, 'callable' => 50400, 'bool' => 70000, 'int' => 70000, 'float' => 70000, 'string' => 70000, 'iterable' => 70100, 'void' => 70100, 'object' => 70200, 'null' => 80000, 'false' => 80000, 'mixed' => 80000, 'never' => 80100, 'true' => 80200]; + private function __construct(int $id) + { + $this->id = $id; + } + /** + * Create a PhpVersion object from major and minor version components. + */ + public static function fromComponents(int $major, int $minor) : self + { + return new self($major * 10000 + $minor * 100); + } + /** + * Get the newest PHP version supported by this library. Support for this version may be partial, + * if it is still under development. + */ + public static function getNewestSupported() : self + { + return self::fromComponents(8, 2); + } + /** + * Get the host PHP version, that is the PHP version we're currently running on. + */ + public static function getHostVersion() : self + { + return self::fromComponents(\PHP_MAJOR_VERSION, \PHP_MINOR_VERSION); + } + /** + * Parse the version from a string like "8.1". + */ + public static function fromString(string $version) : self + { + if (!\preg_match('/^(\\d+)\\.(\\d+)/', $version, $matches)) { + throw new \LogicException("Invalid PHP version \"{$version}\""); } + return self::fromComponents((int) $matches[1], (int) $matches[2]); + } + /** + * Check whether two versions are the same. + */ + public function equals(PhpVersion $other) : bool + { + return $this->id === $other->id; + } + /** + * Check whether this version is greater than or equal to the argument. + */ + public function newerOrEqual(PhpVersion $other) : bool + { + return $this->id >= $other->id; + } + /** + * Check whether this version is older than the argument. + */ + public function older(PhpVersion $other) : bool + { + return $this->id < $other->id; + } + /** + * Check whether this is the host PHP version. + */ + public function isHostVersion() : bool + { + return $this->equals(self::getHostVersion()); + } + /** + * Check whether this PHP version supports the given builtin type. Type name must be lowercase. + */ + public function supportsBuiltinType(string $type) : bool + { + $minVersion = self::BUILTIN_TYPE_VERSIONS[$type] ?? null; + return $minVersion !== null && $this->id >= $minVersion; + } + /** + * Whether this version supports [] array literals. + */ + public function supportsShortArraySyntax() : bool + { + return $this->id >= 50400; + } + /** + * Whether this version supports [] for destructuring. + */ + public function supportsShortArrayDestructuring() : bool + { + return $this->id >= 70100; + } + /** + * Whether this version supports flexible heredoc/nowdoc. + */ + public function supportsFlexibleHeredoc() : bool + { + return $this->id >= 70300; } + /** + * Whether this version supports trailing commas in parameter lists. + */ + public function supportsTrailingCommaInParamList() : bool + { + return $this->id >= 80000; + } + /** + * Whether this version allows "$var =& new Obj". + */ + public function allowsAssignNewByReference() : bool + { + return $this->id < 70000; + } + /** + * Whether this version allows invalid octals like "08". + */ + public function allowsInvalidOctals() : bool + { + return $this->id < 70000; + } + /** + * Whether this version allows DEL (\x7f) to occur in identifiers. + */ + public function allowsDelInIdentifiers() : bool + { + return $this->id < 70100; + } + /** + * Whether this version supports yield in expression context without parentheses. + */ + public function supportsYieldWithoutParentheses() : bool + { + return $this->id >= 70000; + } + /** + * Whether this version supports unicode escape sequences in strings. + */ + public function supportsUnicodeEscapes() : bool + { + return $this->id >= 70000; + } +} +pAttrGroups($node->attrGroups, \true) . $this->pModifiers($node->flags) . ($node->type ? $this->p($node->type) . ' ' : '') . ($node->byRef ? '&' : '') . ($node->variadic ? '...' : '') . $this->p($node->var) . ($node->default ? ' = ' . $this->p($node->default) : ''); } - protected function pArg(Node\Arg $node) + protected function pArg(Node\Arg $node) : string { return ($node->name ? $node->name->toString() . ': ' : '') . ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '') . $this->p($node->value); } - protected function pVariadicPlaceholder(Node\VariadicPlaceholder $node) + protected function pVariadicPlaceholder(Node\VariadicPlaceholder $node) : string { return '...'; } - protected function pConst(Node\Const_ $node) + protected function pConst(Node\Const_ $node) : string { return $node->name . ' = ' . $this->p($node->value); } - protected function pNullableType(Node\NullableType $node) + protected function pNullableType(Node\NullableType $node) : string { return '?' . $this->p($node->type); } - protected function pUnionType(Node\UnionType $node) + protected function pUnionType(Node\UnionType $node) : string { $types = []; foreach ($node->types as $typeNode) { @@ -19874,125 +21549,139 @@ class Standard extends PrettyPrinterAbstract } return \implode('|', $types); } - protected function pIntersectionType(Node\IntersectionType $node) + protected function pIntersectionType(Node\IntersectionType $node) : string { return $this->pImplode($node->types, '&'); } - protected function pIdentifier(Node\Identifier $node) + protected function pIdentifier(Node\Identifier $node) : string { return $node->name; } - protected function pVarLikeIdentifier(Node\VarLikeIdentifier $node) + protected function pVarLikeIdentifier(Node\VarLikeIdentifier $node) : string { return '$' . $node->name; } - protected function pAttribute(Node\Attribute $node) + protected function pAttribute(Node\Attribute $node) : string { return $this->p($node->name) . ($node->args ? '(' . $this->pCommaSeparated($node->args) . ')' : ''); } - protected function pAttributeGroup(Node\AttributeGroup $node) + protected function pAttributeGroup(Node\AttributeGroup $node) : string { return '#[' . $this->pCommaSeparated($node->attrs) . ']'; } // Names - protected function pName(Name $node) + protected function pName(Name $node) : string { - return \implode('\\', $node->parts); + return $node->name; } - protected function pName_FullyQualified(Name\FullyQualified $node) + protected function pName_FullyQualified(Name\FullyQualified $node) : string { - return '\\' . \implode('\\', $node->parts); + return '\\' . $node->name; } - protected function pName_Relative(Name\Relative $node) + protected function pName_Relative(Name\Relative $node) : string { - return 'namespace\\' . \implode('\\', $node->parts); + return 'namespace\\' . $node->name; } // Magic Constants - protected function pScalar_MagicConst_Class(MagicConst\Class_ $node) + protected function pScalar_MagicConst_Class(MagicConst\Class_ $node) : string { return '__CLASS__'; } - protected function pScalar_MagicConst_Dir(MagicConst\Dir $node) + protected function pScalar_MagicConst_Dir(MagicConst\Dir $node) : string { return '__DIR__'; } - protected function pScalar_MagicConst_File(MagicConst\File $node) + protected function pScalar_MagicConst_File(MagicConst\File $node) : string { return '__FILE__'; } - protected function pScalar_MagicConst_Function(MagicConst\Function_ $node) + protected function pScalar_MagicConst_Function(MagicConst\Function_ $node) : string { return '__FUNCTION__'; } - protected function pScalar_MagicConst_Line(MagicConst\Line $node) + protected function pScalar_MagicConst_Line(MagicConst\Line $node) : string { return '__LINE__'; } - protected function pScalar_MagicConst_Method(MagicConst\Method $node) + protected function pScalar_MagicConst_Method(MagicConst\Method $node) : string { return '__METHOD__'; } - protected function pScalar_MagicConst_Namespace(MagicConst\Namespace_ $node) + protected function pScalar_MagicConst_Namespace(MagicConst\Namespace_ $node) : string { return '__NAMESPACE__'; } - protected function pScalar_MagicConst_Trait(MagicConst\Trait_ $node) + protected function pScalar_MagicConst_Trait(MagicConst\Trait_ $node) : string { return '__TRAIT__'; } // Scalars - protected function pScalar_String(Scalar\String_ $node) + private function indentString(string $str) : string + { + return \str_replace("\n", $this->nl, $str); + } + protected function pScalar_String(Scalar\String_ $node) : string { $kind = $node->getAttribute('kind', Scalar\String_::KIND_SINGLE_QUOTED); switch ($kind) { case Scalar\String_::KIND_NOWDOC: $label = $node->getAttribute('docLabel'); if ($label && !$this->containsEndLabel($node->value, $label)) { + $shouldIdent = $this->phpVersion->supportsFlexibleHeredoc(); + $nl = $shouldIdent ? $this->nl : $this->newline; if ($node->value === '') { - return "<<<'{$label}'\n{$label}" . $this->docStringEndToken; + return "<<<'{$label}'{$nl}{$label}{$this->docStringEndToken}"; + } + // Make sure trailing \r is not combined with following \n into CRLF. + if ($node->value[\strlen($node->value) - 1] !== "\r") { + $value = $shouldIdent ? $this->indentString($node->value) : $node->value; + return "<<<'{$label}'{$nl}{$value}{$nl}{$label}{$this->docStringEndToken}"; } - return "<<<'{$label}'\n{$node->value}\n{$label}" . $this->docStringEndToken; } /* break missing intentionally */ + // no break case Scalar\String_::KIND_SINGLE_QUOTED: return $this->pSingleQuotedString($node->value); case Scalar\String_::KIND_HEREDOC: $label = $node->getAttribute('docLabel'); - if ($label && !$this->containsEndLabel($node->value, $label)) { - if ($node->value === '') { - return "<<<{$label}\n{$label}" . $this->docStringEndToken; + $escaped = $this->escapeString($node->value, null); + if ($label && !$this->containsEndLabel($escaped, $label)) { + $nl = $this->phpVersion->supportsFlexibleHeredoc() ? $this->nl : $this->newline; + if ($escaped === '') { + return "<<<{$label}{$nl}{$label}{$this->docStringEndToken}"; } - $escaped = $this->escapeString($node->value, null); - return "<<<{$label}\n" . $escaped . "\n{$label}" . $this->docStringEndToken; + return "<<<{$label}{$nl}{$escaped}{$nl}{$label}{$this->docStringEndToken}"; } /* break missing intentionally */ + // no break case Scalar\String_::KIND_DOUBLE_QUOTED: return '"' . $this->escapeString($node->value, '"') . '"'; } throw new \Exception('Invalid string kind'); } - protected function pScalar_Encapsed(Scalar\Encapsed $node) + protected function pScalar_InterpolatedString(Scalar\InterpolatedString $node) : string { if ($node->getAttribute('kind') === Scalar\String_::KIND_HEREDOC) { $label = $node->getAttribute('docLabel'); if ($label && !$this->encapsedContainsEndLabel($node->parts, $label)) { - if (\count($node->parts) === 1 && $node->parts[0] instanceof Scalar\EncapsedStringPart && $node->parts[0]->value === '') { - return "<<<{$label}\n{$label}" . $this->docStringEndToken; + $nl = $this->phpVersion->supportsFlexibleHeredoc() ? $this->nl : $this->newline; + if (\count($node->parts) === 1 && $node->parts[0] instanceof Node\InterpolatedStringPart && $node->parts[0]->value === '') { + return "<<<{$label}{$nl}{$label}{$this->docStringEndToken}"; } - return "<<<{$label}\n" . $this->pEncapsList($node->parts, null) . "\n{$label}" . $this->docStringEndToken; + return "<<<{$label}{$nl}" . $this->pEncapsList($node->parts, null) . "{$nl}{$label}{$this->docStringEndToken}"; } } return '"' . $this->pEncapsList($node->parts, '"') . '"'; } - protected function pScalar_LNumber(Scalar\LNumber $node) + protected function pScalar_Int(Scalar\Int_ $node) : string { if ($node->value === -\PHP_INT_MAX - 1) { // PHP_INT_MIN cannot be represented as a literal, // because the sign is not part of the literal return '(-' . \PHP_INT_MAX . '-1)'; } - $kind = $node->getAttribute('kind', Scalar\LNumber::KIND_DEC); - if (Scalar\LNumber::KIND_DEC === $kind) { + $kind = $node->getAttribute('kind', Scalar\Int_::KIND_DEC); + if (Scalar\Int_::KIND_DEC === $kind) { return (string) $node->value; } if ($node->value < 0) { @@ -20003,29 +21692,30 @@ class Standard extends PrettyPrinterAbstract $str = (string) $node->value; } switch ($kind) { - case Scalar\LNumber::KIND_BIN: + case Scalar\Int_::KIND_BIN: return $sign . '0b' . \base_convert($str, 10, 2); - case Scalar\LNumber::KIND_OCT: + case Scalar\Int_::KIND_OCT: return $sign . '0' . \base_convert($str, 10, 8); - case Scalar\LNumber::KIND_HEX: + case Scalar\Int_::KIND_HEX: return $sign . '0x' . \base_convert($str, 10, 16); } throw new \Exception('Invalid number kind'); } - protected function pScalar_DNumber(Scalar\DNumber $node) + protected function pScalar_Float(Scalar\Float_ $node) : string { if (!\is_finite($node->value)) { if ($node->value === \INF) { - return '\\INF'; - } elseif ($node->value === -\INF) { - return '-\\INF'; + return '1.0E+1000'; + } + if ($node->value === -\INF) { + return '-1.0E+1000'; } else { return '\\NAN'; } } // Try to find a short full-precision representation $stringValue = \sprintf('%.16G', $node->value); - if ($node->value !== (double) $stringValue) { + if ($node->value !== (float) $stringValue) { $stringValue = \sprintf('%.17G', $node->value); } // %G is locale dependent and there exists no locale-independent alternative. We don't want @@ -20035,319 +21725,312 @@ class Standard extends PrettyPrinterAbstract // ensure that number is really printed as float return \preg_match('/^-?[0-9]+$/', $stringValue) ? $stringValue . '.0' : $stringValue; } - protected function pScalar_EncapsedStringPart(Scalar\EncapsedStringPart $node) - { - throw new \LogicException('Cannot directly print EncapsedStringPart'); - } // Assignments - protected function pExpr_Assign(Expr\Assign $node) + protected function pExpr_Assign(Expr\Assign $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(Expr\Assign::class, $node->var, ' = ', $node->expr); + return $this->pPrefixOp(Expr\Assign::class, $this->p($node->var) . ' = ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_AssignRef(Expr\AssignRef $node) + protected function pExpr_AssignRef(Expr\AssignRef $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(Expr\AssignRef::class, $node->var, ' =& ', $node->expr); + return $this->pPrefixOp(Expr\AssignRef::class, $this->p($node->var) . ' =& ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_AssignOp_Plus(AssignOp\Plus $node) + protected function pExpr_AssignOp_Plus(AssignOp\Plus $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(AssignOp\Plus::class, $node->var, ' += ', $node->expr); + return $this->pPrefixOp(AssignOp\Plus::class, $this->p($node->var) . ' += ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_AssignOp_Minus(AssignOp\Minus $node) + protected function pExpr_AssignOp_Minus(AssignOp\Minus $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(AssignOp\Minus::class, $node->var, ' -= ', $node->expr); + return $this->pPrefixOp(AssignOp\Minus::class, $this->p($node->var) . ' -= ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_AssignOp_Mul(AssignOp\Mul $node) + protected function pExpr_AssignOp_Mul(AssignOp\Mul $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(AssignOp\Mul::class, $node->var, ' *= ', $node->expr); + return $this->pPrefixOp(AssignOp\Mul::class, $this->p($node->var) . ' *= ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_AssignOp_Div(AssignOp\Div $node) + protected function pExpr_AssignOp_Div(AssignOp\Div $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(AssignOp\Div::class, $node->var, ' /= ', $node->expr); + return $this->pPrefixOp(AssignOp\Div::class, $this->p($node->var) . ' /= ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_AssignOp_Concat(AssignOp\Concat $node) + protected function pExpr_AssignOp_Concat(AssignOp\Concat $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(AssignOp\Concat::class, $node->var, ' .= ', $node->expr); + return $this->pPrefixOp(AssignOp\Concat::class, $this->p($node->var) . ' .= ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_AssignOp_Mod(AssignOp\Mod $node) + protected function pExpr_AssignOp_Mod(AssignOp\Mod $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(AssignOp\Mod::class, $node->var, ' %= ', $node->expr); + return $this->pPrefixOp(AssignOp\Mod::class, $this->p($node->var) . ' %= ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_AssignOp_BitwiseAnd(AssignOp\BitwiseAnd $node) + protected function pExpr_AssignOp_BitwiseAnd(AssignOp\BitwiseAnd $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(AssignOp\BitwiseAnd::class, $node->var, ' &= ', $node->expr); + return $this->pPrefixOp(AssignOp\BitwiseAnd::class, $this->p($node->var) . ' &= ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_AssignOp_BitwiseOr(AssignOp\BitwiseOr $node) + protected function pExpr_AssignOp_BitwiseOr(AssignOp\BitwiseOr $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(AssignOp\BitwiseOr::class, $node->var, ' |= ', $node->expr); + return $this->pPrefixOp(AssignOp\BitwiseOr::class, $this->p($node->var) . ' |= ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_AssignOp_BitwiseXor(AssignOp\BitwiseXor $node) + protected function pExpr_AssignOp_BitwiseXor(AssignOp\BitwiseXor $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(AssignOp\BitwiseXor::class, $node->var, ' ^= ', $node->expr); + return $this->pPrefixOp(AssignOp\BitwiseXor::class, $this->p($node->var) . ' ^= ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_AssignOp_ShiftLeft(AssignOp\ShiftLeft $node) + protected function pExpr_AssignOp_ShiftLeft(AssignOp\ShiftLeft $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(AssignOp\ShiftLeft::class, $node->var, ' <<= ', $node->expr); + return $this->pPrefixOp(AssignOp\ShiftLeft::class, $this->p($node->var) . ' <<= ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_AssignOp_ShiftRight(AssignOp\ShiftRight $node) + protected function pExpr_AssignOp_ShiftRight(AssignOp\ShiftRight $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(AssignOp\ShiftRight::class, $node->var, ' >>= ', $node->expr); + return $this->pPrefixOp(AssignOp\ShiftRight::class, $this->p($node->var) . ' >>= ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_AssignOp_Pow(AssignOp\Pow $node) + protected function pExpr_AssignOp_Pow(AssignOp\Pow $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(AssignOp\Pow::class, $node->var, ' **= ', $node->expr); + return $this->pPrefixOp(AssignOp\Pow::class, $this->p($node->var) . ' **= ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_AssignOp_Coalesce(AssignOp\Coalesce $node) + protected function pExpr_AssignOp_Coalesce(AssignOp\Coalesce $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(AssignOp\Coalesce::class, $node->var, ' ??= ', $node->expr); + return $this->pPrefixOp(AssignOp\Coalesce::class, $this->p($node->var) . ' ??= ', $node->expr, $precedence, $lhsPrecedence); } // Binary expressions - protected function pExpr_BinaryOp_Plus(BinaryOp\Plus $node) + protected function pExpr_BinaryOp_Plus(BinaryOp\Plus $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\Plus::class, $node->left, ' + ', $node->right); + return $this->pInfixOp(BinaryOp\Plus::class, $node->left, ' + ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_Minus(BinaryOp\Minus $node) + protected function pExpr_BinaryOp_Minus(BinaryOp\Minus $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\Minus::class, $node->left, ' - ', $node->right); + return $this->pInfixOp(BinaryOp\Minus::class, $node->left, ' - ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_Mul(BinaryOp\Mul $node) + protected function pExpr_BinaryOp_Mul(BinaryOp\Mul $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\Mul::class, $node->left, ' * ', $node->right); + return $this->pInfixOp(BinaryOp\Mul::class, $node->left, ' * ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_Div(BinaryOp\Div $node) + protected function pExpr_BinaryOp_Div(BinaryOp\Div $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\Div::class, $node->left, ' / ', $node->right); + return $this->pInfixOp(BinaryOp\Div::class, $node->left, ' / ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_Concat(BinaryOp\Concat $node) + protected function pExpr_BinaryOp_Concat(BinaryOp\Concat $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\Concat::class, $node->left, ' . ', $node->right); + return $this->pInfixOp(BinaryOp\Concat::class, $node->left, ' . ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_Mod(BinaryOp\Mod $node) + protected function pExpr_BinaryOp_Mod(BinaryOp\Mod $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\Mod::class, $node->left, ' % ', $node->right); + return $this->pInfixOp(BinaryOp\Mod::class, $node->left, ' % ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_BooleanAnd(BinaryOp\BooleanAnd $node) + protected function pExpr_BinaryOp_BooleanAnd(BinaryOp\BooleanAnd $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\BooleanAnd::class, $node->left, ' && ', $node->right); + return $this->pInfixOp(BinaryOp\BooleanAnd::class, $node->left, ' && ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_BooleanOr(BinaryOp\BooleanOr $node) + protected function pExpr_BinaryOp_BooleanOr(BinaryOp\BooleanOr $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\BooleanOr::class, $node->left, ' || ', $node->right); + return $this->pInfixOp(BinaryOp\BooleanOr::class, $node->left, ' || ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_BitwiseAnd(BinaryOp\BitwiseAnd $node) + protected function pExpr_BinaryOp_BitwiseAnd(BinaryOp\BitwiseAnd $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\BitwiseAnd::class, $node->left, ' & ', $node->right); + return $this->pInfixOp(BinaryOp\BitwiseAnd::class, $node->left, ' & ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_BitwiseOr(BinaryOp\BitwiseOr $node) + protected function pExpr_BinaryOp_BitwiseOr(BinaryOp\BitwiseOr $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\BitwiseOr::class, $node->left, ' | ', $node->right); + return $this->pInfixOp(BinaryOp\BitwiseOr::class, $node->left, ' | ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_BitwiseXor(BinaryOp\BitwiseXor $node) + protected function pExpr_BinaryOp_BitwiseXor(BinaryOp\BitwiseXor $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\BitwiseXor::class, $node->left, ' ^ ', $node->right); + return $this->pInfixOp(BinaryOp\BitwiseXor::class, $node->left, ' ^ ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_ShiftLeft(BinaryOp\ShiftLeft $node) + protected function pExpr_BinaryOp_ShiftLeft(BinaryOp\ShiftLeft $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\ShiftLeft::class, $node->left, ' << ', $node->right); + return $this->pInfixOp(BinaryOp\ShiftLeft::class, $node->left, ' << ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_ShiftRight(BinaryOp\ShiftRight $node) + protected function pExpr_BinaryOp_ShiftRight(BinaryOp\ShiftRight $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\ShiftRight::class, $node->left, ' >> ', $node->right); + return $this->pInfixOp(BinaryOp\ShiftRight::class, $node->left, ' >> ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_Pow(BinaryOp\Pow $node) + protected function pExpr_BinaryOp_Pow(BinaryOp\Pow $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\Pow::class, $node->left, ' ** ', $node->right); + return $this->pInfixOp(BinaryOp\Pow::class, $node->left, ' ** ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_LogicalAnd(BinaryOp\LogicalAnd $node) + protected function pExpr_BinaryOp_LogicalAnd(BinaryOp\LogicalAnd $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\LogicalAnd::class, $node->left, ' and ', $node->right); + return $this->pInfixOp(BinaryOp\LogicalAnd::class, $node->left, ' and ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_LogicalOr(BinaryOp\LogicalOr $node) + protected function pExpr_BinaryOp_LogicalOr(BinaryOp\LogicalOr $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\LogicalOr::class, $node->left, ' or ', $node->right); + return $this->pInfixOp(BinaryOp\LogicalOr::class, $node->left, ' or ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_LogicalXor(BinaryOp\LogicalXor $node) + protected function pExpr_BinaryOp_LogicalXor(BinaryOp\LogicalXor $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\LogicalXor::class, $node->left, ' xor ', $node->right); + return $this->pInfixOp(BinaryOp\LogicalXor::class, $node->left, ' xor ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_Equal(BinaryOp\Equal $node) + protected function pExpr_BinaryOp_Equal(BinaryOp\Equal $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\Equal::class, $node->left, ' == ', $node->right); + return $this->pInfixOp(BinaryOp\Equal::class, $node->left, ' == ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_NotEqual(BinaryOp\NotEqual $node) + protected function pExpr_BinaryOp_NotEqual(BinaryOp\NotEqual $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\NotEqual::class, $node->left, ' != ', $node->right); + return $this->pInfixOp(BinaryOp\NotEqual::class, $node->left, ' != ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_Identical(BinaryOp\Identical $node) + protected function pExpr_BinaryOp_Identical(BinaryOp\Identical $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\Identical::class, $node->left, ' === ', $node->right); + return $this->pInfixOp(BinaryOp\Identical::class, $node->left, ' === ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_NotIdentical(BinaryOp\NotIdentical $node) + protected function pExpr_BinaryOp_NotIdentical(BinaryOp\NotIdentical $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\NotIdentical::class, $node->left, ' !== ', $node->right); + return $this->pInfixOp(BinaryOp\NotIdentical::class, $node->left, ' !== ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_Spaceship(BinaryOp\Spaceship $node) + protected function pExpr_BinaryOp_Spaceship(BinaryOp\Spaceship $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\Spaceship::class, $node->left, ' <=> ', $node->right); + return $this->pInfixOp(BinaryOp\Spaceship::class, $node->left, ' <=> ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_Greater(BinaryOp\Greater $node) + protected function pExpr_BinaryOp_Greater(BinaryOp\Greater $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\Greater::class, $node->left, ' > ', $node->right); + return $this->pInfixOp(BinaryOp\Greater::class, $node->left, ' > ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_GreaterOrEqual(BinaryOp\GreaterOrEqual $node) + protected function pExpr_BinaryOp_GreaterOrEqual(BinaryOp\GreaterOrEqual $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\GreaterOrEqual::class, $node->left, ' >= ', $node->right); + return $this->pInfixOp(BinaryOp\GreaterOrEqual::class, $node->left, ' >= ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_Smaller(BinaryOp\Smaller $node) + protected function pExpr_BinaryOp_Smaller(BinaryOp\Smaller $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\Smaller::class, $node->left, ' < ', $node->right); + return $this->pInfixOp(BinaryOp\Smaller::class, $node->left, ' < ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_SmallerOrEqual(BinaryOp\SmallerOrEqual $node) + protected function pExpr_BinaryOp_SmallerOrEqual(BinaryOp\SmallerOrEqual $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\SmallerOrEqual::class, $node->left, ' <= ', $node->right); + return $this->pInfixOp(BinaryOp\SmallerOrEqual::class, $node->left, ' <= ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_BinaryOp_Coalesce(BinaryOp\Coalesce $node) + protected function pExpr_BinaryOp_Coalesce(BinaryOp\Coalesce $node, int $precedence, int $lhsPrecedence) : string { - return $this->pInfixOp(BinaryOp\Coalesce::class, $node->left, ' ?? ', $node->right); + return $this->pInfixOp(BinaryOp\Coalesce::class, $node->left, ' ?? ', $node->right, $precedence, $lhsPrecedence); } - protected function pExpr_Instanceof(Expr\Instanceof_ $node) + protected function pExpr_Instanceof(Expr\Instanceof_ $node, int $precedence, int $lhsPrecedence) : string { - list($precedence, $associativity) = $this->precedenceMap[Expr\Instanceof_::class]; - return $this->pPrec($node->expr, $precedence, $associativity, -1) . ' instanceof ' . $this->pNewVariable($node->class); + return $this->pPostfixOp(Expr\Instanceof_::class, $node->expr, ' instanceof ' . $this->pNewOperand($node->class), $precedence, $lhsPrecedence); } // Unary expressions - protected function pExpr_BooleanNot(Expr\BooleanNot $node) + protected function pExpr_BooleanNot(Expr\BooleanNot $node, int $precedence, int $lhsPrecedence) : string { - return $this->pPrefixOp(Expr\BooleanNot::class, '!', $node->expr); + return $this->pPrefixOp(Expr\BooleanNot::class, '!', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_BitwiseNot(Expr\BitwiseNot $node) + protected function pExpr_BitwiseNot(Expr\BitwiseNot $node, int $precedence, int $lhsPrecedence) : string { - return $this->pPrefixOp(Expr\BitwiseNot::class, '~', $node->expr); + return $this->pPrefixOp(Expr\BitwiseNot::class, '~', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_UnaryMinus(Expr\UnaryMinus $node) + protected function pExpr_UnaryMinus(Expr\UnaryMinus $node, int $precedence, int $lhsPrecedence) : string { - if ($node->expr instanceof Expr\UnaryMinus || $node->expr instanceof Expr\PreDec) { - // Enforce -(-$expr) instead of --$expr - return '-(' . $this->p($node->expr) . ')'; - } - return $this->pPrefixOp(Expr\UnaryMinus::class, '-', $node->expr); + return $this->pPrefixOp(Expr\UnaryMinus::class, '-', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_UnaryPlus(Expr\UnaryPlus $node) + protected function pExpr_UnaryPlus(Expr\UnaryPlus $node, int $precedence, int $lhsPrecedence) : string { - if ($node->expr instanceof Expr\UnaryPlus || $node->expr instanceof Expr\PreInc) { - // Enforce +(+$expr) instead of ++$expr - return '+(' . $this->p($node->expr) . ')'; - } - return $this->pPrefixOp(Expr\UnaryPlus::class, '+', $node->expr); + return $this->pPrefixOp(Expr\UnaryPlus::class, '+', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_PreInc(Expr\PreInc $node) + protected function pExpr_PreInc(Expr\PreInc $node) : string { - return $this->pPrefixOp(Expr\PreInc::class, '++', $node->var); + return '++' . $this->p($node->var); } - protected function pExpr_PreDec(Expr\PreDec $node) + protected function pExpr_PreDec(Expr\PreDec $node) : string { - return $this->pPrefixOp(Expr\PreDec::class, '--', $node->var); + return '--' . $this->p($node->var); } - protected function pExpr_PostInc(Expr\PostInc $node) + protected function pExpr_PostInc(Expr\PostInc $node) : string { - return $this->pPostfixOp(Expr\PostInc::class, $node->var, '++'); + return $this->p($node->var) . '++'; } - protected function pExpr_PostDec(Expr\PostDec $node) + protected function pExpr_PostDec(Expr\PostDec $node) : string { - return $this->pPostfixOp(Expr\PostDec::class, $node->var, '--'); + return $this->p($node->var) . '--'; } - protected function pExpr_ErrorSuppress(Expr\ErrorSuppress $node) + protected function pExpr_ErrorSuppress(Expr\ErrorSuppress $node, int $precedence, int $lhsPrecedence) : string { - return $this->pPrefixOp(Expr\ErrorSuppress::class, '@', $node->expr); + return $this->pPrefixOp(Expr\ErrorSuppress::class, '@', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_YieldFrom(Expr\YieldFrom $node) + protected function pExpr_YieldFrom(Expr\YieldFrom $node, int $precedence, int $lhsPrecedence) : string { - return $this->pPrefixOp(Expr\YieldFrom::class, 'yield from ', $node->expr); + return $this->pPrefixOp(Expr\YieldFrom::class, 'yield from ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_Print(Expr\Print_ $node) + protected function pExpr_Print(Expr\Print_ $node, int $precedence, int $lhsPrecedence) : string { - return $this->pPrefixOp(Expr\Print_::class, 'print ', $node->expr); + return $this->pPrefixOp(Expr\Print_::class, 'print ', $node->expr, $precedence, $lhsPrecedence); } // Casts - protected function pExpr_Cast_Int(Cast\Int_ $node) + protected function pExpr_Cast_Int(Cast\Int_ $node, int $precedence, int $lhsPrecedence) : string { - return $this->pPrefixOp(Cast\Int_::class, '(int) ', $node->expr); + return $this->pPrefixOp(Cast\Int_::class, '(int) ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_Cast_Double(Cast\Double $node) + protected function pExpr_Cast_Double(Cast\Double $node, int $precedence, int $lhsPrecedence) : string { $kind = $node->getAttribute('kind', Cast\Double::KIND_DOUBLE); if ($kind === Cast\Double::KIND_DOUBLE) { $cast = '(double)'; } elseif ($kind === Cast\Double::KIND_FLOAT) { $cast = '(float)'; - } elseif ($kind === Cast\Double::KIND_REAL) { + } else { + \assert($kind === Cast\Double::KIND_REAL); $cast = '(real)'; } - return $this->pPrefixOp(Cast\Double::class, $cast . ' ', $node->expr); + return $this->pPrefixOp(Cast\Double::class, $cast . ' ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_Cast_String(Cast\String_ $node) + protected function pExpr_Cast_String(Cast\String_ $node, int $precedence, int $lhsPrecedence) : string { - return $this->pPrefixOp(Cast\String_::class, '(string) ', $node->expr); + return $this->pPrefixOp(Cast\String_::class, '(string) ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_Cast_Array(Cast\Array_ $node) + protected function pExpr_Cast_Array(Cast\Array_ $node, int $precedence, int $lhsPrecedence) : string { - return $this->pPrefixOp(Cast\Array_::class, '(array) ', $node->expr); + return $this->pPrefixOp(Cast\Array_::class, '(array) ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_Cast_Object(Cast\Object_ $node) + protected function pExpr_Cast_Object(Cast\Object_ $node, int $precedence, int $lhsPrecedence) : string { - return $this->pPrefixOp(Cast\Object_::class, '(object) ', $node->expr); + return $this->pPrefixOp(Cast\Object_::class, '(object) ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_Cast_Bool(Cast\Bool_ $node) + protected function pExpr_Cast_Bool(Cast\Bool_ $node, int $precedence, int $lhsPrecedence) : string { - return $this->pPrefixOp(Cast\Bool_::class, '(bool) ', $node->expr); + return $this->pPrefixOp(Cast\Bool_::class, '(bool) ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_Cast_Unset(Cast\Unset_ $node) + protected function pExpr_Cast_Unset(Cast\Unset_ $node, int $precedence, int $lhsPrecedence) : string { - return $this->pPrefixOp(Cast\Unset_::class, '(unset) ', $node->expr); + return $this->pPrefixOp(Cast\Unset_::class, '(unset) ', $node->expr, $precedence, $lhsPrecedence); } // Function calls and similar constructs - protected function pExpr_FuncCall(Expr\FuncCall $node) + protected function pExpr_FuncCall(Expr\FuncCall $node) : string { return $this->pCallLhs($node->name) . '(' . $this->pMaybeMultiline($node->args) . ')'; } - protected function pExpr_MethodCall(Expr\MethodCall $node) + protected function pExpr_MethodCall(Expr\MethodCall $node) : string { return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name) . '(' . $this->pMaybeMultiline($node->args) . ')'; } - protected function pExpr_NullsafeMethodCall(Expr\NullsafeMethodCall $node) + protected function pExpr_NullsafeMethodCall(Expr\NullsafeMethodCall $node) : string { return $this->pDereferenceLhs($node->var) . '?->' . $this->pObjectProperty($node->name) . '(' . $this->pMaybeMultiline($node->args) . ')'; } - protected function pExpr_StaticCall(Expr\StaticCall $node) + protected function pExpr_StaticCall(Expr\StaticCall $node) : string { - return $this->pDereferenceLhs($node->class) . '::' . ($node->name instanceof Expr ? $node->name instanceof Expr\Variable ? $this->p($node->name) : '{' . $this->p($node->name) . '}' : $node->name) . '(' . $this->pMaybeMultiline($node->args) . ')'; + return $this->pStaticDereferenceLhs($node->class) . '::' . ($node->name instanceof Expr ? $node->name instanceof Expr\Variable ? $this->p($node->name) : '{' . $this->p($node->name) . '}' : $node->name) . '(' . $this->pMaybeMultiline($node->args) . ')'; } - protected function pExpr_Empty(Expr\Empty_ $node) + protected function pExpr_Empty(Expr\Empty_ $node) : string { return 'empty(' . $this->p($node->expr) . ')'; } - protected function pExpr_Isset(Expr\Isset_ $node) + protected function pExpr_Isset(Expr\Isset_ $node) : string { return 'isset(' . $this->pCommaSeparated($node->vars) . ')'; } - protected function pExpr_Eval(Expr\Eval_ $node) + protected function pExpr_Eval(Expr\Eval_ $node) : string { return 'eval(' . $this->p($node->expr) . ')'; } - protected function pExpr_Include(Expr\Include_ $node) + protected function pExpr_Include(Expr\Include_ $node, int $precedence, int $lhsPrecedence) : string { static $map = [Expr\Include_::TYPE_INCLUDE => 'include', Expr\Include_::TYPE_INCLUDE_ONCE => 'include_once', Expr\Include_::TYPE_REQUIRE => 'require', Expr\Include_::TYPE_REQUIRE_ONCE => 'require_once']; - return $map[$node->type] . ' ' . $this->p($node->expr); + return $this->pPrefixOp(Expr\Include_::class, $map[$node->type] . ' ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_List(Expr\List_ $node) + protected function pExpr_List(Expr\List_ $node) : string { - return 'list(' . $this->pCommaSeparated($node->items) . ')'; + $syntax = $node->getAttribute('kind', $this->phpVersion->supportsShortArrayDestructuring() ? Expr\List_::KIND_ARRAY : Expr\List_::KIND_LIST); + if ($syntax === Expr\List_::KIND_ARRAY) { + return '[' . $this->pMaybeMultiline($node->items, \true) . ']'; + } else { + return 'list(' . $this->pMaybeMultiline($node->items, \true) . ')'; + } } // Other - protected function pExpr_Error(Expr\Error $node) + protected function pExpr_Error(Expr\Error $node) : string { throw new \LogicException('Cannot pretty-print AST with Error nodes'); } - protected function pExpr_Variable(Expr\Variable $node) + protected function pExpr_Variable(Expr\Variable $node) : string { if ($node->name instanceof Expr) { return '${' . $this->p($node->name) . '}'; @@ -20355,105 +22038,131 @@ class Standard extends PrettyPrinterAbstract return '$' . $node->name; } } - protected function pExpr_Array(Expr\Array_ $node) + protected function pExpr_Array(Expr\Array_ $node) : string { - $syntax = $node->getAttribute('kind', $this->options['shortArraySyntax'] ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG); + $syntax = $node->getAttribute('kind', $this->shortArraySyntax ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG); if ($syntax === Expr\Array_::KIND_SHORT) { return '[' . $this->pMaybeMultiline($node->items, \true) . ']'; } else { return 'array(' . $this->pMaybeMultiline($node->items, \true) . ')'; } } - protected function pExpr_ArrayItem(Expr\ArrayItem $node) + protected function pKey(?Node $node) : string + { + if ($node === null) { + return ''; + } + // => is not really an operator and does not typically participate in precedence resolution. + // However, there is an exception if yield expressions with keys are involved: + // [yield $a => $b] is interpreted as [(yield $a => $b)], so we need to ensure that + // [(yield $a) => $b] is printed with parentheses. We approximate this by lowering the LHS + // precedence to that of yield (which will also print unnecessary parentheses for rare low + // precedence unary operators like include). + $yieldPrecedence = $this->precedenceMap[Expr\Yield_::class][0]; + return $this->p($node, self::MAX_PRECEDENCE, $yieldPrecedence) . ' => '; + } + protected function pArrayItem(Node\ArrayItem $node) : string { - return (null !== $node->key ? $this->p($node->key) . ' => ' : '') . ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '') . $this->p($node->value); + return $this->pKey($node->key) . ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '') . $this->p($node->value); } - protected function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node) + protected function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node) : string { return $this->pDereferenceLhs($node->var) . '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']'; } - protected function pExpr_ConstFetch(Expr\ConstFetch $node) + protected function pExpr_ConstFetch(Expr\ConstFetch $node) : string { return $this->p($node->name); } - protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node) + protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node) : string { - return $this->pDereferenceLhs($node->class) . '::' . $this->p($node->name); + return $this->pStaticDereferenceLhs($node->class) . '::' . $this->pObjectProperty($node->name); } - protected function pExpr_PropertyFetch(Expr\PropertyFetch $node) + protected function pExpr_PropertyFetch(Expr\PropertyFetch $node) : string { return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name); } - protected function pExpr_NullsafePropertyFetch(Expr\NullsafePropertyFetch $node) + protected function pExpr_NullsafePropertyFetch(Expr\NullsafePropertyFetch $node) : string { return $this->pDereferenceLhs($node->var) . '?->' . $this->pObjectProperty($node->name); } - protected function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node) + protected function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node) : string { - return $this->pDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name); + return $this->pStaticDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name); } - protected function pExpr_ShellExec(Expr\ShellExec $node) + protected function pExpr_ShellExec(Expr\ShellExec $node) : string { return '`' . $this->pEncapsList($node->parts, '`') . '`'; } - protected function pExpr_Closure(Expr\Closure $node) + protected function pExpr_Closure(Expr\Closure $node) : string { - return $this->pAttrGroups($node->attrGroups, \true) . ($node->static ? 'static ' : '') . 'function ' . ($node->byRef ? '&' : '') . '(' . $this->pCommaSeparated($node->params) . ')' . (!empty($node->uses) ? ' use(' . $this->pCommaSeparated($node->uses) . ')' : '') . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '') . ' {' . $this->pStmts($node->stmts) . $this->nl . '}'; + return $this->pAttrGroups($node->attrGroups, \true) . $this->pStatic($node->static) . 'function ' . ($node->byRef ? '&' : '') . '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')' . (!empty($node->uses) ? ' use (' . $this->pCommaSeparated($node->uses) . ')' : '') . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') . ' {' . $this->pStmts($node->stmts) . $this->nl . '}'; } - protected function pExpr_Match(Expr\Match_ $node) + protected function pExpr_Match(Expr\Match_ $node) : string { return 'match (' . $this->p($node->cond) . ') {' . $this->pCommaSeparatedMultiline($node->arms, \true) . $this->nl . '}'; } - protected function pMatchArm(Node\MatchArm $node) + protected function pMatchArm(Node\MatchArm $node) : string { - return ($node->conds ? $this->pCommaSeparated($node->conds) : 'default') . ' => ' . $this->p($node->body); + $result = ''; + if ($node->conds) { + for ($i = 0, $c = \count($node->conds); $i + 1 < $c; $i++) { + $result .= $this->p($node->conds[$i]) . ', '; + } + $result .= $this->pKey($node->conds[$i]); + } else { + $result = 'default => '; + } + return $result . $this->p($node->body); } - protected function pExpr_ArrowFunction(Expr\ArrowFunction $node) + protected function pExpr_ArrowFunction(Expr\ArrowFunction $node, int $precedence, int $lhsPrecedence) : string { - return $this->pAttrGroups($node->attrGroups, \true) . ($node->static ? 'static ' : '') . 'fn' . ($node->byRef ? '&' : '') . '(' . $this->pCommaSeparated($node->params) . ')' . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') . ' => ' . $this->p($node->expr); + return $this->pPrefixOp(Expr\ArrowFunction::class, $this->pAttrGroups($node->attrGroups, \true) . $this->pStatic($node->static) . 'fn' . ($node->byRef ? '&' : '') . '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')' . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') . ' => ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_ClosureUse(Expr\ClosureUse $node) + protected function pClosureUse(Node\ClosureUse $node) : string { return ($node->byRef ? '&' : '') . $this->p($node->var); } - protected function pExpr_New(Expr\New_ $node) + protected function pExpr_New(Expr\New_ $node) : string { if ($node->class instanceof Stmt\Class_) { $args = $node->args ? '(' . $this->pMaybeMultiline($node->args) . ')' : ''; return 'new ' . $this->pClassCommon($node->class, $args); } - return 'new ' . $this->pNewVariable($node->class) . '(' . $this->pMaybeMultiline($node->args) . ')'; + return 'new ' . $this->pNewOperand($node->class) . '(' . $this->pMaybeMultiline($node->args) . ')'; } - protected function pExpr_Clone(Expr\Clone_ $node) + protected function pExpr_Clone(Expr\Clone_ $node, int $precedence, int $lhsPrecedence) : string { - return 'clone ' . $this->p($node->expr); + return $this->pPrefixOp(Expr\Clone_::class, 'clone ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_Ternary(Expr\Ternary $node) + protected function pExpr_Ternary(Expr\Ternary $node, int $precedence, int $lhsPrecedence) : string { // a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator. // this is okay because the part between ? and : never needs parentheses. - return $this->pInfixOp(Expr\Ternary::class, $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else); + return $this->pInfixOp(Expr\Ternary::class, $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else, $precedence, $lhsPrecedence); } - protected function pExpr_Exit(Expr\Exit_ $node) + protected function pExpr_Exit(Expr\Exit_ $node) : string { $kind = $node->getAttribute('kind', Expr\Exit_::KIND_DIE); return ($kind === Expr\Exit_::KIND_EXIT ? 'exit' : 'die') . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : ''); } - protected function pExpr_Throw(Expr\Throw_ $node) + protected function pExpr_Throw(Expr\Throw_ $node, int $precedence, int $lhsPrecedence) : string { - return 'throw ' . $this->p($node->expr); + return $this->pPrefixOp(Expr\Throw_::class, 'throw ', $node->expr, $precedence, $lhsPrecedence); } - protected function pExpr_Yield(Expr\Yield_ $node) + protected function pExpr_Yield(Expr\Yield_ $node, int $precedence, int $lhsPrecedence) : string { if ($node->value === null) { - return 'yield'; + $opPrecedence = $this->precedenceMap[Expr\Yield_::class][0]; + return $opPrecedence >= $lhsPrecedence ? '(yield)' : 'yield'; } else { - // this is a bit ugly, but currently there is no way to detect whether the parentheses are necessary - return '(yield ' . ($node->key !== null ? $this->p($node->key) . ' => ' : '') . $this->p($node->value) . ')'; + if (!$this->phpVersion->supportsYieldWithoutParentheses()) { + return '(yield ' . $this->pKey($node->key) . $this->p($node->value) . ')'; + } + return $this->pPrefixOp(Expr\Yield_::class, 'yield ' . $this->pKey($node->key), $node->value, $precedence, $lhsPrecedence); } } // Declarations - protected function pStmt_Namespace(Stmt\Namespace_ $node) + protected function pStmt_Namespace(Stmt\Namespace_ $node) : string { if ($this->canUseSemicolonNamespaces) { return 'namespace ' . $this->p($node->name) . ';' . $this->nl . $this->pStmts($node->stmts, \false); @@ -20461,215 +22170,221 @@ class Standard extends PrettyPrinterAbstract return 'namespace' . (null !== $node->name ? ' ' . $this->p($node->name) : '') . ' {' . $this->pStmts($node->stmts) . $this->nl . '}'; } } - protected function pStmt_Use(Stmt\Use_ $node) + protected function pStmt_Use(Stmt\Use_ $node) : string { return 'use ' . $this->pUseType($node->type) . $this->pCommaSeparated($node->uses) . ';'; } - protected function pStmt_GroupUse(Stmt\GroupUse $node) + protected function pStmt_GroupUse(Stmt\GroupUse $node) : string { return 'use ' . $this->pUseType($node->type) . $this->pName($node->prefix) . '\\{' . $this->pCommaSeparated($node->uses) . '};'; } - protected function pStmt_UseUse(Stmt\UseUse $node) + protected function pUseItem(Node\UseItem $node) : string { return $this->pUseType($node->type) . $this->p($node->name) . (null !== $node->alias ? ' as ' . $node->alias : ''); } - protected function pUseType($type) + protected function pUseType(int $type) : string { return $type === Stmt\Use_::TYPE_FUNCTION ? 'function ' : ($type === Stmt\Use_::TYPE_CONSTANT ? 'const ' : ''); } - protected function pStmt_Interface(Stmt\Interface_ $node) + protected function pStmt_Interface(Stmt\Interface_ $node) : string { return $this->pAttrGroups($node->attrGroups) . 'interface ' . $node->name . (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; } - protected function pStmt_Enum(Stmt\Enum_ $node) + protected function pStmt_Enum(Stmt\Enum_ $node) : string { - return $this->pAttrGroups($node->attrGroups) . 'enum ' . $node->name . ($node->scalarType ? " : {$node->scalarType}" : '') . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; + return $this->pAttrGroups($node->attrGroups) . 'enum ' . $node->name . ($node->scalarType ? ' : ' . $this->p($node->scalarType) : '') . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; } - protected function pStmt_Class(Stmt\Class_ $node) + protected function pStmt_Class(Stmt\Class_ $node) : string { return $this->pClassCommon($node, ' ' . $node->name); } - protected function pStmt_Trait(Stmt\Trait_ $node) + protected function pStmt_Trait(Stmt\Trait_ $node) : string { return $this->pAttrGroups($node->attrGroups) . 'trait ' . $node->name . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; } - protected function pStmt_EnumCase(Stmt\EnumCase $node) + protected function pStmt_EnumCase(Stmt\EnumCase $node) : string { return $this->pAttrGroups($node->attrGroups) . 'case ' . $node->name . ($node->expr ? ' = ' . $this->p($node->expr) : '') . ';'; } - protected function pStmt_TraitUse(Stmt\TraitUse $node) + protected function pStmt_TraitUse(Stmt\TraitUse $node) : string { return 'use ' . $this->pCommaSeparated($node->traits) . (empty($node->adaptations) ? ';' : ' {' . $this->pStmts($node->adaptations) . $this->nl . '}'); } - protected function pStmt_TraitUseAdaptation_Precedence(Stmt\TraitUseAdaptation\Precedence $node) + protected function pStmt_TraitUseAdaptation_Precedence(Stmt\TraitUseAdaptation\Precedence $node) : string { return $this->p($node->trait) . '::' . $node->method . ' insteadof ' . $this->pCommaSeparated($node->insteadof) . ';'; } - protected function pStmt_TraitUseAdaptation_Alias(Stmt\TraitUseAdaptation\Alias $node) + protected function pStmt_TraitUseAdaptation_Alias(Stmt\TraitUseAdaptation\Alias $node) : string { return (null !== $node->trait ? $this->p($node->trait) . '::' : '') . $node->method . ' as' . (null !== $node->newModifier ? ' ' . \rtrim($this->pModifiers($node->newModifier), ' ') : '') . (null !== $node->newName ? ' ' . $node->newName : '') . ';'; } - protected function pStmt_Property(Stmt\Property $node) + protected function pStmt_Property(Stmt\Property $node) : string { return $this->pAttrGroups($node->attrGroups) . (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags)) . ($node->type ? $this->p($node->type) . ' ' : '') . $this->pCommaSeparated($node->props) . ';'; } - protected function pStmt_PropertyProperty(Stmt\PropertyProperty $node) + protected function pPropertyItem(Node\PropertyItem $node) : string { return '$' . $node->name . (null !== $node->default ? ' = ' . $this->p($node->default) : ''); } - protected function pStmt_ClassMethod(Stmt\ClassMethod $node) + protected function pStmt_ClassMethod(Stmt\ClassMethod $node) : string { - return $this->pAttrGroups($node->attrGroups) . $this->pModifiers($node->flags) . 'function ' . ($node->byRef ? '&' : '') . $node->name . '(' . $this->pMaybeMultiline($node->params) . ')' . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '') . (null !== $node->stmts ? $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}' : ';'); + return $this->pAttrGroups($node->attrGroups) . $this->pModifiers($node->flags) . 'function ' . ($node->byRef ? '&' : '') . $node->name . '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')' . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') . (null !== $node->stmts ? $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}' : ';'); } - protected function pStmt_ClassConst(Stmt\ClassConst $node) + protected function pStmt_ClassConst(Stmt\ClassConst $node) : string { - return $this->pAttrGroups($node->attrGroups) . $this->pModifiers($node->flags) . 'const ' . $this->pCommaSeparated($node->consts) . ';'; + return $this->pAttrGroups($node->attrGroups) . $this->pModifiers($node->flags) . 'const ' . (null !== $node->type ? $this->p($node->type) . ' ' : '') . $this->pCommaSeparated($node->consts) . ';'; } - protected function pStmt_Function(Stmt\Function_ $node) + protected function pStmt_Function(Stmt\Function_ $node) : string { - return $this->pAttrGroups($node->attrGroups) . 'function ' . ($node->byRef ? '&' : '') . $node->name . '(' . $this->pCommaSeparated($node->params) . ')' . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; + return $this->pAttrGroups($node->attrGroups) . 'function ' . ($node->byRef ? '&' : '') . $node->name . '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')' . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; } - protected function pStmt_Const(Stmt\Const_ $node) + protected function pStmt_Const(Stmt\Const_ $node) : string { return 'const ' . $this->pCommaSeparated($node->consts) . ';'; } - protected function pStmt_Declare(Stmt\Declare_ $node) + protected function pStmt_Declare(Stmt\Declare_ $node) : string { return 'declare (' . $this->pCommaSeparated($node->declares) . ')' . (null !== $node->stmts ? ' {' . $this->pStmts($node->stmts) . $this->nl . '}' : ';'); } - protected function pStmt_DeclareDeclare(Stmt\DeclareDeclare $node) + protected function pDeclareItem(Node\DeclareItem $node) : string { return $node->key . '=' . $this->p($node->value); } // Control flow - protected function pStmt_If(Stmt\If_ $node) + protected function pStmt_If(Stmt\If_ $node) : string { return 'if (' . $this->p($node->cond) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}' . ($node->elseifs ? ' ' . $this->pImplode($node->elseifs, ' ') : '') . (null !== $node->else ? ' ' . $this->p($node->else) : ''); } - protected function pStmt_ElseIf(Stmt\ElseIf_ $node) + protected function pStmt_ElseIf(Stmt\ElseIf_ $node) : string { return 'elseif (' . $this->p($node->cond) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}'; } - protected function pStmt_Else(Stmt\Else_ $node) + protected function pStmt_Else(Stmt\Else_ $node) : string { + if (\count($node->stmts) === 1 && $node->stmts[0] instanceof Stmt\If_) { + // Print as "else if" rather than "else { if }" + return 'else ' . $this->p($node->stmts[0]); + } return 'else {' . $this->pStmts($node->stmts) . $this->nl . '}'; } - protected function pStmt_For(Stmt\For_ $node) + protected function pStmt_For(Stmt\For_ $node) : string { return 'for (' . $this->pCommaSeparated($node->init) . ';' . (!empty($node->cond) ? ' ' : '') . $this->pCommaSeparated($node->cond) . ';' . (!empty($node->loop) ? ' ' : '') . $this->pCommaSeparated($node->loop) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}'; } - protected function pStmt_Foreach(Stmt\Foreach_ $node) + protected function pStmt_Foreach(Stmt\Foreach_ $node) : string { return 'foreach (' . $this->p($node->expr) . ' as ' . (null !== $node->keyVar ? $this->p($node->keyVar) . ' => ' : '') . ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}'; } - protected function pStmt_While(Stmt\While_ $node) + protected function pStmt_While(Stmt\While_ $node) : string { return 'while (' . $this->p($node->cond) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}'; } - protected function pStmt_Do(Stmt\Do_ $node) + protected function pStmt_Do(Stmt\Do_ $node) : string { return 'do {' . $this->pStmts($node->stmts) . $this->nl . '} while (' . $this->p($node->cond) . ');'; } - protected function pStmt_Switch(Stmt\Switch_ $node) + protected function pStmt_Switch(Stmt\Switch_ $node) : string { return 'switch (' . $this->p($node->cond) . ') {' . $this->pStmts($node->cases) . $this->nl . '}'; } - protected function pStmt_Case(Stmt\Case_ $node) + protected function pStmt_Case(Stmt\Case_ $node) : string { return (null !== $node->cond ? 'case ' . $this->p($node->cond) : 'default') . ':' . $this->pStmts($node->stmts); } - protected function pStmt_TryCatch(Stmt\TryCatch $node) + protected function pStmt_TryCatch(Stmt\TryCatch $node) : string { return 'try {' . $this->pStmts($node->stmts) . $this->nl . '}' . ($node->catches ? ' ' . $this->pImplode($node->catches, ' ') : '') . ($node->finally !== null ? ' ' . $this->p($node->finally) : ''); } - protected function pStmt_Catch(Stmt\Catch_ $node) + protected function pStmt_Catch(Stmt\Catch_ $node) : string { return 'catch (' . $this->pImplode($node->types, '|') . ($node->var !== null ? ' ' . $this->p($node->var) : '') . ') {' . $this->pStmts($node->stmts) . $this->nl . '}'; } - protected function pStmt_Finally(Stmt\Finally_ $node) + protected function pStmt_Finally(Stmt\Finally_ $node) : string { return 'finally {' . $this->pStmts($node->stmts) . $this->nl . '}'; } - protected function pStmt_Break(Stmt\Break_ $node) + protected function pStmt_Break(Stmt\Break_ $node) : string { return 'break' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';'; } - protected function pStmt_Continue(Stmt\Continue_ $node) + protected function pStmt_Continue(Stmt\Continue_ $node) : string { return 'continue' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';'; } - protected function pStmt_Return(Stmt\Return_ $node) + protected function pStmt_Return(Stmt\Return_ $node) : string { return 'return' . (null !== $node->expr ? ' ' . $this->p($node->expr) : '') . ';'; } - protected function pStmt_Throw(Stmt\Throw_ $node) - { - return 'throw ' . $this->p($node->expr) . ';'; - } - protected function pStmt_Label(Stmt\Label $node) + protected function pStmt_Label(Stmt\Label $node) : string { return $node->name . ':'; } - protected function pStmt_Goto(Stmt\Goto_ $node) + protected function pStmt_Goto(Stmt\Goto_ $node) : string { return 'goto ' . $node->name . ';'; } // Other - protected function pStmt_Expression(Stmt\Expression $node) + protected function pStmt_Expression(Stmt\Expression $node) : string { return $this->p($node->expr) . ';'; } - protected function pStmt_Echo(Stmt\Echo_ $node) + protected function pStmt_Echo(Stmt\Echo_ $node) : string { return 'echo ' . $this->pCommaSeparated($node->exprs) . ';'; } - protected function pStmt_Static(Stmt\Static_ $node) + protected function pStmt_Static(Stmt\Static_ $node) : string { return 'static ' . $this->pCommaSeparated($node->vars) . ';'; } - protected function pStmt_Global(Stmt\Global_ $node) + protected function pStmt_Global(Stmt\Global_ $node) : string { return 'global ' . $this->pCommaSeparated($node->vars) . ';'; } - protected function pStmt_StaticVar(Stmt\StaticVar $node) + protected function pStaticVar(Node\StaticVar $node) : string { return $this->p($node->var) . (null !== $node->default ? ' = ' . $this->p($node->default) : ''); } - protected function pStmt_Unset(Stmt\Unset_ $node) + protected function pStmt_Unset(Stmt\Unset_ $node) : string { return 'unset(' . $this->pCommaSeparated($node->vars) . ');'; } - protected function pStmt_InlineHTML(Stmt\InlineHTML $node) + protected function pStmt_InlineHTML(Stmt\InlineHTML $node) : string { - $newline = $node->getAttribute('hasLeadingNewline', \true) ? "\n" : ''; + $newline = $node->getAttribute('hasLeadingNewline', \true) ? $this->newline : ''; return '?>' . $newline . $node->value . 'remaining; } - protected function pStmt_Nop(Stmt\Nop $node) + protected function pStmt_Nop(Stmt\Nop $node) : string { return ''; } + protected function pStmt_Block(Stmt\Block $node) : string + { + return '{' . $this->pStmts($node->stmts) . $this->nl . '}'; + } // Helpers - protected function pClassCommon(Stmt\Class_ $node, $afterClassToken) + protected function pClassCommon(Stmt\Class_ $node, string $afterClassToken) : string { return $this->pAttrGroups($node->attrGroups, $node->name === null) . $this->pModifiers($node->flags) . 'class' . $afterClassToken . (null !== $node->extends ? ' extends ' . $this->p($node->extends) : '') . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; } - protected function pObjectProperty($node) + protected function pObjectProperty(Node $node) : string { if ($node instanceof Expr) { return '{' . $this->p($node) . '}'; } else { - return $node; + \assert($node instanceof Node\Identifier); + return $node->name; } } - protected function pEncapsList(array $encapsList, $quote) + /** @param (Expr|Node\InterpolatedStringPart)[] $encapsList */ + protected function pEncapsList(array $encapsList, ?string $quote) : string { $return = ''; foreach ($encapsList as $element) { - if ($element instanceof Scalar\EncapsedStringPart) { + if ($element instanceof Node\InterpolatedStringPart) { $return .= $this->escapeString($element->value, $quote); } else { $return .= '{' . $this->p($element) . '}'; @@ -20677,15 +22392,26 @@ class Standard extends PrettyPrinterAbstract } return $return; } - protected function pSingleQuotedString(string $string) + protected function pSingleQuotedString(string $string) : string { - return '\'' . \addcslashes($string, '\'\\') . '\''; + // It is idiomatic to only escape backslashes when necessary, i.e. when followed by ', \ or + // the end of the string ('Foo\Bar' instead of 'Foo\\Bar'). However, we also don't want to + // produce an odd number of backslashes, so '\\\\a' should not get rendered as '\\\a', even + // though that would be legal. + $regex = '/\'|\\\\(?=[\'\\\\]|$)|(?<=\\\\)\\\\/'; + return '\'' . \preg_replace($regex, '\\\\$0', $string) . '\''; } - protected function escapeString($string, $quote) + protected function escapeString(string $string, ?string $quote) : string { if (null === $quote) { // For doc strings, don't escape newlines $escaped = \addcslashes($string, "\t\f\v\$\\"); + // But do escape isolated \r. Combined with the terminating newline, it might get + // interpreted as \r\n and dropped from the string contents. + $escaped = \preg_replace('/\\r(?!\\n)/', '\\r', $escaped); + if ($this->phpVersion->supportsFlexibleHeredoc()) { + $escaped = $this->indentString($escaped); + } } else { $escaped = \addcslashes($string, "\n\r\t\f\v\$" . $quote . "\\"); } @@ -20706,30 +22432,28 @@ class Standard extends PrettyPrinterAbstract | (?<=[\\xF0-\\xF4])[\\x80-\\xBF](?![\\x80-\\xBF]{2}) # Short 4 byte sequence | (?<=[\\xF0-\\xF4][\\x80-\\xBF])[\\x80-\\xBF](?![\\x80-\\xBF]) # Short 4 byte sequence (2) )/x'; - return \preg_replace_callback($regex, function ($matches) { + return \preg_replace_callback($regex, function ($matches) : string { \assert(\strlen($matches[0]) === 1); $hex = \dechex(\ord($matches[0])); return '\\x' . \str_pad($hex, 2, '0', \STR_PAD_LEFT); }, $escaped); } - protected function containsEndLabel($string, $label, $atStart = \true, $atEnd = \true) + protected function containsEndLabel(string $string, string $label, bool $atStart = \true) : bool { - $start = $atStart ? '(?:^|[\\r\\n])' : '[\\r\\n]'; - $end = $atEnd ? '(?:$|[;\\r\\n])' : '[;\\r\\n]'; - return \false !== \strpos($string, $label) && \preg_match('/' . $start . $label . $end . '/', $string); + $start = $atStart ? '(?:^|[\\r\\n])[ \\t]*' : '[\\r\\n][ \\t]*'; + return \false !== \strpos($string, $label) && \preg_match('/' . $start . $label . '(?:$|[^_A-Za-z0-9\\x80-\\xff])/', $string); } - protected function encapsedContainsEndLabel(array $parts, $label) + /** @param (Expr|Node\InterpolatedStringPart)[] $parts */ + protected function encapsedContainsEndLabel(array $parts, string $label) : bool { foreach ($parts as $i => $part) { - $atStart = $i === 0; - $atEnd = $i === \count($parts) - 1; - if ($part instanceof Scalar\EncapsedStringPart && $this->containsEndLabel($part->value, $label, $atStart, $atEnd)) { + if ($part instanceof Node\InterpolatedStringPart && $this->containsEndLabel($this->escapeString($part->value, null), $label, $i === 0)) { return \true; } } return \false; } - protected function pDereferenceLhs(Node $node) + protected function pDereferenceLhs(Node $node) : string { if (!$this->dereferenceLhsRequiresParens($node)) { return $this->p($node); @@ -20737,7 +22461,15 @@ class Standard extends PrettyPrinterAbstract return '(' . $this->p($node) . ')'; } } - protected function pCallLhs(Node $node) + protected function pStaticDereferenceLhs(Node $node) : string + { + if (!$this->staticDereferenceLhsRequiresParens($node)) { + return $this->p($node); + } else { + return '(' . $this->p($node) . ')'; + } + } + protected function pCallLhs(Node $node) : string { if (!$this->callLhsRequiresParens($node)) { return $this->p($node); @@ -20745,16 +22477,18 @@ class Standard extends PrettyPrinterAbstract return '(' . $this->p($node) . ')'; } } - protected function pNewVariable(Node $node) + protected function pNewOperand(Node $node) : string { - // TODO: This is not fully accurate. - return $this->pDereferenceLhs($node); + if (!$this->newOperandRequiresParens($node)) { + return $this->p($node); + } else { + return '(' . $this->p($node) . ')'; + } } /** * @param Node[] $nodes - * @return bool */ - protected function hasNodeWithComments(array $nodes) + protected function hasNodeWithComments(array $nodes) : bool { foreach ($nodes as $node) { if ($node && $node->getComments()) { @@ -20763,7 +22497,8 @@ class Standard extends PrettyPrinterAbstract } return \false; } - protected function pMaybeMultiline(array $nodes, bool $trailingComma = \false) + /** @param Node[] $nodes */ + protected function pMaybeMultiline(array $nodes, bool $trailingComma = \false) : string { if (!$this->hasNodeWithComments($nodes)) { return $this->pCommaSeparated($nodes); @@ -20771,6 +22506,7 @@ class Standard extends PrettyPrinterAbstract return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . $this->nl; } } + /** @param Node\AttributeGroup[] $nodes */ protected function pAttrGroups(array $nodes, bool $inline = \false) : string { $result = ''; @@ -20787,162 +22523,201 @@ declare (strict_types=1); namespace PHPUnit\PhpParser; use PHPUnit\PhpParser\Internal\DiffElem; +use PHPUnit\PhpParser\Internal\Differ; use PHPUnit\PhpParser\Internal\PrintableNewAnonClassNode; use PHPUnit\PhpParser\Internal\TokenStream; +use PHPUnit\PhpParser\Node\AttributeGroup; use PHPUnit\PhpParser\Node\Expr; use PHPUnit\PhpParser\Node\Expr\AssignOp; use PHPUnit\PhpParser\Node\Expr\BinaryOp; use PHPUnit\PhpParser\Node\Expr\Cast; +use PHPUnit\PhpParser\Node\IntersectionType; +use PHPUnit\PhpParser\Node\MatchArm; +use PHPUnit\PhpParser\Node\Param; use PHPUnit\PhpParser\Node\Scalar; use PHPUnit\PhpParser\Node\Stmt; -abstract class PrettyPrinterAbstract +use PHPUnit\PhpParser\Node\UnionType; +abstract class PrettyPrinterAbstract implements PrettyPrinter { - const FIXUP_PREC_LEFT = 0; + protected const FIXUP_PREC_LEFT = 0; // LHS operand affected by precedence - const FIXUP_PREC_RIGHT = 1; + protected const FIXUP_PREC_RIGHT = 1; // RHS operand affected by precedence - const FIXUP_CALL_LHS = 2; + protected const FIXUP_PREC_UNARY = 2; + // Only operand affected by precedence + protected const FIXUP_CALL_LHS = 3; // LHS of call - const FIXUP_DEREF_LHS = 3; + protected const FIXUP_DEREF_LHS = 4; // LHS of dereferencing operation - const FIXUP_BRACED_NAME = 4; + protected const FIXUP_STATIC_DEREF_LHS = 5; + // LHS of static dereferencing operation + protected const FIXUP_BRACED_NAME = 6; // Name operand that may require bracing - const FIXUP_VAR_BRACED_NAME = 5; + protected const FIXUP_VAR_BRACED_NAME = 7; // Name operand that may require ${} bracing - const FIXUP_ENCAPSED = 6; + protected const FIXUP_ENCAPSED = 8; // Encapsed string part - protected $precedenceMap = [ - // [precedence, associativity] - // where for precedence -1 is %left, 0 is %nonassoc and 1 is %right - BinaryOp\Pow::class => [0, 1], - Expr\BitwiseNot::class => [10, 1], - Expr\PreInc::class => [10, 1], - Expr\PreDec::class => [10, 1], - Expr\PostInc::class => [10, -1], - Expr\PostDec::class => [10, -1], - Expr\UnaryPlus::class => [10, 1], - Expr\UnaryMinus::class => [10, 1], - Cast\Int_::class => [10, 1], - Cast\Double::class => [10, 1], - Cast\String_::class => [10, 1], - Cast\Array_::class => [10, 1], - Cast\Object_::class => [10, 1], - Cast\Bool_::class => [10, 1], - Cast\Unset_::class => [10, 1], - Expr\ErrorSuppress::class => [10, 1], - Expr\Instanceof_::class => [20, 0], - Expr\BooleanNot::class => [30, 1], - BinaryOp\Mul::class => [40, -1], - BinaryOp\Div::class => [40, -1], - BinaryOp\Mod::class => [40, -1], - BinaryOp\Plus::class => [50, -1], - BinaryOp\Minus::class => [50, -1], - BinaryOp\Concat::class => [50, -1], - BinaryOp\ShiftLeft::class => [60, -1], - BinaryOp\ShiftRight::class => [60, -1], - BinaryOp\Smaller::class => [70, 0], - BinaryOp\SmallerOrEqual::class => [70, 0], - BinaryOp\Greater::class => [70, 0], - BinaryOp\GreaterOrEqual::class => [70, 0], - BinaryOp\Equal::class => [80, 0], - BinaryOp\NotEqual::class => [80, 0], - BinaryOp\Identical::class => [80, 0], - BinaryOp\NotIdentical::class => [80, 0], - BinaryOp\Spaceship::class => [80, 0], - BinaryOp\BitwiseAnd::class => [90, -1], - BinaryOp\BitwiseXor::class => [100, -1], - BinaryOp\BitwiseOr::class => [110, -1], - BinaryOp\BooleanAnd::class => [120, -1], - BinaryOp\BooleanOr::class => [130, -1], - BinaryOp\Coalesce::class => [140, 1], - Expr\Ternary::class => [150, 0], - // parser uses %left for assignments, but they really behave as %right - Expr\Assign::class => [160, 1], - Expr\AssignRef::class => [160, 1], - AssignOp\Plus::class => [160, 1], - AssignOp\Minus::class => [160, 1], - AssignOp\Mul::class => [160, 1], - AssignOp\Div::class => [160, 1], - AssignOp\Concat::class => [160, 1], - AssignOp\Mod::class => [160, 1], - AssignOp\BitwiseAnd::class => [160, 1], - AssignOp\BitwiseOr::class => [160, 1], - AssignOp\BitwiseXor::class => [160, 1], - AssignOp\ShiftLeft::class => [160, 1], - AssignOp\ShiftRight::class => [160, 1], - AssignOp\Pow::class => [160, 1], - AssignOp\Coalesce::class => [160, 1], - Expr\YieldFrom::class => [165, 1], - Expr\Print_::class => [168, 1], - BinaryOp\LogicalAnd::class => [170, -1], - BinaryOp\LogicalXor::class => [180, -1], - BinaryOp\LogicalOr::class => [190, -1], - Expr\Include_::class => [200, -1], + protected const FIXUP_NEW = 9; + // New/instanceof operand + protected const MAX_PRECEDENCE = 1000; + /** @var array */ + protected array $precedenceMap = [ + // [precedence, precedenceLHS, precedenceRHS] + // Where the latter two are the precedences to use for the LHS and RHS of a binary operator, + // where 1 is added to one of the sides depending on associativity. This information is not + // used for unary operators and set to -1. + Expr\Clone_::class => [-10, 0, 1], + BinaryOp\Pow::class => [0, 0, 1], + Expr\BitwiseNot::class => [10, -1, -1], + Expr\UnaryPlus::class => [10, -1, -1], + Expr\UnaryMinus::class => [10, -1, -1], + Cast\Int_::class => [10, -1, -1], + Cast\Double::class => [10, -1, -1], + Cast\String_::class => [10, -1, -1], + Cast\Array_::class => [10, -1, -1], + Cast\Object_::class => [10, -1, -1], + Cast\Bool_::class => [10, -1, -1], + Cast\Unset_::class => [10, -1, -1], + Expr\ErrorSuppress::class => [10, -1, -1], + Expr\Instanceof_::class => [20, -1, -1], + Expr\BooleanNot::class => [30, -1, -1], + BinaryOp\Mul::class => [40, 41, 40], + BinaryOp\Div::class => [40, 41, 40], + BinaryOp\Mod::class => [40, 41, 40], + BinaryOp\Plus::class => [50, 51, 50], + BinaryOp\Minus::class => [50, 51, 50], + BinaryOp\Concat::class => [50, 51, 50], + BinaryOp\ShiftLeft::class => [60, 61, 60], + BinaryOp\ShiftRight::class => [60, 61, 60], + BinaryOp\Smaller::class => [70, 70, 70], + BinaryOp\SmallerOrEqual::class => [70, 70, 70], + BinaryOp\Greater::class => [70, 70, 70], + BinaryOp\GreaterOrEqual::class => [70, 70, 70], + BinaryOp\Equal::class => [80, 80, 80], + BinaryOp\NotEqual::class => [80, 80, 80], + BinaryOp\Identical::class => [80, 80, 80], + BinaryOp\NotIdentical::class => [80, 80, 80], + BinaryOp\Spaceship::class => [80, 80, 80], + BinaryOp\BitwiseAnd::class => [90, 91, 90], + BinaryOp\BitwiseXor::class => [100, 101, 100], + BinaryOp\BitwiseOr::class => [110, 111, 110], + BinaryOp\BooleanAnd::class => [120, 121, 120], + BinaryOp\BooleanOr::class => [130, 131, 130], + BinaryOp\Coalesce::class => [140, 140, 141], + Expr\Ternary::class => [150, -1, -1], + Expr\Assign::class => [160, -1, -1], + Expr\AssignRef::class => [160, -1, -1], + AssignOp\Plus::class => [160, -1, -1], + AssignOp\Minus::class => [160, -1, -1], + AssignOp\Mul::class => [160, -1, -1], + AssignOp\Div::class => [160, -1, -1], + AssignOp\Concat::class => [160, -1, -1], + AssignOp\Mod::class => [160, -1, -1], + AssignOp\BitwiseAnd::class => [160, -1, -1], + AssignOp\BitwiseOr::class => [160, -1, -1], + AssignOp\BitwiseXor::class => [160, -1, -1], + AssignOp\ShiftLeft::class => [160, -1, -1], + AssignOp\ShiftRight::class => [160, -1, -1], + AssignOp\Pow::class => [160, -1, -1], + AssignOp\Coalesce::class => [160, -1, -1], + Expr\YieldFrom::class => [170, -1, -1], + Expr\Yield_::class => [175, -1, -1], + Expr\Print_::class => [180, -1, -1], + BinaryOp\LogicalAnd::class => [190, 191, 190], + BinaryOp\LogicalXor::class => [200, 201, 200], + BinaryOp\LogicalOr::class => [210, 211, 210], + Expr\Include_::class => [220, -1, -1], + Expr\ArrowFunction::class => [230, -1, -1], + Expr\Throw_::class => [240, -1, -1], ]; /** @var int Current indentation level. */ - protected $indentLevel; + protected int $indentLevel; + /** @var string Newline style. Does not include current indentation. */ + protected string $newline; /** @var string Newline including current indentation. */ - protected $nl; - /** @var string Token placed at end of doc string to ensure it is followed by a newline. */ - protected $docStringEndToken; + protected string $nl; + /** @var string|null Token placed at end of doc string to ensure it is followed by a newline. + * Null if flexible doc strings are used. */ + protected ?string $docStringEndToken; /** @var bool Whether semicolon namespaces can be used (i.e. no global namespace is used) */ - protected $canUseSemicolonNamespaces; - /** @var array Pretty printer options */ - protected $options; - /** @var TokenStream Original tokens for use in format-preserving pretty print */ - protected $origTokens; - /** @var Internal\Differ Differ for node lists */ - protected $nodeListDiffer; - /** @var bool[] Map determining whether a certain character is a label character */ - protected $labelCharMap; + protected bool $canUseSemicolonNamespaces; + /** @var bool Whether to use short array syntax if the node specifies no preference */ + protected bool $shortArraySyntax; + /** @var PhpVersion PHP version to target */ + protected PhpVersion $phpVersion; + /** @var TokenStream|null Original tokens for use in format-preserving pretty print */ + protected ?TokenStream $origTokens; + /** @var Internal\Differ Differ for node lists */ + protected Differ $nodeListDiffer; + /** @var array Map determining whether a certain character is a label character */ + protected array $labelCharMap; + /** + * @var array> Map from token classes and subnode names to FIXUP_* constants. + * This is used during format-preserving prints to place additional parens/braces if necessary. + */ + protected array $fixupMap; /** - * @var int[][] Map from token classes and subnode names to FIXUP_* constants. This is used - * during format-preserving prints to place additional parens/braces if necessary. + * @var array Map from "{$node->getType()}->{$subNode}" + * to ['left' => $l, 'right' => $r], where $l and $r specify the token type that needs to be stripped + * when removing this node. */ - protected $fixupMap; + protected array $removalMap; /** - * @var int[][] Map from "{$node->getType()}->{$subNode}" to ['left' => $l, 'right' => $r], - * where $l and $r specify the token type that needs to be stripped when removing - * this node. + * @var array Map from + * "{$node->getType()}->{$subNode}" to [$find, $beforeToken, $extraLeft, $extraRight]. + * $find is an optional token after which the insertion occurs. $extraLeft/Right + * are optionally added before/after the main insertions. */ - protected $removalMap; + protected array $insertionMap; /** - * @var mixed[] Map from "{$node->getType()}->{$subNode}" to [$find, $beforeToken, $extraLeft, $extraRight]. - * $find is an optional token after which the insertion occurs. $extraLeft/Right - * are optionally added before/after the main insertions. + * @var array Map From "{$class}->{$subNode}" to string that should be inserted + * between elements of this list subnode. */ - protected $insertionMap; + protected array $listInsertionMap; /** - * @var string[] Map From "{$node->getType()}->{$subNode}" to string that should be inserted - * between elements of this list subnode. + * @var array */ - protected $listInsertionMap; - protected $emptyListInsertionMap; - /** @var int[] Map from "{$node->getType()}->{$subNode}" to token before which the modifiers - * should be reprinted. */ - protected $modifierChangeMap; + protected array $emptyListInsertionMap; + /** @var array Map from "{$class}->{$subNode}" to [$printFn, $token] + * where $printFn is the function to print the modifiers and $token is the token before which + * the modifiers should be reprinted. */ + protected array $modifierChangeMap; /** * Creates a pretty printer instance using the given options. * * Supported options: - * * bool $shortArraySyntax = false: Whether to use [] instead of array() as the default array - * syntax, if the node does not specify a format. - * - * @param array $options Dictionary of formatting options + * * PhpVersion $phpVersion: The PHP version to target (default to PHP 7.4). This option + * controls compatibility of the generated code with older PHP + * versions in cases where a simple stylistic choice exists (e.g. + * array() vs []). It is safe to pretty-print an AST for a newer + * PHP version while specifying an older target (but the result will + * of course not be compatible with the older version in that case). + * * string $newline: The newline style to use. Should be "\n" (default) or "\r\n". + * * bool $shortArraySyntax: Whether to use [] instead of array() as the default array + * syntax, if the node does not specify a format. Defaults to whether + * the phpVersion support short array syntax. + * + * @param array{ + * phpVersion?: PhpVersion, newline?: string, shortArraySyntax?: bool + * } $options Dictionary of formatting options */ public function __construct(array $options = []) { - $this->docStringEndToken = '_DOC_STRING_END_' . \mt_rand(); - $defaultOptions = ['shortArraySyntax' => \false]; - $this->options = $options + $defaultOptions; + $this->phpVersion = $options['phpVersion'] ?? PhpVersion::fromComponents(7, 4); + $this->newline = $options['newline'] ?? "\n"; + if ($this->newline !== "\n" && $this->newline != "\r\n") { + throw new \LogicException('Option "newline" must be one of "\\n" or "\\r\\n"'); + } + $this->shortArraySyntax = $options['shortArraySyntax'] ?? $this->phpVersion->supportsShortArraySyntax(); + $this->docStringEndToken = $this->phpVersion->supportsFlexibleHeredoc() ? null : '_DOC_STRING_END_' . \mt_rand(); } /** * Reset pretty printing state. */ - protected function resetState() + protected function resetState() : void { $this->indentLevel = 0; - $this->nl = "\n"; + $this->nl = $this->newline; $this->origTokens = null; } /** @@ -20950,15 +22725,15 @@ abstract class PrettyPrinterAbstract * * @param int $level Level in number of spaces */ - protected function setIndentLevel(int $level) + protected function setIndentLevel(int $level) : void { $this->indentLevel = $level; - $this->nl = "\n" . \str_repeat(' ', $level); + $this->nl = $this->newline . \str_repeat(' ', $level); } /** * Increase indentation level. */ - protected function indent() + protected function indent() : void { $this->indentLevel += 4; $this->nl .= ' '; @@ -20966,11 +22741,11 @@ abstract class PrettyPrinterAbstract /** * Decrease indentation level. */ - protected function outdent() + protected function outdent() : void { \assert($this->indentLevel >= 4); $this->indentLevel -= 4; - $this->nl = "\n" . \str_repeat(' ', $this->indentLevel); + $this->nl = $this->newline . \str_repeat(' ', $this->indentLevel); } /** * Pretty prints an array of statements. @@ -21007,11 +22782,11 @@ abstract class PrettyPrinterAbstract public function prettyPrintFile(array $stmts) : string { if (!$stmts) { - return "newline . $this->newline; } - $p = "prettyPrint($stmts); + $p = "newline . $this->newline . $this->prettyPrint($stmts); if ($stmts[0] instanceof Stmt\InlineHTML) { - $p = \preg_replace('/^<\\?php\\s+\\?>\\n?/', '', $p); + $p = \preg_replace('/^<\\?php\\s+\\?>\\r?\\n?/', '', $p); } if ($stmts[\count($stmts) - 1] instanceof Stmt\InlineHTML) { $p = \preg_replace('/<\\?php$/', '', \rtrim($p)); @@ -21023,7 +22798,7 @@ abstract class PrettyPrinterAbstract * * @param Node[] $nodes Array of nodes */ - protected function preprocessNodes(array $nodes) + protected function preprocessNodes(array $nodes) : void { /* We can use semicolon-namespaces unless there is a global namespace declaration */ $this->canUseSemicolonNamespaces = \true; @@ -21035,23 +22810,22 @@ abstract class PrettyPrinterAbstract } } /** - * Handles (and removes) no-indent and doc-string-end tokens. - * - * @param string $str - * @return string + * Handles (and removes) doc-string-end tokens. */ protected function handleMagicTokens(string $str) : string { - // Replace doc-string-end tokens with nothing or a newline - $str = \str_replace($this->docStringEndToken . ";\n", ";\n", $str); - $str = \str_replace($this->docStringEndToken, "\n", $str); + if ($this->docStringEndToken !== null) { + // Replace doc-string-end tokens with nothing or a newline + $str = \str_replace($this->docStringEndToken . ';' . $this->newline, ';' . $this->newline, $str); + $str = \str_replace($this->docStringEndToken, $this->newline, $str); + } return $str; } /** * Pretty prints an array of nodes (statements) and indents them optionally. * - * @param Node[] $nodes Array of nodes - * @param bool $indent Whether to indent the printed nodes + * @param Node[] $nodes Array of nodes + * @param bool $indent Whether to indent the printed nodes * * @return string Pretty printed statements */ @@ -21079,76 +22853,88 @@ abstract class PrettyPrinterAbstract /** * Pretty-print an infix operation while taking precedence into account. * - * @param string $class Node class of operator - * @param Node $leftNode Left-hand side node + * @param string $class Node class of operator + * @param Node $leftNode Left-hand side node * @param string $operatorString String representation of the operator - * @param Node $rightNode Right-hand side node + * @param Node $rightNode Right-hand side node + * @param int $precedence Precedence of parent operator + * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator * * @return string Pretty printed infix operation */ - protected function pInfixOp(string $class, Node $leftNode, string $operatorString, Node $rightNode) : string + protected function pInfixOp(string $class, Node $leftNode, string $operatorString, Node $rightNode, int $precedence, int $lhsPrecedence) : string { - list($precedence, $associativity) = $this->precedenceMap[$class]; - return $this->pPrec($leftNode, $precedence, $associativity, -1) . $operatorString . $this->pPrec($rightNode, $precedence, $associativity, 1); + list($opPrecedence, $newPrecedenceLHS, $newPrecedenceRHS) = $this->precedenceMap[$class]; + $prefix = ''; + $suffix = ''; + if ($opPrecedence >= $precedence) { + $prefix = '('; + $suffix = ')'; + $lhsPrecedence = self::MAX_PRECEDENCE; + } + return $prefix . $this->p($leftNode, $newPrecedenceLHS, $newPrecedenceLHS) . $operatorString . $this->p($rightNode, $newPrecedenceRHS, $lhsPrecedence) . $suffix; } /** * Pretty-print a prefix operation while taking precedence into account. * - * @param string $class Node class of operator + * @param string $class Node class of operator * @param string $operatorString String representation of the operator - * @param Node $node Node + * @param Node $node Node + * @param int $precedence Precedence of parent operator + * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator * * @return string Pretty printed prefix operation */ - protected function pPrefixOp(string $class, string $operatorString, Node $node) : string + protected function pPrefixOp(string $class, string $operatorString, Node $node, int $precedence, int $lhsPrecedence) : string { - list($precedence, $associativity) = $this->precedenceMap[$class]; - return $operatorString . $this->pPrec($node, $precedence, $associativity, 1); + $opPrecedence = $this->precedenceMap[$class][0]; + $prefix = ''; + $suffix = ''; + if ($opPrecedence >= $lhsPrecedence) { + $prefix = '('; + $suffix = ')'; + $lhsPrecedence = self::MAX_PRECEDENCE; + } + $printedArg = $this->p($node, $opPrecedence, $lhsPrecedence); + if ($operatorString === '+' && $printedArg[0] === '+' || $operatorString === '-' && $printedArg[0] === '-') { + // Avoid printing +(+$a) as ++$a and similar. + $printedArg = '(' . $printedArg . ')'; + } + return $prefix . $operatorString . $printedArg . $suffix; } /** * Pretty-print a postfix operation while taking precedence into account. * - * @param string $class Node class of operator + * @param string $class Node class of operator * @param string $operatorString String representation of the operator - * @param Node $node Node + * @param Node $node Node + * @param int $precedence Precedence of parent operator + * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator * * @return string Pretty printed postfix operation */ - protected function pPostfixOp(string $class, Node $node, string $operatorString) : string - { - list($precedence, $associativity) = $this->precedenceMap[$class]; - return $this->pPrec($node, $precedence, $associativity, -1) . $operatorString; - } - /** - * Prints an expression node with the least amount of parentheses necessary to preserve the meaning. - * - * @param Node $node Node to pretty print - * @param int $parentPrecedence Precedence of the parent operator - * @param int $parentAssociativity Associativity of parent operator - * (-1 is left, 0 is nonassoc, 1 is right) - * @param int $childPosition Position of the node relative to the operator - * (-1 is left, 1 is right) - * - * @return string The pretty printed node - */ - protected function pPrec(Node $node, int $parentPrecedence, int $parentAssociativity, int $childPosition) : string + protected function pPostfixOp(string $class, Node $node, string $operatorString, int $precedence, int $lhsPrecedence) : string { - $class = \get_class($node); - if (isset($this->precedenceMap[$class])) { - $childPrecedence = $this->precedenceMap[$class][0]; - if ($childPrecedence > $parentPrecedence || $parentPrecedence === $childPrecedence && $parentAssociativity !== $childPosition) { - return '(' . $this->p($node) . ')'; - } + $opPrecedence = $this->precedenceMap[$class][0]; + $prefix = ''; + $suffix = ''; + if ($opPrecedence >= $precedence) { + $prefix = '('; + $suffix = ')'; + $lhsPrecedence = self::MAX_PRECEDENCE; + } + if ($opPrecedence < $lhsPrecedence) { + $lhsPrecedence = $opPrecedence; } - return $this->p($node); + return $prefix . $this->p($node, $opPrecedence, $lhsPrecedence) . $operatorString . $suffix; } /** * Pretty prints an array of nodes and implodes the printed values. * * @param Node[] $nodes Array of Nodes to be printed - * @param string $glue Character to implode with + * @param string $glue Character to implode with * - * @return string Imploded pretty printed nodes + * @return string Imploded pretty printed nodes> $pre */ protected function pImplode(array $nodes, string $glue = '') : string { @@ -21178,8 +22964,8 @@ abstract class PrettyPrinterAbstract * * The result includes a leading newline and one level of indentation (same as pStmts). * - * @param Node[] $nodes Array of Nodes to be printed - * @param bool $trailingComma Whether to use a trailing comma + * @param Node[] $nodes Array of Nodes to be printed + * @param bool $trailingComma Whether to use a trailing comma * * @return string Comma separated pretty printed nodes in multiline style */ @@ -21231,11 +23017,9 @@ abstract class PrettyPrinterAbstract * * The CloningVisitor must be run on the AST prior to modification. * * The original tokens must be provided, using the getTokens() method on the lexer. * - * @param Node[] $stmts Modified AST with links to original AST - * @param Node[] $origStmts Original AST with token offset information - * @param array $origTokens Tokens of the original code - * - * @return string + * @param Node[] $stmts Modified AST with links to original AST + * @param Node[] $origStmts Original AST with token offset information + * @param Token[] $origTokens Tokens of the original code */ public function printFormatPreserving(array $stmts, array $origStmts, array $origTokens) : string { @@ -21253,17 +23037,17 @@ abstract class PrettyPrinterAbstract $pos = 0; $result = $this->pArray($stmts, $origStmts, $pos, 0, 'File', 'stmts', null); if (null !== $result) { - $result .= $this->origTokens->getTokenCode($pos, \count($origTokens), 0); + $result .= $this->origTokens->getTokenCode($pos, \count($origTokens) - 1, 0); } else { // Fallback // TODO Add pStmts($stmts, \false); + $result = "newline . $this->pStmts($stmts, \false); } - return \ltrim($this->handleMagicTokens($result)); + return $this->handleMagicTokens($result); } - protected function pFallback(Node $node) + protected function pFallback(Node $node, int $precedence, int $lhsPrecedence) : string { - return $this->{'p' . $node->getType()}($node); + return $this->{'p' . $node->getType()}($node, $precedence, $lhsPrecedence); } /** * Pretty prints a node. @@ -21271,20 +23055,22 @@ abstract class PrettyPrinterAbstract * This method also handles formatting preservation for nodes. * * @param Node $node Node to be pretty printed + * @param int $precedence Precedence of parent operator + * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator * @param bool $parentFormatPreserved Whether parent node has preserved formatting * * @return string Pretty printed node */ - protected function p(Node $node, $parentFormatPreserved = \false) : string + protected function p(Node $node, int $precedence = self::MAX_PRECEDENCE, int $lhsPrecedence = self::MAX_PRECEDENCE, bool $parentFormatPreserved = \false) : string { // No orig tokens means this is a normal pretty print without preservation of formatting if (!$this->origTokens) { - return $this->{'p' . $node->getType()}($node); + return $this->{'p' . $node->getType()}($node, $precedence, $lhsPrecedence); } - /** @var Node $origNode */ + /** @var Node|null $origNode */ $origNode = $node->getAttribute('origNode'); if (null === $origNode) { - return $this->pFallback($node); + return $this->pFallback($node, $precedence, $lhsPrecedence); } $class = \get_class($node); \assert($class === \get_class($origNode)); @@ -21294,14 +23080,16 @@ abstract class PrettyPrinterAbstract $fallbackNode = $node; if ($node instanceof Expr\New_ && $node->class instanceof Stmt\Class_) { // Normalize node structure of anonymous classes + \assert($origNode instanceof Expr\New_); $node = PrintableNewAnonClassNode::fromNewNode($node); $origNode = PrintableNewAnonClassNode::fromNewNode($origNode); + $class = PrintableNewAnonClassNode::class; } // InlineHTML node does not contain closing and opening PHP tags. If the parent formatting // is not preserved, then we need to use the fallback code to make sure the tags are // printed. if ($node instanceof Stmt\InlineHTML && !$parentFormatPreserved) { - return $this->pFallback($fallbackNode); + return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence); } $indentAdjustment = $this->indentLevel - $this->origTokens->getIndentationBefore($startPos); $type = $node->getType(); @@ -21318,28 +23106,22 @@ abstract class PrettyPrinterAbstract } if (\is_array($subNode) && \is_array($origSubNode)) { // Array subnode changed, we might be able to reconstruct it - $listResult = $this->pArray($subNode, $origSubNode, $pos, $indentAdjustment, $type, $subNodeName, $fixupInfo[$subNodeName] ?? null); + $listResult = $this->pArray($subNode, $origSubNode, $pos, $indentAdjustment, $class, $subNodeName, $fixupInfo[$subNodeName] ?? null); if (null === $listResult) { - return $this->pFallback($fallbackNode); + return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence); } $result .= $listResult; continue; } - if (\is_int($subNode) && \is_int($origSubNode)) { - // Check if this is a modifier change - $key = $type . '->' . $subNodeName; - if (!isset($this->modifierChangeMap[$key])) { - return $this->pFallback($fallbackNode); - } - $findToken = $this->modifierChangeMap[$key]; - $result .= $this->pModifiers($subNode); - $pos = $this->origTokens->findRight($pos, $findToken); - continue; + // Check if this is a modifier change + $key = $class . '->' . $subNodeName; + if (!isset($this->modifierChangeMap[$key])) { + return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence); } - // If a non-node, non-array subnode changed, we don't be able to do a partial - // reconstructions, as we don't have enough offset information. Pretty print the - // whole node instead. - return $this->pFallback($fallbackNode); + [$printFn, $findToken] = $this->modifierChangeMap[$key]; + $result .= $this->{$printFn}($subNode); + $pos = $this->origTokens->findRight($pos, $findToken); + continue; } $extraLeft = ''; $extraRight = ''; @@ -21355,7 +23137,7 @@ abstract class PrettyPrinterAbstract // A node has been inserted, check if we have insertion information for it $key = $type . '->' . $subNodeName; if (!isset($this->insertionMap[$key])) { - return $this->pFallback($fallbackNode); + return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence); } list($findToken, $beforeToken, $extraLeft, $extraRight) = $this->insertionMap[$key]; if (null !== $findToken) { @@ -21373,7 +23155,7 @@ abstract class PrettyPrinterAbstract // A node has been removed, check if we have removal information for it $key = $type . '->' . $subNodeName; if (!isset($this->removalMap[$key])) { - return $this->pFallback($fallbackNode); + return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence); } // Adjust positions to account for additional tokens that must be skipped $removalInfo = $this->removalMap[$key]; @@ -21396,7 +23178,7 @@ abstract class PrettyPrinterAbstract $fixup = $fixupInfo[$subNodeName]; $res = $this->pFixup($fixup, $subNode, $class, $subStartPos, $subEndPos); } else { - $res = $this->p($subNode, \true); + $res = $this->p($subNode, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, \true); } $this->safeAppend($result, $res); $this->setIndentLevel($origIndentLevel); @@ -21410,20 +23192,20 @@ abstract class PrettyPrinterAbstract /** * Perform a format-preserving pretty print of an array. * - * @param array $nodes New nodes - * @param array $origNodes Original nodes - * @param int $pos Current token position (updated by reference) - * @param int $indentAdjustment Adjustment for indentation - * @param string $parentNodeType Type of the containing node. - * @param string $subNodeName Name of array subnode. - * @param null|int $fixup Fixup information for array item nodes + * @param Node[] $nodes New nodes + * @param Node[] $origNodes Original nodes + * @param int $pos Current token position (updated by reference) + * @param int $indentAdjustment Adjustment for indentation + * @param string $parentNodeClass Class of the containing node. + * @param string $subNodeName Name of array subnode. + * @param null|int $fixup Fixup information for array item nodes * * @return null|string Result of pretty print or null if cannot preserve formatting */ - protected function pArray(array $nodes, array $origNodes, int &$pos, int $indentAdjustment, string $parentNodeType, string $subNodeName, $fixup) + protected function pArray(array $nodes, array $origNodes, int &$pos, int $indentAdjustment, string $parentNodeClass, string $subNodeName, ?int $fixup) : ?string { $diff = $this->nodeListDiffer->diffWithReplacements($origNodes, $nodes); - $mapKey = $parentNodeType . '->' . $subNodeName; + $mapKey = $parentNodeClass . '->' . $subNodeName; $insertStr = $this->listInsertionMap[$mapKey] ?? null; $isStmtList = $subNodeName === 'stmts'; $beforeFirstKeepOrReplace = \true; @@ -21450,9 +23232,9 @@ abstract class PrettyPrinterAbstract $result = ''; foreach ($diff as $i => $diffElem) { $diffType = $diffElem->type; - /** @var Node|null $arrItem */ + /** @var Node|string|null $arrItem */ $arrItem = $diffElem->new; - /** @var Node|null $origArrItem */ + /** @var Node|string|null $origArrItem */ $origArrItem = $diffElem->old; if ($diffType === DiffElem::TYPE_KEEP || $diffType === DiffElem::TYPE_REPLACE) { $beforeFirstKeepOrReplace = \false; @@ -21483,8 +23265,8 @@ abstract class PrettyPrinterAbstract $commentStartPos = $itemStartPos; } if ($skipRemovedNode) { - if ($isStmtList && ($this->origTokens->haveBracesInRange($pos, $itemStartPos) || $this->origTokens->haveTagInRange($pos, $itemStartPos))) { - // We'd remove the brace of a code block. + if ($isStmtList && $this->origTokens->haveTagInRange($pos, $itemStartPos)) { + // We'd remove an opening/closing PHP tag. // TODO: Preserve formatting. $this->setIndentLevel($origIndentLevel); return null; @@ -21501,7 +23283,7 @@ abstract class PrettyPrinterAbstract $result .= $this->pComments($delayedAddComments) . $this->nl; } } - $this->safeAppend($result, $this->p($delayedAddNode, \true)); + $this->safeAppend($result, $this->p($delayedAddNode, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, \true)); if ($insertNewline) { $result .= $insertStr . $this->nl; } else { @@ -21524,9 +23306,14 @@ abstract class PrettyPrinterAbstract // We don't have insertion information for this list type return null; } + if (!$arrItem instanceof Node) { + // We only support list insertion of nodes. + return null; + } // We go multiline if the original code was multiline, // or if it's an array item with a comment above it. - if ($insertStr === ', ' && ($this->isMultiline($origNodes) || $arrItem->getComments())) { + // Match always uses multiline formatting. + if ($insertStr === ', ' && ($this->isMultiline($origNodes) || $arrItem->getComments() || $parentNodeClass === Expr\Match_::class)) { $insertStr = ','; $insertNewline = \true; } @@ -21567,8 +23354,8 @@ abstract class PrettyPrinterAbstract $result .= $this->origTokens->getTokenCode($pos, $itemStartPos, $indentAdjustment); $skipRemovedNode = \true; } else { - if ($isStmtList && ($this->origTokens->haveBracesInRange($pos, $itemStartPos) || $this->origTokens->haveTagInRange($pos, $itemStartPos))) { - // We'd remove the brace of a code block. + if ($isStmtList && $this->origTokens->haveTagInRange($pos, $itemStartPos)) { + // We'd remove an opening/closing PHP tag. // TODO: Preserve formatting. return null; } @@ -21581,7 +23368,7 @@ abstract class PrettyPrinterAbstract if (null !== $fixup && $arrItem->getAttribute('origNode') !== $origArrItem) { $res = $this->pFixup($fixup, $arrItem, null, $itemStartPos, $itemEndPos); } else { - $res = $this->p($arrItem, \true); + $res = $this->p($arrItem, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, \true); } $this->safeAppend($result, $res); $this->setIndentLevel($origIndentLevel); @@ -21610,7 +23397,7 @@ abstract class PrettyPrinterAbstract $result .= $this->nl; } } - $result .= $this->p($delayedAddNode, \true); + $result .= $this->p($delayedAddNode, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, \true); $first = \false; } $result .= $extraRight === "\n" ? $this->nl : $extraRight; @@ -21624,22 +23411,34 @@ abstract class PrettyPrinterAbstract * are required to preserve program semantics in a certain context (e.g. to maintain precedence * or because only certain expressions are allowed in certain places). * - * @param int $fixup Fixup type - * @param Node $subNode Subnode to print + * @param int $fixup Fixup type + * @param Node $subNode Subnode to print * @param string|null $parentClass Class of parent node - * @param int $subStartPos Original start pos of subnode - * @param int $subEndPos Original end pos of subnode + * @param int $subStartPos Original start pos of subnode + * @param int $subEndPos Original end pos of subnode * * @return string Result of fixed-up print of subnode */ - protected function pFixup(int $fixup, Node $subNode, $parentClass, int $subStartPos, int $subEndPos) : string + protected function pFixup(int $fixup, Node $subNode, ?string $parentClass, int $subStartPos, int $subEndPos) : string { switch ($fixup) { case self::FIXUP_PREC_LEFT: + // We use a conservative approximation where lhsPrecedence == precedence. + if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) { + $precedence = $this->precedenceMap[$parentClass][1]; + return $this->p($subNode, $precedence, $precedence); + } + break; case self::FIXUP_PREC_RIGHT: if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) { - list($precedence, $associativity) = $this->precedenceMap[$parentClass]; - return $this->pPrec($subNode, $precedence, $associativity, $fixup === self::FIXUP_PREC_LEFT ? -1 : 1); + $precedence = $this->precedenceMap[$parentClass][2]; + return $this->p($subNode, $precedence, $precedence); + } + break; + case self::FIXUP_PREC_UNARY: + if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) { + $precedence = $this->precedenceMap[$parentClass][0]; + return $this->p($subNode, $precedence, $precedence); } break; case self::FIXUP_CALL_LHS: @@ -21652,6 +23451,16 @@ abstract class PrettyPrinterAbstract return '(' . $this->p($subNode) . ')'; } break; + case self::FIXUP_STATIC_DEREF_LHS: + if ($this->staticDereferenceLhsRequiresParens($subNode) && !$this->origTokens->haveParens($subStartPos, $subEndPos)) { + return '(' . $this->p($subNode) . ')'; + } + break; + case self::FIXUP_NEW: + if ($this->newOperandRequiresParens($subNode) && !$this->origTokens->haveParens($subStartPos, $subEndPos)) { + return '(' . $this->p($subNode) . ')'; + } + break; case self::FIXUP_BRACED_NAME: case self::FIXUP_VAR_BRACED_NAME: if ($subNode instanceof Expr && !$this->origTokens->haveBraces($subStartPos, $subEndPos)) { @@ -21659,7 +23468,7 @@ abstract class PrettyPrinterAbstract } break; case self::FIXUP_ENCAPSED: - if (!$subNode instanceof Scalar\EncapsedStringPart && !$this->origTokens->haveBraces($subStartPos, $subEndPos)) { + if (!$subNode instanceof Node\InterpolatedStringPart && !$this->origTokens->haveBraces($subStartPos, $subEndPos)) { return '{' . $this->p($subNode) . '}'; } break; @@ -21674,11 +23483,8 @@ abstract class PrettyPrinterAbstract * * Example: "echo" and "$x" result in "echo$x", but "echo" and "x" result in "echo x". * Without safeAppend the result would be "echox", which does not preserve semantics. - * - * @param string $str - * @param string $append */ - protected function safeAppend(string &$str, string $append) + protected function safeAppend(string &$str, string $append) : void { if ($str === "") { $str = $append; @@ -21705,7 +23511,7 @@ abstract class PrettyPrinterAbstract return !($node instanceof Node\Name || $node instanceof Expr\Variable || $node instanceof Expr\ArrayDimFetch || $node instanceof Expr\FuncCall || $node instanceof Expr\MethodCall || $node instanceof Expr\NullsafeMethodCall || $node instanceof Expr\StaticCall || $node instanceof Expr\Array_); } /** - * Determines whether the LHS of a dereferencing operation must be wrapped in parenthesis. + * Determines whether the LHS of an array/object operation must be wrapped in parentheses. * * @param Node $node LHS of dereferencing operation * @@ -21713,7 +23519,39 @@ abstract class PrettyPrinterAbstract */ protected function dereferenceLhsRequiresParens(Node $node) : bool { - return !($node instanceof Expr\Variable || $node instanceof Node\Name || $node instanceof Expr\ArrayDimFetch || $node instanceof Expr\PropertyFetch || $node instanceof Expr\NullsafePropertyFetch || $node instanceof Expr\StaticPropertyFetch || $node instanceof Expr\FuncCall || $node instanceof Expr\MethodCall || $node instanceof Expr\NullsafeMethodCall || $node instanceof Expr\StaticCall || $node instanceof Expr\Array_ || $node instanceof Scalar\String_ || $node instanceof Expr\ConstFetch || $node instanceof Expr\ClassConstFetch); + // A constant can occur on the LHS of an array/object deref, but not a static deref. + return $this->staticDereferenceLhsRequiresParens($node) && !$node instanceof Expr\ConstFetch; + } + /** + * Determines whether the LHS of a static operation must be wrapped in parentheses. + * + * @param Node $node LHS of dereferencing operation + * + * @return bool Whether parentheses are required + */ + protected function staticDereferenceLhsRequiresParens(Node $node) : bool + { + return !($node instanceof Expr\Variable || $node instanceof Node\Name || $node instanceof Expr\ArrayDimFetch || $node instanceof Expr\PropertyFetch || $node instanceof Expr\NullsafePropertyFetch || $node instanceof Expr\StaticPropertyFetch || $node instanceof Expr\FuncCall || $node instanceof Expr\MethodCall || $node instanceof Expr\NullsafeMethodCall || $node instanceof Expr\StaticCall || $node instanceof Expr\Array_ || $node instanceof Scalar\String_ || $node instanceof Expr\ClassConstFetch); + } + /** + * Determines whether an expression used in "new" or "instanceof" requires parentheses. + * + * @param Node $node New or instanceof operand + * + * @return bool Whether parentheses are required + */ + protected function newOperandRequiresParens(Node $node) : bool + { + if ($node instanceof Node\Name || $node instanceof Expr\Variable) { + return \false; + } + if ($node instanceof Expr\ArrayDimFetch || $node instanceof Expr\PropertyFetch || $node instanceof Expr\NullsafePropertyFetch) { + return $this->newOperandRequiresParens($node->var); + } + if ($node instanceof Expr\StaticPropertyFetch) { + return $this->newOperandRequiresParens($node->class); + } + return \true; } /** * Print modifiers, including trailing whitespace. @@ -21722,9 +23560,13 @@ abstract class PrettyPrinterAbstract * * @return string Printed modifiers */ - protected function pModifiers(int $modifiers) + protected function pModifiers(int $modifiers) : string { - return ($modifiers & Stmt\Class_::MODIFIER_PUBLIC ? 'public ' : '') . ($modifiers & Stmt\Class_::MODIFIER_PROTECTED ? 'protected ' : '') . ($modifiers & Stmt\Class_::MODIFIER_PRIVATE ? 'private ' : '') . ($modifiers & Stmt\Class_::MODIFIER_STATIC ? 'static ' : '') . ($modifiers & Stmt\Class_::MODIFIER_ABSTRACT ? 'abstract ' : '') . ($modifiers & Stmt\Class_::MODIFIER_FINAL ? 'final ' : '') . ($modifiers & Stmt\Class_::MODIFIER_READONLY ? 'readonly ' : ''); + return ($modifiers & Modifiers::FINAL ? 'final ' : '') . ($modifiers & Modifiers::ABSTRACT ? 'abstract ' : '') . ($modifiers & Modifiers::PUBLIC ? 'public ' : '') . ($modifiers & Modifiers::PROTECTED ? 'protected ' : '') . ($modifiers & Modifiers::PRIVATE ? 'private ' : '') . ($modifiers & Modifiers::STATIC ? 'static ' : '') . ($modifiers & Modifiers::READONLY ? 'readonly ' : ''); + } + protected function pStatic(bool $static) : string + { + return $static ? 'static ' : ''; } /** * Determine whether a list of nodes uses multiline formatting. @@ -21762,17 +23604,18 @@ abstract class PrettyPrinterAbstract * * The label char map determines whether a certain character may occur in a label. */ - protected function initializeLabelCharMap() + protected function initializeLabelCharMap() : void { - if ($this->labelCharMap) { + if (isset($this->labelCharMap)) { return; } $this->labelCharMap = []; for ($i = 0; $i < 256; $i++) { - // Since PHP 7.1 The lower range is 0x80. However, we also want to support code for - // older versions. $chr = \chr($i); - $this->labelCharMap[$chr] = $i >= 0x7f || \ctype_alnum($chr); + $this->labelCharMap[$chr] = $i >= 0x80 || \ctype_alnum($chr); + } + if ($this->phpVersion->allowsDelInIdentifiers()) { + $this->labelCharMap[""] = \true; } } /** @@ -21780,9 +23623,9 @@ abstract class PrettyPrinterAbstract * * The node list differ is used to determine differences between two array subnodes. */ - protected function initializeNodeListDiffer() + protected function initializeNodeListDiffer() : void { - if ($this->nodeListDiffer) { + if (isset($this->nodeListDiffer)) { return; } $this->nodeListDiffer = new Internal\Differ(function ($a, $b) { @@ -21799,42 +23642,19 @@ abstract class PrettyPrinterAbstract * The fixup map is used to determine whether a certain subnode of a certain node may require * some kind of "fixup" operation, e.g. the addition of parenthesis or braces. */ - protected function initializeFixupMap() + protected function initializeFixupMap() : void { - if ($this->fixupMap) { + if (isset($this->fixupMap)) { return; } - $this->fixupMap = [ - Expr\PreInc::class => ['var' => self::FIXUP_PREC_RIGHT], - Expr\PreDec::class => ['var' => self::FIXUP_PREC_RIGHT], - Expr\PostInc::class => ['var' => self::FIXUP_PREC_LEFT], - Expr\PostDec::class => ['var' => self::FIXUP_PREC_LEFT], - Expr\Instanceof_::class => ['expr' => self::FIXUP_PREC_LEFT, 'class' => self::FIXUP_PREC_RIGHT], - Expr\Ternary::class => ['cond' => self::FIXUP_PREC_LEFT, 'else' => self::FIXUP_PREC_RIGHT], - Expr\FuncCall::class => ['name' => self::FIXUP_CALL_LHS], - Expr\StaticCall::class => ['class' => self::FIXUP_DEREF_LHS], - Expr\ArrayDimFetch::class => ['var' => self::FIXUP_DEREF_LHS], - Expr\ClassConstFetch::class => ['var' => self::FIXUP_DEREF_LHS], - Expr\New_::class => ['class' => self::FIXUP_DEREF_LHS], - // TODO: FIXUP_NEW_VARIABLE - Expr\MethodCall::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME], - Expr\NullsafeMethodCall::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME], - Expr\StaticPropertyFetch::class => ['class' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_VAR_BRACED_NAME], - Expr\PropertyFetch::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME], - Expr\NullsafePropertyFetch::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME], - Scalar\Encapsed::class => ['parts' => self::FIXUP_ENCAPSED], - ]; + $this->fixupMap = [Expr\Instanceof_::class => ['expr' => self::FIXUP_PREC_UNARY, 'class' => self::FIXUP_NEW], Expr\Ternary::class => ['cond' => self::FIXUP_PREC_LEFT, 'else' => self::FIXUP_PREC_RIGHT], Expr\Yield_::class => ['value' => self::FIXUP_PREC_UNARY], Expr\FuncCall::class => ['name' => self::FIXUP_CALL_LHS], Expr\StaticCall::class => ['class' => self::FIXUP_STATIC_DEREF_LHS], Expr\ArrayDimFetch::class => ['var' => self::FIXUP_DEREF_LHS], Expr\ClassConstFetch::class => ['class' => self::FIXUP_STATIC_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME], Expr\New_::class => ['class' => self::FIXUP_NEW], Expr\MethodCall::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME], Expr\NullsafeMethodCall::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME], Expr\StaticPropertyFetch::class => ['class' => self::FIXUP_STATIC_DEREF_LHS, 'name' => self::FIXUP_VAR_BRACED_NAME], Expr\PropertyFetch::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME], Expr\NullsafePropertyFetch::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME], Scalar\InterpolatedString::class => ['parts' => self::FIXUP_ENCAPSED]]; $binaryOps = [BinaryOp\Pow::class, BinaryOp\Mul::class, BinaryOp\Div::class, BinaryOp\Mod::class, BinaryOp\Plus::class, BinaryOp\Minus::class, BinaryOp\Concat::class, BinaryOp\ShiftLeft::class, BinaryOp\ShiftRight::class, BinaryOp\Smaller::class, BinaryOp\SmallerOrEqual::class, BinaryOp\Greater::class, BinaryOp\GreaterOrEqual::class, BinaryOp\Equal::class, BinaryOp\NotEqual::class, BinaryOp\Identical::class, BinaryOp\NotIdentical::class, BinaryOp\Spaceship::class, BinaryOp\BitwiseAnd::class, BinaryOp\BitwiseXor::class, BinaryOp\BitwiseOr::class, BinaryOp\BooleanAnd::class, BinaryOp\BooleanOr::class, BinaryOp\Coalesce::class, BinaryOp\LogicalAnd::class, BinaryOp\LogicalXor::class, BinaryOp\LogicalOr::class]; foreach ($binaryOps as $binaryOp) { $this->fixupMap[$binaryOp] = ['left' => self::FIXUP_PREC_LEFT, 'right' => self::FIXUP_PREC_RIGHT]; } - $assignOps = [Expr\Assign::class, Expr\AssignRef::class, AssignOp\Plus::class, AssignOp\Minus::class, AssignOp\Mul::class, AssignOp\Div::class, AssignOp\Concat::class, AssignOp\Mod::class, AssignOp\BitwiseAnd::class, AssignOp\BitwiseOr::class, AssignOp\BitwiseXor::class, AssignOp\ShiftLeft::class, AssignOp\ShiftRight::class, AssignOp\Pow::class, AssignOp\Coalesce::class]; - foreach ($assignOps as $assignOp) { - $this->fixupMap[$assignOp] = ['var' => self::FIXUP_PREC_LEFT, 'expr' => self::FIXUP_PREC_RIGHT]; - } - $prefixOps = [Expr\BitwiseNot::class, Expr\BooleanNot::class, Expr\UnaryPlus::class, Expr\UnaryMinus::class, Cast\Int_::class, Cast\Double::class, Cast\String_::class, Cast\Array_::class, Cast\Object_::class, Cast\Bool_::class, Cast\Unset_::class, Expr\ErrorSuppress::class, Expr\YieldFrom::class, Expr\Print_::class, Expr\Include_::class]; + $prefixOps = [Expr\Clone_::class, Expr\BitwiseNot::class, Expr\BooleanNot::class, Expr\UnaryPlus::class, Expr\UnaryMinus::class, Cast\Int_::class, Cast\Double::class, Cast\String_::class, Cast\Array_::class, Cast\Object_::class, Cast\Bool_::class, Cast\Unset_::class, Expr\ErrorSuppress::class, Expr\YieldFrom::class, Expr\Print_::class, Expr\Include_::class, Expr\Assign::class, Expr\AssignRef::class, AssignOp\Plus::class, AssignOp\Minus::class, AssignOp\Mul::class, AssignOp\Div::class, AssignOp\Concat::class, AssignOp\Mod::class, AssignOp\BitwiseAnd::class, AssignOp\BitwiseOr::class, AssignOp\BitwiseXor::class, AssignOp\ShiftLeft::class, AssignOp\ShiftRight::class, AssignOp\Pow::class, AssignOp\Coalesce::class, Expr\ArrowFunction::class, Expr\Throw_::class]; foreach ($prefixOps as $prefixOp) { - $this->fixupMap[$prefixOp] = ['expr' => self::FIXUP_PREC_RIGHT]; + $this->fixupMap[$prefixOp] = ['expr' => self::FIXUP_PREC_UNARY]; } } /** @@ -21843,9 +23663,9 @@ abstract class PrettyPrinterAbstract * The removal map is used to determine which additional tokens should be removed when a * certain node is replaced by null. */ - protected function initializeRemovalMap() + protected function initializeRemovalMap() : void { - if ($this->removalMap) { + if (isset($this->removalMap)) { return; } $stripBoth = ['left' => \T_WHITESPACE, 'right' => \T_WHITESPACE]; @@ -21854,20 +23674,20 @@ abstract class PrettyPrinterAbstract $stripDoubleArrow = ['right' => \T_DOUBLE_ARROW]; $stripColon = ['left' => ':']; $stripEquals = ['left' => '=']; - $this->removalMap = ['Expr_ArrayDimFetch->dim' => $stripBoth, 'Expr_ArrayItem->key' => $stripDoubleArrow, 'Expr_ArrowFunction->returnType' => $stripColon, 'Expr_Closure->returnType' => $stripColon, 'Expr_Exit->expr' => $stripBoth, 'Expr_Ternary->if' => $stripBoth, 'Expr_Yield->key' => $stripDoubleArrow, 'Expr_Yield->value' => $stripBoth, 'Param->type' => $stripRight, 'Param->default' => $stripEquals, 'Stmt_Break->num' => $stripBoth, 'Stmt_Catch->var' => $stripLeft, 'Stmt_ClassMethod->returnType' => $stripColon, 'Stmt_Class->extends' => ['left' => \T_EXTENDS], 'Stmt_Enum->scalarType' => $stripColon, 'Stmt_EnumCase->expr' => $stripEquals, 'Expr_PrintableNewAnonClass->extends' => ['left' => \T_EXTENDS], 'Stmt_Continue->num' => $stripBoth, 'Stmt_Foreach->keyVar' => $stripDoubleArrow, 'Stmt_Function->returnType' => $stripColon, 'Stmt_If->else' => $stripLeft, 'Stmt_Namespace->name' => $stripLeft, 'Stmt_Property->type' => $stripRight, 'Stmt_PropertyProperty->default' => $stripEquals, 'Stmt_Return->expr' => $stripBoth, 'Stmt_StaticVar->default' => $stripEquals, 'Stmt_TraitUseAdaptation_Alias->newName' => $stripLeft, 'Stmt_TryCatch->finally' => $stripLeft]; + $this->removalMap = ['Expr_ArrayDimFetch->dim' => $stripBoth, 'ArrayItem->key' => $stripDoubleArrow, 'Expr_ArrowFunction->returnType' => $stripColon, 'Expr_Closure->returnType' => $stripColon, 'Expr_Exit->expr' => $stripBoth, 'Expr_Ternary->if' => $stripBoth, 'Expr_Yield->key' => $stripDoubleArrow, 'Expr_Yield->value' => $stripBoth, 'Param->type' => $stripRight, 'Param->default' => $stripEquals, 'Stmt_Break->num' => $stripBoth, 'Stmt_Catch->var' => $stripLeft, 'Stmt_ClassConst->type' => $stripRight, 'Stmt_ClassMethod->returnType' => $stripColon, 'Stmt_Class->extends' => ['left' => \T_EXTENDS], 'Stmt_Enum->scalarType' => $stripColon, 'Stmt_EnumCase->expr' => $stripEquals, 'Expr_PrintableNewAnonClass->extends' => ['left' => \T_EXTENDS], 'Stmt_Continue->num' => $stripBoth, 'Stmt_Foreach->keyVar' => $stripDoubleArrow, 'Stmt_Function->returnType' => $stripColon, 'Stmt_If->else' => $stripLeft, 'Stmt_Namespace->name' => $stripLeft, 'Stmt_Property->type' => $stripRight, 'PropertyItem->default' => $stripEquals, 'Stmt_Return->expr' => $stripBoth, 'Stmt_StaticVar->default' => $stripEquals, 'Stmt_TraitUseAdaptation_Alias->newName' => $stripLeft, 'Stmt_TryCatch->finally' => $stripLeft]; } - protected function initializeInsertionMap() + protected function initializeInsertionMap() : void { - if ($this->insertionMap) { + if (isset($this->insertionMap)) { return; } // TODO: "yield" where both key and value are inserted doesn't work // [$find, $beforeToken, $extraLeft, $extraRight] $this->insertionMap = [ 'Expr_ArrayDimFetch->dim' => ['[', \false, null, null], - 'Expr_ArrayItem->key' => [null, \false, null, ' => '], - 'Expr_ArrowFunction->returnType' => [')', \false, ' : ', null], - 'Expr_Closure->returnType' => [')', \false, ' : ', null], + 'ArrayItem->key' => [null, \false, null, ' => '], + 'Expr_ArrowFunction->returnType' => [')', \false, ': ', null], + 'Expr_Closure->returnType' => [')', \false, ': ', null], 'Expr_Ternary->if' => ['?', \false, ' ', ' '], 'Expr_Yield->key' => [\T_YIELD, \false, null, ' => '], 'Expr_Yield->value' => [\T_YIELD, \false, ' ', null], @@ -21875,138 +23695,213 @@ abstract class PrettyPrinterAbstract 'Param->default' => [null, \false, ' = ', null], 'Stmt_Break->num' => [\T_BREAK, \false, ' ', null], 'Stmt_Catch->var' => [null, \false, ' ', null], - 'Stmt_ClassMethod->returnType' => [')', \false, ' : ', null], + 'Stmt_ClassMethod->returnType' => [')', \false, ': ', null], + 'Stmt_ClassConst->type' => [\T_CONST, \false, ' ', null], 'Stmt_Class->extends' => [null, \false, ' extends ', null], 'Stmt_Enum->scalarType' => [null, \false, ' : ', null], 'Stmt_EnumCase->expr' => [null, \false, ' = ', null], - 'Expr_PrintableNewAnonClass->extends' => [null, ' extends ', null], + 'Expr_PrintableNewAnonClass->extends' => [null, \false, ' extends ', null], 'Stmt_Continue->num' => [\T_CONTINUE, \false, ' ', null], 'Stmt_Foreach->keyVar' => [\T_AS, \false, null, ' => '], - 'Stmt_Function->returnType' => [')', \false, ' : ', null], + 'Stmt_Function->returnType' => [')', \false, ': ', null], 'Stmt_If->else' => [null, \false, ' ', null], 'Stmt_Namespace->name' => [\T_NAMESPACE, \false, ' ', null], 'Stmt_Property->type' => [\T_VARIABLE, \true, null, ' '], - 'Stmt_PropertyProperty->default' => [null, \false, ' = ', null], + 'PropertyItem->default' => [null, \false, ' = ', null], 'Stmt_Return->expr' => [\T_RETURN, \false, ' ', null], 'Stmt_StaticVar->default' => [null, \false, ' = ', null], //'Stmt_TraitUseAdaptation_Alias->newName' => [T_AS, false, ' ', null], // TODO 'Stmt_TryCatch->finally' => [null, \false, ' ', null], ]; } - protected function initializeListInsertionMap() + protected function initializeListInsertionMap() : void { - if ($this->listInsertionMap) { + if (isset($this->listInsertionMap)) { return; } $this->listInsertionMap = [ // special //'Expr_ShellExec->parts' => '', // TODO These need to be treated more carefully - //'Scalar_Encapsed->parts' => '', - 'Stmt_Catch->types' => '|', - 'UnionType->types' => '|', - 'IntersectionType->types' => '&', - 'Stmt_If->elseifs' => ' ', - 'Stmt_TryCatch->catches' => ' ', + //'Scalar_InterpolatedString->parts' => '', + Stmt\Catch_::class . '->types' => '|', + UnionType::class . '->types' => '|', + IntersectionType::class . '->types' => '&', + Stmt\If_::class . '->elseifs' => ' ', + Stmt\TryCatch::class . '->catches' => ' ', // comma-separated lists - 'Expr_Array->items' => ', ', - 'Expr_ArrowFunction->params' => ', ', - 'Expr_Closure->params' => ', ', - 'Expr_Closure->uses' => ', ', - 'Expr_FuncCall->args' => ', ', - 'Expr_Isset->vars' => ', ', - 'Expr_List->items' => ', ', - 'Expr_MethodCall->args' => ', ', - 'Expr_NullsafeMethodCall->args' => ', ', - 'Expr_New->args' => ', ', - 'Expr_PrintableNewAnonClass->args' => ', ', - 'Expr_StaticCall->args' => ', ', - 'Stmt_ClassConst->consts' => ', ', - 'Stmt_ClassMethod->params' => ', ', - 'Stmt_Class->implements' => ', ', - 'Stmt_Enum->implements' => ', ', - 'Expr_PrintableNewAnonClass->implements' => ', ', - 'Stmt_Const->consts' => ', ', - 'Stmt_Declare->declares' => ', ', - 'Stmt_Echo->exprs' => ', ', - 'Stmt_For->init' => ', ', - 'Stmt_For->cond' => ', ', - 'Stmt_For->loop' => ', ', - 'Stmt_Function->params' => ', ', - 'Stmt_Global->vars' => ', ', - 'Stmt_GroupUse->uses' => ', ', - 'Stmt_Interface->extends' => ', ', - 'Stmt_Match->arms' => ', ', - 'Stmt_Property->props' => ', ', - 'Stmt_StaticVar->vars' => ', ', - 'Stmt_TraitUse->traits' => ', ', - 'Stmt_TraitUseAdaptation_Precedence->insteadof' => ', ', - 'Stmt_Unset->vars' => ', ', - 'Stmt_Use->uses' => ', ', - 'MatchArm->conds' => ', ', - 'AttributeGroup->attrs' => ', ', + Expr\Array_::class . '->items' => ', ', + Expr\ArrowFunction::class . '->params' => ', ', + Expr\Closure::class . '->params' => ', ', + Expr\Closure::class . '->uses' => ', ', + Expr\FuncCall::class . '->args' => ', ', + Expr\Isset_::class . '->vars' => ', ', + Expr\List_::class . '->items' => ', ', + Expr\MethodCall::class . '->args' => ', ', + Expr\NullsafeMethodCall::class . '->args' => ', ', + Expr\New_::class . '->args' => ', ', + PrintableNewAnonClassNode::class . '->args' => ', ', + Expr\StaticCall::class . '->args' => ', ', + Stmt\ClassConst::class . '->consts' => ', ', + Stmt\ClassMethod::class . '->params' => ', ', + Stmt\Class_::class . '->implements' => ', ', + Stmt\Enum_::class . '->implements' => ', ', + PrintableNewAnonClassNode::class . '->implements' => ', ', + Stmt\Const_::class . '->consts' => ', ', + Stmt\Declare_::class . '->declares' => ', ', + Stmt\Echo_::class . '->exprs' => ', ', + Stmt\For_::class . '->init' => ', ', + Stmt\For_::class . '->cond' => ', ', + Stmt\For_::class . '->loop' => ', ', + Stmt\Function_::class . '->params' => ', ', + Stmt\Global_::class . '->vars' => ', ', + Stmt\GroupUse::class . '->uses' => ', ', + Stmt\Interface_::class . '->extends' => ', ', + Expr\Match_::class . '->arms' => ', ', + Stmt\Property::class . '->props' => ', ', + Stmt\StaticVar::class . '->vars' => ', ', + Stmt\TraitUse::class . '->traits' => ', ', + Stmt\TraitUseAdaptation\Precedence::class . '->insteadof' => ', ', + Stmt\Unset_::class . '->vars' => ', ', + Stmt\UseUse::class . '->uses' => ', ', + MatchArm::class . '->conds' => ', ', + AttributeGroup::class . '->attrs' => ', ', // statement lists - 'Expr_Closure->stmts' => "\n", - 'Stmt_Case->stmts' => "\n", - 'Stmt_Catch->stmts' => "\n", - 'Stmt_Class->stmts' => "\n", - 'Stmt_Enum->stmts' => "\n", - 'Expr_PrintableNewAnonClass->stmts' => "\n", - 'Stmt_Interface->stmts' => "\n", - 'Stmt_Trait->stmts' => "\n", - 'Stmt_ClassMethod->stmts' => "\n", - 'Stmt_Declare->stmts' => "\n", - 'Stmt_Do->stmts' => "\n", - 'Stmt_ElseIf->stmts' => "\n", - 'Stmt_Else->stmts' => "\n", - 'Stmt_Finally->stmts' => "\n", - 'Stmt_Foreach->stmts' => "\n", - 'Stmt_For->stmts' => "\n", - 'Stmt_Function->stmts' => "\n", - 'Stmt_If->stmts' => "\n", - 'Stmt_Namespace->stmts' => "\n", - 'Stmt_Class->attrGroups' => "\n", - 'Stmt_Enum->attrGroups' => "\n", - 'Stmt_EnumCase->attrGroups' => "\n", - 'Stmt_Interface->attrGroups' => "\n", - 'Stmt_Trait->attrGroups' => "\n", - 'Stmt_Function->attrGroups' => "\n", - 'Stmt_ClassMethod->attrGroups' => "\n", - 'Stmt_ClassConst->attrGroups' => "\n", - 'Stmt_Property->attrGroups' => "\n", - 'Expr_PrintableNewAnonClass->attrGroups' => ' ', - 'Expr_Closure->attrGroups' => ' ', - 'Expr_ArrowFunction->attrGroups' => ' ', - 'Param->attrGroups' => ' ', - 'Stmt_Switch->cases' => "\n", - 'Stmt_TraitUse->adaptations' => "\n", - 'Stmt_TryCatch->stmts' => "\n", - 'Stmt_While->stmts' => "\n", + Expr\Closure::class . '->stmts' => "\n", + Stmt\Case_::class . '->stmts' => "\n", + Stmt\Catch_::class . '->stmts' => "\n", + Stmt\Class_::class . '->stmts' => "\n", + Stmt\Enum_::class . '->stmts' => "\n", + PrintableNewAnonClassNode::class . '->stmts' => "\n", + Stmt\Interface_::class . '->stmts' => "\n", + Stmt\Trait_::class . '->stmts' => "\n", + Stmt\ClassMethod::class . '->stmts' => "\n", + Stmt\Declare_::class . '->stmts' => "\n", + Stmt\Do_::class . '->stmts' => "\n", + Stmt\ElseIf_::class . '->stmts' => "\n", + Stmt\Else_::class . '->stmts' => "\n", + Stmt\Finally_::class . '->stmts' => "\n", + Stmt\Foreach_::class . '->stmts' => "\n", + Stmt\For_::class . '->stmts' => "\n", + Stmt\Function_::class . '->stmts' => "\n", + Stmt\If_::class . '->stmts' => "\n", + Stmt\Namespace_::class . '->stmts' => "\n", + Stmt\Block::class . '->stmts' => "\n", + // Attribute groups + Stmt\Class_::class . '->attrGroups' => "\n", + Stmt\Enum_::class . '->attrGroups' => "\n", + Stmt\EnumCase::class . '->attrGroups' => "\n", + Stmt\Interface_::class . '->attrGroups' => "\n", + Stmt\Trait_::class . '->attrGroups' => "\n", + Stmt\Function_::class . '->attrGroups' => "\n", + Stmt\ClassMethod::class . '->attrGroups' => "\n", + Stmt\ClassConst::class . '->attrGroups' => "\n", + Stmt\Property::class . '->attrGroups' => "\n", + PrintableNewAnonClassNode::class . '->attrGroups' => ' ', + Expr\Closure::class . '->attrGroups' => ' ', + Expr\ArrowFunction::class . '->attrGroups' => ' ', + Param::class . '->attrGroups' => ' ', + Stmt\Switch_::class . '->cases' => "\n", + Stmt\TraitUse::class . '->adaptations' => "\n", + Stmt\TryCatch::class . '->stmts' => "\n", + Stmt\While_::class . '->stmts' => "\n", // dummy for top-level context 'File->stmts' => "\n", ]; } - protected function initializeEmptyListInsertionMap() + protected function initializeEmptyListInsertionMap() : void { - if ($this->emptyListInsertionMap) { + if (isset($this->emptyListInsertionMap)) { return; } // TODO Insertion into empty statement lists. // [$find, $extraLeft, $extraRight] - $this->emptyListInsertionMap = ['Expr_ArrowFunction->params' => ['(', '', ''], 'Expr_Closure->uses' => [')', ' use(', ')'], 'Expr_Closure->params' => ['(', '', ''], 'Expr_FuncCall->args' => ['(', '', ''], 'Expr_MethodCall->args' => ['(', '', ''], 'Expr_NullsafeMethodCall->args' => ['(', '', ''], 'Expr_New->args' => ['(', '', ''], 'Expr_PrintableNewAnonClass->args' => ['(', '', ''], 'Expr_PrintableNewAnonClass->implements' => [null, ' implements ', ''], 'Expr_StaticCall->args' => ['(', '', ''], 'Stmt_Class->implements' => [null, ' implements ', ''], 'Stmt_Enum->implements' => [null, ' implements ', ''], 'Stmt_ClassMethod->params' => ['(', '', ''], 'Stmt_Interface->extends' => [null, ' extends ', ''], 'Stmt_Function->params' => ['(', '', ''], 'Stmt_Interface->attrGroups' => [null, '', "\n"], 'Stmt_Class->attrGroups' => [null, '', "\n"], 'Stmt_ClassConst->attrGroups' => [null, '', "\n"], 'Stmt_ClassMethod->attrGroups' => [null, '', "\n"], 'Stmt_Function->attrGroups' => [null, '', "\n"], 'Stmt_Property->attrGroups' => [null, '', "\n"], 'Stmt_Trait->attrGroups' => [null, '', "\n"], 'Expr_ArrowFunction->attrGroups' => [null, '', ' '], 'Expr_Closure->attrGroups' => [null, '', ' '], 'Expr_PrintableNewAnonClass->attrGroups' => [\T_NEW, ' ', '']]; + $this->emptyListInsertionMap = [Expr\ArrowFunction::class . '->params' => ['(', '', ''], Expr\Closure::class . '->uses' => [')', ' use (', ')'], Expr\Closure::class . '->params' => ['(', '', ''], Expr\FuncCall::class . '->args' => ['(', '', ''], Expr\MethodCall::class . '->args' => ['(', '', ''], Expr\NullsafeMethodCall::class . '->args' => ['(', '', ''], Expr\New_::class . '->args' => ['(', '', ''], PrintableNewAnonClassNode::class . '->args' => ['(', '', ''], PrintableNewAnonClassNode::class . '->implements' => [null, ' implements ', ''], Expr\StaticCall::class . '->args' => ['(', '', ''], Stmt\Class_::class . '->implements' => [null, ' implements ', ''], Stmt\Enum_::class . '->implements' => [null, ' implements ', ''], Stmt\ClassMethod::class . '->params' => ['(', '', ''], Stmt\Interface_::class . '->extends' => [null, ' extends ', ''], Stmt\Function_::class . '->params' => ['(', '', ''], Stmt\Interface_::class . '->attrGroups' => [null, '', "\n"], Stmt\Class_::class . '->attrGroups' => [null, '', "\n"], Stmt\ClassConst::class . '->attrGroups' => [null, '', "\n"], Stmt\ClassMethod::class . '->attrGroups' => [null, '', "\n"], Stmt\Function_::class . '->attrGroups' => [null, '', "\n"], Stmt\Property::class . '->attrGroups' => [null, '', "\n"], Stmt\Trait_::class . '->attrGroups' => [null, '', "\n"], Expr\ArrowFunction::class . '->attrGroups' => [null, '', ' '], Expr\Closure::class . '->attrGroups' => [null, '', ' '], PrintableNewAnonClassNode::class . '->attrGroups' => [\T_NEW, ' ', '']]; } - protected function initializeModifierChangeMap() + protected function initializeModifierChangeMap() : void { - if ($this->modifierChangeMap) { + if (isset($this->modifierChangeMap)) { return; } - $this->modifierChangeMap = ['Stmt_ClassConst->flags' => \T_CONST, 'Stmt_ClassMethod->flags' => \T_FUNCTION, 'Stmt_Class->flags' => \T_CLASS, 'Stmt_Property->flags' => \T_VARIABLE, 'Param->flags' => \T_VARIABLE]; + $this->modifierChangeMap = [Stmt\ClassConst::class . '->flags' => ['pModifiers', \T_CONST], Stmt\ClassMethod::class . '->flags' => ['pModifiers', \T_FUNCTION], Stmt\Class_::class . '->flags' => ['pModifiers', \T_CLASS], Stmt\Property::class . '->flags' => ['pModifiers', \T_VARIABLE], PrintableNewAnonClassNode::class . '->flags' => ['pModifiers', \T_CLASS], Param::class . '->flags' => ['pModifiers', \T_VARIABLE], Expr\Closure::class . '->static' => ['pStatic', \T_FUNCTION], Expr\ArrowFunction::class . '->static' => ['pStatic', \T_FN]]; // List of integer subnodes that are not modifiers: // Expr_Include->type // Stmt_GroupUse->type // Stmt_Use->type - // Stmt_UseUse->type + // UseItem->type } } +pos + \strlen($this->text); + } + /** Get 1-based end line number of the token. */ + public function getEndLine() : int + { + return $this->line + \substr_count($this->text, "\n"); + } +} + + * @psalm-var array> + */ + private array $linesToBeIgnored = []; + /** + * @psalm-var array */ private array $tests = []; /** @@ -24641,6 +26546,7 @@ final class CodeCoverage private array $parentClassesExcludedFromUnintentionallyCoveredCodeCheck = []; private ?FileAnalyser $analyser = null; private ?string $cacheDirectory = null; + private ?Directory $cachedReport = null; public function __construct(Driver $driver, Filter $filter) { $this->driver = $driver; @@ -24653,7 +26559,10 @@ final class CodeCoverage */ public function getReport() : Directory { - return (new Builder($this->analyser()))->build($this); + if ($this->cachedReport === null) { + $this->cachedReport = (new Builder($this->analyser()))->build($this); + } + return $this->cachedReport; } /** * Clears collected code coverage data. @@ -24664,6 +26573,14 @@ final class CodeCoverage $this->currentSize = null; $this->data = new ProcessedCodeCoverageData(); $this->tests = []; + $this->cachedReport = null; + } + /** + * @internal + */ + public function clearCache() : void + { + $this->cachedReport = null; } /** * Returns the filter object used. @@ -24692,14 +26609,14 @@ final class CodeCoverage $this->data = $data; } /** - * @psalm-return array + * @psalm-return array */ public function getTests() : array { return $this->tests; } /** - * @psalm-param array $tests + * @psalm-param array $tests */ public function setTests(array $tests) : void { @@ -24713,21 +26630,29 @@ final class CodeCoverage $this->currentId = $id; $this->currentSize = $size; $this->driver->start(); + $this->cachedReport = null; } - public function stop(bool $append = \true, TestStatus $status = null, array|false $linesToBeCovered = [], array $linesToBeUsed = []) : RawCodeCoverageData + /** + * @psalm-param array> $linesToBeIgnored + */ + public function stop(bool $append = \true, TestStatus $status = null, array|false $linesToBeCovered = [], array $linesToBeUsed = [], array $linesToBeIgnored = []) : RawCodeCoverageData { $data = $this->driver->stop(); - $this->append($data, null, $append, $status, $linesToBeCovered, $linesToBeUsed); + $this->linesToBeIgnored = array_merge_recursive($this->linesToBeIgnored, $linesToBeIgnored); + $this->append($data, null, $append, $status, $linesToBeCovered, $linesToBeUsed, $linesToBeIgnored); $this->currentId = null; $this->currentSize = null; + $this->cachedReport = null; return $data; } /** + * @psalm-param array> $linesToBeIgnored + * * @throws ReflectionException * @throws TestIdMissingException * @throws UnintentionallyCoveredCodeException */ - public function append(RawCodeCoverageData $rawData, string $id = null, bool $append = \true, TestStatus $status = null, array|false $linesToBeCovered = [], array $linesToBeUsed = []) : void + public function append(RawCodeCoverageData $rawData, string $id = null, bool $append = \true, TestStatus $status = null, array|false $linesToBeCovered = [], array $linesToBeUsed = [], array $linesToBeIgnored = []) : void { if ($id === null) { $id = $this->currentId; @@ -24735,6 +26660,7 @@ final class CodeCoverage if ($id === null) { throw new TestIdMissingException(); } + $this->cachedReport = null; if ($status === null) { $status = TestStatus::unknown(); } @@ -24745,20 +26671,21 @@ final class CodeCoverage $this->applyFilter($rawData); $this->applyExecutableLinesFilter($rawData); if ($this->useAnnotationsForIgnoringCode) { - $this->applyIgnoredLinesFilter($rawData); + $this->applyIgnoredLinesFilter($rawData, $linesToBeIgnored); } $this->data->initializeUnseenData($rawData); if (!$append) { return; } - if ($id !== self::UNCOVERED_FILES) { - $this->applyCoversAndUsesFilter($rawData, $linesToBeCovered, $linesToBeUsed, $size); - if (empty($rawData->lineCoverage())) { - return; - } - $this->tests[$id] = ['size' => $size->asString(), 'status' => $status->asString()]; - $this->data->markCodeAsExecutedByTestCase($id, $rawData); + if ($id === self::UNCOVERED_FILES) { + return; + } + $this->applyCoversAndUsesFilter($rawData, $linesToBeCovered, $linesToBeUsed, $size); + if (empty($rawData->lineCoverage())) { + return; } + $this->tests[$id] = ['size' => $size->asString(), 'status' => $status->asString()]; + $this->data->markCodeAsExecutedByTestCase($id, $rawData); } /** * Merges the data from another instance. @@ -24768,6 +26695,7 @@ final class CodeCoverage $this->filter->includeFiles($that->filter()->files()); $this->data->merge($that->data); $this->tests = array_merge($this->tests, $that->getTests()); + $this->cachedReport = null; } public function enableCheckForUnintentionallyCoveredCode() : void { @@ -24899,12 +26827,18 @@ final class CodeCoverage $data->markExecutableLineByBranch($filename, $linesToBranchMap); } } - private function applyIgnoredLinesFilter(RawCodeCoverageData $data) : void + /** + * @psalm-param array> $linesToBeIgnored + */ + private function applyIgnoredLinesFilter(RawCodeCoverageData $data, array $linesToBeIgnored) : void { foreach (array_keys($data->lineCoverage()) as $filename) { if (!$this->filter->isFile($filename)) { continue; } + if (isset($linesToBeIgnored[$filename])) { + $data->removeCoverageDataForLines($filename, $linesToBeIgnored[$filename]); + } $data->removeCoverageDataForLines($filename, $this->analyser()->ignoredLinesFor($filename)); } } @@ -24916,7 +26850,7 @@ final class CodeCoverage $uncoveredFiles = array_diff($this->filter->files(), $this->data->coveredFiles()); foreach ($uncoveredFiles as $uncoveredFile) { if (is_file($uncoveredFile)) { - $this->append(RawCodeCoverageData::fromUncoveredFile($uncoveredFile, $this->analyser()), self::UNCOVERED_FILES); + $this->append(RawCodeCoverageData::fromUncoveredFile($uncoveredFile, $this->analyser()), self::UNCOVERED_FILES, linesToBeIgnored: $this->linesToBeIgnored); } } } @@ -25000,7 +26934,7 @@ final class CodeCoverage } $this->analyser = new ParsingFileAnalyser($this->useAnnotationsForIgnoringCode, $this->ignoreDeprecatedCode); if ($this->cachesStaticAnalysis()) { - $this->analyser = new CachingFileAnalyser($this->cacheDirectory, $this->analyser); + $this->analyser = new CachingFileAnalyser($this->cacheDirectory, $this->analyser, $this->useAnnotationsForIgnoringCode, $this->ignoreDeprecatedCode); } return $this->analyser; } @@ -25028,18 +26962,41 @@ use function ksort; use PHPUnit\SebastianBergmann\CodeCoverage\Driver\Driver; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage + * + * @psalm-import-type XdebugFunctionCoverageType from \SebastianBergmann\CodeCoverage\Driver\XdebugDriver + * + * @psalm-type TestIdType = string */ final class ProcessedCodeCoverageData { /** * Line coverage data. * An array of filenames, each having an array of linenumbers, each executable line having an array of testcase ids. + * + * @psalm-var array>> */ private array $lineCoverage = []; /** * Function coverage data. * Maintains base format of raw data (@see https://xdebug.org/docs/code_coverage), but each 'hit' entry is an array * of testcase ids. + * + * @psalm-var array, + * out: array, + * out_hit: array, + * }>, + * paths: array, + * hit: list, + * }>, + * hit: list + * }>> */ private array $functionCoverage = []; public function initializeUnseenData(RawCodeCoverageData $rawData) : void @@ -25181,6 +27138,8 @@ final class ProcessedCodeCoverageData } /** * For a function we have never seen before, copy all data over and simply init the 'hit' array. + * + * @psalm-param XdebugFunctionCoverageType $functionData */ private function initPreviouslyUnseenFunction(string $file, string $functionName, array $functionData) : void { @@ -25196,6 +27155,8 @@ final class ProcessedCodeCoverageData * For a function we have seen before, only copy over and init the 'hit' array for any unseen branches and paths. * Techniques such as mocking and where the contents of a file are different vary during tests (e.g. compiling * containers) mean that the functions inside a file cannot be relied upon to be static. + * + * @psalm-param XdebugFunctionCoverageType $functionData */ private function initPreviouslySeenFunction(string $file, string $functionName, array $functionData) : void { @@ -25236,12 +27197,19 @@ use function explode; use function file_get_contents; use function in_array; use function is_file; +use function preg_replace; use function range; +use function str_ends_with; +use function str_starts_with; use function trim; use PHPUnit\SebastianBergmann\CodeCoverage\Driver\Driver; use PHPUnit\SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage + * + * @psalm-import-type XdebugFunctionsCoverageType from \SebastianBergmann\CodeCoverage\Driver\XdebugDriver + * @psalm-import-type XdebugCodeCoverageWithoutPathCoverageType from \SebastianBergmann\CodeCoverage\Driver\XdebugDriver + * @psalm-import-type XdebugCodeCoverageWithPathCoverageType from \SebastianBergmann\CodeCoverage\Driver\XdebugDriver */ final class RawCodeCoverageData { @@ -25250,22 +27218,37 @@ final class RawCodeCoverageData */ private static array $emptyLineCache = []; /** - * @see https://xdebug.org/docs/code_coverage for format + * @psalm-var XdebugCodeCoverageWithoutPathCoverageType */ private array $lineCoverage; /** - * @see https://xdebug.org/docs/code_coverage for format + * @psalm-var array */ private array $functionCoverage; + /** + * @psalm-param XdebugCodeCoverageWithoutPathCoverageType $rawCoverage + */ public static function fromXdebugWithoutPathCoverage(array $rawCoverage) : self { return new self($rawCoverage, []); } + /** + * @psalm-param XdebugCodeCoverageWithPathCoverageType $rawCoverage + */ public static function fromXdebugWithPathCoverage(array $rawCoverage) : self { $lineCoverage = []; $functionCoverage = []; foreach ($rawCoverage as $file => $fileCoverageData) { + // Xdebug annotates the function name of traits, strip that off + foreach ($fileCoverageData['functions'] as $existingKey => $data) { + if (str_ends_with($existingKey, '}') && !str_starts_with($existingKey, '{')) { + // don't want to catch {main} + $newKey = preg_replace('/\\{.*}$/', '', $existingKey); + $fileCoverageData['functions'][$newKey] = $data; + unset($fileCoverageData['functions'][$existingKey]); + } + } $lineCoverage[$file] = $fileCoverageData['lines']; $functionCoverage[$file] = $fileCoverageData['functions']; } @@ -25279,6 +27262,10 @@ final class RawCodeCoverageData } return new self([$filename => $lineCoverage], []); } + /** + * @psalm-param XdebugCodeCoverageWithoutPathCoverageType $lineCoverage + * @psalm-param array $functionCoverage + */ private function __construct(array $lineCoverage, array $functionCoverage) { $this->lineCoverage = $lineCoverage; @@ -25289,10 +27276,16 @@ final class RawCodeCoverageData { $this->lineCoverage = $this->functionCoverage = []; } + /** + * @psalm-return XdebugCodeCoverageWithoutPathCoverageType + */ public function lineCoverage() : array { return $this->lineCoverage; } + /** + * @psalm-return array + */ public function functionCoverage() : array { return $this->functionCoverage; @@ -25679,6 +27672,34 @@ use PHPUnit\SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData; use PHPUnit\SebastianBergmann\CodeCoverage\Filter; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage + * + * @see https://xdebug.org/docs/code_coverage#xdebug_get_code_coverage + * + * @psalm-type XdebugLinesCoverageType = array + * @psalm-type XdebugBranchCoverageType = array{ + * op_start: int, + * op_end: int, + * line_start: int, + * line_end: int, + * hit: int, + * out: array, + * out_hit: array, + * } + * @psalm-type XdebugPathCoverageType = array{ + * path: array, + * hit: int, + * } + * @psalm-type XdebugFunctionCoverageType = array{ + * branches: array, + * paths: array, + * } + * @psalm-type XdebugFunctionsCoverageType = array + * @psalm-type XdebugPathAndBranchesCoverageType = array{ + * lines: XdebugLinesCoverageType, + * functions: XdebugFunctionsCoverageType, + * } + * @psalm-type XdebugCodeCoverageWithoutPathCoverageType = array + * @psalm-type XdebugCodeCoverageWithPathCoverageType = array */ final class XdebugDriver extends Driver { @@ -25718,8 +27739,10 @@ final class XdebugDriver extends Driver $data = xdebug_get_code_coverage(); xdebug_stop_code_coverage(); if ($this->collectsBranchAndPathCoverage()) { + /* @var XdebugCodeCoverageWithPathCoverageType $data */ return RawCodeCoverageData::fromXdebugWithPathCoverage($data); } + /* @var XdebugCodeCoverageWithoutPathCoverageType $data */ return RawCodeCoverageData::fromXdebugWithoutPathCoverage($data); } public function nameAndVersion() : string @@ -25837,6 +27860,23 @@ declare (strict_types=1); */ namespace PHPUnit\SebastianBergmann\CodeCoverage; +use RuntimeException; +final class FileCouldNotBeWrittenException extends RuntimeException implements Exception +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\SebastianBergmann\CodeCoverage; + final class InvalidArgumentException extends \InvalidArgumentException implements Exception { } @@ -26177,6 +28217,9 @@ final class Filter * @psalm-var array */ private array $isFileCache = []; + /** + * @deprecated + */ public function includeDirectory(string $directory, string $suffix = '.php', string $prefix = '') : void { foreach ((new FileIteratorFacade())->getFilesAsArray($directory, $suffix, $prefix) as $file) { @@ -26200,12 +28243,18 @@ final class Filter } $this->files[$filename] = \true; } + /** + * @deprecated + */ public function excludeDirectory(string $directory, string $suffix = '.php', string $prefix = '') : void { foreach ((new FileIteratorFacade())->getFilesAsArray($directory, $suffix, $prefix) as $file) { $this->excludeFile($file); } } + /** + * @deprecated + */ public function excludeFile(string $filename) : void { $filename = realpath($filename); @@ -26294,6 +28343,11 @@ use Countable; use PHPUnit\SebastianBergmann\CodeCoverage\Util\Percentage; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage + * + * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser + * @psalm-import-type ProcessedFunctionType from \SebastianBergmann\CodeCoverage\Node\File + * @psalm-import-type ProcessedClassType from \SebastianBergmann\CodeCoverage\Node\File + * @psalm-import-type ProcessedTraitType from \SebastianBergmann\CodeCoverage\Node\File */ abstract class AbstractNode implements Countable { @@ -26388,11 +28442,20 @@ abstract class AbstractNode implements Countable { return $this->numberOfTestedFunctions() + $this->numberOfTestedMethods(); } + /** + * @psalm-return array + */ public abstract function classes() : array; + /** + * @psalm-return array + */ public abstract function traits() : array; + /** + * @psalm-return array + */ public abstract function functions() : array; /** - * @psalm-return array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int} + * @psalm-return LinesOfCodeType */ public abstract function linesOfCode() : array; public abstract function numberOfExecutableLines() : int; @@ -26464,6 +28527,8 @@ use PHPUnit\SebastianBergmann\CodeCoverage\Data\ProcessedCodeCoverageData; use PHPUnit\SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage + * + * @psalm-import-type TestType from \SebastianBergmann\CodeCoverage\CodeCoverage */ final class Builder { @@ -26482,7 +28547,7 @@ final class Builder return $root; } /** - * @psalm-param array $tests + * @psalm-param array $tests */ private function addItems(Directory $root, array $items, array $tests) : void { @@ -26539,6 +28604,8 @@ final class Builder * ) * ) * + * + * @psalm-return array, functionCoverage: array>}>> */ private function buildDirectoryStructure(ProcessedCodeCoverageData $data) : array { @@ -26702,6 +28769,8 @@ use IteratorAggregate; use RecursiveIteratorIterator; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage + * + * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser */ final class Directory extends AbstractNode implements IteratorAggregate { @@ -26721,7 +28790,7 @@ final class Directory extends AbstractNode implements IteratorAggregate private ?array $traits = null; private ?array $functions = null; /** - * @psalm-var null|array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int} + * @psalm-var null|LinesOfCodeType */ private ?array $linesOfCode = null; private int $numFiles = -1; @@ -26810,7 +28879,7 @@ final class Directory extends AbstractNode implements IteratorAggregate return $this->functions; } /** - * @psalm-return array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int} + * @psalm-return LinesOfCodeType */ public function linesOfCode() : array { @@ -26984,9 +29053,86 @@ use function count; use function range; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage + * + * @psalm-import-type CodeUnitFunctionType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor + * @psalm-import-type CodeUnitMethodType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor + * @psalm-import-type CodeUnitClassType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor + * @psalm-import-type CodeUnitTraitType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor + * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser + * @psalm-import-type LinesType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser + * + * @psalm-type ProcessedFunctionType = array{ + * functionName: string, + * namespace: string, + * signature: string, + * startLine: int, + * endLine: int, + * executableLines: int, + * executedLines: int, + * executableBranches: int, + * executedBranches: int, + * executablePaths: int, + * executedPaths: int, + * ccn: int, + * coverage: int|float, + * crap: int|string, + * link: string + * } + * @psalm-type ProcessedMethodType = array{ + * methodName: string, + * visibility: string, + * signature: string, + * startLine: int, + * endLine: int, + * executableLines: int, + * executedLines: int, + * executableBranches: int, + * executedBranches: int, + * executablePaths: int, + * executedPaths: int, + * ccn: int, + * coverage: float|int, + * crap: int|string, + * link: string + * } + * @psalm-type ProcessedClassType = array{ + * className: string, + * namespace: string, + * methods: array, + * startLine: int, + * executableLines: int, + * executedLines: int, + * executableBranches: int, + * executedBranches: int, + * executablePaths: int, + * executedPaths: int, + * ccn: int, + * coverage: int|float, + * crap: int|string, + * link: string + * } + * @psalm-type ProcessedTraitType = array{ + * traitName: string, + * namespace: string, + * methods: array, + * startLine: int, + * executableLines: int, + * executedLines: int, + * executableBranches: int, + * executedBranches: int, + * executablePaths: int, + * executedPaths: int, + * ccn: int, + * coverage: float|int, + * crap: int|string, + * link: string + * } */ final class File extends AbstractNode { + /** + * @psalm-var array> + */ private array $lineCoverageData; private array $functionCoverageData; private readonly array $testData; @@ -26996,11 +29142,20 @@ final class File extends AbstractNode private int $numExecutedBranches = 0; private int $numExecutablePaths = 0; private int $numExecutedPaths = 0; + /** + * @psalm-var array + */ private array $classes = []; + /** + * @psalm-var array + */ private array $traits = []; + /** + * @psalm-var array + */ private array $functions = []; /** - * @psalm-return array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int} + * @psalm-var LinesOfCodeType */ private readonly array $linesOfCode; private ?int $numClasses = null; @@ -27010,9 +29165,16 @@ final class File extends AbstractNode private ?int $numMethods = null; private ?int $numTestedMethods = null; private ?int $numTestedFunctions = null; + /** + * @var array + */ private array $codeUnitsByLine = []; /** - * @psalm-param array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int} $linesOfCode + * @psalm-param array> $lineCoverageData + * @psalm-param LinesOfCodeType $linesOfCode + * @psalm-param array $classes + * @psalm-param array $traits + * @psalm-param array $functions */ public function __construct(string $name, AbstractNode $parent, array $lineCoverageData, array $functionCoverageData, array $testData, array $classes, array $traits, array $functions, array $linesOfCode) { @@ -27027,6 +29189,9 @@ final class File extends AbstractNode { return 1; } + /** + * @psalm-return array> + */ public function lineCoverageData() : array { return $this->lineCoverageData; @@ -27051,9 +29216,6 @@ final class File extends AbstractNode { return $this->functions; } - /** - * @psalm-return array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int} - */ public function linesOfCode() : array { return $this->linesOfCode; @@ -27178,6 +29340,11 @@ final class File extends AbstractNode } return $this->numTestedFunctions; } + /** + * @psalm-param array $classes + * @psalm-param array $traits + * @psalm-param array $functions + */ private function calculateStatistics(array $classes, array $traits, array $functions) : void { foreach (range(1, $this->linesOfCode['linesOfCode']) as $lineNumber) { @@ -27253,6 +29420,9 @@ final class File extends AbstractNode } } } + /** + * @psalm-param array $classes + */ private function processClasses(array $classes) : void { $link = $this->id() . '.html#'; @@ -27275,6 +29445,9 @@ final class File extends AbstractNode } } } + /** + * @psalm-param array $traits + */ private function processTraits(array $traits) : void { $link = $this->id() . '.html#'; @@ -27297,6 +29470,9 @@ final class File extends AbstractNode } } } + /** + * @psalm-param array $functions + */ private function processFunctions(array $functions) : void { $link = $this->id() . '.html#'; @@ -27323,6 +29499,11 @@ final class File extends AbstractNode $this->numExecutedPaths += $this->functions[$functionName]['executedPaths']; } } + /** + * @psalm-param CodeUnitMethodType $method + * + * @psalm-return ProcessedMethodType + */ private function newMethod(string $className, string $methodName, array $method, string $link) : array { $methodData = ['methodName' => $methodName, 'visibility' => $method['visibility'], 'signature' => $method['signature'], 'startLine' => $method['startLine'], 'endLine' => $method['endLine'], 'executableLines' => 0, 'executedLines' => 0, 'executableBranches' => 0, 'executedBranches' => 0, 'executablePaths' => 0, 'executedPaths' => 0, 'ccn' => $method['ccn'], 'coverage' => 0, 'crap' => 0, 'link' => $link . $method['startLine']]; @@ -27441,6 +29622,7 @@ use function is_string; use function ksort; use function max; use function range; +use function strpos; use function time; use DOMDocument; use PHPUnit\SebastianBergmann\CodeCoverage\CodeCoverage; @@ -27496,7 +29678,7 @@ final class Clover } $methodCount = 0; foreach (range($method['startLine'], $method['endLine']) as $line) { - if (isset($coverageData[$line]) && $coverageData[$line] !== null) { + if (isset($coverageData[$line])) { $methodCount = max($methodCount, count($coverageData[$line])); } } @@ -27601,7 +29783,9 @@ final class Clover $xmlProject->appendChild($xmlMetrics); $buffer = $xmlDocument->saveXML(); if ($target !== null) { - Filesystem::createDirectory(dirname($target)); + if (!strpos($target, '://') !== \false) { + Filesystem::createDirectory(dirname($target)); + } if (@file_put_contents($target, $buffer) === \false) { throw new WriteOperationFailedException($target); } @@ -27629,6 +29813,7 @@ use function file_put_contents; use function preg_match; use function range; use function str_replace; +use function strpos; use function time; use DOMImplementation; use PHPUnit\SebastianBergmann\CodeCoverage\CodeCoverage; @@ -27738,7 +29923,7 @@ final class Cobertura $methodLinesElement = $document->createElement('lines'); $methodElement->appendChild($methodLinesElement); foreach (range($method['startLine'], $method['endLine']) as $line) { - if (!isset($coverageData[$line]) || $coverageData[$line] === null) { + if (!isset($coverageData[$line])) { continue; } $methodLineElement = $document->createElement('line'); @@ -27751,7 +29936,7 @@ final class Cobertura $methodsElement->appendChild($methodElement); } } - if ($report->numberOfFunctions() === 0) { + if ($item->numberOfFunctions() === 0) { $packageElement->setAttribute('complexity', (string) $packageComplexity); continue; } @@ -27767,7 +29952,7 @@ final class Cobertura $classElement->appendChild($methodsElement); $classLinesElement = $document->createElement('lines'); $classElement->appendChild($classLinesElement); - $functions = $report->functions(); + $functions = $item->functions(); foreach ($functions as $functionName => $function) { if ($function['executableLines'] === 0) { continue; @@ -27794,7 +29979,7 @@ final class Cobertura $methodLinesElement = $document->createElement('lines'); $methodElement->appendChild($methodLinesElement); foreach (range($function['startLine'], $function['endLine']) as $line) { - if (!isset($coverageData[$line]) || $coverageData[$line] === null) { + if (!isset($coverageData[$line])) { continue; } $methodLineElement = $document->createElement('line'); @@ -27820,7 +30005,9 @@ final class Cobertura $coverageElement->setAttribute('complexity', (string) $complexity); $buffer = $document->saveXML(); if ($target !== null) { - Filesystem::createDirectory(dirname($target)); + if (!strpos($target, '://') !== \false) { + Filesystem::createDirectory(dirname($target)); + } if (@file_put_contents($target, $buffer) === \false) { throw new WriteOperationFailedException($target); } @@ -27847,6 +30034,7 @@ use function file_put_contents; use function htmlspecialchars; use function is_string; use function round; +use function strpos; use DOMDocument; use PHPUnit\SebastianBergmann\CodeCoverage\CodeCoverage; use PHPUnit\SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException; @@ -27927,7 +30115,9 @@ final class Crap4j $root->appendChild($methodsNode); $buffer = $document->saveXML(); if ($target !== null) { - Filesystem::createDirectory(dirname($target)); + if (!strpos($target, '://') !== \false) { + Filesystem::createDirectory(dirname($target)); + } if (@file_put_contents($target, $buffer) === \false) { throw new WriteOperationFailedException($target); } @@ -28071,9 +30261,11 @@ use function date; use function dirname; use function str_ends_with; use PHPUnit\SebastianBergmann\CodeCoverage\CodeCoverage; +use PHPUnit\SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException; use PHPUnit\SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode; use PHPUnit\SebastianBergmann\CodeCoverage\Report\Thresholds; use PHPUnit\SebastianBergmann\CodeCoverage\Util\Filesystem; +use PHPUnit\SebastianBergmann\Template\Exception; use PHPUnit\SebastianBergmann\Template\Template; final class Facade { @@ -28137,7 +30329,11 @@ final class Facade { $template = new Template($this->templatePath . 'css/style.css', '{{', '}}'); $template->setVar(['success-low' => $this->colors->successLow(), 'success-medium' => $this->colors->successMedium(), 'success-high' => $this->colors->successHigh(), 'warning' => $this->colors->warning(), 'danger' => $this->colors->danger()]); - $template->renderTo($this->directory($target . '_css') . 'style.css'); + try { + $template->renderTo($this->directory($target . '_css') . 'style.css'); + } catch (Exception $e) { + throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e); + } } private function directory(string $directory) : string { @@ -28341,8 +30537,10 @@ use function floor; use function json_encode; use function sprintf; use function str_replace; +use PHPUnit\SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException; use PHPUnit\SebastianBergmann\CodeCoverage\Node\AbstractNode; use PHPUnit\SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode; +use PHPUnit\SebastianBergmann\Template\Exception; use PHPUnit\SebastianBergmann\Template\Template; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage @@ -28361,7 +30559,11 @@ final class Dashboard extends Renderer $insufficientCoverage = $this->insufficientCoverage($classes, $baseLink); $projectRisks = $this->projectRisks($classes, $baseLink); $template->setVar(['insufficient_coverage_classes' => $insufficientCoverage['class'], 'insufficient_coverage_methods' => $insufficientCoverage['method'], 'project_risks_classes' => $projectRisks['class'], 'project_risks_methods' => $projectRisks['method'], 'complexity_class' => $complexity['class'], 'complexity_method' => $complexity['method'], 'class_coverage_distribution' => $coverageDistribution['class'], 'method_coverage_distribution' => $coverageDistribution['method']]); - $template->renderTo($file); + try { + $template->renderTo($file); + } catch (Exception $e) { + throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e); + } } protected function activeBreadcrumb(AbstractNode $node) : string { @@ -28497,8 +30699,10 @@ namespace PHPUnit\SebastianBergmann\CodeCoverage\Report\Html; use function count; use function sprintf; use function str_repeat; +use PHPUnit\SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException; use PHPUnit\SebastianBergmann\CodeCoverage\Node\AbstractNode as Node; use PHPUnit\SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode; +use PHPUnit\SebastianBergmann\Template\Exception; use PHPUnit\SebastianBergmann\Template\Template; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage @@ -28518,7 +30722,11 @@ final class Directory extends Renderer $items .= $this->renderItem($item); } $template->setVar(['id' => $node->id(), 'items' => $items]); - $template->renderTo($file); + try { + $template->renderTo($file); + } catch (Exception $e) { + throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e); + } } private function renderItem(Node $node, bool $total = \false) : string { @@ -28629,9 +30837,7 @@ use function array_keys; use function array_merge; use function array_pop; use function array_unique; -use function constant; use function count; -use function defined; use function explode; use function file_get_contents; use function htmlspecialchars; @@ -28644,8 +30850,10 @@ use function str_ends_with; use function str_replace; use function token_get_all; use function trim; +use PHPUnit\SebastianBergmann\CodeCoverage\FileCouldNotBeWrittenException; use PHPUnit\SebastianBergmann\CodeCoverage\Node\File as FileNode; use PHPUnit\SebastianBergmann\CodeCoverage\Util\Percentage; +use PHPUnit\SebastianBergmann\Template\Exception; use PHPUnit\SebastianBergmann\Template\Template; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage @@ -28655,7 +30863,7 @@ final class File extends Renderer /** * @psalm-var array */ - private static array $keywordTokens = []; + private const KEYWORD_TOKENS = [T_ABSTRACT => \true, T_ARRAY => \true, T_AS => \true, T_BREAK => \true, T_CALLABLE => \true, T_CASE => \true, T_CATCH => \true, T_CLASS => \true, T_CLONE => \true, T_CONST => \true, T_CONTINUE => \true, T_DECLARE => \true, T_DEFAULT => \true, T_DO => \true, T_ECHO => \true, T_ELSE => \true, T_ELSEIF => \true, T_EMPTY => \true, T_ENDDECLARE => \true, T_ENDFOR => \true, T_ENDFOREACH => \true, T_ENDIF => \true, T_ENDSWITCH => \true, T_ENDWHILE => \true, \T_ENUM => \true, T_EVAL => \true, T_EXIT => \true, T_EXTENDS => \true, T_FINAL => \true, T_FINALLY => \true, \T_FN => \true, T_FOR => \true, T_FOREACH => \true, T_FUNCTION => \true, T_GLOBAL => \true, T_GOTO => \true, T_HALT_COMPILER => \true, T_IF => \true, T_IMPLEMENTS => \true, T_INCLUDE => \true, T_INCLUDE_ONCE => \true, T_INSTANCEOF => \true, T_INSTEADOF => \true, T_INTERFACE => \true, T_ISSET => \true, T_LIST => \true, \T_MATCH => \true, T_NAMESPACE => \true, T_NEW => \true, T_PRINT => \true, T_PRIVATE => \true, T_PROTECTED => \true, T_PUBLIC => \true, \T_READONLY => \true, T_REQUIRE => \true, T_REQUIRE_ONCE => \true, T_RETURN => \true, T_STATIC => \true, T_SWITCH => \true, T_THROW => \true, T_TRAIT => \true, T_TRY => \true, T_UNSET => \true, T_USE => \true, T_VAR => \true, T_WHILE => \true, T_YIELD => \true, T_YIELD_FROM => \true]; private static array $formattedSourceCache = []; private int $htmlSpecialCharsFlags = ENT_COMPAT | ENT_HTML401 | ENT_SUBSTITUTE; public function render(FileNode $node, string $file) : void @@ -28664,12 +30872,24 @@ final class File extends Renderer $template = new Template($templateName, '{{', '}}'); $this->setCommonTemplateVariables($template, $node); $template->setVar(['items' => $this->renderItems($node), 'lines' => $this->renderSourceWithLineCoverage($node), 'legend' => '

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

', 'structure' => '']); - $template->renderTo($file . '.html'); + try { + $template->renderTo($file . '.html'); + } catch (Exception $e) { + throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e); + } if ($this->hasBranchCoverage) { $template->setVar(['items' => $this->renderItems($node), 'lines' => $this->renderSourceWithBranchCoverage($node), 'legend' => '

Fully coveredPartially coveredNot covered

', 'structure' => $this->renderBranchStructure($node)]); - $template->renderTo($file . '_branch.html'); + try { + $template->renderTo($file . '_branch.html'); + } catch (Exception $e) { + throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e); + } $template->setVar(['items' => $this->renderItems($node), 'lines' => $this->renderSourceWithPathCoverage($node), 'legend' => '

Fully coveredPartially coveredNot covered

', 'structure' => $this->renderPathStructure($node)]); - $template->renderTo($file . '_path.html'); + try { + $template->renderTo($file . '_path.html'); + } catch (Exception $e) { + throw new FileCouldNotBeWrittenException($e->getMessage(), $e->getCode(), $e); + } } } private function renderItems(FileNode $node) : string @@ -29187,30 +31407,7 @@ final class File extends Renderer } private function isKeyword(int $token) : bool { - return isset(self::keywordTokens()[$token]); - } - /** - * @psalm-return array - */ - private static function keywordTokens() : array - { - if (self::$keywordTokens !== []) { - return self::$keywordTokens; - } - self::$keywordTokens = [T_ABSTRACT => \true, T_ARRAY => \true, T_AS => \true, T_BREAK => \true, T_CALLABLE => \true, T_CASE => \true, T_CATCH => \true, T_CLASS => \true, T_CLONE => \true, T_CONST => \true, T_CONTINUE => \true, T_DECLARE => \true, T_DEFAULT => \true, T_DO => \true, T_ECHO => \true, T_ELSE => \true, T_ELSEIF => \true, T_EMPTY => \true, T_ENDDECLARE => \true, T_ENDFOR => \true, T_ENDFOREACH => \true, T_ENDIF => \true, T_ENDSWITCH => \true, T_ENDWHILE => \true, T_EVAL => \true, T_EXIT => \true, T_EXTENDS => \true, T_FINAL => \true, T_FINALLY => \true, T_FOR => \true, T_FOREACH => \true, T_FUNCTION => \true, T_GLOBAL => \true, T_GOTO => \true, T_HALT_COMPILER => \true, T_IF => \true, T_IMPLEMENTS => \true, T_INCLUDE => \true, T_INCLUDE_ONCE => \true, T_INSTANCEOF => \true, T_INSTEADOF => \true, T_INTERFACE => \true, T_ISSET => \true, T_LIST => \true, T_NAMESPACE => \true, T_NEW => \true, T_PRINT => \true, T_PRIVATE => \true, T_PROTECTED => \true, T_PUBLIC => \true, T_REQUIRE => \true, T_REQUIRE_ONCE => \true, T_RETURN => \true, T_STATIC => \true, T_SWITCH => \true, T_THROW => \true, T_TRAIT => \true, T_TRY => \true, T_UNSET => \true, T_USE => \true, T_VAR => \true, T_WHILE => \true, T_YIELD => \true, T_YIELD_FROM => \true]; - if (defined('T_FN')) { - self::$keywordTokens[constant('T_FN')] = \true; - } - if (defined('T_MATCH')) { - self::$keywordTokens[constant('T_MATCH')] = \true; - } - if (defined('T_ENUM')) { - self::$keywordTokens[constant('T_ENUM')] = \true; - } - if (defined('T_READONLY')) { - self::$keywordTokens[constant('T_READONLY')] = \true; - } - return self::$keywordTokens; + return isset(self::KEYWORD_TOKENS[$token]); } }
@@ -29365,7 +31562,7 @@ svg text { .scrollbox { height:245px; - overflow-x:hidden; + overflow-x:scroll; overflow-y:scroll; } @@ -30430,6 +32627,7 @@ namespace PHPUnit\SebastianBergmann\CodeCoverage\Report; use function dirname; use function file_put_contents; use function serialize; +use function strpos; use PHPUnit\SebastianBergmann\CodeCoverage\CodeCoverage; use PHPUnit\SebastianBergmann\CodeCoverage\Driver\WriteOperationFailedException; use PHPUnit\SebastianBergmann\CodeCoverage\Util\Filesystem; @@ -30437,9 +32635,12 @@ final class PHP { public function process(CodeCoverage $coverage, ?string $target = null) : string { + $coverage->clearCache(); $buffer = "contextNode = $context; } + /** + * @param TestType $result + */ public function addTest(string $test, array $result) : void { $node = $this->contextNode->appendChild($this->contextNode->ownerDocument->createElementNS('https://schema.phpunit.de/coverage/1.0', 'test')); @@ -31535,7 +33741,7 @@ final class CacheWarmer { public function warmCache(string $cacheDirectory, bool $useAnnotationsForIgnoringCode, bool $ignoreDeprecatedCode, Filter $filter) : void { - $analyser = new CachingFileAnalyser($cacheDirectory, new ParsingFileAnalyser($useAnnotationsForIgnoringCode, $ignoreDeprecatedCode)); + $analyser = new CachingFileAnalyser($cacheDirectory, new ParsingFileAnalyser($useAnnotationsForIgnoringCode, $ignoreDeprecatedCode), $useAnnotationsForIgnoringCode, $ignoreDeprecatedCode); foreach ($filter->files() as $file) { $analyser->process($file); } @@ -31565,18 +33771,24 @@ use PHPUnit\SebastianBergmann\CodeCoverage\Util\Filesystem; use PHPUnit\SebastianBergmann\FileIterator\Facade as FileIteratorFacade; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage + * + * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser */ final class CachingFileAnalyser implements FileAnalyser { private static ?string $cacheVersion = null; + private readonly string $directory; private readonly FileAnalyser $analyser; + private readonly bool $useAnnotationsForIgnoringCode; + private readonly bool $ignoreDeprecatedCode; private array $cache = []; - private readonly string $directory; - public function __construct(string $directory, FileAnalyser $analyser) + public function __construct(string $directory, FileAnalyser $analyser, bool $useAnnotationsForIgnoringCode, bool $ignoreDeprecatedCode) { Filesystem::createDirectory($directory); $this->analyser = $analyser; $this->directory = $directory; + $this->useAnnotationsForIgnoringCode = $useAnnotationsForIgnoringCode; + $this->ignoreDeprecatedCode = $ignoreDeprecatedCode; } public function classesIn(string $filename) : array { @@ -31600,7 +33812,7 @@ final class CachingFileAnalyser implements FileAnalyser return $this->cache[$filename]['functionsIn']; } /** - * @psalm-return array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int} + * @psalm-return LinesOfCodeType */ public function linesOfCodeFor(string $filename) : array { @@ -31647,7 +33859,8 @@ final class CachingFileAnalyser implements FileAnalyser } private function cacheFile(string $filename) : string { - return $this->directory . \DIRECTORY_SEPARATOR . md5($filename . "\x00" . file_get_contents($filename) . "\x00" . self::cacheVersion()); + $cacheKey = md5(implode("\x00", [$filename, file_get_contents($filename), self::cacheVersion(), $this->useAnnotationsForIgnoringCode, $this->ignoreDeprecatedCode])); + return $this->directory . \DIRECTORY_SEPARATOR . $cacheKey; } private static function cacheVersion() : string { @@ -31698,19 +33911,53 @@ use PHPUnit\PhpParser\NodeVisitorAbstract; use PHPUnit\SebastianBergmann\Complexity\CyclomaticComplexityCalculatingVisitor; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage + * + * @psalm-type CodeUnitFunctionType = array{ + * name: string, + * namespacedName: string, + * namespace: string, + * signature: string, + * startLine: int, + * endLine: int, + * ccn: int + * } + * @psalm-type CodeUnitMethodType = array{ + * methodName: string, + * signature: string, + * visibility: string, + * startLine: int, + * endLine: int, + * ccn: int + * } + * @psalm-type CodeUnitClassType = array{ + * name: string, + * namespacedName: string, + * namespace: string, + * startLine: int, + * endLine: int, + * methods: array + * } + * @psalm-type CodeUnitTraitType = array{ + * name: string, + * namespacedName: string, + * namespace: string, + * startLine: int, + * endLine: int, + * methods: array + * } */ final class CodeUnitFindingVisitor extends NodeVisitorAbstract { /** - * @psalm-var array}> + * @psalm-var array */ private array $classes = []; /** - * @psalm-var array}> + * @psalm-var array */ private array $traits = []; /** - * @psalm-var array + * @psalm-var array */ private array $functions = []; public function enterNode(Node $node) : void @@ -31738,21 +33985,21 @@ final class CodeUnitFindingVisitor extends NodeVisitorAbstract $this->processFunction($node); } /** - * @psalm-return array}> + * @psalm-return array */ public function classes() : array { return $this->classes; } /** - * @psalm-return array}> + * @psalm-return array */ public function traits() : array { return $this->traits; } /** - * @psalm-return array + * @psalm-return array */ public function functions() : array { @@ -31919,13 +34166,15 @@ use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\NodeVisitorAbstract; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage + * + * @psalm-import-type LinesType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser */ final class ExecutableLinesFindingVisitor extends NodeVisitorAbstract { private int $nextBranch = 0; private readonly string $source; /** - * @psalm-var array + * @psalm-var LinesType */ private array $executableLinesGroupedByBranch = []; /** @@ -31968,14 +34217,37 @@ final class ExecutableLinesFindingVisitor extends NodeVisitorAbstract } return; } - if ($node instanceof Node\Stmt\Declare_ || $node instanceof Node\Stmt\DeclareDeclare || $node instanceof Node\Stmt\Else_ || $node instanceof Node\Stmt\EnumCase || $node instanceof Node\Stmt\Finally_ || $node instanceof Node\Stmt\Label || $node instanceof Node\Stmt\Namespace_ || $node instanceof Node\Stmt\Nop || $node instanceof Node\Stmt\Switch_ || $node instanceof Node\Stmt\TryCatch || $node instanceof Node\Stmt\Use_ || $node instanceof Node\Stmt\UseUse || $node instanceof Node\Expr\ConstFetch || $node instanceof Node\Expr\Match_ || $node instanceof Node\Expr\Variable || $node instanceof Node\ComplexType || $node instanceof Node\Const_ || $node instanceof Node\Identifier || $node instanceof Node\Name || $node instanceof Node\Param || $node instanceof Node\Scalar) { + if ($node instanceof Node\Stmt\Declare_ || $node instanceof Node\Stmt\DeclareDeclare || $node instanceof Node\Stmt\Else_ || $node instanceof Node\Stmt\EnumCase || $node instanceof Node\Stmt\Finally_ || $node instanceof Node\Stmt\GroupUse || $node instanceof Node\Stmt\Label || $node instanceof Node\Stmt\Namespace_ || $node instanceof Node\Stmt\Nop || $node instanceof Node\Stmt\Switch_ || $node instanceof Node\Stmt\TryCatch || $node instanceof Node\Stmt\Use_ || $node instanceof Node\Stmt\UseUse || $node instanceof Node\Expr\ConstFetch || $node instanceof Node\Expr\Match_ || $node instanceof Node\Expr\Variable || $node instanceof Node\Expr\Throw_ || $node instanceof Node\ComplexType || $node instanceof Node\Const_ || $node instanceof Node\Identifier || $node instanceof Node\Name || $node instanceof Node\Param || $node instanceof Node\Scalar) { return; } + /* + * nikic/php-parser ^4.18 represents throw statements + * as Stmt\Throw_ objects + */ if ($node instanceof Node\Stmt\Throw_) { $this->setLineBranch($node->expr->getEndLine(), $node->expr->getEndLine(), ++$this->nextBranch); return; } + /* + * nikic/php-parser ^5 represents throw statements + * as Stmt\Expression objects that contain an + * Expr\Throw_ object + */ + if ($node instanceof Node\Stmt\Expression && $node->expr instanceof Node\Expr\Throw_) { + $this->setLineBranch($node->expr->expr->getEndLine(), $node->expr->expr->getEndLine(), ++$this->nextBranch); + return; + } if ($node instanceof Node\Stmt\Enum_ || $node instanceof Node\Stmt\Function_ || $node instanceof Node\Stmt\Class_ || $node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Expr\Closure || $node instanceof Node\Stmt\Trait_) { + if ($node instanceof Node\Stmt\Function_ || $node instanceof Node\Stmt\ClassMethod) { + $unsets = []; + foreach ($node->getParams() as $param) { + foreach (range($param->getStartLine(), $param->getEndLine()) as $line) { + $unsets[$line] = \true; + } + } + unset($unsets[$node->getEndLine()]); + $this->unsets += $unsets; + } $isConcreteClassLike = $node instanceof Node\Stmt\Enum_ || $node instanceof Node\Stmt\Class_ || $node instanceof Node\Stmt\Trait_; if (null !== $node->stmts) { foreach ($node->stmts as $stmt) { @@ -31995,7 +34267,7 @@ final class ExecutableLinesFindingVisitor extends NodeVisitorAbstract } $hasEmptyBody = [] === $node->stmts || null === $node->stmts || 1 === count($node->stmts) && $node->stmts[0] instanceof Node\Stmt\Nop; if ($hasEmptyBody) { - if ($node->getEndLine() === $node->getStartLine()) { + if ($node->getEndLine() === $node->getStartLine() && isset($this->executableLinesGroupedByBranch[$node->getStartLine()])) { return; } $this->setLineBranch($node->getEndLine(), $node->getEndLine(), ++$this->nextBranch); @@ -32106,6 +34378,9 @@ final class ExecutableLinesFindingVisitor extends NodeVisitorAbstract } $this->executableLinesGroupedByBranch = array_diff_key($this->executableLinesGroupedByBranch, $this->unsets); } + /** + * @psalm-return LinesType + */ public function executableLinesGroupedByBranch() : array { return $this->executableLinesGroupedByBranch; @@ -32132,17 +34407,46 @@ namespace PHPUnit\SebastianBergmann\CodeCoverage\StaticAnalysis; /** * @internal This class is not covered by the backward compatibility promise for phpunit/php-code-coverage + * + * @psalm-import-type CodeUnitFunctionType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor + * @psalm-import-type CodeUnitMethodType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor + * @psalm-import-type CodeUnitClassType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor + * @psalm-import-type CodeUnitTraitType from \SebastianBergmann\CodeCoverage\StaticAnalysis\CodeUnitFindingVisitor + * @psalm-import-type LinesOfCodeType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser + * @psalm-import-type LinesType from \SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser + * + * @psalm-type LinesOfCodeType = array{ + * linesOfCode: int, + * commentLinesOfCode: int, + * nonCommentLinesOfCode: int + * } + * @psalm-type LinesType = array */ interface FileAnalyser { + /** + * @psalm-return array + */ public function classesIn(string $filename) : array; + /** + * @psalm-return array + */ public function traitsIn(string $filename) : array; + /** + * @psalm-return array + */ public function functionsIn(string $filename) : array; /** - * @psalm-return array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int} + * @psalm-return LinesOfCodeType */ public function linesOfCodeFor(string $filename) : array; + /** + * @psalm-return LinesType + */ public function executableLinesIn(string $filename) : array; + /** + * @psalm-return LinesType + */ public function ignoredLinesFor(string $filename) : array; } > + */ private array $classes = []; + /** + * @psalm-var array> + */ private array $traits = []; + /** + * @psalm-var array> + */ private array $functions = []; /** - * @var array + * @var array */ private array $linesOfCode = []; + /** + * @var array + */ private array $ignoredLines = []; + /** + * @var array + */ private array $executableLines = []; private readonly bool $useAnnotationsForIgnoringCode; private readonly bool $ignoreDeprecatedCode; @@ -32308,9 +34633,6 @@ final class ParsingFileAnalyser implements FileAnalyser $this->analyse($filename); return $this->functions[$filename]; } - /** - * @psalm-return array{linesOfCode: int, commentLinesOfCode: int, nonCommentLinesOfCode: int} - */ public function linesOfCodeFor(string $filename) : array { $this->analyse($filename); @@ -32339,7 +34661,8 @@ final class ParsingFileAnalyser implements FileAnalyser if ($linesOfCode === 0 && !empty($source)) { $linesOfCode = 1; } - $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7, new Lexer()); + assert($linesOfCode > 0); + $parser = (new ParserFactory())->createForHostVersion(); try { $nodes = $parser->parse($source); assert($nodes !== null); @@ -32911,7 +35234,7 @@ final class Version public static function id() : string { if (self::$version === '') { - self::$version = (new VersionId('10.0.2', dirname(__DIR__)))->asString(); + self::$version = (new VersionId('10.1.11', dirname(__DIR__)))->asString(); } return self::$version; } @@ -32956,6 +35279,9 @@ final class ExcludeIterator extends RecursiveFilterIterator $current = $this->current(); assert($current instanceof SplFileInfo); $path = $current->getRealPath(); + if ($path === \false) { + return \false; + } foreach ($this->exclude as $exclude) { if (str_starts_with($path, $exclude)) { return \false; @@ -33001,15 +35327,16 @@ use SplFileInfo; final class Facade { /** - * @psalm-param list|string $suffixes - * @psalm-param list|string $prefixes - * @psalm-param list $exclude + * @psalm-param list|non-empty-string $paths + * @psalm-param list|string $suffixes + * @psalm-param list|string $prefixes + * @psalm-param list $exclude * - * @psalm-return list + * @psalm-return list */ - public function getFilesAsArray(string $path, array|string $suffixes = '', array|string $prefixes = '', array $exclude = []) : array + public function getFilesAsArray(array|string $paths, array|string $suffixes = '', array|string $prefixes = '', array $exclude = []) : array { - $iterator = (new Factory())->getFileIterator($path, $suffixes, $prefixes, $exclude); + $iterator = (new Factory())->getFileIterator($paths, $suffixes, $prefixes, $exclude); $files = []; foreach ($iterator as $file) { assert($file instanceof SplFileInfo); @@ -33055,10 +35382,10 @@ use RecursiveIteratorIterator; final class Factory { /** - * @psalm-param list|string $paths - * @psalm-param list|string $suffixes - * @psalm-param list|string $prefixes - * @psalm-param list $exclude + * @psalm-param list|non-empty-string $paths + * @psalm-param list|string $suffixes + * @psalm-param list|string $prefixes + * @psalm-param list $exclude */ public function getFileIterator(array|string $paths, array|string $suffixes = '', array|string $prefixes = '', array $exclude = []) : AppendIterator { @@ -33090,9 +35417,9 @@ final class Factory return $iterator; } /** - * @psalm-param list $paths + * @psalm-param list $paths * - * @psalm-return list + * @psalm-return list */ private function resolveWildcards(array $paths) : array { @@ -33441,7 +35768,7 @@ final class Template */ public function renderTo(string $target) : void { - if (!file_put_contents($target, $this->render())) { + if (!@file_put_contents($target, $this->render())) { throw new RuntimeException(sprintf('Writing rendered result to "%s" failed', $target)); } } @@ -33747,7 +36074,7 @@ final class TimeSinceStartOfRequestNotAvailableException extends RuntimeExceptio - This Schema file defines the rules by which the XML configuration file of PHPUnit 10.0 may be structured. + This Schema file defines the rules by which the XML configuration file of PHPUnit 10.5 may be structured. @@ -33756,18 +36083,49 @@ final class TimeSinceStartOfRequestNotAvailableException extends RuntimeExceptio Root Element - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -33801,7 +36159,7 @@ final class TimeSinceStartOfRequestNotAvailableException extends RuntimeExceptio - + @@ -33826,23 +36184,6 @@ final class TimeSinceStartOfRequestNotAvailableException extends RuntimeExceptio - - - - - - - - - - - - - - - - - @@ -33865,17 +36206,6 @@ final class TimeSinceStartOfRequestNotAvailableException extends RuntimeExceptio - - - - - - - - - - - @@ -33915,20 +36245,26 @@ final class TimeSinceStartOfRequestNotAvailableException extends RuntimeExceptio + + + + + + + + + + - + - - - - - + @@ -33958,6 +36294,7 @@ final class TimeSinceStartOfRequestNotAvailableException extends RuntimeExceptio + @@ -33975,12 +36312,40 @@ final class TimeSinceStartOfRequestNotAvailableException extends RuntimeExceptio - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -34095,13 +36460,6 @@ final class DeferringDispatcher implements \PHPUnit\Event\SubscribableDispatcher { $this->dispatcher->registerSubscriber($subscriber); } - /** - * @psalm-param class-string $className - */ - public function hasSubscriberFor(string $className) : bool - { - return $this->dispatcher->hasSubscriberFor($className); - } public function dispatch(\PHPUnit\Event\Event $event) : void { if ($this->recording) { @@ -34175,19 +36533,7 @@ final class DirectDispatcher implements \PHPUnit\Event\SubscribableDispatcher $this->subscribers[$eventClassName][] = $subscriber; } /** - * @psalm-param class-string $className - */ - public function hasSubscriberFor(string $className) : bool - { - if ($this->tracers !== []) { - return \true; - } - if (isset($this->subscribers[$className])) { - return \true; - } - return \false; - } - /** + * @throws Throwable * @throws UnknownEventTypeException */ public function dispatch(\PHPUnit\Event\Event $event) : void @@ -34199,9 +36545,11 @@ final class DirectDispatcher implements \PHPUnit\Event\SubscribableDispatcher foreach ($this->tracers as $tracer) { try { $tracer->trace($event); + // @codeCoverageIgnoreStart } catch (Throwable $t) { - $this->ignoreThrowablesFromThirdPartySubscribers($t); + $this->handleThrowable($t); } + // @codeCoverageIgnoreEnd } if (!array_key_exists($eventClassName, $this->subscribers)) { return; @@ -34210,18 +36558,26 @@ final class DirectDispatcher implements \PHPUnit\Event\SubscribableDispatcher try { $subscriber->notify($event); } catch (Throwable $t) { - $this->ignoreThrowablesFromThirdPartySubscribers($t); + $this->handleThrowable($t); } } } /** * @throws Throwable */ - private function ignoreThrowablesFromThirdPartySubscribers(Throwable $t) : void + public function handleThrowable(Throwable $t) : void { - if (str_starts_with($t->getFile(), dirname(__DIR__, 2))) { - throw $t; + if ($this->isThrowableFromThirdPartySubscriber($t)) { + \PHPUnit\Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('Exception in third-party event subscriber: %s%s%s', $t->getMessage(), \PHP_EOL, $t->getTraceAsString())); + return; } + // @codeCoverageIgnoreStart + throw $t; + // @codeCoverageIgnoreEnd + } + private function isThrowableFromThirdPartySubscriber(Throwable $t) : bool + { + return !str_starts_with($t->getFile(), dirname(__DIR__, 2)); } } dispatcher = $dispatcher; @@ -34316,6 +36672,20 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter $this->startSnapshot = $system->snapshot(); $this->previousSnapshot = $system->snapshot(); } + /** + * @deprecated + */ + public function exportObjects() : void + { + $this->exportObjects = \true; + } + /** + * @deprecated + */ + public function exportsObjects() : bool + { + return $this->exportObjects; + } /** * @throws InvalidArgumentException * @throws UnknownEventTypeException @@ -34367,6 +36737,22 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter { $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\ExtensionBootstrapped($this->telemetryInfo(), $className, $parameters)); } + /** + * @throws InvalidArgumentException + * @throws UnknownEventTypeException + */ + public function dataProviderMethodCalled(ClassMethod $testMethod, ClassMethod $dataProviderMethod) : void + { + $this->dispatcher->dispatch(new DataProviderMethodCalled($this->telemetryInfo(), $testMethod, $dataProviderMethod)); + } + /** + * @throws InvalidArgumentException + * @throws UnknownEventTypeException + */ + public function dataProviderMethodFinished(ClassMethod $testMethod, ClassMethod ...$calledMethods) : void + { + $this->dispatcher->dispatch(new DataProviderMethodFinished($this->telemetryInfo(), $testMethod, ...$calledMethods)); + } /** * @throws InvalidArgumentException * @throws UnknownEventTypeException @@ -34407,6 +36793,22 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter { $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\ExecutionStarted($this->telemetryInfo(), $testSuite)); } + /** + * @throws InvalidArgumentException + * @throws UnknownEventTypeException + */ + public function testRunnerDisabledGarbageCollection() : void + { + $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\GarbageCollectionDisabled($this->telemetryInfo())); + } + /** + * @throws InvalidArgumentException + * @throws UnknownEventTypeException + */ + public function testRunnerTriggeredGarbageCollection() : void + { + $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\GarbageCollectionTriggered($this->telemetryInfo())); + } /** * @throws InvalidArgumentException * @throws UnknownEventTypeException @@ -34431,13 +36833,21 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter { $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PreparationStarted($this->telemetryInfo(), $test)); } + /** + * @throws InvalidArgumentException + * @throws UnknownEventTypeException + */ + public function testPreparationFailed(\PHPUnit\Event\Code\Test $test) : void + { + $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PreparationFailed($this->telemetryInfo(), $test)); + } /** * @psalm-param class-string $testClassName * * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testBeforeFirstTestMethodCalled(string $testClassName, \PHPUnit\Event\Code\ClassMethod $calledMethod) : void + public function testBeforeFirstTestMethodCalled(string $testClassName, ClassMethod $calledMethod) : void { $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeFirstTestMethodCalled($this->telemetryInfo(), $testClassName, $calledMethod)); } @@ -34447,7 +36857,7 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testBeforeFirstTestMethodErrored(string $testClassName, \PHPUnit\Event\Code\ClassMethod $calledMethod, Throwable $throwable) : void + public function testBeforeFirstTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable) : void { $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeFirstTestMethodErrored($this->telemetryInfo(), $testClassName, $calledMethod, $throwable)); } @@ -34457,7 +36867,7 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testBeforeFirstTestMethodFinished(string $testClassName, \PHPUnit\Event\Code\ClassMethod ...$calledMethods) : void + public function testBeforeFirstTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods) : void { $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeFirstTestMethodFinished($this->telemetryInfo(), $testClassName, ...$calledMethods)); } @@ -34467,7 +36877,7 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testBeforeTestMethodCalled(string $testClassName, \PHPUnit\Event\Code\ClassMethod $calledMethod) : void + public function testBeforeTestMethodCalled(string $testClassName, ClassMethod $calledMethod) : void { $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeTestMethodCalled($this->telemetryInfo(), $testClassName, $calledMethod)); } @@ -34477,7 +36887,7 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testBeforeTestMethodFinished(string $testClassName, \PHPUnit\Event\Code\ClassMethod ...$calledMethods) : void + public function testBeforeTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods) : void { $this->dispatcher->dispatch(new \PHPUnit\Event\Test\BeforeTestMethodFinished($this->telemetryInfo(), $testClassName, ...$calledMethods)); } @@ -34487,7 +36897,7 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testPreConditionCalled(string $testClassName, \PHPUnit\Event\Code\ClassMethod $calledMethod) : void + public function testPreConditionCalled(string $testClassName, ClassMethod $calledMethod) : void { $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PreConditionCalled($this->telemetryInfo(), $testClassName, $calledMethod)); } @@ -34497,7 +36907,7 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testPreConditionFinished(string $testClassName, \PHPUnit\Event\Code\ClassMethod ...$calledMethods) : void + public function testPreConditionFinished(string $testClassName, ClassMethod ...$calledMethods) : void { $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PreConditionFinished($this->telemetryInfo(), $testClassName, ...$calledMethods)); } @@ -34522,24 +36932,22 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter /** * @throws InvalidArgumentException * @throws UnknownEventTypeException + * + * @deprecated */ public function testAssertionSucceeded(mixed $value, Constraint\Constraint $constraint, string $message) : void { - if (!$this->hasSubscriberFor(\PHPUnit\Event\Test\AssertionSucceeded::class)) { - return; - } - $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AssertionSucceeded($this->telemetryInfo(), (new Exporter())->export($value), $constraint->toString(), $constraint->count(), $message)); + $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AssertionSucceeded($this->telemetryInfo(), Exporter::export($value, $this->exportObjects), $constraint->toString($this->exportObjects), $constraint->count(), $message)); } /** * @throws InvalidArgumentException * @throws UnknownEventTypeException + * + * @deprecated */ public function testAssertionFailed(mixed $value, Constraint\Constraint $constraint, string $message) : void { - if (!$this->hasSubscriberFor(\PHPUnit\Event\Test\AssertionFailed::class)) { - return; - } - $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AssertionFailed($this->telemetryInfo(), (new Exporter())->export($value), $constraint->toString(), $constraint->count(), $message)); + $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AssertionFailed($this->telemetryInfo(), Exporter::export($value, $this->exportObjects), $constraint->toString($this->exportObjects), $constraint->count(), $message)); } /** * @psalm-param class-string $className @@ -34610,7 +37018,7 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter */ public function testCreatedTestProxy(string $className, array $constructorArguments) : void { - $this->dispatcher->dispatch(new \PHPUnit\Event\Test\TestProxyCreated($this->telemetryInfo(), $className, (new Exporter())->export($constructorArguments))); + $this->dispatcher->dispatch(new \PHPUnit\Event\Test\TestProxyCreated($this->telemetryInfo(), $className, Exporter::export($constructorArguments, $this->exportObjects))); } /** * @psalm-param class-string $className @@ -34681,6 +37089,8 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter $this->dispatcher->dispatch(new \PHPUnit\Event\Test\Skipped($this->telemetryInfo(), $test, $message)); } /** + * @psalm-param non-empty-string $message + * * @throws InvalidArgumentException * @throws UnknownEventTypeException */ @@ -34689,62 +37099,92 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpunitDeprecationTriggered($this->telemetryInfo(), $test, $message)); } /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + * * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testTriggeredPhpDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line) : void + public function testTriggeredPhpDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest) : void { - $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpDeprecationTriggered($this->telemetryInfo(), $test, $message, $file, $line)); + $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpDeprecationTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline, $ignoredByTest)); } /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + * * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testTriggeredDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line) : void + public function testTriggeredDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest) : void { - $this->dispatcher->dispatch(new \PHPUnit\Event\Test\DeprecationTriggered($this->telemetryInfo(), $test, $message, $file, $line)); + $this->dispatcher->dispatch(new \PHPUnit\Event\Test\DeprecationTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline, $ignoredByTest)); } /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + * * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testTriggeredError(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line) : void + public function testTriggeredError(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed) : void { - $this->dispatcher->dispatch(new \PHPUnit\Event\Test\ErrorTriggered($this->telemetryInfo(), $test, $message, $file, $line)); + $this->dispatcher->dispatch(new \PHPUnit\Event\Test\ErrorTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed)); } /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + * * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testTriggeredNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line) : void + public function testTriggeredNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline) : void { - $this->dispatcher->dispatch(new \PHPUnit\Event\Test\NoticeTriggered($this->telemetryInfo(), $test, $message, $file, $line)); + $this->dispatcher->dispatch(new \PHPUnit\Event\Test\NoticeTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline)); } /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + * * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testTriggeredPhpNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line) : void + public function testTriggeredPhpNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline) : void { - $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpNoticeTriggered($this->telemetryInfo(), $test, $message, $file, $line)); + $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpNoticeTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline)); } /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + * * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testTriggeredWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line) : void + public function testTriggeredWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline) : void { - $this->dispatcher->dispatch(new \PHPUnit\Event\Test\WarningTriggered($this->telemetryInfo(), $test, $message, $file, $line)); + $this->dispatcher->dispatch(new \PHPUnit\Event\Test\WarningTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline)); } /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + * * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testTriggeredPhpWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line) : void + public function testTriggeredPhpWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline) : void { - $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpWarningTriggered($this->telemetryInfo(), $test, $message, $file, $line)); + $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpWarningTriggered($this->telemetryInfo(), $test, $message, $file, $line, $suppressed, $ignoredByBaseline)); } /** + * @psalm-param non-empty-string $message + * * @throws InvalidArgumentException * @throws UnknownEventTypeException */ @@ -34753,6 +37193,8 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PhpunitErrorTriggered($this->telemetryInfo(), $test, $message)); } /** + * @psalm-param non-empty-string $message + * * @throws InvalidArgumentException * @throws UnknownEventTypeException */ @@ -34784,7 +37226,7 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testPostConditionCalled(string $testClassName, \PHPUnit\Event\Code\ClassMethod $calledMethod) : void + public function testPostConditionCalled(string $testClassName, ClassMethod $calledMethod) : void { $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PostConditionCalled($this->telemetryInfo(), $testClassName, $calledMethod)); } @@ -34794,7 +37236,7 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testPostConditionFinished(string $testClassName, \PHPUnit\Event\Code\ClassMethod ...$calledMethods) : void + public function testPostConditionFinished(string $testClassName, ClassMethod ...$calledMethods) : void { $this->dispatcher->dispatch(new \PHPUnit\Event\Test\PostConditionFinished($this->telemetryInfo(), $testClassName, ...$calledMethods)); } @@ -34804,7 +37246,7 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testAfterTestMethodCalled(string $testClassName, \PHPUnit\Event\Code\ClassMethod $calledMethod) : void + public function testAfterTestMethodCalled(string $testClassName, ClassMethod $calledMethod) : void { $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AfterTestMethodCalled($this->telemetryInfo(), $testClassName, $calledMethod)); } @@ -34814,7 +37256,7 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testAfterTestMethodFinished(string $testClassName, \PHPUnit\Event\Code\ClassMethod ...$calledMethods) : void + public function testAfterTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods) : void { $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AfterTestMethodFinished($this->telemetryInfo(), $testClassName, ...$calledMethods)); } @@ -34824,7 +37266,7 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testAfterLastTestMethodCalled(string $testClassName, \PHPUnit\Event\Code\ClassMethod $calledMethod) : void + public function testAfterLastTestMethodCalled(string $testClassName, ClassMethod $calledMethod) : void { $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AfterLastTestMethodCalled($this->telemetryInfo(), $testClassName, $calledMethod)); } @@ -34834,7 +37276,7 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter * @throws InvalidArgumentException * @throws UnknownEventTypeException */ - public function testAfterLastTestMethodFinished(string $testClassName, \PHPUnit\Event\Code\ClassMethod ...$calledMethods) : void + public function testAfterLastTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods) : void { $this->dispatcher->dispatch(new \PHPUnit\Event\Test\AfterLastTestMethodFinished($this->telemetryInfo(), $testClassName, ...$calledMethods)); } @@ -34862,6 +37304,22 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter { $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\WarningTriggered($this->telemetryInfo(), $message)); } + /** + * @throws InvalidArgumentException + * @throws UnknownEventTypeException + */ + public function testRunnerEnabledGarbageCollection() : void + { + $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\GarbageCollectionEnabled($this->telemetryInfo())); + } + /** + * @throws InvalidArgumentException + * @throws UnknownEventTypeException + */ + public function testRunnerExecutionAborted() : void + { + $this->dispatcher->dispatch(new \PHPUnit\Event\TestRunner\ExecutionAborted($this->telemetryInfo())); + } /** * @throws InvalidArgumentException * @throws UnknownEventTypeException @@ -34896,16 +37354,6 @@ final class DispatchingEmitter implements \PHPUnit\Event\Emitter $this->previousSnapshot = $current; return $info; } - /** - * @psalm-param class-string $className - */ - private function hasSubscriberFor(string $className) : bool - { - if (!$this->dispatcher instanceof \PHPUnit\Event\SubscribableDispatcher) { - return \true; - } - return $this->dispatcher->hasSubscriberFor($className); - } } $parameters */ public function testRunnerBootstrappedExtension(string $className, array $parameters) : void; + public function dataProviderMethodCalled(ClassMethod $testMethod, ClassMethod $dataProviderMethod) : void; + public function dataProviderMethodFinished(ClassMethod $testMethod, ClassMethod ...$calledMethods) : void; public function testSuiteLoaded(TestSuite $testSuite) : void; public function testSuiteFiltered(TestSuite $testSuite) : void; public function testSuiteSorted(int $executionOrder, int $executionOrderDefects, bool $resolveDependencies) : void; public function testRunnerEventFacadeSealed() : void; public function testRunnerExecutionStarted(TestSuite $testSuite) : void; + public function testRunnerDisabledGarbageCollection() : void; + public function testRunnerTriggeredGarbageCollection() : void; public function testSuiteSkipped(TestSuite $testSuite, string $message) : void; public function testSuiteStarted(TestSuite $testSuite) : void; public function testPreparationStarted(\PHPUnit\Event\Code\Test $test) : void; + public function testPreparationFailed(\PHPUnit\Event\Code\Test $test) : void; /** * @psalm-param class-string $testClassName */ - public function testBeforeFirstTestMethodCalled(string $testClassName, \PHPUnit\Event\Code\ClassMethod $calledMethod) : void; + public function testBeforeFirstTestMethodCalled(string $testClassName, ClassMethod $calledMethod) : void; /** * @psalm-param class-string $testClassName */ - public function testBeforeFirstTestMethodErrored(string $testClassName, \PHPUnit\Event\Code\ClassMethod $calledMethod, Throwable $throwable) : void; + public function testBeforeFirstTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable) : void; /** * @psalm-param class-string $testClassName */ - public function testBeforeFirstTestMethodFinished(string $testClassName, \PHPUnit\Event\Code\ClassMethod ...$calledMethods) : void; + public function testBeforeFirstTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods) : void; /** * @psalm-param class-string $testClassName */ - public function testBeforeTestMethodCalled(string $testClassName, \PHPUnit\Event\Code\ClassMethod $calledMethod) : void; + public function testBeforeTestMethodCalled(string $testClassName, ClassMethod $calledMethod) : void; /** * @psalm-param class-string $testClassName */ - public function testBeforeTestMethodFinished(string $testClassName, \PHPUnit\Event\Code\ClassMethod ...$calledMethods) : void; + public function testBeforeTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods) : void; /** * @psalm-param class-string $testClassName */ - public function testPreConditionCalled(string $testClassName, \PHPUnit\Event\Code\ClassMethod $calledMethod) : void; + public function testPreConditionCalled(string $testClassName, ClassMethod $calledMethod) : void; /** * @psalm-param class-string $testClassName */ - public function testPreConditionFinished(string $testClassName, \PHPUnit\Event\Code\ClassMethod ...$calledMethods) : void; + public function testPreConditionFinished(string $testClassName, ClassMethod ...$calledMethods) : void; public function testPrepared(\PHPUnit\Event\Code\Test $test) : void; /** * @psalm-param class-string $className */ public function testRegisteredComparator(string $className) : void; + /** + * @deprecated + */ public function testAssertionSucceeded(mixed $value, Constraint\Constraint $constraint, string $message) : void; + /** + * @deprecated + */ public function testAssertionFailed(mixed $value, Constraint\Constraint $constraint, string $message) : void; /** * @psalm-param class-string $className @@ -35023,18 +37491,68 @@ interface Emitter public function testErrored(\PHPUnit\Event\Code\Test $test, Throwable $throwable) : void; public function testFailed(\PHPUnit\Event\Code\Test $test, Throwable $throwable, ?ComparisonFailure $comparisonFailure) : void; public function testPassed(\PHPUnit\Event\Code\Test $test) : void; + /** + * @psalm-param non-empty-string $message + */ public function testConsideredRisky(\PHPUnit\Event\Code\Test $test, string $message) : void; public function testMarkedAsIncomplete(\PHPUnit\Event\Code\Test $test, Throwable $throwable) : void; + /** + * @psalm-param non-empty-string $message + */ public function testSkipped(\PHPUnit\Event\Code\Test $test, string $message) : void; + /** + * @psalm-param non-empty-string $message + */ public function testTriggeredPhpunitDeprecation(\PHPUnit\Event\Code\Test $test, string $message) : void; - public function testTriggeredPhpDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line) : void; - public function testTriggeredDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line) : void; - public function testTriggeredError(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line) : void; - public function testTriggeredNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line) : void; - public function testTriggeredPhpNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line) : void; - public function testTriggeredWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line) : void; - public function testTriggeredPhpWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line) : void; + /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + */ + public function testTriggeredPhpDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest) : void; + /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + */ + public function testTriggeredDeprecation(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest) : void; + /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + */ + public function testTriggeredError(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed) : void; + /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + */ + public function testTriggeredNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline) : void; + /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + */ + public function testTriggeredPhpNotice(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline) : void; + /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + */ + public function testTriggeredWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline) : void; + /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + */ + public function testTriggeredPhpWarning(\PHPUnit\Event\Code\Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline) : void; + /** + * @psalm-param non-empty-string $message + */ public function testTriggeredPhpunitError(\PHPUnit\Event\Code\Test $test, string $message) : void; + /** + * @psalm-param non-empty-string $message + */ public function testTriggeredPhpunitWarning(\PHPUnit\Event\Code\Test $test, string $message) : void; /** * @psalm-param non-empty-string $output @@ -35044,30 +37562,32 @@ interface Emitter /** * @psalm-param class-string $testClassName */ - public function testPostConditionCalled(string $testClassName, \PHPUnit\Event\Code\ClassMethod $calledMethod) : void; + public function testPostConditionCalled(string $testClassName, ClassMethod $calledMethod) : void; /** * @psalm-param class-string $testClassName */ - public function testPostConditionFinished(string $testClassName, \PHPUnit\Event\Code\ClassMethod ...$calledMethods) : void; + public function testPostConditionFinished(string $testClassName, ClassMethod ...$calledMethods) : void; /** * @psalm-param class-string $testClassName */ - public function testAfterTestMethodCalled(string $testClassName, \PHPUnit\Event\Code\ClassMethod $calledMethod) : void; + public function testAfterTestMethodCalled(string $testClassName, ClassMethod $calledMethod) : void; /** * @psalm-param class-string $testClassName */ - public function testAfterTestMethodFinished(string $testClassName, \PHPUnit\Event\Code\ClassMethod ...$calledMethods) : void; + public function testAfterTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods) : void; /** * @psalm-param class-string $testClassName */ - public function testAfterLastTestMethodCalled(string $testClassName, \PHPUnit\Event\Code\ClassMethod $calledMethod) : void; + public function testAfterLastTestMethodCalled(string $testClassName, ClassMethod $calledMethod) : void; /** * @psalm-param class-string $testClassName */ - public function testAfterLastTestMethodFinished(string $testClassName, \PHPUnit\Event\Code\ClassMethod ...$calledMethods) : void; + public function testAfterLastTestMethodFinished(string $testClassName, ClassMethod ...$calledMethods) : void; public function testSuiteFinished(TestSuite $testSuite) : void; public function testRunnerTriggeredDeprecation(string $message) : void; public function testRunnerTriggeredWarning(string $message) : void; + public function testRunnerEnabledGarbageCollection() : void; + public function testRunnerExecutionAborted() : void; public function testRunnerExecutionFinished() : void; public function testRunnerFinished() : void; public function applicationFinished(int $shellExitCode) : void; @@ -35349,6 +37869,8 @@ use PHPUnit\Event\Event; use PHPUnit\Event\Telemetry; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + * + * @deprecated */ final class AssertionFailed implements Event { @@ -35406,6 +37928,8 @@ namespace PHPUnit\Event\Test; use PHPUnit\Event\Subscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + * + * @deprecated */ interface AssertionFailedSubscriber extends Subscriber { @@ -35429,6 +37953,8 @@ use PHPUnit\Event\Event; use PHPUnit\Event\Telemetry; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + * + * @deprecated */ final class AssertionSucceeded implements Event { @@ -35486,6 +38012,8 @@ namespace PHPUnit\Event\Test; use PHPUnit\Event\Subscriber; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + * + * @deprecated */ interface AssertionSucceededSubscriber extends Subscriber { @@ -36708,7 +39236,13 @@ final class ConsideredRisky implements Event { private readonly Telemetry\Info $telemetryInfo; private readonly Code\Test $test; + /** + * @psalm-var non-empty-string + */ private readonly string $message; + /** + * @psalm-param non-empty-string $message + */ public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test, string $message) { $this->telemetryInfo = $telemetryInfo; @@ -36723,6 +39257,9 @@ final class ConsideredRisky implements Event { return $this->test; } + /** + * @psalm-return non-empty-string + */ public function message() : string { return $this->message; @@ -36780,16 +39317,36 @@ final class DeprecationTriggered implements Event { private readonly Telemetry\Info $telemetryInfo; private readonly Test $test; + /** + * @psalm-var non-empty-string + */ private readonly string $message; + /** + * @psalm-var non-empty-string + */ private readonly string $file; + /** + * @psalm-var positive-int + */ private readonly int $line; - public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line) + private readonly bool $suppressed; + private readonly bool $ignoredByBaseline; + private readonly bool $ignoredByTest; + /** + * @psalm-param non-empty-string $message + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + */ + public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line, bool $suppressed, bool $ignoredByBaseline, bool $ignoredByTest) { $this->telemetryInfo = $telemetryInfo; $this->test = $test; $this->message = $message; $this->file = $file; $this->line = $line; + $this->suppressed = $suppressed; + $this->ignoredByBaseline = $ignoredByBaseline; + $this->ignoredByTest = $ignoredByTest; } public function telemetryInfo() : Telemetry\Info { @@ -36799,25 +39356,54 @@ final class DeprecationTriggered implements Event { return $this->test; } + /** + * @psalm-return non-empty-string + */ public function message() : string { return $this->message; } + /** + * @psalm-return non-empty-string + */ public function file() : string { return $this->file; } + /** + * @psalm-return positive-int + */ public function line() : int { return $this->line; } + public function wasSuppressed() : bool + { + return $this->suppressed; + } + public function ignoredByBaseline() : bool + { + return $this->ignoredByBaseline; + } + public function ignoredByTest() : bool + { + return $this->ignoredByTest; + } public function asString() : string { $message = $this->message; if (!empty($message)) { $message = PHP_EOL . $message; } - return sprintf('Test Triggered Deprecation (%s)%s', $this->test->id(), $message); + $status = ''; + if ($this->ignoredByTest) { + $status = 'Test-Ignored '; + } elseif ($this->ignoredByBaseline) { + $status = 'Baseline-Ignored '; + } elseif ($this->suppressed) { + $status = 'Suppressed '; + } + return sprintf('Test Triggered %sDeprecation (%s)%s', $status, $this->test->id(), $message); } } telemetryInfo = $telemetryInfo; $this->test = $test; $this->message = $message; $this->file = $file; $this->line = $line; + $this->suppressed = $suppressed; } public function telemetryInfo() : Telemetry\Info { @@ -36887,25 +39489,38 @@ final class ErrorTriggered implements Event { return $this->test; } + /** + * @psalm-return non-empty-string + */ public function message() : string { return $this->message; } + /** + * @psalm-return non-empty-string + */ public function file() : string { return $this->file; } + /** + * @psalm-return positive-int + */ public function line() : int { return $this->line; } + public function wasSuppressed() : bool + { + return $this->suppressed; + } public function asString() : string { $message = $this->message; if (!empty($message)) { $message = PHP_EOL . $message; } - return sprintf('Test Triggered Error (%s)%s', $this->test->id(), $message); + return sprintf('Test Triggered %sError (%s)%s', $this->wasSuppressed() ? 'Suppressed ' : '', $this->test->id(), $message); } } telemetryInfo = $telemetryInfo; $this->test = $test; $this->message = $message; $this->file = $file; $this->line = $line; + $this->suppressed = $suppressed; + $this->ignoredByBaseline = $ignoredByBaseline; } public function telemetryInfo() : Telemetry\Info { @@ -36975,25 +39608,48 @@ final class NoticeTriggered implements Event { return $this->test; } + /** + * @psalm-return non-empty-string + */ public function message() : string { return $this->message; } + /** + * @psalm-return non-empty-string + */ public function file() : string { return $this->file; } + /** + * @psalm-return positive-int + */ public function line() : int { return $this->line; } + public function wasSuppressed() : bool + { + return $this->suppressed; + } + public function ignoredByBaseline() : bool + { + return $this->ignoredByBaseline; + } public function asString() : string { $message = $this->message; if (!empty($message)) { $message = PHP_EOL . $message; } - return sprintf('Test Triggered Notice (%s)%s', $this->test->id(), $message); + $status = ''; + if ($this->ignoredByBaseline) { + $status = 'Baseline-Ignored '; + } elseif ($this->suppressed) { + $status = 'Suppressed '; + } + return sprintf('Test Triggered %sNotice (%s)%s', $status, $this->test->id(), $message); } } telemetryInfo = $telemetryInfo; $this->test = $test; $this->message = $message; $this->file = $file; $this->line = $line; + $this->suppressed = $suppressed; + $this->ignoredByBaseline = $ignoredByBaseline; + $this->ignoredByTest = $ignoredByTest; } public function telemetryInfo() : Telemetry\Info { @@ -37063,105 +39739,38 @@ final class PhpDeprecationTriggered implements Event { return $this->test; } + /** + * @psalm-return non-empty-string + */ public function message() : string { return $this->message; } + /** + * @psalm-return non-empty-string + */ public function file() : string { return $this->file; } + /** + * @psalm-return positive-int + */ public function line() : int { return $this->line; } - public function asString() : string - { - $message = $this->message; - if (!empty($message)) { - $message = PHP_EOL . $message; - } - return sprintf('Test Triggered PHP Deprecation (%s)%s', $this->test->id(), $message); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Event\Test; - -use PHPUnit\Event\Subscriber; -/** - * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit - */ -interface PhpDeprecationTriggeredSubscriber extends Subscriber -{ - public function notify(\PHPUnit\Event\Test\PhpDeprecationTriggered $event) : void; -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Event\Test; - -use const PHP_EOL; -use function sprintf; -use PHPUnit\Event\Code\Test; -use PHPUnit\Event\Event; -use PHPUnit\Event\Telemetry; -/** - * @psalm-immutable - * - * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit - */ -final class PhpNoticeTriggered implements Event -{ - private readonly Telemetry\Info $telemetryInfo; - private readonly Test $test; - private readonly string $message; - private readonly string $file; - private readonly int $line; - public function __construct(Telemetry\Info $telemetryInfo, Test $test, string $message, string $file, int $line) - { - $this->telemetryInfo = $telemetryInfo; - $this->test = $test; - $this->message = $message; - $this->file = $file; - $this->line = $line; - } - public function telemetryInfo() : Telemetry\Info - { - return $this->telemetryInfo; - } - public function test() : Test - { - return $this->test; - } - public function message() : string + public function wasSuppressed() : bool { - return $this->message; + return $this->suppressed; } - public function file() : string + public function ignoredByBaseline() : bool { - return $this->file; + return $this->ignoredByBaseline; } - public function line() : int + public function ignoredByTest() : bool { - return $this->line; + return $this->ignoredByTest; } public function asString() : string { @@ -37169,7 +39778,15 @@ final class PhpNoticeTriggered implements Event if (!empty($message)) { $message = PHP_EOL . $message; } - return sprintf('Test Triggered PHP Notice (%s)%s', $this->test->id(), $message); + $status = ''; + if ($this->ignoredByTest) { + $status = 'Test-Ignored '; + } elseif ($this->ignoredByBaseline) { + $status = 'Baseline-Ignored '; + } elseif ($this->suppressed) { + $status = 'Suppressed '; + } + return sprintf('Test Triggered %sPHP Deprecation (%s)%s', $status, $this->test->id(), $message); } } telemetryInfo = $telemetryInfo; $this->test = $test; $this->message = $message; $this->file = $file; $this->line = $line; + $this->suppressed = $suppressed; + $this->ignoredByBaseline = $ignoredByBaseline; } public function telemetryInfo() : Telemetry\Info { @@ -37239,25 +39874,48 @@ final class PhpWarningTriggered implements Event { return $this->test; } + /** + * @psalm-return non-empty-string + */ public function message() : string { return $this->message; } + /** + * @psalm-return non-empty-string + */ public function file() : string { return $this->file; } + /** + * @psalm-return positive-int + */ public function line() : int { return $this->line; } + public function wasSuppressed() : bool + { + return $this->suppressed; + } + public function ignoredByBaseline() : bool + { + return $this->ignoredByBaseline; + } public function asString() : string { $message = $this->message; if (!empty($message)) { $message = PHP_EOL . $message; } - return sprintf('Test Triggered PHP Warning (%s)%s', $this->test->id(), $message); + $status = ''; + if ($this->ignoredByBaseline) { + $status = 'Baseline-Ignored '; + } elseif ($this->suppressed) { + $status = 'Suppressed '; + } + return sprintf('Test Triggered %sPHP Notice (%s)%s', $status, $this->test->id(), $message); } } telemetryInfo = $telemetryInfo; $this->test = $test; $this->message = $message; + $this->file = $file; + $this->line = $line; + $this->suppressed = $suppressed; + $this->ignoredByBaseline = $ignoredByBaseline; } public function telemetryInfo() : Telemetry\Info { @@ -37323,17 +40003,48 @@ final class PhpunitDeprecationTriggered implements Event { return $this->test; } + /** + * @psalm-return non-empty-string + */ public function message() : string { return $this->message; } + /** + * @psalm-return non-empty-string + */ + public function file() : string + { + return $this->file; + } + /** + * @psalm-return positive-int + */ + public function line() : int + { + return $this->line; + } + public function wasSuppressed() : bool + { + return $this->suppressed; + } + public function ignoredByBaseline() : bool + { + return $this->ignoredByBaseline; + } public function asString() : string { $message = $this->message; if (!empty($message)) { $message = PHP_EOL . $message; } - return sprintf('Test Triggered PHPUnit Deprecation (%s)%s', $this->test->id(), $message); + $status = ''; + if ($this->ignoredByBaseline) { + $status = 'Baseline-Ignored '; + } elseif ($this->suppressed) { + $status = 'Suppressed '; + } + return sprintf('Test Triggered %sPHP Warning (%s)%s', $status, $this->test->id(), $message); } } telemetryInfo = $telemetryInfo; @@ -37399,6 +40116,9 @@ final class PhpunitErrorTriggered implements Event { return $this->test; } + /** + * @psalm-return non-empty-string + */ public function message() : string { return $this->message; @@ -37409,7 +40129,7 @@ final class PhpunitErrorTriggered implements Event if (!empty($message)) { $message = PHP_EOL . $message; } - return sprintf('Test Triggered PHPUnit Error (%s)%s', $this->test->id(), $message); + return sprintf('Test Triggered PHPUnit Deprecation (%s)%s', $this->test->id(), $message); } } telemetryInfo = $telemetryInfo; @@ -37475,17 +40202,20 @@ final class PhpunitWarningTriggered implements Event { return $this->test; } + /** + * @psalm-return non-empty-string + */ public function message() : string { return $this->message; } public function asString() : string { - $message = $this->message; + $message = trim($this->message); if (!empty($message)) { $message = PHP_EOL . $message; } - return sprintf('Test Triggered PHPUnit Warning (%s)%s', $this->test->id(), $message); + return sprintf('Test Triggered PHPUnit Error (%s)%s', $this->test->id(), $message); } } telemetryInfo = $telemetryInfo; $this->test = $test; $this->message = $message; - $this->file = $file; - $this->line = $line; } public function telemetryInfo() : Telemetry\Info { @@ -37555,25 +40287,20 @@ final class WarningTriggered implements Event { return $this->test; } + /** + * @psalm-return non-empty-string + */ public function message() : string { return $this->message; } - public function file() : string - { - return $this->file; - } - public function line() : int - { - return $this->line; - } public function asString() : string { $message = $this->message; if (!empty($message)) { $message = PHP_EOL . $message; } - return sprintf('Test Triggered Warning (%s)%s', $this->test->id(), $message); + return sprintf('Test Triggered PHPUnit Warning (%s)%s', $this->test->id(), $message); } } telemetryInfo = $telemetryInfo; $this->test = $test; - $this->numberOfAssertionsPerformed = $numberOfAssertionsPerformed; + $this->message = $message; + $this->file = $file; + $this->line = $line; + $this->suppressed = $suppressed; + $this->ignoredByBaseline = $ignoredByBaseline; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } - public function test() : Code\Test + public function test() : Test { return $this->test; } - public function numberOfAssertionsPerformed() : int + /** + * @psalm-return non-empty-string + */ + public function message() : string { - return $this->numberOfAssertionsPerformed; + return $this->message; + } + /** + * @psalm-return non-empty-string + */ + public function file() : string + { + return $this->file; + } + /** + * @psalm-return positive-int + */ + public function line() : int + { + return $this->line; + } + public function wasSuppressed() : bool + { + return $this->suppressed; + } + public function ignoredByBaseline() : bool + { + return $this->ignoredByBaseline; } public function asString() : string { - return sprintf('Test Finished (%s)', $this->test->id()); + $message = $this->message; + if (!empty($message)) { + $message = PHP_EOL . $message; + } + $status = ''; + if ($this->ignoredByBaseline) { + $status = 'Baseline-Ignored '; + } elseif ($this->suppressed) { + $status = 'Suppressed '; + } + return sprintf('Test Triggered %sWarning (%s)%s', $status, $this->test->id(), $message); } } telemetryInfo = $telemetryInfo; - $this->test = $test; + $this->testMethod = $testMethod; + $this->dataProviderMethod = $dataProviderMethod; } - public function telemetryInfo() : Telemetry\Info + public function telemetryInfo() : Info { return $this->telemetryInfo; } - public function test() : Code\Test + public function testMethod() : ClassMethod { - return $this->test; + return $this->testMethod; + } + public function dataProviderMethod() : ClassMethod + { + return $this->dataProviderMethod; } public function asString() : string { - return sprintf('Test Preparation Started (%s)', $this->test->id()); + return sprintf('Data Provider Method Called (%s::%s for test method %s::%s)', $this->dataProviderMethod->className(), $this->dataProviderMethod->methodName(), $this->testMethod->className(), $this->testMethod->methodName()); } } + */ + private readonly array $calledMethods; + public function __construct(Telemetry\Info $telemetryInfo, ClassMethod $testMethod, ClassMethod ...$calledMethods) { $this->telemetryInfo = $telemetryInfo; - $this->test = $test; + $this->testMethod = $testMethod; + $this->calledMethods = $calledMethods; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } - public function test() : Code\Test + public function testMethod() : ClassMethod { - return $this->test; + return $this->testMethod; + } + /** + * @psalm-return list + */ + public function calledMethods() : array + { + return $this->calledMethods; } public function asString() : string { - return sprintf('Test Prepared (%s)', $this->test->id()); + $buffer = sprintf('Data Provider Method Finished for %s::%s:', $this->testMethod->className(), $this->testMethod->methodName()); + foreach ($this->calledMethods as $calledMethod) { + $buffer .= sprintf(PHP_EOL . '- %s::%s', $calledMethod->className(), $calledMethod->methodName()); + } + return $buffer; } } telemetryInfo = $telemetryInfo; $this->test = $test; - $this->throwable = $throwable; + $this->numberOfAssertionsPerformed = $numberOfAssertionsPerformed; } public function telemetryInfo() : Telemetry\Info { @@ -37841,17 +40648,13 @@ final class Errored implements Event { return $this->test; } - public function throwable() : Throwable + public function numberOfAssertionsPerformed() : int { - return $this->throwable; + return $this->numberOfAssertionsPerformed; } public function asString() : string { - $message = $this->throwable->message(); - if (!empty($message)) { - $message = PHP_EOL . $message; - } - return sprintf('Test Errored (%s)%s', $this->test->id(), $message); + return sprintf('Test Finished (%s)', $this->test->id()); } } telemetryInfo = $telemetryInfo; $this->test = $test; - $this->throwable = $throwable; - $this->comparisonFailure = $comparisonFailure; } public function telemetryInfo() : Telemetry\Info { @@ -37921,34 +40717,9 @@ final class Failed implements Event { return $this->test; } - public function throwable() : Throwable - { - return $this->throwable; - } - /** - * @psalm-assert-if-true !null $this->comparisonFailure - */ - public function hasComparisonFailure() : bool - { - return $this->comparisonFailure !== null; - } - /** - * @throws NoComparisonFailureException - */ - public function comparisonFailure() : ComparisonFailure - { - if ($this->comparisonFailure === null) { - throw new \PHPUnit\Event\Test\NoComparisonFailureException(); - } - return $this->comparisonFailure; - } public function asString() : string { - $message = $this->throwable->message(); - if (!empty($message)) { - $message = PHP_EOL . $message; - } - return sprintf('Test Failed (%s)%s', $this->test->id(), $message); + return sprintf('Test Preparation Failed (%s)', $this->test->id()); } } telemetryInfo = $telemetryInfo; $this->test = $test; - $this->throwable = $throwable; } public function telemetryInfo() : Telemetry\Info { @@ -38015,17 +40782,9 @@ final class MarkedIncomplete implements Event { return $this->test; } - public function throwable() : Throwable - { - return $this->throwable; - } public function asString() : string { - $message = $this->throwable->message(); - if (!empty($message)) { - $message = PHP_EOL . $message; - } - return sprintf('Test Marked Incomplete (%s)%s', $this->test->id(), $message); + return sprintf('Test Preparation Started (%s)', $this->test->id()); } } test->id()); + return sprintf('Test Prepared (%s)', $this->test->id()); } } telemetryInfo = $telemetryInfo; $this->test = $test; - $this->message = $message; + $this->throwable = $throwable; } public function telemetryInfo() : Telemetry\Info { @@ -38156,17 +40917,17 @@ final class Skipped implements Event { return $this->test; } - public function message() : string + public function throwable() : Throwable { - return $this->message; + return $this->throwable; } public function asString() : string { - $message = $this->message; + $message = trim($this->throwable->message()); if (!empty($message)) { $message = PHP_EOL . $message; } - return sprintf('Test Skipped (%s)%s', $this->test->id(), $message); + return sprintf('Test Errored (%s)%s', $this->test->id(), $message); } } telemetryInfo = $telemetryInfo; - $this->output = $output; + $this->test = $test; + $this->throwable = $throwable; + $this->comparisonFailure = $comparisonFailure; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } + public function test() : Code\Test + { + return $this->test; + } + public function throwable() : Throwable + { + return $this->throwable; + } /** - * @psalm-return non-empty-string + * @psalm-assert-if-true !null $this->comparisonFailure */ - public function output() : string + public function hasComparisonFailure() : bool { - return $this->output; + return $this->comparisonFailure !== null; + } + /** + * @throws NoComparisonFailureException + */ + public function comparisonFailure() : ComparisonFailure + { + if ($this->comparisonFailure === null) { + throw new \PHPUnit\Event\Test\NoComparisonFailureException(); + } + return $this->comparisonFailure; } public function asString() : string { - return sprintf('Test Printed Unexpected Output%s%s', \PHP_EOL, $this->output); + $message = trim($this->throwable->message()); + if (!empty($message)) { + $message = PHP_EOL . $message; + } + return sprintf('Test Failed (%s)%s', $this->test->id(), $message); } } telemetryInfo = $telemetryInfo; - $this->className = $className; + $this->test = $test; + $this->throwable = $throwable; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } - /** - * @psalm-return class-string - */ - public function className() : string + public function test() : Code\Test { - return $this->className; + return $this->test; + } + public function throwable() : Throwable + { + return $this->throwable; } public function asString() : string { - return sprintf('Mock Object Created (%s)', $this->className); + $message = trim($this->throwable->message()); + if (!empty($message)) { + $message = PHP_EOL . $message; + } + return sprintf('Test Marked Incomplete (%s)%s', $this->test->id(), $message); } } telemetryInfo = $telemetryInfo; - $this->className = $className; + $this->test = $test; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } - /** - * @psalm-return class-string - */ - public function className() : string + public function test() : Code\Test { - return $this->className; + return $this->test; } public function asString() : string { - return sprintf('Mock Object Created (%s)', $this->className); + return sprintf('Test Passed (%s)', $this->test->id()); } } - */ - private readonly array $interfaces; - /** - * @psalm-param list $interfaces - */ - public function __construct(Telemetry\Info $telemetryInfo, array $interfaces) + private readonly Code\Test $test; + private readonly string $message; + public function __construct(Telemetry\Info $telemetryInfo, Code\Test $test, string $message) { $this->telemetryInfo = $telemetryInfo; - $this->interfaces = $interfaces; + $this->test = $test; + $this->message = $message; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } - /** - * @return list - */ - public function interfaces() : array + public function test() : Code\Test { - return $this->interfaces; + return $this->test; + } + public function message() : string + { + return $this->message; } public function asString() : string { - return sprintf('Mock Object Created (%s)', implode('&', $this->interfaces)); + $message = $this->message; + if (!empty($message)) { + $message = PHP_EOL . $message; + } + return sprintf('Test Skipped (%s)%s', $this->test->id(), $message); } } telemetryInfo = $telemetryInfo; - $this->traitName = $traitName; + $this->output = $output; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } /** - * @psalm-return trait-string + * @psalm-return non-empty-string */ - public function traitName() : string + public function output() : string { - return $this->traitName; + return $this->output; } public function asString() : string { - return sprintf('Mock Object Created (%s)', $this->traitName); + return sprintf('Test Printed Unexpected Output%s%s', \PHP_EOL, $this->output); } } - */ - private readonly array $methods; - private readonly bool $callOriginalConstructor; - private readonly array $options; + private readonly string $className; /** - * @psalm-param class-string $originalClassName - * @psalm-param class-string $mockClassName + * @psalm-param class-string $className */ - public function __construct(Telemetry\Info $telemetryInfo, string $wsdlFile, string $originalClassName, string $mockClassName, array $methods, bool $callOriginalConstructor, array $options) + public function __construct(Telemetry\Info $telemetryInfo, string $className) { $this->telemetryInfo = $telemetryInfo; - $this->wsdlFile = $wsdlFile; - $this->originalClassName = $originalClassName; - $this->mockClassName = $mockClassName; - $this->methods = $methods; - $this->callOriginalConstructor = $callOriginalConstructor; - $this->options = $options; + $this->className = $className; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } - public function wsdlFile() : string - { - return $this->wsdlFile; - } - /** - * @psalm-return class-string - */ - public function originalClassName() : string - { - return $this->originalClassName; - } /** * @psalm-return class-string */ - public function mockClassName() : string - { - return $this->mockClassName; - } - /** - * @psalm-return list - */ - public function methods() : array - { - return $this->methods; - } - public function callOriginalConstructor() : bool - { - return $this->callOriginalConstructor; - } - public function options() : array + public function className() : string { - return $this->options; + return $this->className; } public function asString() : string { - return sprintf('Mock Object Created (%s)', $this->wsdlFile); + return sprintf('Mock Object Created (%s)', $this->className); } } - */ - private readonly array $methodNames; /** * @psalm-param class-string $className */ - public function __construct(Telemetry\Info $telemetryInfo, string $className, string ...$methodNames) + public function __construct(Telemetry\Info $telemetryInfo, string $className) { $this->telemetryInfo = $telemetryInfo; $this->className = $className; - $this->methodNames = $methodNames; } public function telemetryInfo() : Telemetry\Info { @@ -38724,16 +41461,9 @@ final class PartialMockObjectCreated implements Event { return $this->className; } - /** - * @psalm-return list - */ - public function methodNames() : array - { - return $this->methodNames; - } public function asString() : string { - return sprintf('Partial Mock Object Created (%s)', $this->className); + return sprintf('Mock Object Created (%s)', $this->className); } } */ - private readonly string $className; - private readonly string $constructorArguments; + private readonly array $interfaces; /** - * @psalm-param class-string $className + * @psalm-param list $interfaces */ - public function __construct(Telemetry\Info $telemetryInfo, string $className, string $constructorArguments) + public function __construct(Telemetry\Info $telemetryInfo, array $interfaces) { $this->telemetryInfo = $telemetryInfo; - $this->className = $className; - $this->constructorArguments = $constructorArguments; + $this->interfaces = $interfaces; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } /** - * @psalm-return class-string + * @return list */ - public function className() : string - { - return $this->className; - } - public function constructorArguments() : string + public function interfaces() : array { - return $this->constructorArguments; + return $this->interfaces; } public function asString() : string { - return sprintf('Test Proxy Created (%s)', $this->className); + return sprintf('Mock Object Created (%s)', implode('&', $this->interfaces)); } } telemetryInfo = $telemetryInfo; - $this->className = $className; + $this->traitName = $traitName; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } /** - * @return class-string + * @psalm-return trait-string */ - public function className() : string + public function traitName() : string { - return $this->className; + return $this->traitName; } public function asString() : string { - return sprintf('Test Stub Created (%s)', $this->className); + return sprintf('Mock Object Created (%s)', $this->traitName); } } + * @psalm-var class-string */ - private readonly array $interfaces; + private readonly string $originalClassName; /** - * @psalm-param list $interfaces + * @psalm-var class-string */ - public function __construct(Telemetry\Info $telemetryInfo, array $interfaces) + private readonly string $mockClassName; + /** + * @psalm-var list + */ + private readonly array $methods; + private readonly bool $callOriginalConstructor; + private readonly array $options; + /** + * @psalm-param class-string $originalClassName + * @psalm-param class-string $mockClassName + */ + public function __construct(Telemetry\Info $telemetryInfo, string $wsdlFile, string $originalClassName, string $mockClassName, array $methods, bool $callOriginalConstructor, array $options) { $this->telemetryInfo = $telemetryInfo; - $this->interfaces = $interfaces; + $this->wsdlFile = $wsdlFile; + $this->originalClassName = $originalClassName; + $this->mockClassName = $mockClassName; + $this->methods = $methods; + $this->callOriginalConstructor = $callOriginalConstructor; + $this->options = $options; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } + public function wsdlFile() : string + { + return $this->wsdlFile; + } /** - * @return list + * @psalm-return class-string */ - public function interfaces() : array + public function originalClassName() : string { - return $this->interfaces; + return $this->originalClassName; + } + /** + * @psalm-return class-string + */ + public function mockClassName() : string + { + return $this->mockClassName; + } + /** + * @psalm-return list + */ + public function methods() : array + { + return $this->methods; + } + public function callOriginalConstructor() : bool + { + return $this->callOriginalConstructor; + } + public function options() : array + { + return $this->options; } public function asString() : string { - return sprintf('Test Stub Created (%s)', implode('&', $this->interfaces)); + return sprintf('Mock Object Created (%s)', $this->wsdlFile); } } + */ + private readonly array $methodNames; + /** + * @psalm-param class-string $className + */ + public function __construct(Telemetry\Info $telemetryInfo, string $className, string ...$methodNames) { $this->telemetryInfo = $telemetryInfo; - $this->filename = $filename; + $this->className = $className; + $this->methodNames = $methodNames; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } - public function filename() : string + /** + * @psalm-return class-string + */ + public function className() : string { - return $this->filename; + return $this->className; + } + /** + * @psalm-return list + */ + public function methodNames() : array + { + return $this->methodNames; } public function asString() : string { - return sprintf('Bootstrap Finished (%s)', $this->filename); + return sprintf('Partial Mock Object Created (%s)', $this->className); } } telemetryInfo = $telemetryInfo; - $this->configuration = $configuration; + $this->className = $className; + $this->constructorArguments = $constructorArguments; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } - public function configuration() : Configuration + /** + * @psalm-return class-string + */ + public function className() : string { - return $this->configuration; + return $this->className; + } + public function constructorArguments() : string + { + return $this->constructorArguments; } public function asString() : string { - return 'Test Runner Configured'; + return sprintf('Test Proxy Created (%s)', $this->className); } } telemetryInfo = $telemetryInfo; - $this->message = $message; + $this->className = $className; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } - public function message() : string + /** + * @return class-string + */ + public function className() : string { - return $this->message; + return $this->className; } public function asString() : string { - return sprintf('Test Runner Triggered Deprecation (%s)', $this->message); + return sprintf('Test Stub Created (%s)', $this->className); } } + */ + private readonly array $interfaces; + /** + * @psalm-param list $interfaces + */ + public function __construct(Telemetry\Info $telemetryInfo, array $interfaces) { $this->telemetryInfo = $telemetryInfo; + $this->interfaces = $interfaces; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } + /** + * @return list + */ + public function interfaces() : array + { + return $this->interfaces; + } public function asString() : string { - return 'Event Facade Sealed'; + return sprintf('Test Stub Created (%s)', implode('&', $this->interfaces)); } } telemetryInfo = $telemetryInfo; + $this->filename = $filename; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } + public function filename() : string + { + return $this->filename; + } public function asString() : string { - return 'Test Runner Execution Finished'; + return sprintf('Bootstrap Finished (%s)', $this->filename); } } telemetryInfo = $telemetryInfo; - $this->testSuite = $testSuite; + $this->configuration = $configuration; } public function telemetryInfo() : Telemetry\Info { return $this->telemetryInfo; } - public function testSuite() : TestSuite + public function configuration() : Configuration { - return $this->testSuite; + return $this->configuration; } public function asString() : string { - return sprintf('Test Runner Execution Started (%d test%s)', $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : ''); + return 'Test Runner Configured'; } } + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use function sprintf; +use PHPUnit\Event\Event; +use PHPUnit\Event\Telemetry; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +final class DeprecationTriggered implements Event +{ + private readonly Telemetry\Info $telemetryInfo; + private readonly string $message; + public function __construct(Telemetry\Info $telemetryInfo, string $message) + { + $this->telemetryInfo = $telemetryInfo; + $this->message = $message; + } + public function telemetryInfo() : Telemetry\Info + { + return $this->telemetryInfo; + } + public function message() : string + { + return $this->message; + } + public function asString() : string + { + return sprintf('Test Runner Triggered Deprecation (%s)', $this->message); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use PHPUnit\Event\Subscriber; +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +interface DeprecationTriggeredSubscriber extends Subscriber +{ + public function notify(\PHPUnit\Event\TestRunner\DeprecationTriggered $event) : void; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use PHPUnit\Event\Event; +use PHPUnit\Event\Telemetry; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +final class EventFacadeSealed implements Event +{ + private readonly Telemetry\Info $telemetryInfo; + public function __construct(Telemetry\Info $telemetryInfo) + { + $this->telemetryInfo = $telemetryInfo; + } + public function telemetryInfo() : Telemetry\Info + { + return $this->telemetryInfo; + } + public function asString() : string + { + return 'Event Facade Sealed'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use PHPUnit\Event\Subscriber; +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +interface EventFacadeSealedSubscriber extends Subscriber +{ + public function notify(\PHPUnit\Event\TestRunner\EventFacadeSealed $event) : void; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use PHPUnit\Event\Event; +use PHPUnit\Event\Telemetry; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +final class ExecutionAborted implements Event +{ + private readonly Telemetry\Info $telemetryInfo; + public function __construct(Telemetry\Info $telemetryInfo) + { + $this->telemetryInfo = $telemetryInfo; + } + public function telemetryInfo() : Telemetry\Info + { + return $this->telemetryInfo; + } + public function asString() : string + { + return 'Test Runner Execution Aborted'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use PHPUnit\Event\Subscriber; +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +interface ExecutionAbortedSubscriber extends Subscriber +{ + public function notify(\PHPUnit\Event\TestRunner\ExecutionAborted $event) : void; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use PHPUnit\Event\Event; +use PHPUnit\Event\Telemetry; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +final class ExecutionFinished implements Event +{ + private readonly Telemetry\Info $telemetryInfo; + public function __construct(Telemetry\Info $telemetryInfo) + { + $this->telemetryInfo = $telemetryInfo; + } + public function telemetryInfo() : Telemetry\Info + { + return $this->telemetryInfo; + } + public function asString() : string + { + return 'Test Runner Execution Finished'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use PHPUnit\Event\Subscriber; +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +interface ExecutionFinishedSubscriber extends Subscriber +{ + public function notify(\PHPUnit\Event\TestRunner\ExecutionFinished $event) : void; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use function sprintf; +use PHPUnit\Event\Event; +use PHPUnit\Event\Telemetry; +use PHPUnit\Event\TestSuite\TestSuite; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +final class ExecutionStarted implements Event +{ + private readonly Telemetry\Info $telemetryInfo; + private readonly TestSuite $testSuite; + public function __construct(Telemetry\Info $telemetryInfo, TestSuite $testSuite) + { + $this->telemetryInfo = $telemetryInfo; + $this->testSuite = $testSuite; + } + public function telemetryInfo() : Telemetry\Info + { + return $this->telemetryInfo; + } + public function testSuite() : TestSuite + { + return $this->testSuite; + } + public function asString() : string + { + return sprintf('Test Runner Execution Started (%d test%s)', $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : ''); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use PHPUnit\Event\Subscriber; +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +interface ExecutionStartedSubscriber extends Subscriber +{ + public function notify(\PHPUnit\Event\TestRunner\ExecutionStarted $event) : void; } telemetryInfo = $telemetryInfo; + } + public function telemetryInfo() : Telemetry\Info + { + return $this->telemetryInfo; + } + public function asString() : string + { + return 'Test Runner Disabled Garbage Collection'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use PHPUnit\Event\Subscriber; +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +interface GarbageCollectionDisabledSubscriber extends Subscriber +{ + public function notify(\PHPUnit\Event\TestRunner\GarbageCollectionDisabled $event) : void; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use PHPUnit\Event\Event; +use PHPUnit\Event\Telemetry; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +final class GarbageCollectionEnabled implements Event +{ + private readonly Telemetry\Info $telemetryInfo; + public function __construct(Telemetry\Info $telemetryInfo) + { + $this->telemetryInfo = $telemetryInfo; + } + public function telemetryInfo() : Telemetry\Info + { + return $this->telemetryInfo; + } + public function asString() : string + { + return 'Test Runner Enabled Garbage Collection'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use PHPUnit\Event\Subscriber; +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +interface GarbageCollectionEnabledSubscriber extends Subscriber +{ + public function notify(\PHPUnit\Event\TestRunner\GarbageCollectionEnabled $event) : void; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use PHPUnit\Event\Event; +use PHPUnit\Event\Telemetry; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +final class GarbageCollectionTriggered implements Event +{ + private readonly Telemetry\Info $telemetryInfo; + public function __construct(Telemetry\Info $telemetryInfo) + { + $this->telemetryInfo = $telemetryInfo; + } + public function telemetryInfo() : Telemetry\Info + { + return $this->telemetryInfo; + } + public function asString() : string + { + return 'Test Runner Triggered Garbage Collection'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + +use PHPUnit\Event\Subscriber; +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +interface GarbageCollectionTriggeredSubscriber extends Subscriber +{ + public function notify(\PHPUnit\Event\TestRunner\GarbageCollectionTriggered $event) : void; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\TestRunner; + use PHPUnit\Event\Event; use PHPUnit\Event\Telemetry; /** @@ -39796,11 +43102,7 @@ final class Finished implements Event } public function asString() : string { - $name = ''; - if (!empty($this->testSuite->name())) { - $name = $this->testSuite->name() . ', '; - } - return sprintf('Test Suite Finished (%s%d test%s)', $name, $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : ''); + return sprintf('Test Suite Finished (%s, %d test%s)', $this->testSuite->name(), $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : ''); } } testSuite->name())) { - $name = $this->testSuite->name() . ', '; - } - return sprintf('Test Suite Skipped (%s%s)', $name, $this->message); + return sprintf('Test Suite Skipped (%s, %s)', $this->testSuite->name(), $this->message); } } testSuite->name())) { - $name = $this->testSuite->name() . ', '; - } - return sprintf('Test Suite Started (%s%d test%s)', $name, $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : ''); + return sprintf('Test Suite Started (%s, %d test%s)', $this->testSuite->name(), $this->testSuite->count(), $this->testSuite->count() !== 1 ? 's' : ''); } } + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\Code; + +use PHPUnit\Event\Exception; +use RuntimeException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class NoTestCaseObjectOnCallStackException extends RuntimeException implements Exception +{ + public function __construct() + { + parent::__construct('Cannot find TestCase object on call stack'); + } +} +emitter; + } + public function __construct() + { + $this->emitter = $this->createDispatchingEmitter(); + } /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ - public static function registerSubscribers(\PHPUnit\Event\Subscriber ...$subscribers) : void + public function registerSubscribers(\PHPUnit\Event\Subscriber ...$subscribers) : void { foreach ($subscribers as $subscriber) { - self::registerSubscriber($subscriber); + $this->registerSubscriber($subscriber); } } /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ - public static function registerSubscriber(\PHPUnit\Event\Subscriber $subscriber) : void + public function registerSubscriber(\PHPUnit\Event\Subscriber $subscriber) : void { - if (self::$sealed) { + if ($this->sealed) { throw new \PHPUnit\Event\EventFacadeIsSealedException(); } - self::deferredDispatcher()->registerSubscriber($subscriber); + $this->deferredDispatcher()->registerSubscriber($subscriber); } /** * @throws EventFacadeIsSealedException */ - public static function registerTracer(\PHPUnit\Event\Tracer\Tracer $tracer) : void + public function registerTracer(\PHPUnit\Event\Tracer\Tracer $tracer) : void { - if (self::$sealed) { + if ($this->sealed) { throw new \PHPUnit\Event\EventFacadeIsSealedException(); } - self::deferredDispatcher()->registerTracer($tracer); + $this->deferredDispatcher()->registerTracer($tracer); } - public static function emitter() : \PHPUnit\Event\Emitter - { - if (self::$emitter === null) { - self::$emitter = self::createDispatchingEmitter(); - } - return self::$emitter; - } - /** @noinspection PhpUnused */ - public static function initForIsolation(HRTime $offset) : \PHPUnit\Event\CollectingDispatcher + /** + * @codeCoverageIgnore + * + * @noinspection PhpUnused + */ + public function initForIsolation(HRTime $offset, bool $exportObjects) : \PHPUnit\Event\CollectingDispatcher { $dispatcher = new \PHPUnit\Event\CollectingDispatcher(); - self::$emitter = new \PHPUnit\Event\DispatchingEmitter($dispatcher, new \PHPUnit\Event\Telemetry\System(new \PHPUnit\Event\Telemetry\SystemStopWatchWithOffset($offset), new \PHPUnit\Event\Telemetry\SystemMemoryMeter())); - self::$sealed = \true; + $this->emitter = new \PHPUnit\Event\DispatchingEmitter($dispatcher, new \PHPUnit\Event\Telemetry\System(new \PHPUnit\Event\Telemetry\SystemStopWatchWithOffset($offset), new \PHPUnit\Event\Telemetry\SystemMemoryMeter(), $this->garbageCollectorStatusProvider())); + if ($exportObjects) { + $this->emitter->exportObjects(); + } + $this->sealed = \true; return $dispatcher; } - public static function forward(\PHPUnit\Event\EventCollection $events) : void + public function forward(\PHPUnit\Event\EventCollection $events) : void { - if (self::$suspended !== null) { + if ($this->suspended !== null) { return; } - $dispatcher = self::deferredDispatcher(); + $dispatcher = $this->deferredDispatcher(); foreach ($events as $event) { $dispatcher->dispatch($event); } } - public static function seal() : void + public function seal() : void { - self::deferredDispatcher()->flush(); - self::$sealed = \true; - self::emitter()->testRunnerEventFacadeSealed(); + $this->deferredDispatcher()->flush(); + $this->sealed = \true; + $this->emitter->testRunnerEventFacadeSealed(); } - private static function createDispatchingEmitter() : \PHPUnit\Event\DispatchingEmitter + private function createDispatchingEmitter() : \PHPUnit\Event\DispatchingEmitter { - return new \PHPUnit\Event\DispatchingEmitter(self::deferredDispatcher(), self::createTelemetrySystem()); + return new \PHPUnit\Event\DispatchingEmitter($this->deferredDispatcher(), $this->createTelemetrySystem()); } - private static function createTelemetrySystem() : \PHPUnit\Event\Telemetry\System + private function createTelemetrySystem() : \PHPUnit\Event\Telemetry\System { - return new \PHPUnit\Event\Telemetry\System(new \PHPUnit\Event\Telemetry\SystemStopWatch(), new \PHPUnit\Event\Telemetry\SystemMemoryMeter()); + return new \PHPUnit\Event\Telemetry\System(new \PHPUnit\Event\Telemetry\SystemStopWatch(), new \PHPUnit\Event\Telemetry\SystemMemoryMeter(), $this->garbageCollectorStatusProvider()); } - private static function deferredDispatcher() : \PHPUnit\Event\DeferringDispatcher + private function deferredDispatcher() : \PHPUnit\Event\DeferringDispatcher { - if (self::$deferringDispatcher === null) { - self::$deferringDispatcher = new \PHPUnit\Event\DeferringDispatcher(new \PHPUnit\Event\DirectDispatcher(self::typeMap())); + if ($this->deferringDispatcher === null) { + $this->deferringDispatcher = new \PHPUnit\Event\DeferringDispatcher(new \PHPUnit\Event\DirectDispatcher($this->typeMap())); } - return self::$deferringDispatcher; + return $this->deferringDispatcher; } - private static function typeMap() : \PHPUnit\Event\TypeMap + private function typeMap() : \PHPUnit\Event\TypeMap { - if (self::$typeMap === null) { + if ($this->typeMap === null) { $typeMap = new \PHPUnit\Event\TypeMap(); - self::registerDefaultTypes($typeMap); - self::$typeMap = $typeMap; + $this->registerDefaultTypes($typeMap); + $this->typeMap = $typeMap; } - return self::$typeMap; + return $this->typeMap; } - private static function registerDefaultTypes(\PHPUnit\Event\TypeMap $typeMap) : void + private function registerDefaultTypes(\PHPUnit\Event\TypeMap $typeMap) : void { - $defaultEvents = [\PHPUnit\Event\Application\Started::class, \PHPUnit\Event\Application\Finished::class, \PHPUnit\Event\Test\MarkedIncomplete::class, \PHPUnit\Event\Test\AfterLastTestMethodCalled::class, \PHPUnit\Event\Test\AfterLastTestMethodFinished::class, \PHPUnit\Event\Test\AfterTestMethodCalled::class, \PHPUnit\Event\Test\AfterTestMethodFinished::class, \PHPUnit\Event\Test\AssertionSucceeded::class, \PHPUnit\Event\Test\AssertionFailed::class, \PHPUnit\Event\Test\BeforeFirstTestMethodCalled::class, \PHPUnit\Event\Test\BeforeFirstTestMethodErrored::class, \PHPUnit\Event\Test\BeforeFirstTestMethodFinished::class, \PHPUnit\Event\Test\BeforeTestMethodCalled::class, \PHPUnit\Event\Test\BeforeTestMethodFinished::class, \PHPUnit\Event\Test\ComparatorRegistered::class, \PHPUnit\Event\Test\ConsideredRisky::class, \PHPUnit\Event\Test\DeprecationTriggered::class, \PHPUnit\Event\Test\Errored::class, \PHPUnit\Event\Test\ErrorTriggered::class, \PHPUnit\Event\Test\Failed::class, \PHPUnit\Event\Test\Finished::class, \PHPUnit\Event\Test\NoticeTriggered::class, \PHPUnit\Event\Test\Passed::class, \PHPUnit\Event\Test\PhpDeprecationTriggered::class, \PHPUnit\Event\Test\PhpNoticeTriggered::class, \PHPUnit\Event\Test\PhpunitDeprecationTriggered::class, \PHPUnit\Event\Test\PhpunitErrorTriggered::class, \PHPUnit\Event\Test\PhpunitWarningTriggered::class, \PHPUnit\Event\Test\PhpWarningTriggered::class, \PHPUnit\Event\Test\PostConditionCalled::class, \PHPUnit\Event\Test\PostConditionFinished::class, \PHPUnit\Event\Test\PreConditionCalled::class, \PHPUnit\Event\Test\PreConditionFinished::class, \PHPUnit\Event\Test\PreparationStarted::class, \PHPUnit\Event\Test\Prepared::class, \PHPUnit\Event\Test\PrintedUnexpectedOutput::class, \PHPUnit\Event\Test\Skipped::class, \PHPUnit\Event\Test\WarningTriggered::class, \PHPUnit\Event\Test\MockObjectCreated::class, \PHPUnit\Event\Test\MockObjectForAbstractClassCreated::class, \PHPUnit\Event\Test\MockObjectForIntersectionOfInterfacesCreated::class, \PHPUnit\Event\Test\MockObjectForTraitCreated::class, \PHPUnit\Event\Test\MockObjectFromWsdlCreated::class, \PHPUnit\Event\Test\PartialMockObjectCreated::class, \PHPUnit\Event\Test\TestProxyCreated::class, \PHPUnit\Event\Test\TestStubCreated::class, \PHPUnit\Event\Test\TestStubForIntersectionOfInterfacesCreated::class, \PHPUnit\Event\TestRunner\BootstrapFinished::class, \PHPUnit\Event\TestRunner\Configured::class, \PHPUnit\Event\TestRunner\EventFacadeSealed::class, \PHPUnit\Event\TestRunner\ExecutionFinished::class, \PHPUnit\Event\TestRunner\ExecutionStarted::class, \PHPUnit\Event\TestRunner\ExtensionLoadedFromPhar::class, \PHPUnit\Event\TestRunner\ExtensionBootstrapped::class, \PHPUnit\Event\TestRunner\Finished::class, \PHPUnit\Event\TestRunner\Started::class, \PHPUnit\Event\TestRunner\DeprecationTriggered::class, \PHPUnit\Event\TestRunner\WarningTriggered::class, \PHPUnit\Event\TestSuite\Filtered::class, \PHPUnit\Event\TestSuite\Finished::class, \PHPUnit\Event\TestSuite\Loaded::class, \PHPUnit\Event\TestSuite\Skipped::class, \PHPUnit\Event\TestSuite\Sorted::class, \PHPUnit\Event\TestSuite\Started::class]; + $defaultEvents = [\PHPUnit\Event\Application\Started::class, \PHPUnit\Event\Application\Finished::class, \PHPUnit\Event\Test\DataProviderMethodCalled::class, \PHPUnit\Event\Test\DataProviderMethodFinished::class, \PHPUnit\Event\Test\MarkedIncomplete::class, \PHPUnit\Event\Test\AfterLastTestMethodCalled::class, \PHPUnit\Event\Test\AfterLastTestMethodFinished::class, \PHPUnit\Event\Test\AfterTestMethodCalled::class, \PHPUnit\Event\Test\AfterTestMethodFinished::class, \PHPUnit\Event\Test\AssertionSucceeded::class, \PHPUnit\Event\Test\AssertionFailed::class, \PHPUnit\Event\Test\BeforeFirstTestMethodCalled::class, \PHPUnit\Event\Test\BeforeFirstTestMethodErrored::class, \PHPUnit\Event\Test\BeforeFirstTestMethodFinished::class, \PHPUnit\Event\Test\BeforeTestMethodCalled::class, \PHPUnit\Event\Test\BeforeTestMethodFinished::class, \PHPUnit\Event\Test\ComparatorRegistered::class, \PHPUnit\Event\Test\ConsideredRisky::class, \PHPUnit\Event\Test\DeprecationTriggered::class, \PHPUnit\Event\Test\Errored::class, \PHPUnit\Event\Test\ErrorTriggered::class, \PHPUnit\Event\Test\Failed::class, \PHPUnit\Event\Test\Finished::class, \PHPUnit\Event\Test\NoticeTriggered::class, \PHPUnit\Event\Test\Passed::class, \PHPUnit\Event\Test\PhpDeprecationTriggered::class, \PHPUnit\Event\Test\PhpNoticeTriggered::class, \PHPUnit\Event\Test\PhpunitDeprecationTriggered::class, \PHPUnit\Event\Test\PhpunitErrorTriggered::class, \PHPUnit\Event\Test\PhpunitWarningTriggered::class, \PHPUnit\Event\Test\PhpWarningTriggered::class, \PHPUnit\Event\Test\PostConditionCalled::class, \PHPUnit\Event\Test\PostConditionFinished::class, \PHPUnit\Event\Test\PreConditionCalled::class, \PHPUnit\Event\Test\PreConditionFinished::class, \PHPUnit\Event\Test\PreparationStarted::class, \PHPUnit\Event\Test\Prepared::class, \PHPUnit\Event\Test\PreparationFailed::class, \PHPUnit\Event\Test\PrintedUnexpectedOutput::class, \PHPUnit\Event\Test\Skipped::class, \PHPUnit\Event\Test\WarningTriggered::class, \PHPUnit\Event\Test\MockObjectCreated::class, \PHPUnit\Event\Test\MockObjectForAbstractClassCreated::class, \PHPUnit\Event\Test\MockObjectForIntersectionOfInterfacesCreated::class, \PHPUnit\Event\Test\MockObjectForTraitCreated::class, \PHPUnit\Event\Test\MockObjectFromWsdlCreated::class, \PHPUnit\Event\Test\PartialMockObjectCreated::class, \PHPUnit\Event\Test\TestProxyCreated::class, \PHPUnit\Event\Test\TestStubCreated::class, \PHPUnit\Event\Test\TestStubForIntersectionOfInterfacesCreated::class, \PHPUnit\Event\TestRunner\BootstrapFinished::class, \PHPUnit\Event\TestRunner\Configured::class, \PHPUnit\Event\TestRunner\EventFacadeSealed::class, \PHPUnit\Event\TestRunner\ExecutionAborted::class, \PHPUnit\Event\TestRunner\ExecutionFinished::class, \PHPUnit\Event\TestRunner\ExecutionStarted::class, \PHPUnit\Event\TestRunner\ExtensionLoadedFromPhar::class, \PHPUnit\Event\TestRunner\ExtensionBootstrapped::class, \PHPUnit\Event\TestRunner\Finished::class, \PHPUnit\Event\TestRunner\Started::class, \PHPUnit\Event\TestRunner\DeprecationTriggered::class, \PHPUnit\Event\TestRunner\WarningTriggered::class, \PHPUnit\Event\TestRunner\GarbageCollectionDisabled::class, \PHPUnit\Event\TestRunner\GarbageCollectionTriggered::class, \PHPUnit\Event\TestRunner\GarbageCollectionEnabled::class, \PHPUnit\Event\TestSuite\Filtered::class, \PHPUnit\Event\TestSuite\Finished::class, \PHPUnit\Event\TestSuite\Loaded::class, \PHPUnit\Event\TestSuite\Skipped::class, \PHPUnit\Event\TestSuite\Sorted::class, \PHPUnit\Event\TestSuite\Started::class]; foreach ($defaultEvents as $eventClass) { $typeMap->addMapping($eventClass . 'Subscriber', $eventClass); } } + private function garbageCollectorStatusProvider() : \PHPUnit\Event\Telemetry\GarbageCollectorStatusProvider + { + if (!isset(gc_status()['running'])) { + // @codeCoverageIgnoreStart + return new Php81GarbageCollectorStatusProvider(); + // @codeCoverageIgnoreEnd + } + return new Php83GarbageCollectorStatusProvider(); + } } mapping)) { - throw new \PHPUnit\Event\SubscriberTypeAlreadyRegisteredException(sprintf('Subscriber type "%s" already registered - cannot overwrite', $subscriberInterface)); - } - if (in_array($eventClass, $this->mapping, \true)) { - throw new \PHPUnit\Event\EventAlreadyAssignedException(sprintf('Event "%s" already assigned - cannot add multiple subscriber types for an event type', $eventClass)); - } + $this->ensureSubscriberInterfaceExists($subscriberInterface); + $this->ensureSubscriberInterfaceExtendsInterface($subscriberInterface); + $this->ensureEventClassExists($eventClass); + $this->ensureEventClassImplementsEventInterface($eventClass); + $this->ensureSubscriberWasNotAlreadyRegistered($subscriberInterface); + $this->ensureEventWasNotAlreadyAssigned($eventClass); $this->mapping[$subscriberInterface] = $eventClass; } public function isKnownSubscriberType(\PHPUnit\Event\Subscriber $subscriber) : bool @@ -40688,6 +44023,72 @@ final class TypeMap } throw new \PHPUnit\Event\MapError(sprintf('Subscriber "%s" does not implement a known interface', $subscriber::class)); } + /** + * @psalm-param class-string $subscriberInterface + * + * @throws UnknownSubscriberException + */ + private function ensureSubscriberInterfaceExists(string $subscriberInterface) : void + { + if (!interface_exists($subscriberInterface)) { + throw new \PHPUnit\Event\UnknownSubscriberException(sprintf('Subscriber "%s" does not exist or is not an interface', $subscriberInterface)); + } + } + /** + * @psalm-param class-string $eventClass + * + * @throws UnknownEventException + */ + private function ensureEventClassExists(string $eventClass) : void + { + if (!class_exists($eventClass)) { + throw new \PHPUnit\Event\UnknownEventException(sprintf('Event class "%s" does not exist', $eventClass)); + } + } + /** + * @psalm-param class-string $subscriberInterface + * + * @throws InvalidSubscriberException + */ + private function ensureSubscriberInterfaceExtendsInterface(string $subscriberInterface) : void + { + if (!in_array(\PHPUnit\Event\Subscriber::class, class_implements($subscriberInterface), \true)) { + throw new \PHPUnit\Event\InvalidSubscriberException(sprintf('Subscriber "%s" does not extend Subscriber interface', $subscriberInterface)); + } + } + /** + * @psalm-param class-string $eventClass + * + * @throws InvalidEventException + */ + private function ensureEventClassImplementsEventInterface(string $eventClass) : void + { + if (!in_array(\PHPUnit\Event\Event::class, class_implements($eventClass), \true)) { + throw new \PHPUnit\Event\InvalidEventException(sprintf('Event "%s" does not implement Event interface', $eventClass)); + } + } + /** + * @psalm-param class-string $subscriberInterface + * + * @throws SubscriberTypeAlreadyRegisteredException + */ + private function ensureSubscriberWasNotAlreadyRegistered(string $subscriberInterface) : void + { + if (array_key_exists($subscriberInterface, $this->mapping)) { + throw new \PHPUnit\Event\SubscriberTypeAlreadyRegisteredException(sprintf('Subscriber type "%s" already registered', $subscriberInterface)); + } + } + /** + * @psalm-param class-string $eventClass + * + * @throws EventAlreadyAssignedException + */ + private function ensureEventWasNotAlreadyAssigned(string $eventClass) : void + { + if (in_array($eventClass, $this->mapping, \true)) { + throw new \PHPUnit\Event\EventAlreadyAssignedException(sprintf('Event "%s" already assigned', $eventClass)); + } + } } seconds(); - $minutes = 00; - $hours = 00; + $minutes = 0; + $hours = 0; if ($seconds > 60 * 60) { $hours = floor($seconds / 60 / 60); $seconds -= $hours * 60 * 60; @@ -41177,6 +44578,185 @@ declare (strict_types=1); */ namespace PHPUnit\Event\Telemetry; +use PHPUnit\Event\RuntimeException; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +final class GarbageCollectorStatus +{ + private readonly int $runs; + private readonly int $collected; + private readonly int $threshold; + private readonly int $roots; + private readonly ?float $applicationTime; + private readonly ?float $collectorTime; + private readonly ?float $destructorTime; + private readonly ?float $freeTime; + private readonly ?bool $running; + private readonly ?bool $protected; + private readonly ?bool $full; + private readonly ?int $bufferSize; + public function __construct(int $runs, int $collected, int $threshold, int $roots, ?float $applicationTime, ?float $collectorTime, ?float $destructorTime, ?float $freeTime, ?bool $running, ?bool $protected, ?bool $full, ?int $bufferSize) + { + $this->runs = $runs; + $this->collected = $collected; + $this->threshold = $threshold; + $this->roots = $roots; + $this->applicationTime = $applicationTime; + $this->collectorTime = $collectorTime; + $this->destructorTime = $destructorTime; + $this->freeTime = $freeTime; + $this->running = $running; + $this->protected = $protected; + $this->full = $full; + $this->bufferSize = $bufferSize; + } + public function runs() : int + { + return $this->runs; + } + public function collected() : int + { + return $this->collected; + } + public function threshold() : int + { + return $this->threshold; + } + public function roots() : int + { + return $this->roots; + } + /** + * @psalm-assert-if-true !null $this->applicationTime + * @psalm-assert-if-true !null $this->collectorTime + * @psalm-assert-if-true !null $this->destructorTime + * @psalm-assert-if-true !null $this->freeTime + * @psalm-assert-if-true !null $this->running + * @psalm-assert-if-true !null $this->protected + * @psalm-assert-if-true !null $this->full + * @psalm-assert-if-true !null $this->bufferSize + */ + public function hasExtendedInformation() : bool + { + return $this->running !== null; + } + /** + * @throws RuntimeException on PHP < 8.3 + */ + public function applicationTime() : float + { + if ($this->applicationTime === null) { + throw new RuntimeException('Information not available'); + } + return $this->applicationTime; + } + /** + * @throws RuntimeException on PHP < 8.3 + */ + public function collectorTime() : float + { + if ($this->collectorTime === null) { + throw new RuntimeException('Information not available'); + } + return $this->collectorTime; + } + /** + * @throws RuntimeException on PHP < 8.3 + */ + public function destructorTime() : float + { + if ($this->destructorTime === null) { + throw new RuntimeException('Information not available'); + } + return $this->destructorTime; + } + /** + * @throws RuntimeException on PHP < 8.3 + */ + public function freeTime() : float + { + if ($this->freeTime === null) { + throw new RuntimeException('Information not available'); + } + return $this->freeTime; + } + /** + * @throws RuntimeException on PHP < 8.3 + */ + public function isRunning() : bool + { + if ($this->running === null) { + throw new RuntimeException('Information not available'); + } + return $this->running; + } + /** + * @throws RuntimeException on PHP < 8.3 + */ + public function isProtected() : bool + { + if ($this->protected === null) { + throw new RuntimeException('Information not available'); + } + return $this->protected; + } + /** + * @throws RuntimeException on PHP < 8.3 + */ + public function isFull() : bool + { + if ($this->full === null) { + throw new RuntimeException('Information not available'); + } + return $this->full; + } + /** + * @throws RuntimeException on PHP < 8.3 + */ + public function bufferSize() : int + { + if ($this->bufferSize === null) { + throw new RuntimeException('Information not available'); + } + return $this->bufferSize; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\Telemetry; + +/** + * @internal This interface is not covered by the backward compatibility promise for PHPUnit + */ +interface GarbageCollectorStatusProvider +{ + public function status() : \PHPUnit\Event\Telemetry\GarbageCollectorStatus; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\Telemetry; + use function sprintf; use PHPUnit\Event\InvalidArgumentException; /** @@ -41311,6 +44891,10 @@ final class Info { return $this->memorySincePrevious; } + public function garbageCollectorStatus() : \PHPUnit\Event\Telemetry\GarbageCollectorStatus + { + return $this->current->garbageCollectorStatus(); + } public function asString() : string { return sprintf('[%s / %s] [%d bytes]', $this->durationSinceStart()->asString(), $this->durationSincePrevious()->asString(), $this->memoryUsage()->bytes()); @@ -41330,7 +44914,7 @@ declare (strict_types=1); namespace PHPUnit\Event\Telemetry; /** - * @internal This class is not covered by the backward compatibility promise for PHPUnit + * @internal This interface is not covered by the backward compatibility promise for PHPUnit */ interface MemoryMeter { @@ -41388,6 +44972,58 @@ declare (strict_types=1); */ namespace PHPUnit\Event\Telemetry; +use function gc_status; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + * + * @codeCoverageIgnore + */ +final class Php81GarbageCollectorStatusProvider implements \PHPUnit\Event\Telemetry\GarbageCollectorStatusProvider +{ + public function status() : \PHPUnit\Event\Telemetry\GarbageCollectorStatus + { + $status = gc_status(); + return new \PHPUnit\Event\Telemetry\GarbageCollectorStatus($status['runs'], $status['collected'], $status['threshold'], $status['roots'], null, null, null, null, null, null, null, null); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\Telemetry; + +use function gc_status; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Php83GarbageCollectorStatusProvider implements \PHPUnit\Event\Telemetry\GarbageCollectorStatusProvider +{ + public function status() : \PHPUnit\Event\Telemetry\GarbageCollectorStatus + { + $status = gc_status(); + return new \PHPUnit\Event\Telemetry\GarbageCollectorStatus($status['runs'], $status['collected'], $status['threshold'], $status['roots'], $status['application_time'], $status['collector_time'], $status['destructor_time'], $status['free_time'], $status['running'], $status['protected'], $status['full'], $status['buffer_size']); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Event\Telemetry; + /** * @psalm-immutable * @@ -41398,11 +45034,13 @@ final class Snapshot private readonly \PHPUnit\Event\Telemetry\HRTime $time; private readonly \PHPUnit\Event\Telemetry\MemoryUsage $memoryUsage; private readonly \PHPUnit\Event\Telemetry\MemoryUsage $peakMemoryUsage; - public function __construct(\PHPUnit\Event\Telemetry\HRTime $time, \PHPUnit\Event\Telemetry\MemoryUsage $memoryUsage, \PHPUnit\Event\Telemetry\MemoryUsage $peakMemoryUsage) + private readonly \PHPUnit\Event\Telemetry\GarbageCollectorStatus $garbageCollectorStatus; + public function __construct(\PHPUnit\Event\Telemetry\HRTime $time, \PHPUnit\Event\Telemetry\MemoryUsage $memoryUsage, \PHPUnit\Event\Telemetry\MemoryUsage $peakMemoryUsage, \PHPUnit\Event\Telemetry\GarbageCollectorStatus $garbageCollectorStatus) { $this->time = $time; $this->memoryUsage = $memoryUsage; $this->peakMemoryUsage = $peakMemoryUsage; + $this->garbageCollectorStatus = $garbageCollectorStatus; } public function time() : \PHPUnit\Event\Telemetry\HRTime { @@ -41416,6 +45054,10 @@ final class Snapshot { return $this->peakMemoryUsage; } + public function garbageCollectorStatus() : \PHPUnit\Event\Telemetry\GarbageCollectorStatus + { + return $this->garbageCollectorStatus; + } } stopWatch = $stopWatch; $this->memoryMeter = $memoryMeter; + $this->garbageCollectorStatusProvider = $garbageCollectorStatusProvider; } public function snapshot() : \PHPUnit\Event\Telemetry\Snapshot { - return new \PHPUnit\Event\Telemetry\Snapshot($this->stopWatch->current(), $this->memoryMeter->memoryUsage(), $this->memoryMeter->peakMemoryUsage()); + return new \PHPUnit\Event\Telemetry\Snapshot($this->stopWatch->current(), $this->memoryMeter->memoryUsage(), $this->memoryMeter->peakMemoryUsage(), $this->garbageCollectorStatusProvider->status()); } } file(); } + /** + * @psalm-return non-empty-string + */ public function name() : string { return $this->file(); @@ -41622,11 +45270,20 @@ namespace PHPUnit\Event\Code; */ abstract class Test { + /** + * @psalm-var non-empty-string + */ private readonly string $file; + /** + * @psalm-param non-empty-string $file + */ public function __construct(string $file) { $this->file = $file; } + /** + * @psalm-return non-empty-string + */ public function file() : string { return $this->file; @@ -41645,7 +45302,13 @@ abstract class Test { return \false; } + /** + * @psalm-return non-empty-string + */ public abstract function id() : string; + /** + * @psalm-return non-empty-string + */ public abstract function name() : string; } dataSetName = $dataSetName; + $this->dataAsStringForResultOutput = $dataAsStringForResultOutput; parent::__construct($data); } public function dataSetName() : int|string { return $this->dataSetName; } + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function dataAsStringForResultOutput() : string + { + return $this->dataAsStringForResultOutput; + } /** * @psalm-assert-if-true DataFromDataProvider $this */ @@ -42116,7 +45788,6 @@ namespace PHPUnit\Event\Code; use function assert; use function is_int; use function sprintf; -use PHPUnit\Event\TestData\NoDataSetFromDataProviderException; use PHPUnit\Event\TestData\TestDataCollection; use PHPUnit\Metadata\MetadataCollection; /** @@ -42134,6 +45805,9 @@ final class TestMethod extends \PHPUnit\Event\Code\Test * @psalm-var non-empty-string */ private readonly string $methodName; + /** + * @psalm-var non-negative-int + */ private readonly int $line; private readonly \PHPUnit\Event\Code\TestDox $testDox; private readonly MetadataCollection $metadata; @@ -42141,6 +45815,8 @@ final class TestMethod extends \PHPUnit\Event\Code\Test /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName + * @psalm-param non-empty-string $file + * @psalm-param non-negative-int $line */ public function __construct(string $className, string $methodName, string $file, int $line, \PHPUnit\Event\Code\TestDox $testDox, MetadataCollection $metadata, TestDataCollection $testData) { @@ -42166,6 +45842,9 @@ final class TestMethod extends \PHPUnit\Event\Code\Test { return $this->methodName; } + /** + * @psalm-return non-negative-int + */ public function line() : int { return $this->line; @@ -42190,7 +45869,7 @@ final class TestMethod extends \PHPUnit\Event\Code\Test return \true; } /** - * @throws NoDataSetFromDataProviderException + * @psalm-return non-empty-string */ public function id() : string { @@ -42201,14 +45880,14 @@ final class TestMethod extends \PHPUnit\Event\Code\Test return $buffer; } /** - * @throws NoDataSetFromDataProviderException + * @psalm-return non-empty-string */ public function nameWithClass() : string { return $this->className . '::' . $this->name(); } /** - * @throws NoDataSetFromDataProviderException + * @psalm-return non-empty-string */ public function name() : string { @@ -42238,15 +45917,17 @@ declare (strict_types=1); namespace PHPUnit\Event\Code; use function assert; +use function debug_backtrace; use function is_numeric; +use PHPUnit\Event\Facade as EventFacade; use PHPUnit\Event\TestData\DataFromDataProvider; use PHPUnit\Event\TestData\DataFromTestDependency; use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException; use PHPUnit\Event\TestData\TestDataCollection; use PHPUnit\Framework\TestCase; use PHPUnit\Metadata\Parser\Registry as MetadataRegistry; +use PHPUnit\Util\Exporter; use PHPUnit\Util\Reflection; -use PHPUnit\SebastianBergmann\Exporter\Exporter; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ @@ -42260,7 +45941,19 @@ final class TestMethodBuilder $methodName = $testCase->name(); assert(!empty($methodName)); $location = Reflection::sourceLocationFor($testCase::class, $methodName); - return new \PHPUnit\Event\Code\TestMethod($testCase::class, $methodName, $location['file'], $location['line'], \PHPUnit\Event\Code\TestDoxBuilder::fromTestCase($testCase), MetadataRegistry::parser()->for($testCase::class, $methodName), self::dataFor($testCase)); + return new \PHPUnit\Event\Code\TestMethod($testCase::class, $methodName, $location['file'], $location['line'], \PHPUnit\Event\Code\TestDoxBuilder::fromTestCase($testCase), MetadataRegistry::parser()->forClassAndMethod($testCase::class, $methodName), self::dataFor($testCase)); + } + /** + * @throws NoTestCaseObjectOnCallStackException + */ + public static function fromCallStack() : \PHPUnit\Event\Code\TestMethod + { + foreach (debug_backtrace() as $frame) { + if (isset($frame['object']) && $frame['object'] instanceof TestCase) { + return $frame['object']->valueObjectForEvents(); + } + } + throw new \PHPUnit\Event\Code\NoTestCaseObjectOnCallStackException(); } /** * @throws MoreThanOneDataSetFromDataProviderException @@ -42273,10 +45966,10 @@ final class TestMethodBuilder if (is_numeric($dataSetName)) { $dataSetName = (int) $dataSetName; } - $testData[] = DataFromDataProvider::from($dataSetName, (new Exporter())->export($testCase->providedData())); + $testData[] = DataFromDataProvider::from($dataSetName, Exporter::export($testCase->providedData(), EventFacade::emitter()->exportsObjects()), $testCase->dataSetAsStringWithData()); } if ($testCase->hasDependencyInput()) { - $testData[] = DataFromTestDependency::from((new Exporter())->export($testCase->dependencyInput())); + $testData[] = DataFromTestDependency::from(Exporter::export($testCase->dependencyInput(), EventFacade::emitter()->exportsObjects())); } return TestDataCollection::fromArray($testData); } @@ -42302,15 +45995,24 @@ use PHPUnit\Event\Code\TestCollection; */ abstract class TestSuite { + /** + * @psalm-var non-empty-string + */ private readonly string $name; private readonly int $count; private readonly TestCollection $tests; + /** + * @psalm-param non-empty-string $name + */ public function __construct(string $name, int $size, TestCollection $tests) { $this->name = $name; $this->count = $size; $this->tests = $tests; } + /** + * @psalm-return non-empty-string + */ public function name() : string { return $this->name; @@ -42359,6 +46061,7 @@ declare (strict_types=1); namespace PHPUnit\Event\TestSuite; use function explode; +use PHPUnit\Event\Code\Test; use PHPUnit\Event\Code\TestCollection; use PHPUnit\Event\RuntimeException; use PHPUnit\Framework\DataProviderTestSuite; @@ -42379,7 +46082,7 @@ final class TestSuiteBuilder public static function from(FrameworkTestSuite $testSuite) : \PHPUnit\Event\TestSuite\TestSuite { $groups = []; - foreach ($testSuite->getGroupDetails() as $groupName => $tests) { + foreach ($testSuite->groupDetails() as $groupName => $tests) { if (!isset($groups[$groupName])) { $groups[$groupName] = []; } @@ -42388,16 +46091,12 @@ final class TestSuiteBuilder } } $tests = []; - foreach ($testSuite->tests() as $test) { - if ($test instanceof TestCase || $test instanceof PhptTestCase) { - $tests[] = $test->valueObjectForEvents(); - } - } + self::process($testSuite, $tests); if ($testSuite instanceof DataProviderTestSuite) { - [$className, $methodName] = explode('::', $testSuite->getName()); + [$className, $methodName] = explode('::', $testSuite->name()); try { $reflector = new ReflectionMethod($className, $methodName); - return new \PHPUnit\Event\TestSuite\TestSuiteForTestMethodWithDataProvider($testSuite->getName(), $testSuite->count(), TestCollection::fromArray($tests), $className, $methodName, $reflector->getFileName(), $reflector->getStartLine()); + return new \PHPUnit\Event\TestSuite\TestSuiteForTestMethodWithDataProvider($testSuite->name(), $testSuite->count(), TestCollection::fromArray($tests), $className, $methodName, $reflector->getFileName(), $reflector->getStartLine()); // @codeCoverageIgnoreStart } catch (ReflectionException $e) { throw new RuntimeException($e->getMessage(), $e->getCode(), $e); @@ -42406,15 +46105,30 @@ final class TestSuiteBuilder } if ($testSuite->isForTestClass()) { try { - $reflector = new ReflectionClass($testSuite->getName()); - return new \PHPUnit\Event\TestSuite\TestSuiteForTestClass($testSuite->getName(), $testSuite->count(), TestCollection::fromArray($tests), $reflector->getFileName(), $reflector->getStartLine()); + $reflector = new ReflectionClass($testSuite->name()); + return new \PHPUnit\Event\TestSuite\TestSuiteForTestClass($testSuite->name(), $testSuite->count(), TestCollection::fromArray($tests), $reflector->getFileName(), $reflector->getStartLine()); // @codeCoverageIgnoreStart } catch (ReflectionException $e) { throw new RuntimeException($e->getMessage(), $e->getCode(), $e); } // @codeCoverageIgnoreEnd } - return new \PHPUnit\Event\TestSuite\TestSuiteWithName($testSuite->getName(), $testSuite->count(), TestCollection::fromArray($tests)); + return new \PHPUnit\Event\TestSuite\TestSuiteWithName($testSuite->name(), $testSuite->count(), TestCollection::fromArray($tests)); + } + /** + * @psalm-param list $tests + */ + private static function process(FrameworkTestSuite $testSuite, array &$tests) : void + { + foreach ($testSuite->getIterator() as $test) { + if ($test instanceof FrameworkTestSuite) { + self::process($test, $tests); + continue; + } + if ($test instanceof TestCase || $test instanceof PhptTestCase) { + $tests[] = $test->valueObjectForEvents(); + } + } } } getMessage(), ThrowableToStringMapper::map($t), Filter::getFilteredStacktrace($t), $previous); + return new \PHPUnit\Event\Code\Throwable($t::class, $t->getMessage(), ThrowableToStringMapper::map($t), Filter::getFilteredStacktrace($t, \false), $previous); } } - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework\Attributes; - -use Attribute; -/** - * @psalm-immutable - * - * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit - */ -#[Attribute(Attribute::TARGET_CLASS)] -final class Medium -{ -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework\Attributes; - -use Attribute; -/** - * @psalm-immutable - * - * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit - */ -#[Attribute(Attribute::TARGET_METHOD)] -final class PostCondition -{ -} - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513 */ -namespace PHPUnit\Framework\Attributes; - -use Attribute; -/** - * @psalm-immutable - * - * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit - */ -#[Attribute(Attribute::TARGET_METHOD)] -final class PreCondition +#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)] +final class IgnoreClassForCodeCoverage { + /** + * @psalm-var class-string + */ + private readonly string $className; + /** + * @psalm-param class-string $className + */ + public function __construct(string $className) + { + $this->className = $className; + } + /** + * @psalm-return class-string + */ + public function className() : string + { + return $this->className; + } } enabled = $enabled; - } - public function enabled() : bool - { - return $this->enabled; - } } functionName = $functionName; + } + /** + * @psalm-return non-empty-string + */ + public function functionName() : string + { + return $this->functionName; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Attributes; + +use Attribute; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513 + */ +#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)] +final class IgnoreMethodForCodeCoverage +{ + /** + * @psalm-var class-string + */ + private readonly string $className; + /** + * @psalm-var non-empty-string + */ + private readonly string $methodName; + /** + * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName + */ + public function __construct(string $className, string $methodName) + { + $this->className = $className; + $this->methodName = $methodName; + } + /** + * @psalm-return class-string + */ + public function className() : string + { + return $this->className; + } + /** + * @psalm-return non-empty-string + */ + public function methodName() : string + { + return $this->methodName; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Attributes; + +use Attribute; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +#[Attribute(Attribute::TARGET_CLASS)] +final class Large +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Attributes; + +use Attribute; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +#[Attribute(Attribute::TARGET_CLASS)] +final class Medium +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Attributes; + +use Attribute; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +#[Attribute(Attribute::TARGET_METHOD)] +final class PostCondition +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Attributes; + +use Attribute; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +#[Attribute(Attribute::TARGET_METHOD)] +final class PreCondition +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Attributes; + +use Attribute; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)] +final class PreserveGlobalState +{ + private readonly bool $enabled; + public function __construct(bool $enabled) + { + $this->enabled = $enabled; + } + public function enabled() : bool + { + return $this->enabled; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Attributes; + +use Attribute; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] +final class RequiresFunction { /** * @psalm-var non-empty-string @@ -48726,6 +52694,29 @@ final class UsesFunction } + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Attributes; + +use Attribute; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +#[Attribute(Attribute::TARGET_METHOD)] +final class WithoutErrorHandler +{ +} +exporter()->export($this->value); + return 'is greater than ' . Exporter::export($this->value, $exportObjects); } /** * Evaluates the constraint for parameter $other. Returns true if the @@ -49035,7 +53027,7 @@ final class IsEmpty extends \PHPUnit\Framework\Constraint\Constraint protected function failureDescription(mixed $other) : string { $type = gettype($other); - return sprintf('%s %s %s', str_starts_with($type, 'a') || str_starts_with($type, 'o') ? 'an' : 'a', $type, $this->toString()); + return sprintf('%s %s %s', str_starts_with($type, 'a') || str_starts_with($type, 'o') ? 'an' : 'a', $type, $this->toString(\true)); } } exporter()->export($this->value); + return 'is less than ' . Exporter::export($this->value, $exportObjects); } /** * Evaluates the constraint for parameter $other. Returns true if the @@ -49090,6 +53083,7 @@ declare (strict_types=1); */ namespace PHPUnit\Framework\Constraint; +use Countable; use PHPUnit\Framework\Exception; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit @@ -49097,7 +53091,7 @@ use PHPUnit\Framework\Exception; final class SameSize extends \PHPUnit\Framework\Constraint\Count { /** - * @psalm-param \Countable|iterable $expected + * @psalm-param Countable|iterable $expected * * @throws Exception */ @@ -49119,18 +53113,19 @@ declare (strict_types=1); */ namespace PHPUnit\Framework\Constraint; +use function gettype; use function sprintf; +use function strtolower; use Countable; use PHPUnit\Framework\ExpectationFailedException; use PHPUnit\Framework\SelfDescribing; +use PHPUnit\Util\Exporter; use PHPUnit\SebastianBergmann\Comparator\ComparisonFailure; -use PHPUnit\SebastianBergmann\Exporter\Exporter; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ abstract class Constraint implements Countable, SelfDescribing { - private ?Exporter $exporter = null; /** * Evaluates the constraint for parameter $other. * @@ -49164,20 +53159,18 @@ abstract class Constraint implements Countable, SelfDescribing { return 1; } - protected function exporter() : Exporter + /** + * @deprecated + */ + protected function exporter() : \PHPUnit\SebastianBergmann\Exporter\Exporter { - if ($this->exporter === null) { - $this->exporter = new Exporter(); - } - return $this->exporter; + return new \PHPUnit\SebastianBergmann\Exporter\Exporter(); } /** * Evaluates the constraint for parameter $other. Returns true if the * constraint is met, false otherwise. * * This method can be overridden to implement the evaluation algorithm. - * - * @codeCoverageIgnore */ protected function matches(mixed $other) : bool { @@ -49221,7 +53214,7 @@ abstract class Constraint implements Countable, SelfDescribing */ protected function failureDescription(mixed $other) : string { - return $this->exporter()->export($other) . ' ' . $this->toString(); + return Exporter::export($other, \true) . ' ' . $this->toString(\true); } /** * Returns a custom string representation of the constraint object when it @@ -49257,7 +53250,7 @@ abstract class Constraint implements Countable, SelfDescribing if ($string === '') { return ''; } - return $this->exporter()->export($other) . ' ' . $string; + return Exporter::export($other, \true) . ' ' . $string; } /** * Reduces the sub-expression starting at $this by skipping degenerate @@ -49323,6 +53316,25 @@ abstract class Constraint implements Countable, SelfDescribing { return $this; } + /** + * @psalm-return non-empty-string + */ + protected function valueToTypeStringFragment(mixed $value) : string + { + $type = strtolower(gettype($value)); + if ($type === 'double') { + $type = 'float'; + } + if ($type === 'resource (closed)') { + $type = 'closed resource'; + } + return match ($type) { + 'array', 'integer', 'object' => 'an ' . $type . ' ', + 'boolean', 'closed resource', 'float', 'resource', 'string' => 'a ' . $type . ' ', + 'null' => 'null ', + default => 'a value of ' . $type . ' ', + }; + } } value)) { @@ -49407,7 +53420,7 @@ final class IsEqual extends \PHPUnit\Framework\Constraint\Constraint if ($this->delta != 0) { $delta = sprintf(' with delta <%F>', $this->delta); } - return sprintf('is equal to %s%s', $this->exporter()->export($this->value), $delta); + return sprintf('is equal to %s%s', Exporter::export($this->value, $exportObjects), $delta); } } getComparatorFor($this->value, $other); - $comparator->assertEquals($this->value, $other, 0.0, \true, \false); + $comparator->assertEquals($this->value, $other, 0.0, \true); } catch (ComparisonFailure $f) { if ($returnResult) { return \false; @@ -49475,7 +53489,7 @@ final class IsEqualCanonicalizing extends \PHPUnit\Framework\Constraint\Constrai /** * Returns a string representation of the constraint. */ - public function toString() : string + public function toString(bool $exportObjects = \false) : string { if (is_string($this->value)) { if (str_contains($this->value, "\n")) { @@ -49483,7 +53497,7 @@ final class IsEqualCanonicalizing extends \PHPUnit\Framework\Constraint\Constrai } return sprintf("is equal to '%s'", $this->value); } - return sprintf('is equal to %s', $this->exporter()->export($this->value)); + return sprintf('is equal to %s', Exporter::export($this->value, $exportObjects)); } } value)) { if (str_contains($this->value, "\n")) { @@ -49559,7 +53574,7 @@ final class IsEqualIgnoringCase extends \PHPUnit\Framework\Constraint\Constraint } return sprintf("is equal to '%s'", $this->value); } - return sprintf('is equal to %s', $this->exporter()->export($this->value)); + return sprintf('is equal to %s', Exporter::export($this->value, $exportObjects)); } } ', $this->exporter()->export($this->value), $this->delta); + return sprintf('is equal to %s with delta <%F>', Exporter::export($this->value, $exportObjects), $this->delta); } } exporter()->export($other), $this->exporter()->export($this->expectedCode)); + return sprintf('%s is equal to expected exception code %s', Exporter::export($other, \true), Exporter::export($this->expectedCode, \true)); } } expectedMessage === '') { return 'exception message is empty'; } - return 'exception message contains ' . $this->exporter()->export($this->expectedMessage); + return 'exception message contains ' . Exporter::export($this->expectedMessage); } protected function matches(mixed $other) : bool { @@ -49809,6 +53827,7 @@ namespace PHPUnit\Framework\Constraint; use function preg_match; use function sprintf; use Exception; +use PHPUnit\Util\Exporter; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ @@ -49821,7 +53840,7 @@ final class ExceptionMessageMatchesRegularExpression extends \PHPUnit\Framework\ } public function toString() : string { - return 'exception message matches ' . $this->exporter()->export($this->regularExpression); + return 'exception message matches ' . Exporter::export($this->regularExpression); } /** * Evaluates the constraint for parameter $other. Returns true if the @@ -50096,12 +54115,16 @@ declare (strict_types=1); */ namespace PHPUnit\Framework\Constraint; +use function explode; +use function gettype; use function is_array; use function is_object; use function is_string; use function sprintf; use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Util\Exporter; use PHPUnit\SebastianBergmann\Comparator\ComparisonFailure; +use UnitEnum; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ @@ -50136,9 +54159,9 @@ final class IsIdentical extends \PHPUnit\Framework\Constraint\Constraint if (is_string($this->value) && is_string($other)) { $f = new ComparisonFailure($this->value, $other, sprintf("'%s'", $this->value), sprintf("'%s'", $other)); } - // if both values are array, make sure a diff is generated - if (is_array($this->value) && is_array($other)) { - $f = new ComparisonFailure($this->value, $other, $this->exporter()->export($this->value), $this->exporter()->export($other)); + // if both values are array or enums, make sure a diff is generated + if (is_array($this->value) && is_array($other) || $this->value instanceof UnitEnum && $other instanceof UnitEnum) { + $f = new ComparisonFailure($this->value, $other, Exporter::export($this->value, \true), Exporter::export($other, \true)); } $this->fail($other, $description, $f); } @@ -50147,12 +54170,12 @@ final class IsIdentical extends \PHPUnit\Framework\Constraint\Constraint /** * Returns a string representation of the constraint. */ - public function toString() : string + public function toString(bool $exportObjects = \false) : string { if (is_object($this->value)) { return 'is identical to an object of class "' . $this->value::class . '"'; } - return 'is identical to ' . $this->exporter()->export($this->value); + return 'is identical to ' . Exporter::export($this->value, $exportObjects); } /** * Returns the description of the failure. @@ -50165,6 +54188,9 @@ final class IsIdentical extends \PHPUnit\Framework\Constraint\Constraint if (is_object($this->value) && is_object($other)) { return 'two variables reference the same object'; } + if (explode(' ', gettype($this->value), 2)[0] === 'resource' && explode(' ', gettype($other), 2)[0] === 'resource') { + return 'two variables reference the same resource'; + } if (is_string($this->value) && is_string($other)) { return 'two strings are identical'; } @@ -50446,7 +54472,70 @@ final class ObjectEquals extends \PHPUnit\Framework\Constraint\Constraint } protected function failureDescription(mixed $other) : string { - return $this->toString(); + return $this->toString(\true); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use function gettype; +use function is_object; +use function sprintf; +use ReflectionObject; +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +final class ObjectHasProperty extends \PHPUnit\Framework\Constraint\Constraint +{ + private readonly string $propertyName; + public function __construct(string $propertyName) + { + $this->propertyName = $propertyName; + } + /** + * Returns a string representation of the constraint. + */ + public function toString() : string + { + return sprintf('has property "%s"', $this->propertyName); + } + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches(mixed $other) : bool + { + if (!is_object($other)) { + return \false; + } + return (new ReflectionObject($other))->hasProperty($this->propertyName); + } + /** + * Returns the description of the failure. + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + */ + protected function failureDescription(mixed $other) : string + { + if (is_object($other)) { + return sprintf('object of class "%s" %s', $other::class, $this->toString(\true)); + } + return sprintf('"%s" (%s) %s', $other, gettype($other), $this->toString(\true)); } } '/\\b' . preg_quote($s, '/') . '/', $positives); if (count($matches) > 0) { $nonInput = $matches[2]; @@ -50978,6 +55070,7 @@ declare (strict_types=1); */ namespace PHPUnit\Framework\Constraint; +use function is_string; use function json_decode; use function json_last_error; use function sprintf; @@ -50999,7 +55092,7 @@ final class IsJson extends \PHPUnit\Framework\Constraint\Constraint */ protected function matches(mixed $other) : bool { - if ($other === '') { + if (!is_string($other) || $other === '') { return \false; } json_decode($other); @@ -51016,15 +55109,18 @@ final class IsJson extends \PHPUnit\Framework\Constraint\Constraint */ protected function failureDescription(mixed $other) : string { + if (!is_string($other)) { + return $this->valueToTypeStringFragment($other) . 'is valid JSON'; + } if ($other === '') { return 'an empty string is valid JSON'; } - json_decode($other); - return sprintf('%s is valid JSON (%s)', $this->exporter()->shortenedExport($other), $this->determineJsonError(json_last_error())); + return sprintf('a string is valid JSON (%s)', $this->determineJsonError($other)); } - private function determineJsonError(int $error) : string + private function determineJsonError(string $json) : string { - return match ($error) { + json_decode($json); + return match (json_last_error()) { \JSON_ERROR_NONE => '', \JSON_ERROR_DEPTH => 'Maximum stack depth exceeded', \JSON_ERROR_STATE_MISMATCH => 'Underflow or the modes mismatch', @@ -51090,25 +55186,28 @@ declare (strict_types=1); namespace PHPUnit\Framework\Constraint; use function is_string; +use function mb_detect_encoding; use function mb_stripos; use function mb_strtolower; use function sprintf; use function str_contains; +use function strlen; use function strtr; +use PHPUnit\Util\Exporter; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class StringContains extends \PHPUnit\Framework\Constraint\Constraint { - private readonly string $string; + private readonly string $needle; private readonly bool $ignoreCase; private readonly bool $ignoreLineEndings; - public function __construct(string $string, bool $ignoreCase = \false, bool $ignoreLineEndings = \false) + public function __construct(string $needle, bool $ignoreCase = \false, bool $ignoreLineEndings = \false) { if ($ignoreLineEndings) { - $string = $this->normalizeLineEndings($string); + $needle = $this->normalizeLineEndings($needle); } - $this->string = $string; + $this->needle = $needle; $this->ignoreCase = $ignoreCase; $this->ignoreLineEndings = $ignoreLineEndings; } @@ -51117,11 +55216,20 @@ final class StringContains extends \PHPUnit\Framework\Constraint\Constraint */ public function toString() : string { - $string = $this->string; + $needle = $this->needle; if ($this->ignoreCase) { - $string = mb_strtolower($this->string, 'UTF-8'); + $needle = mb_strtolower($this->needle, 'UTF-8'); } - return sprintf('contains "%s"', $string); + return sprintf('contains "%s" [%s](length: %s)', $needle, $this->getDetectedEncoding($needle), strlen($needle)); + } + public function failureDescription(mixed $other) : string + { + $stringifiedHaystack = Exporter::export($other, \true); + $haystackEncoding = $this->getDetectedEncoding($other); + $haystackLength = $this->getHaystackLength($other); + $haystackInformation = sprintf('%s [%s](length: %s) ', $stringifiedHaystack, $haystackEncoding, $haystackLength); + $needleInformation = $this->toString(\true); + return $haystackInformation . $needleInformation; } /** * Evaluates the constraint for parameter $other. Returns true if the @@ -51129,31 +55237,56 @@ final class StringContains extends \PHPUnit\Framework\Constraint\Constraint */ protected function matches(mixed $other) : bool { - if ('' === $this->string) { + $haystack = $other; + if ('' === $this->needle) { return \true; } - if (!is_string($other)) { + if (!is_string($haystack)) { return \false; } if ($this->ignoreLineEndings) { - $other = $this->normalizeLineEndings($other); + $haystack = $this->normalizeLineEndings($haystack); } if ($this->ignoreCase) { /* - * We must use the multi byte safe version so we can accurately compare non latin upper characters with + * We must use the multibyte-safe version, so we can accurately compare non-latin uppercase characters with * their lowercase equivalents. */ - return mb_stripos($other, $this->string, 0, 'UTF-8') !== \false; + return mb_stripos($haystack, $this->needle, 0, 'UTF-8') !== \false; } /* - * Use the non multi byte safe functions to see if the string is contained in $other. + * Use the non-multibyte safe functions to see if the string is contained in $other. * - * This function is very fast and we don't care about the character position in the string. + * This function is very fast, and we don't care about the character position in the string. * - * Additionally, we want this method to be binary safe so we can check if some binary data is in other binary + * Additionally, we want this method to be binary safe, so we can check if some binary data is in other binary * data. */ - return str_contains($other, $this->string); + return str_contains($haystack, $this->needle); + } + private function getDetectedEncoding(mixed $other) : string + { + if ($this->ignoreCase) { + return 'Encoding ignored'; + } + if (!is_string($other)) { + return 'Encoding detection failed'; + } + $detectedEncoding = mb_detect_encoding($other, null, \true); + if (!$detectedEncoding) { + return 'Encoding detection failed'; + } + return $detectedEncoding; + } + private function getHaystackLength(mixed $haystack) : int + { + if (!is_string($haystack)) { + return 0; + } + if ($this->ignoreLineEndings) { + $haystack = $this->normalizeLineEndings($haystack); + } + return strlen($haystack); } private function normalizeLineEndings(string $string) : string { @@ -51395,6 +55528,7 @@ namespace PHPUnit\Framework\Constraint; use function array_key_exists; use function is_array; use ArrayAccess; +use PHPUnit\Util\Exporter; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ @@ -51410,7 +55544,7 @@ final class ArrayHasKey extends \PHPUnit\Framework\Constraint\Constraint */ public function toString() : string { - return 'has the key ' . $this->exporter()->export($this->key); + return 'has the key ' . Exporter::export($this->key); } /** * Evaluates the constraint for parameter $other. Returns true if the @@ -51434,7 +55568,7 @@ final class ArrayHasKey extends \PHPUnit\Framework\Constraint\Constraint */ protected function failureDescription(mixed $other) : string { - return 'an array ' . $this->toString(); + return 'an array ' . $this->toString(\true); } } 'an ' . $type . ' ' . $this->toString(), - 'boolean', 'closed resource', 'float', 'resource', 'string' => 'a ' . $type . ' ' . $this->toString(), - 'null' => 'null ' . $this->toString(), - default => 'a value of ' . $type . ' ' . $this->toString(), - }; + return $this->valueToTypeStringFragment($other) . $this->toString(\true); } } exporter()->export($this->value); + return 'contains ' . Exporter::export($this->value, $exportObjects); } /** * Returns the description of the failure. @@ -51540,7 +55661,7 @@ abstract class TraversableContains extends \PHPUnit\Framework\Constraint\Constra */ protected function failureDescription(mixed $other) : string { - return sprintf('%s %s', is_array($other) ? 'an array' : 'a traversable', $this->toString()); + return sprintf('%s %s', is_array($other) ? 'an array' : 'a traversable', $this->toString(\true)); } protected function value() : mixed { @@ -51709,7 +55830,13 @@ use PHPUnit\Framework\UnknownClassOrInterfaceException; */ final class IsInstanceOf extends \PHPUnit\Framework\Constraint\Constraint { + /** + * @psalm-var class-string + */ private readonly string $name; + /** + * @psalm-var 'class'|'interface' + */ private readonly string $type; /** * @throws UnknownClassOrInterfaceException @@ -51748,7 +55875,7 @@ final class IsInstanceOf extends \PHPUnit\Framework\Constraint\Constraint */ protected function failureDescription(mixed $other) : string { - return sprintf('%s is an instance of %s %s', $this->exporter()->shortenedExport($other), $this->type, $this->name); + return $this->valueToTypeStringFragment($other) . $this->toString(\true); } } */ private const KNOWN_TYPES = ['array' => \true, 'boolean' => \true, 'bool' => \true, 'double' => \true, 'float' => \true, 'integer' => \true, 'int' => \true, 'null' => \true, 'numeric' => \true, 'object' => \true, 'real' => \true, 'resource' => \true, 'resource (closed)' => \true, 'string' => \true, 'scalar' => \true, 'callable' => \true, 'iterable' => \true]; + /** + * @psalm-var 'array'|'boolean'|'bool'|'double'|'float'|'integer'|'int'|'null'|'numeric'|'object'|'real'|'resource'|'resource (closed)'|'string'|'scalar'|'callable'|'iterable' + */ private readonly string $type; /** + * @psalm-param 'array'|'boolean'|'bool'|'double'|'float'|'integer'|'int'|'null'|'numeric'|'object'|'real'|'resource'|'resource (closed)'|'string'|'scalar'|'callable'|'iterable' $type + * * @throws UnknownTypeException */ public function __construct(string $type) @@ -51967,9 +56099,7 @@ final class DataProviderTestSuite extends \PHPUnit\Framework\TestSuite $this->dependencies = $dependencies; foreach ($this->tests() as $test) { if (!$test instanceof \PHPUnit\Framework\TestCase) { - // @codeCoverageIgnoreStart continue; - // @codeCoverageIgnoreStart } $test->setDependencies($dependencies); } @@ -51980,7 +56110,7 @@ final class DataProviderTestSuite extends \PHPUnit\Framework\TestSuite public function provides() : array { if ($this->providedTests === null) { - $this->providedTests = [new \PHPUnit\Framework\ExecutionOrderDependency($this->getName())]; + $this->providedTests = [new \PHPUnit\Framework\ExecutionOrderDependency($this->name())]; } return $this->providedTests; } @@ -51998,7 +56128,7 @@ final class DataProviderTestSuite extends \PHPUnit\Framework\TestSuite */ public function size() : TestSize { - [$className, $methodName] = explode('::', $this->getName()); + [$className, $methodName] = explode('::', $this->name()); return (new Groups())->size($className, $methodName); } } @@ -52079,38 +56209,9 @@ declare (strict_types=1); */ namespace PHPUnit\Framework; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class Error extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\SelfDescribing -{ - /** - * Wrapper for getMessage() which is declared as final. - */ - public function toString() : string - { - return $this->getMessage(); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework; - use function array_keys; use function get_object_vars; -use PHPUnit\Util\Filter; -use PHPUnit\Util\ThrowableToStringMapper; use RuntimeException; -use Stringable; use Throwable; /** * Base class for all PHPUnit Framework exceptions. @@ -52134,7 +56235,7 @@ use Throwable; * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ -class Exception extends RuntimeException implements \PHPUnit\Exception, Stringable +class Exception extends RuntimeException implements \PHPUnit\Exception { protected array $serializableTrace; public function __construct(string $message = '', int $code = 0, Throwable $previous = null) @@ -52145,17 +56246,6 @@ class Exception extends RuntimeException implements \PHPUnit\Exception, Stringab unset($this->serializableTrace[$key]['args']); } } - /** - * @throws Exception - */ - public function __toString() : string - { - $string = ThrowableToStringMapper::map($this); - if ($trace = Filter::getFilteredStacktrace($this)) { - $string .= "\n" . $trace; - } - return $string; - } public function __sleep() : array { return array_keys(get_object_vars($this)); @@ -52645,30 +56735,6 @@ declare (strict_types=1); */ namespace PHPUnit\Framework; -use function sprintf; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class UnknownClassException extends \PHPUnit\Framework\InvalidArgumentException -{ - public function __construct(string $name) - { - parent::__construct(sprintf('Class "%s" does not exist', $name)); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework; - use function sprintf; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit @@ -52855,62 +56921,65 @@ declare (strict_types=1); */ namespace PHPUnit\Framework\MockObject; -use PHPUnit\Framework\MockObject\Builder\InvocationMocker as InvocationMockerBuilder; -use PHPUnit\Framework\MockObject\Rule\InvocationOrder; +use PHPUnit\SebastianBergmann\Type\Type; /** - * @internal This trait is not covered by the backward compatibility promise for PHPUnit + * @internal This class is not covered by the backward compatibility promise for PHPUnit */ -trait Api +final class ConfigurableMethod { /** - * @psalm-var list + * @psalm-var non-empty-string */ - private static array $__phpunit_configurableMethods; - private object $__phpunit_originalObject; - private bool $__phpunit_returnValueGeneration = \true; - private ?\PHPUnit\Framework\MockObject\InvocationHandler $__phpunit_invocationMocker = null; - /** @noinspection MagicMethodsValidityInspection */ - public static function __phpunit_initConfigurableMethods(\PHPUnit\Framework\MockObject\ConfigurableMethod ...$configurableMethods) : void - { - if (isset(static::$__phpunit_configurableMethods)) { - throw new \PHPUnit\Framework\MockObject\ConfigurableMethodsAlreadyInitializedException('Configurable methods is already initialized and can not be reinitialized'); - } - static::$__phpunit_configurableMethods = $configurableMethods; - } - /** @noinspection MagicMethodsValidityInspection */ - public function __phpunit_setOriginalObject(object $originalObject) : void + private readonly string $name; + /** + * @psalm-var array + */ + private readonly array $defaultParameterValues; + /** + * @psalm-var non-negative-int + */ + private readonly int $numberOfParameters; + private readonly Type $returnType; + /** + * @psalm-param non-empty-string $name + * @psalm-param array $defaultParameterValues + * @psalm-param non-negative-int $numberOfParameters + */ + public function __construct(string $name, array $defaultParameterValues, int $numberOfParameters, Type $returnType) { - $this->__phpunit_originalObject = $originalObject; + $this->name = $name; + $this->defaultParameterValues = $defaultParameterValues; + $this->numberOfParameters = $numberOfParameters; + $this->returnType = $returnType; } - /** @noinspection MagicMethodsValidityInspection */ - public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration) : void + /** + * @psalm-return non-empty-string + */ + public function name() : string { - $this->__phpunit_returnValueGeneration = $returnValueGeneration; + return $this->name; } - /** @noinspection MagicMethodsValidityInspection */ - public function __phpunit_getInvocationHandler() : \PHPUnit\Framework\MockObject\InvocationHandler + /** + * @psalm-return array + */ + public function defaultParameterValues() : array { - if ($this->__phpunit_invocationMocker === null) { - $this->__phpunit_invocationMocker = new \PHPUnit\Framework\MockObject\InvocationHandler(static::$__phpunit_configurableMethods, $this->__phpunit_returnValueGeneration); - } - return $this->__phpunit_invocationMocker; + return $this->defaultParameterValues; } - /** @noinspection MagicMethodsValidityInspection */ - public function __phpunit_hasMatchers() : bool + /** + * @psalm-return non-negative-int + */ + public function numberOfParameters() : int { - return $this->__phpunit_getInvocationHandler()->hasMatchers(); + return $this->numberOfParameters; } - /** @noinspection MagicMethodsValidityInspection */ - public function __phpunit_verify(bool $unsetInvocationMocker = \true) : void + public function mayReturn(mixed $value) : bool { - $this->__phpunit_getInvocationHandler()->verify(); - if ($unsetInvocationMocker) { - $this->__phpunit_invocationMocker = null; - } + return $this->returnType->isAssignable(Type::fromValue($value, \false)); } - public function expects(InvocationOrder $matcher) : InvocationMockerBuilder + public function returnTypeDeclaration() : string { - return $this->__phpunit_getInvocationHandler()->expects($matcher); + return $this->returnType->asString(); } } expects(new AnyInvokedCount()); - return call_user_func_array([$expects, 'method'], func_get_args()); - } } __phpunit_invocationMocker = clone $this->__phpunit_getInvocationHandler(); + parent::__construct(sprintf('Trying to configure method "%s" with addMethods(), but it exists in class "%s". Use onlyMethods() for methods that exist in the class', $methodName, $type)); } } __phpunit_invocationMocker = clone $this->__phpunit_getInvocationHandler(); - parent::__clone(); + parent::__construct(sprintf('Trying to configure method "%s" with onlyMethods(), but it does not exist in class "%s"', $methodName, $type)); } } - */ - private readonly array $configurableMethods; - /** - * @psalm-var ?array - */ - private ?array $configurableMethodNames = null; - public function __construct(InvocationHandler $handler, Matcher $matcher, ConfigurableMethod ...$configurableMethods) - { - $this->invocationHandler = $handler; - $this->matcher = $matcher; - $this->configurableMethods = $configurableMethods; - } - /** - * @throws MatcherAlreadyRegisteredException - * - * @return $this - */ - public function id(string $id) : self - { - $this->invocationHandler->registerMatcher($id, $this->matcher); - return $this; - } - /** - * @return $this - */ - public function will(Stub $stub) : \PHPUnit\Framework\MockObject\Builder\Identity - { - $this->matcher->setStub($stub); - return $this; - } - /** - * @throws IncompatibleReturnValueException - */ - public function willReturn(mixed $value, mixed ...$nextValues) : self - { - if (count($nextValues) === 0) { - $this->ensureTypeOfReturnValues([$value]); - $stub = $value instanceof Stub ? $value : new ReturnStub($value); - } else { - $values = array_merge([$value], $nextValues); - $this->ensureTypeOfReturnValues($values); - $stub = new ConsecutiveCalls($values); - } - return $this->will($stub); - } - public function willReturnReference(mixed &$reference) : self - { - $stub = new ReturnReference($reference); - return $this->will($stub); - } - public function willReturnMap(array $valueMap) : self - { - $stub = new ReturnValueMap($valueMap); - return $this->will($stub); - } - public function willReturnArgument(int $argumentIndex) : self - { - $stub = new ReturnArgument($argumentIndex); - return $this->will($stub); - } - public function willReturnCallback(callable $callback) : self - { - $stub = new ReturnCallback($callback); - return $this->will($stub); - } - public function willReturnSelf() : self - { - $stub = new ReturnSelf(); - return $this->will($stub); - } - public function willReturnOnConsecutiveCalls(mixed ...$values) : self - { - $stub = new ConsecutiveCalls($values); - return $this->will($stub); - } - public function willThrowException(Throwable $exception) : self - { - $stub = new Exception($exception); - return $this->will($stub); - } - /** - * @return $this - */ - public function after(string $id) : self - { - $this->matcher->setAfterMatchBuilderId($id); - return $this; - } - /** - * @throws \PHPUnit\Framework\Exception - * @throws MethodNameNotConfiguredException - * @throws MethodParametersAlreadyConfiguredException - * - * @return $this - */ - public function with(mixed ...$arguments) : self - { - $this->ensureParametersCanBeConfigured(); - $this->matcher->setParametersRule(new Rule\Parameters($arguments)); - return $this; - } - /** - * @throws MethodNameNotConfiguredException - * @throws MethodParametersAlreadyConfiguredException - * - * @return $this - */ - public function withAnyParameters() : self - { - $this->ensureParametersCanBeConfigured(); - $this->matcher->setParametersRule(new Rule\AnyParameters()); - return $this; - } - /** - * @throws \PHPUnit\Framework\InvalidArgumentException - * @throws MethodCannotBeConfiguredException - * @throws MethodNameAlreadyConfiguredException - * - * @return $this - */ - public function method(Constraint|string $constraint) : self - { - if ($this->matcher->hasMethodNameRule()) { - throw new MethodNameAlreadyConfiguredException(); - } - if (is_string($constraint)) { - $this->configurableMethodNames ??= array_flip(array_map(static fn(ConfigurableMethod $configurable) => strtolower($configurable->name()), $this->configurableMethods)); - if (!array_key_exists(strtolower($constraint), $this->configurableMethodNames)) { - throw new MethodCannotBeConfiguredException($constraint); - } - } - $this->matcher->setMethodNameRule(new Rule\MethodName($constraint)); - return $this; - } - /** - * @throws MethodNameNotConfiguredException - * @throws MethodParametersAlreadyConfiguredException - */ - private function ensureParametersCanBeConfigured() : void - { - if (!$this->matcher->hasMethodNameRule()) { - throw new MethodNameNotConfiguredException(); - } - if ($this->matcher->hasParametersRule()) { - throw new MethodParametersAlreadyConfiguredException(); - } - } - private function configuredMethod() : ?ConfigurableMethod - { - $configuredMethod = null; - foreach ($this->configurableMethods as $configurableMethod) { - if ($this->matcher->methodNameRule()->matchesName($configurableMethod->name())) { - if ($configuredMethod !== null) { - return null; - } - $configuredMethod = $configurableMethod; - } - } - return $configuredMethod; - } - /** - * @throws IncompatibleReturnValueException - */ - private function ensureTypeOfReturnValues(array $values) : void + public function __construct(\PHPUnit\Framework\MockObject\ConfigurableMethod $method, mixed $value) { - $configuredMethod = $this->configuredMethod(); - if ($configuredMethod === null) { - return; - } - foreach ($values as $value) { - if (!$configuredMethod->mayReturn($value)) { - throw new IncompatibleReturnValueException($configuredMethod, $value); - } - } + parent::__construct(sprintf('Method %s may not return value of type %s, its declared return type is "%s"', $method->name(), get_debug_type($value), $method->returnTypeDeclaration())); } } > $valueMap - */ - public function willReturnMap(array $valueMap) : self; - public function willReturnArgument(int $argumentIndex) : self; - public function willReturnCallback(callable $callback) : self; - public function willReturnSelf() : self; - public function willReturnOnConsecutiveCalls(mixed ...$values) : self; - public function willThrowException(Throwable $exception) : self; + public function __construct(string $id) + { + parent::__construct(sprintf('No builder found for match builder identification <%s>', $id)); + } } - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework\MockObject\Builder; - -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -interface ParametersMatch extends \PHPUnit\Framework\MockObject\Builder\Stub -{ - /** - * Defines the expectation which must occur before the current is valid. - */ - public function after(string $id) : \PHPUnit\Framework\MockObject\Builder\Stub; - /** - * Sets the parameters to match for, each parameter to this function will - * be part of match. To perform specific matches or constraints create a - * new PHPUnit\Framework\Constraint\Constraint and use it for the parameter. - * If the parameter value is not a constraint it will use the - * PHPUnit\Framework\Constraint\IsEqual for the value. - * - * Some examples: - * - * // match first parameter with value 2 - * $b->with(2); - * // match first parameter with value 'smock' and second identical to 42 - * $b->with('smock', new PHPUnit\Framework\Constraint\IsEqual(42)); - * - */ - public function with(mixed ...$arguments) : self; - /** - * Sets a rule which allows any kind of parameters. - * - * Some examples: - * - * // match any number of parameters - * $b->withAnyParameters(); - * - */ - public function withAnyParameters() : self; -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework\MockObject\Builder; - -use PHPUnit\Framework\MockObject\Stub\Stub as BaseStub; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -interface Stub extends \PHPUnit\Framework\MockObject\Builder\Identity -{ - /** - * Stubs the matching method with the stub object $stub. Any invocations of - * the matched method will now be handled by the stub instead. - */ - public function will(BaseStub $stub) : \PHPUnit\Framework\MockObject\Builder\Identity; -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework\MockObject; - -use PHPUnit\SebastianBergmann\Type\Type; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class ConfigurableMethod -{ - private readonly string $name; - private readonly Type $returnType; - public function __construct(string $name, Type $returnType) - { - $this->name = $name; - $this->returnType = $returnType; - } - public function name() : string - { - return $this->name; - } - public function mayReturn(mixed $value) : bool - { - if ($value === null && $this->returnType->allowsNull()) { - return \true; - } - return $this->returnType->isAssignable(Type::fromValue($value, \false)); - } - public function returnTypeDeclaration() : string - { - return $this->returnType->asString(); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework\MockObject; - -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class BadMethodCallException extends \BadMethodCallException implements \PHPUnit\Framework\MockObject\Exception -{ -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework\MockObject; - -use function sprintf; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class CannotUseAddMethodsException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception +final class MatcherAlreadyRegisteredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception { - public function __construct(string $type, string $methodName) + public function __construct(string $id) { - parent::__construct(sprintf('Trying to configure method "%s" with addMethods(), but it exists in class "%s". Use onlyMethods() for methods that exist in the class', $methodName, $type)); + parent::__construct(sprintf('Matcher with id <%s> is already registered', $id)); } } $methods - */ - public function __construct(array $methods) + public function __construct(\PHPUnit\Framework\MockObject\Invocation $invocation) { - parent::__construct(sprintf('Cannot double using a method list that contains duplicates: "%s" (duplicate: "%s")', implode(', ', $methods), implode(', ', array_unique(array_diff_assoc($methods, array_unique($methods)))))); + parent::__construct(sprintf('No return value is configured for %s::%s() and return value generation is disabled', $invocation->className(), $invocation->methodName())); } } name(), get_debug_type($value), $method->returnTypeDeclaration())); + parent::__construct(sprintf('Class "%s" already exists', $className)); } } ', $id)); + parent::__construct(sprintf('Class "%s" is declared "final" and cannot be doubled', $className)); } } is already registered', $id)); + parent::__construct(sprintf('Class "%s" is declared "readonly" and cannot be doubled', $className)); } } - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework\MockObject; - -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class MethodNameAlreadyConfiguredException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception +final class DuplicateMethodException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception { - public function __construct() + /** + * @psalm-param list $methods + */ + public function __construct(array $methods) { - parent::__construct('Method name is already configured'); + parent::__construct(sprintf('Cannot double using a method list that contains duplicates: "%s" (duplicate: "%s")', implode(', ', $methods), implode(', ', array_unique(array_diff_assoc($methods, array_unique($methods)))))); } } className(), $invocation->methodName())); - } } - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework\MockObject; - -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class SoapExtensionNotAvailableException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception +final class SoapExtensionNotAvailableException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception { public function __construct() { @@ -53955,13 +57592,13 @@ declare (strict_types=1); * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -namespace PHPUnit\Framework\MockObject; +namespace PHPUnit\Framework\MockObject\Generator; use function sprintf; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ -final class UnknownClassException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception +final class UnknownClassException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception { public function __construct(string $className) { @@ -53979,13 +57616,15 @@ declare (strict_types=1); * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -namespace PHPUnit\Framework\MockObject; +namespace PHPUnit\Framework\MockObject\Generator; use function sprintf; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5243 */ -final class UnknownTraitException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception +final class UnknownTraitException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception { public function __construct(string $traitName) { @@ -54003,13 +57642,13 @@ declare (strict_types=1); * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -namespace PHPUnit\Framework\MockObject; +namespace PHPUnit\Framework\MockObject\Generator; use function sprintf; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ -final class UnknownTypeException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Exception +final class UnknownTypeException extends \PHPUnit\Framework\Exception implements \PHPUnit\Framework\MockObject\Generator\Exception { public function __construct(string $type) { @@ -54027,7 +57666,7 @@ declare (strict_types=1); * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -namespace PHPUnit\Framework\MockObject; +namespace PHPUnit\Framework\MockObject\Generator; use const PHP_EOL; use const PREG_OFFSET_CAPTURE; @@ -54064,6 +57703,16 @@ use Exception; use Iterator; use IteratorAggregate; use PHPUnit\Framework\InvalidArgumentException; +use PHPUnit\Framework\MockObject\ConfigurableMethod; +use PHPUnit\Framework\MockObject\DoubledCloneMethod; +use PHPUnit\Framework\MockObject\Method; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\MockObject\MockObjectApi; +use PHPUnit\Framework\MockObject\MockObjectInternal; +use PHPUnit\Framework\MockObject\ProxiedCloneMethod; +use PHPUnit\Framework\MockObject\Stub; +use PHPUnit\Framework\MockObject\StubApi; +use PHPUnit\Framework\MockObject\StubInternal; use ReflectionClass; use ReflectionMethod; use SoapClient; @@ -54075,20 +57724,17 @@ use Traversable; */ final class Generator { - use \PHPUnit\Framework\MockObject\TemplateLoader; + use \PHPUnit\Framework\MockObject\Generator\TemplateLoader; /** * @var array */ private const EXCLUDED_METHOD_NAMES = ['__CLASS__' => \true, '__DIR__' => \true, '__FILE__' => \true, '__FUNCTION__' => \true, '__LINE__' => \true, '__METHOD__' => \true, '__NAMESPACE__' => \true, '__TRAIT__' => \true, '__clone' => \true, '__halt_compiler' => \true]; + /** + * @psalm-var array + */ private static array $cache = []; /** - * Returns a mock object for the specified class. - * - * @psalm-template RealInstanceType of object - * - * @psalm-param class-string $type - * - * @psalm-return MockObject&RealInstanceType + * Returns a test double for the specified class. * * @throws ClassAlreadyExistsException * @throws ClassIsEnumerationException @@ -54101,7 +57747,7 @@ final class Generator * @throws RuntimeException * @throws UnknownTypeException */ - public function getMock(string $type, ?array $methods = [], array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, bool $cloneArguments = \true, bool $callOriginalMethods = \false, object $proxyTarget = null, bool $allowMockingUnknownTypes = \true, bool $returnValueGeneration = \true) : \PHPUnit\Framework\MockObject\MockObject + public function testDouble(string $type, bool $mockObject, ?array $methods = [], array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, bool $cloneArguments = \true, bool $callOriginalMethods = \false, object $proxyTarget = null, bool $allowMockingUnknownTypes = \true, bool $returnValueGeneration = \true) : MockObject|Stub { if ($type === Traversable::class) { $type = Iterator::class; @@ -54112,11 +57758,16 @@ final class Generator $this->ensureValidMethods($methods); $this->ensureMockedClassDoesNotAlreadyExist($mockClassName); if (!$callOriginalConstructor && $callOriginalMethods) { - throw new \PHPUnit\Framework\MockObject\OriginalConstructorInvocationRequiredException(); + throw new \PHPUnit\Framework\MockObject\Generator\OriginalConstructorInvocationRequiredException(); } - $mock = $this->generate($type, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods); + $mock = $this->generate($type, $mockObject, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods); $object = $this->getObject($mock, $type, $callOriginalConstructor, $arguments, $callOriginalMethods, $proxyTarget, $returnValueGeneration); - assert($object instanceof \PHPUnit\Framework\MockObject\MockObject); + assert($object instanceof $type); + if ($mockObject) { + assert($object instanceof MockObject); + } else { + assert($object instanceof Stub); + } return $object; } /** @@ -54125,23 +57776,23 @@ final class Generator * @throws RuntimeException * @throws UnknownTypeException */ - public function getMockForInterfaces(array $interfaces, bool $callAutoload = \true) : \PHPUnit\Framework\MockObject\MockObject + public function testDoubleForInterfaceIntersection(array $interfaces, bool $mockObject, bool $callAutoload = \true) : MockObject|Stub { if (count($interfaces) < 2) { - throw new \PHPUnit\Framework\MockObject\RuntimeException('At least two interfaces must be specified'); + throw new \PHPUnit\Framework\MockObject\Generator\RuntimeException('At least two interfaces must be specified'); } foreach ($interfaces as $interface) { if (!interface_exists($interface, $callAutoload)) { - throw new \PHPUnit\Framework\MockObject\UnknownTypeException($interface); + throw new \PHPUnit\Framework\MockObject\Generator\UnknownTypeException($interface); } } sort($interfaces); $methods = []; foreach ($interfaces as $interface) { - $methods = array_merge($methods, $this->getClassMethods($interface)); + $methods = array_merge($methods, $this->namesOfMethodsIn($interface)); } if (count(array_unique($methods)) < count($methods)) { - throw new \PHPUnit\Framework\MockObject\RuntimeException('Interfaces must not declare the same method'); + throw new \PHPUnit\Framework\MockObject\Generator\RuntimeException('Interfaces must not declare the same method'); } $unqualifiedNames = []; foreach ($interfaces as $interface) { @@ -54155,7 +57806,7 @@ final class Generator $template = $this->loadTemplate('intersection.tpl'); $template->setVar(['intersection' => $intersectionName, 'interfaces' => implode(', ', $interfaces)]); eval($template->render()); - return $this->getMock($intersectionName); + return $this->testDouble($intersectionName, $mockObject); } /** * Returns a mock object for the specified abstract class with all abstract @@ -54163,12 +57814,6 @@ final class Generator * * Concrete methods to mock can be specified with the $mockedMethods parameter. * - * @psalm-template RealInstanceType of object - * - * @psalm-param class-string $originalClassName - * - * @psalm-return MockObject&RealInstanceType - * * @throws ClassAlreadyExistsException * @throws ClassIsEnumerationException * @throws ClassIsFinalException @@ -54181,17 +57826,13 @@ final class Generator * @throws RuntimeException * @throws UnknownClassException * @throws UnknownTypeException + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5241 */ - public function getMockForAbstractClass(string $originalClassName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, array $mockedMethods = null, bool $cloneArguments = \true) : \PHPUnit\Framework\MockObject\MockObject + public function mockObjectForAbstractClass(string $originalClassName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, array $mockedMethods = null, bool $cloneArguments = \true) : MockObject { if (class_exists($originalClassName, $callAutoload) || interface_exists($originalClassName, $callAutoload)) { - try { - $reflector = new ReflectionClass($originalClassName); - // @codeCoverageIgnoreStart - } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); - } - // @codeCoverageIgnoreEnd + $reflector = $this->reflectClass($originalClassName); $methods = $mockedMethods; foreach ($reflector->getMethods() as $method) { if ($method->isAbstract() && !in_array($method->getName(), $methods ?? [], \true)) { @@ -54201,9 +57842,12 @@ final class Generator if (empty($methods)) { $methods = null; } - return $this->getMock($originalClassName, $methods, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $cloneArguments); + $mockObject = $this->testDouble($originalClassName, \true, $methods, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $cloneArguments); + assert($mockObject instanceof $originalClassName); + assert($mockObject instanceof MockObject); + return $mockObject; } - throw new \PHPUnit\Framework\MockObject\UnknownClassException($originalClassName); + throw new \PHPUnit\Framework\MockObject\Generator\UnknownClassException($originalClassName); } /** * Returns a mock object for the specified trait with all abstract methods @@ -54225,18 +57869,20 @@ final class Generator * @throws UnknownClassException * @throws UnknownTraitException * @throws UnknownTypeException + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5243 */ - public function getMockForTrait(string $traitName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, array $mockedMethods = null, bool $cloneArguments = \true) : \PHPUnit\Framework\MockObject\MockObject + public function mockObjectForTrait(string $traitName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, array $mockedMethods = null, bool $cloneArguments = \true) : MockObject { if (!trait_exists($traitName, $callAutoload)) { - throw new \PHPUnit\Framework\MockObject\UnknownTraitException($traitName); + throw new \PHPUnit\Framework\MockObject\Generator\UnknownTraitException($traitName); } $className = $this->generateClassName($traitName, '', 'Trait_'); $classTemplate = $this->loadTemplate('trait_class.tpl'); $classTemplate->setVar(['prologue' => 'abstract ', 'class_name' => $className['className'], 'trait_name' => $traitName]); - $mockTrait = new \PHPUnit\Framework\MockObject\MockTrait($classTemplate->render(), $className['className']); + $mockTrait = new \PHPUnit\Framework\MockObject\Generator\MockTrait($classTemplate->render(), $className['className']); $mockTrait->generate(); - return $this->getMockForAbstractClass($className['className'], $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments); + return $this->mockObjectForAbstractClass($className['className'], $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments); } /** * Returns an object for the specified trait. @@ -54246,16 +57892,18 @@ final class Generator * @throws ReflectionException * @throws RuntimeException * @throws UnknownTraitException + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5244 */ - public function getObjectForTrait(string $traitName, string $traitClassName = '', bool $callAutoload = \true, bool $callOriginalConstructor = \false, array $arguments = []) : object + public function objectForTrait(string $traitName, string $traitClassName = '', bool $callAutoload = \true, bool $callOriginalConstructor = \false, array $arguments = []) : object { if (!trait_exists($traitName, $callAutoload)) { - throw new \PHPUnit\Framework\MockObject\UnknownTraitException($traitName); + throw new \PHPUnit\Framework\MockObject\Generator\UnknownTraitException($traitName); } $className = $this->generateClassName($traitName, $traitClassName, 'Trait_'); $classTemplate = $this->loadTemplate('trait_class.tpl'); $classTemplate->setVar(['prologue' => '', 'class_name' => $className['className'], 'trait_name' => $traitName]); - return $this->getObject(new \PHPUnit\Framework\MockObject\MockTrait($classTemplate->render(), $className['className']), '', $callOriginalConstructor, $arguments); + return $this->getObject(new \PHPUnit\Framework\MockObject\Generator\MockTrait($classTemplate->render(), $className['className']), '', $callOriginalConstructor, $arguments); } /** * @throws ClassIsEnumerationException @@ -54263,26 +57911,32 @@ final class Generator * @throws ClassIsReadonlyException * @throws ReflectionException * @throws RuntimeException + * + * @todo This method is only public because it is used to test generated code in PHPT tests + * + * @see https://github.com/sebastianbergmann/phpunit/issues/5476 */ - public function generate(string $type, array $methods = null, string $mockClassName = '', bool $callOriginalClone = \true, bool $callAutoload = \true, bool $cloneArguments = \true, bool $callOriginalMethods = \false) : \PHPUnit\Framework\MockObject\MockClass + public function generate(string $type, bool $mockObject, array $methods = null, string $mockClassName = '', bool $callOriginalClone = \true, bool $callAutoload = \true, bool $cloneArguments = \true, bool $callOriginalMethods = \false) : \PHPUnit\Framework\MockObject\Generator\MockClass { if ($mockClassName !== '') { - return $this->generateMock($type, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods); + return $this->generateCodeForTestDoubleClass($type, $mockObject, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods); } - $key = md5($type . serialize($methods) . serialize($callOriginalClone) . serialize($cloneArguments) . serialize($callOriginalMethods)); + $key = md5($type . ($mockObject ? 'MockObject' : 'TestStub') . serialize($methods) . serialize($callOriginalClone) . serialize($cloneArguments) . serialize($callOriginalMethods)); if (!isset(self::$cache[$key])) { - self::$cache[$key] = $this->generateMock($type, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods); + self::$cache[$key] = $this->generateCodeForTestDoubleClass($type, $mockObject, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods); } return self::$cache[$key]; } /** * @throws RuntimeException * @throws SoapExtensionNotAvailableException + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5242 */ public function generateClassFromWsdl(string $wsdlFile, string $className, array $methods = [], array $options = []) : string { if (!extension_loaded('soap')) { - throw new \PHPUnit\Framework\MockObject\SoapExtensionNotAvailableException(); + throw new \PHPUnit\Framework\MockObject\Generator\SoapExtensionNotAvailableException(); } $options['cache_wsdl'] = WSDL_CACHE_NONE; try { @@ -54290,7 +57944,7 @@ final class Generator $_methods = array_unique($client->__getFunctions()); unset($client); } catch (SoapFault $e) { - throw new \PHPUnit\Framework\MockObject\RuntimeException($e->getMessage(), $e->getCode(), $e); + throw new \PHPUnit\Framework\MockObject\Generator\RuntimeException($e->getMessage(), $e->getCode(), $e); } sort($_methods); $methodTemplate = $this->loadTemplate('wsdl_method.tpl'); @@ -54329,28 +57983,6 @@ final class Generator $classTemplate->setVar(['namespace' => $namespace, 'class_name' => $className, 'wsdl' => $wsdlFile, 'options' => $optionsBuffer, 'methods' => $methodsBuffer]); return $classTemplate->render(); } - /** - * @throws ReflectionException - * - * @psalm-return list - */ - public function getClassMethods(string $className) : array - { - try { - $class = new ReflectionClass($className); - // @codeCoverageIgnoreStart - } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); - } - // @codeCoverageIgnoreEnd - $methods = []; - foreach ($class->getMethods() as $method) { - if ($method->isPublic() || $method->isAbstract()) { - $methods[] = $method->getName(); - } - } - return $methods; - } /** * @throws ReflectionException * @@ -54358,41 +57990,15 @@ final class Generator */ public function mockClassMethods(string $className, bool $callOriginalMethods, bool $cloneArguments) : array { - try { - $class = new ReflectionClass($className); - // @codeCoverageIgnoreStart - } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); - } - // @codeCoverageIgnoreEnd + $class = $this->reflectClass($className); $methods = []; foreach ($class->getMethods() as $method) { if (($method->isPublic() || $method->isAbstract()) && $this->canMethodBeDoubled($method)) { - $methods[] = \PHPUnit\Framework\MockObject\MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments); + $methods[] = \PHPUnit\Framework\MockObject\Generator\MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments); } } return $methods; } - /** - * @throws ReflectionException - * - * @psalm-return list - */ - public function mockInterfaceMethods(string $interfaceName, bool $cloneArguments) : array - { - try { - $class = new ReflectionClass($interfaceName); - // @codeCoverageIgnoreStart - } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); - } - // @codeCoverageIgnoreEnd - $methods = []; - foreach ($class->getMethods() as $method) { - $methods[] = \PHPUnit\Framework\MockObject\MockMethod::fromReflection($method, \false, $cloneArguments); - } - return $methods; - } /** * @psalm-param class-string $interfaceName * @@ -54402,13 +58008,7 @@ final class Generator */ private function userDefinedInterfaceMethods(string $interfaceName) : array { - try { - // @codeCoverageIgnoreStart - $interface = new ReflectionClass($interfaceName); - } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); - } - // @codeCoverageIgnoreEnd + $interface = $this->reflectClass($interfaceName); $methods = []; foreach ($interface->getMethods() as $method) { if (!$method->isUserDefined()) { @@ -54422,14 +58022,14 @@ final class Generator * @throws ReflectionException * @throws RuntimeException */ - private function getObject(\PHPUnit\Framework\MockObject\MockType $mockClass, string $type = '', bool $callOriginalConstructor = \false, array $arguments = [], bool $callOriginalMethods = \false, object $proxyTarget = null, bool $returnValueGeneration = \true) : object + private function getObject(\PHPUnit\Framework\MockObject\Generator\MockType $mockClass, string $type = '', bool $callOriginalConstructor = \false, array $arguments = [], bool $callOriginalMethods = \false, object $proxyTarget = null, bool $returnValueGeneration = \true) : object { $className = $mockClass->generate(); $object = $this->instantiate($className, $callOriginalConstructor, $arguments); if ($callOriginalMethods) { $this->instantiateProxyTarget($proxyTarget, $object, $type, $arguments); } - if ($object instanceof \PHPUnit\Framework\MockObject\MockObject) { + if ($object instanceof StubInternal) { $object->__phpunit_setReturnValueGeneration($returnValueGeneration); } return $object; @@ -54441,17 +58041,18 @@ final class Generator * @throws ReflectionException * @throws RuntimeException */ - private function generateMock(string $type, ?array $explicitMethods, string $mockClassName, bool $callOriginalClone, bool $callAutoload, bool $cloneArguments, bool $callOriginalMethods) : \PHPUnit\Framework\MockObject\MockClass + private function generateCodeForTestDoubleClass(string $type, bool $mockObject, ?array $explicitMethods, string $mockClassName, bool $callOriginalClone, bool $callAutoload, bool $cloneArguments, bool $callOriginalMethods) : \PHPUnit\Framework\MockObject\Generator\MockClass { - $classTemplate = $this->loadTemplate('mocked_class.tpl'); + $classTemplate = $this->loadTemplate('test_double_class.tpl'); $additionalInterfaces = []; - $mockedCloneMethod = \false; - $unmockedCloneMethod = \false; + $doubledCloneMethod = \false; + $proxiedCloneMethod = \false; $isClass = \false; $isInterface = \false; $class = null; - $mockMethods = new \PHPUnit\Framework\MockObject\MockMethodSet(); - $_mockClassName = $this->generateClassName($type, $mockClassName, 'Mock_'); + $mockMethods = new \PHPUnit\Framework\MockObject\Generator\MockMethodSet(); + $testDoubleClassPrefix = $mockObject ? 'MockObject_' : 'TestStub_'; + $_mockClassName = $this->generateClassName($type, $mockClassName, $testDoubleClassPrefix); if (class_exists($_mockClassName['fullClassName'], $callAutoload)) { $isClass = \true; } elseif (interface_exists($_mockClassName['fullClassName'], $callAutoload)) { @@ -54463,36 +58064,24 @@ final class Generator $prologue = 'namespace ' . $_mockClassName['namespaceName'] . " {\n\n" . $prologue . "}\n\n" . "namespace {\n\n"; $epilogue = "\n\n}"; } - $mockedCloneMethod = \true; + $doubledCloneMethod = \true; } else { - try { - $class = new ReflectionClass($_mockClassName['fullClassName']); - // @codeCoverageIgnoreStart - } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); - } - // @codeCoverageIgnoreEnd + $class = $this->reflectClass($_mockClassName['fullClassName']); if ($class->isEnum()) { - throw new \PHPUnit\Framework\MockObject\ClassIsEnumerationException($_mockClassName['fullClassName']); + throw new \PHPUnit\Framework\MockObject\Generator\ClassIsEnumerationException($_mockClassName['fullClassName']); } if ($class->isFinal()) { - throw new \PHPUnit\Framework\MockObject\ClassIsFinalException($_mockClassName['fullClassName']); + throw new \PHPUnit\Framework\MockObject\Generator\ClassIsFinalException($_mockClassName['fullClassName']); } if (method_exists($class, 'isReadOnly') && $class->isReadOnly()) { - throw new \PHPUnit\Framework\MockObject\ClassIsReadonlyException($_mockClassName['fullClassName']); + throw new \PHPUnit\Framework\MockObject\Generator\ClassIsReadonlyException($_mockClassName['fullClassName']); } // @see https://github.com/sebastianbergmann/phpunit/issues/2995 if ($isInterface && $class->implementsInterface(Throwable::class)) { $actualClassName = Exception::class; $additionalInterfaces[] = $class->getName(); $isInterface = \false; - try { - $class = new ReflectionClass($actualClassName); - // @codeCoverageIgnoreStart - } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); - } - // @codeCoverageIgnoreEnd + $class = $this->reflectClass($actualClassName); foreach ($this->userDefinedInterfaceMethods($_mockClassName['fullClassName']) as $method) { $methodName = $method->getName(); if ($class->hasMethod($methodName)) { @@ -54501,9 +58090,9 @@ final class Generator continue; } } - $mockMethods->addMethods(\PHPUnit\Framework\MockObject\MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments)); + $mockMethods->addMethods(\PHPUnit\Framework\MockObject\Generator\MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments)); } - $_mockClassName = $this->generateClassName($actualClassName, $_mockClassName['className'], 'Mock_'); + $_mockClassName = $this->generateClassName($actualClassName, $_mockClassName['className'], $testDoubleClassPrefix); } // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/103 if ($isInterface && $class->implementsInterface(Traversable::class) && !$class->implementsInterface(Iterator::class) && !$class->implementsInterface(IteratorAggregate::class)) { @@ -54514,30 +58103,30 @@ final class Generator $cloneMethod = $class->getMethod('__clone'); if (!$cloneMethod->isFinal()) { if ($callOriginalClone && !$isInterface) { - $unmockedCloneMethod = \true; + $proxiedCloneMethod = \true; } else { - $mockedCloneMethod = \true; + $doubledCloneMethod = \true; } } } else { - $mockedCloneMethod = \true; + $doubledCloneMethod = \true; } } if ($isClass && $explicitMethods === []) { $mockMethods->addMethods(...$this->mockClassMethods($_mockClassName['fullClassName'], $callOriginalMethods, $cloneArguments)); } if ($isInterface && ($explicitMethods === [] || $explicitMethods === null)) { - $mockMethods->addMethods(...$this->mockInterfaceMethods($_mockClassName['fullClassName'], $cloneArguments)); + $mockMethods->addMethods(...$this->interfaceMethods($_mockClassName['fullClassName'], $cloneArguments)); } if (is_array($explicitMethods)) { foreach ($explicitMethods as $methodName) { if ($class !== null && $class->hasMethod($methodName)) { $method = $class->getMethod($methodName); if ($this->canMethodBeDoubled($method)) { - $mockMethods->addMethods(\PHPUnit\Framework\MockObject\MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments)); + $mockMethods->addMethods(\PHPUnit\Framework\MockObject\Generator\MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments)); } } else { - $mockMethods->addMethods(\PHPUnit\Framework\MockObject\MockMethod::fromName($_mockClassName['fullClassName'], $methodName, $cloneArguments)); + $mockMethods->addMethods(\PHPUnit\Framework\MockObject\Generator\MockMethod::fromName($_mockClassName['fullClassName'], $methodName, $cloneArguments)); } } } @@ -54545,21 +58134,29 @@ final class Generator $configurable = []; foreach ($mockMethods->asArray() as $mockMethod) { $mockedMethods .= $mockMethod->generateCode(); - $configurable[] = new \PHPUnit\Framework\MockObject\ConfigurableMethod($mockMethod->methodName(), $mockMethod->returnType()); + $configurable[] = new ConfigurableMethod($mockMethod->methodName(), $mockMethod->defaultParameterValues(), $mockMethod->numberOfParameters(), $mockMethod->returnType()); + } + /** @psalm-var trait-string[] $traits */ + $traits = [StubApi::class]; + if ($mockObject) { + $traits[] = MockObjectApi::class; } - $method = ''; if (!$mockMethods->hasMethod('method') && (!isset($class) || !$class->hasMethod('method'))) { - $method = PHP_EOL . ' use \\PHPUnit\\Framework\\MockObject\\Method;'; + $traits[] = Method::class; + } + if ($doubledCloneMethod) { + $traits[] = DoubledCloneMethod::class; } - $cloneTrait = ''; - if ($mockedCloneMethod) { - $cloneTrait = PHP_EOL . ' use \\PHPUnit\\Framework\\MockObject\\MockedCloneMethod;'; + if ($proxiedCloneMethod) { + $traits[] = ProxiedCloneMethod::class; } - if ($unmockedCloneMethod) { - $cloneTrait = PHP_EOL . ' use \\PHPUnit\\Framework\\MockObject\\UnmockedCloneMethod;'; + $useStatements = ''; + foreach ($traits as $trait) { + $useStatements .= sprintf(' use %s;' . PHP_EOL, $trait); } - $classTemplate->setVar(['prologue' => $prologue ?? '', 'epilogue' => $epilogue ?? '', 'class_declaration' => $this->generateMockClassDeclaration($_mockClassName, $isInterface, $additionalInterfaces), 'clone' => $cloneTrait, 'mock_class_name' => $_mockClassName['className'], 'mocked_methods' => $mockedMethods, 'method' => $method]); - return new \PHPUnit\Framework\MockObject\MockClass($classTemplate->render(), $_mockClassName['className'], $configurable); + unset($traits); + $classTemplate->setVar(['prologue' => $prologue ?? '', 'epilogue' => $epilogue ?? '', 'class_declaration' => $this->generateTestDoubleClassDeclaration($mockObject, $_mockClassName, $isInterface, $additionalInterfaces), 'use_statements' => $useStatements, 'mock_class_name' => $_mockClassName['className'], 'mocked_methods' => $mockedMethods]); + return new \PHPUnit\Framework\MockObject\Generator\MockClass($classTemplate->render(), $_mockClassName['className'], $configurable); } private function generateClassName(string $type, string $className, string $prefix) : array { @@ -54582,10 +58179,14 @@ final class Generator } return ['className' => $className, 'originalClassName' => $type, 'fullClassName' => $fullClassName, 'namespaceName' => $namespaceName]; } - private function generateMockClassDeclaration(array $mockClassName, bool $isInterface, array $additionalInterfaces = []) : string + private function generateTestDoubleClassDeclaration(bool $mockObject, array $mockClassName, bool $isInterface, array $additionalInterfaces = []) : string { + if ($mockObject) { + $additionalInterfaces[] = MockObjectInternal::class; + } else { + $additionalInterfaces[] = StubInternal::class; + } $buffer = 'class '; - $additionalInterfaces[] = \PHPUnit\Framework\MockObject\MockObject::class; $interfaces = implode(', ', $additionalInterfaces); if ($isInterface) { $buffer .= sprintf('%s implements %s', $mockClassName['className'], $interfaces); @@ -54627,7 +58228,7 @@ final class Generator private function ensureKnownType(string $type, bool $callAutoload) : void { if (!class_exists($type, $callAutoload) && !interface_exists($type, $callAutoload)) { - throw new \PHPUnit\Framework\MockObject\UnknownTypeException($type); + throw new \PHPUnit\Framework\MockObject\Generator\UnknownTypeException($type); } } /** @@ -54636,16 +58237,17 @@ final class Generator */ private function ensureValidMethods(?array $methods) : void { - if (null !== $methods) { - foreach ($methods as $method) { - if (!preg_match('~[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*~', (string) $method)) { - throw new \PHPUnit\Framework\MockObject\InvalidMethodNameException((string) $method); - } - } - if ($methods !== array_unique($methods)) { - throw new \PHPUnit\Framework\MockObject\DuplicateMethodException($methods); + if ($methods === null) { + return; + } + foreach ($methods as $method) { + if (!preg_match('~[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*~', (string) $method)) { + throw new \PHPUnit\Framework\MockObject\Generator\InvalidMethodNameException((string) $method); } } + if ($methods !== array_unique($methods)) { + throw new \PHPUnit\Framework\MockObject\Generator\DuplicateMethodException($methods); + } } /** * @throws ClassAlreadyExistsException @@ -54654,15 +58256,9 @@ final class Generator private function ensureMockedClassDoesNotAlreadyExist(string $mockClassName) : void { if ($mockClassName !== '' && class_exists($mockClassName, \false)) { - try { - $reflector = new ReflectionClass($mockClassName); - // @codeCoverageIgnoreStart - } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); - } - // @codeCoverageIgnoreEnd - if (!$reflector->implementsInterface(\PHPUnit\Framework\MockObject\MockObject::class)) { - throw new \PHPUnit\Framework\MockObject\ClassAlreadyExistsException($mockClassName); + $reflector = $this->reflectClass($mockClassName); + if (!$reflector->implementsInterface(MockObject::class)) { + throw new \PHPUnit\Framework\MockObject\Generator\ClassAlreadyExistsException($mockClassName); } } } @@ -54681,7 +58277,7 @@ final class Generator return (new ReflectionClass($className))->newInstanceArgs($arguments); // @codeCoverageIgnoreStart } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); + throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e); } // @codeCoverageIgnoreEnd } @@ -54689,9 +58285,9 @@ final class Generator return (new ReflectionClass($className))->newInstanceWithoutConstructor(); // @codeCoverageIgnoreStart } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); + throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e); + // @codeCoverageIgnoreEnd } - // @codeCoverageIgnoreEnd } /** * @psalm-param class-string $type @@ -54710,137 +58306,64 @@ final class Generator $proxyTarget = $class->newInstanceArgs($arguments); // @codeCoverageIgnoreStart } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); + throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e); } // @codeCoverageIgnoreEnd } } $object->__phpunit_setOriginalObject($proxyTarget); } -} - - @trigger_error({deprecation}, E_USER_DEPRECATED); -declare(strict_types=1); - -interface {intersection} extends {interfaces} -{ -} -declare(strict_types=1); - -{prologue}{class_declaration} -{ - use \PHPUnit\Framework\MockObject\Api;{method}{clone} -{mocked_methods}}{epilogue} - - {modifier} function {reference}{method_name}({arguments_decl}){return_declaration} - {{deprecation} - $__phpunit_arguments = [{arguments_call}]; - $__phpunit_count = func_num_args(); - - if ($__phpunit_count > {arguments_count}) { - $__phpunit_arguments_tmp = func_get_args(); - - for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) { - $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i]; - } - } - - $__phpunit_result = $this->__phpunit_getInvocationHandler()->invoke( - new \PHPUnit\Framework\MockObject\Invocation( - '{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments} - ) - ); - - return $__phpunit_result; - } - - {modifier} function {reference}{method_name}({arguments_decl}){return_declaration} - {{deprecation} - $__phpunit_arguments = [{arguments_call}]; - $__phpunit_count = func_num_args(); - - if ($__phpunit_count > {arguments_count}) { - $__phpunit_arguments_tmp = func_get_args(); - - for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) { - $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i]; - } - } - - $this->__phpunit_getInvocationHandler()->invoke( - new \PHPUnit\Framework\MockObject\Invocation( - '{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments} - ) - ); - } - - {modifier} function {reference}{method_name}({arguments_decl}){return_declaration} + /** + * @psalm-param class-string $className + * + * @throws ReflectionException + */ + private function reflectClass(string $className) : ReflectionClass { - throw new \PHPUnit\Framework\MockObject\BadMethodCallException('Static method "{method_name}" cannot be invoked on mock object'); + try { + $class = new ReflectionClass($className); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e); + } + // @codeCoverageIgnoreEnd + return $class; } - - {modifier} function {reference}{method_name}({arguments_decl}){return_declaration} + /** + * @psalm-param class-string $classOrInterfaceName + * + * @psalm-return list + * + * @throws ReflectionException + */ + private function namesOfMethodsIn(string $classOrInterfaceName) : array { - $__phpunit_arguments = [{arguments_call}]; - $__phpunit_count = func_num_args(); - - if ($__phpunit_count > {arguments_count}) { - $__phpunit_arguments_tmp = func_get_args(); - - for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) { - $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i]; + $class = $this->reflectClass($classOrInterfaceName); + $methods = []; + foreach ($class->getMethods() as $method) { + if ($method->isPublic() || $method->isAbstract()) { + $methods[] = $method->getName(); } } - - $this->__phpunit_getInvocationHandler()->invoke( - new \PHPUnit\Framework\MockObject\Invocation( - '{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments}, true - ) - ); - - return call_user_func_array(array($this->__phpunit_originalObject, "{method_name}"), $__phpunit_arguments); + return $methods; } - - {modifier} function {reference}{method_name}({arguments_decl}){return_declaration} + /** + * @psalm-param class-string $interfaceName + * + * @psalm-return list + * + * @throws ReflectionException + */ + private function interfaceMethods(string $interfaceName, bool $cloneArguments) : array { - $__phpunit_arguments = [{arguments_call}]; - $__phpunit_count = func_num_args(); - - if ($__phpunit_count > {arguments_count}) { - $__phpunit_arguments_tmp = func_get_args(); - - for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) { - $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i]; - } + $class = $this->reflectClass($interfaceName); + $methods = []; + foreach ($class->getMethods() as $method) { + $methods[] = \PHPUnit\Framework\MockObject\Generator\MockMethod::fromReflection($method, \false, $cloneArguments); } - - $this->__phpunit_getInvocationHandler()->invoke( - new \PHPUnit\Framework\MockObject\Invocation( - '{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments}, true - ) - ); - - call_user_func_array(array($this->__phpunit_originalObject, "{method_name}"), $__phpunit_arguments); + return $methods; } -declare(strict_types=1); - -{prologue}class {class_name} -{ - use {trait_name}; } -declare(strict_types=1); - -{namespace}class {class_name} extends \SoapClient -{ - public function __construct($wsdl, array $options) - { - parent::__construct('{wsdl}', $options); - } -{methods}} - - public function {method_name}({arguments}) - { - } className = $className; - $this->methodName = $methodName; - $this->parameters = $parameters; - $this->object = $object; - $this->proxiedCall = $proxiedCall; - if (strtolower($methodName) === '__tostring') { - $returnType = 'string'; - } - if (str_starts_with($returnType, '?')) { - $returnType = substr($returnType, 1); - $this->isReturnTypeNullable = \true; - } - $this->returnType = $returnType; - if (!$cloneObjects) { - return; - } - foreach ($this->parameters as $key => $value) { - if (is_object($value)) { - $this->parameters[$key] = Cloner::clone($value); - } - } - } - public function className() : string - { - return $this->className; - } - public function methodName() : string - { - return $this->methodName; - } - public function parameters() : array - { - return $this->parameters; - } + private readonly string $classCode; /** - * @throws Exception + * @psalm-var class-string */ - public function generateReturnValue() : mixed - { - if ($this->isReturnTypeNullable || $this->proxiedCall) { - return null; - } - $intersection = \false; - $union = \false; - $unionContainsIntersections = \false; - if (str_contains($this->returnType, '|')) { - $types = explode('|', $this->returnType); - $union = \true; - if (str_contains($this->returnType, '(')) { - $unionContainsIntersections = \true; - } - } elseif (str_contains($this->returnType, '&')) { - $types = explode('&', $this->returnType); - $intersection = \true; - } else { - $types = [$this->returnType]; - } - $types = array_map('strtolower', $types); - if (!$intersection && !$unionContainsIntersections) { - if (in_array('', $types, \true) || in_array('null', $types, \true) || in_array('mixed', $types, \true) || in_array('void', $types, \true)) { - return null; - } - if (in_array('true', $types, \true)) { - return \true; - } - if (in_array('false', $types, \true) || in_array('bool', $types, \true)) { - return \false; - } - if (in_array('float', $types, \true)) { - return 0.0; - } - if (in_array('int', $types, \true)) { - return 0; - } - if (in_array('string', $types, \true)) { - return ''; - } - if (in_array('array', $types, \true)) { - return []; - } - if (in_array('static', $types, \true)) { - try { - return (new ReflectionClass($this->object::class))->newInstanceWithoutConstructor(); - // @codeCoverageIgnoreStart - } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); - } - // @codeCoverageIgnoreEnd - } - if (in_array('object', $types, \true)) { - return new stdClass(); - } - if (in_array('callable', $types, \true) || in_array('closure', $types, \true)) { - return static function () : void { - }; - } - if (in_array('traversable', $types, \true) || in_array('generator', $types, \true) || in_array('iterable', $types, \true)) { - $generator = static function () : \Generator { - yield from []; - }; - return $generator(); - } - if (!$union) { - try { - return (new \PHPUnit\Framework\MockObject\Generator())->getMock($this->returnType, [], [], '', \false); - } catch (Throwable $t) { - if ($t instanceof \PHPUnit\Framework\MockObject\Exception) { - throw $t; - } - throw new \PHPUnit\Framework\MockObject\RuntimeException($t->getMessage(), (int) $t->getCode(), $t); - } - } - } - if ($intersection && $this->onlyInterfaces($types)) { - try { - return (new \PHPUnit\Framework\MockObject\Generator())->getMockForInterfaces($types); - } catch (Throwable $t) { - throw new \PHPUnit\Framework\MockObject\RuntimeException(sprintf('Return value for %s::%s() cannot be generated: %s', $this->className, $this->methodName, $t->getMessage()), (int) $t->getCode()); - } - } - $reason = ''; - if ($union) { - $reason = ' because the declared return type is a union'; - } elseif ($intersection) { - $reason = ' because the declared return type is an intersection'; - } - throw new \PHPUnit\Framework\MockObject\RuntimeException(sprintf('Return value for %s::%s() cannot be generated%s, please configure a return value for this method', $this->className, $this->methodName, $reason)); - } - public function toString() : string - { - $exporter = new Exporter(); - return sprintf('%s::%s(%s)%s', $this->className, $this->methodName, implode(', ', array_map([$exporter, 'shortenedExport'], $this->parameters)), $this->returnType ? sprintf(': %s', $this->returnType) : ''); - } - public function object() : object + private readonly string $mockName; + /** + * @psalm-var list + */ + private readonly array $configurableMethods; + /** + * @psalm-param class-string $mockName + * @psalm-param list $configurableMethods + */ + public function __construct(string $classCode, string $mockName, array $configurableMethods) { - return $this->object; + $this->classCode = $classCode; + $this->mockName = $mockName; + $this->configurableMethods = $configurableMethods; } /** - * @psalm-param non-empty-list $types + * @psalm-return class-string */ - private function onlyInterfaces(array $types) : bool + public function generate() : string { - foreach ($types as $type) { - if (!interface_exists($type)) { - return \false; - } + if (!class_exists($this->mockName, \false)) { + eval($this->classCode); + call_user_func([$this->mockName, '__phpunit_initConfigurableMethods'], ...$this->configurableMethods); } - return \true; + return $this->mockName; + } + public function classCode() : string + { + return $this->classCode; } } + * @psalm-var class-string */ - private array $matchers = []; + private readonly string $className; /** - * @psalm-var array + * @psalm-var non-empty-string */ - private array $matcherMap = []; + private readonly string $methodName; + private readonly bool $cloneArguments; + private readonly string $modifier; + private readonly string $argumentsForDeclaration; + private readonly string $argumentsForCall; + private readonly Type $returnType; + private readonly string $reference; + private readonly bool $callOriginalMethod; + private readonly bool $static; + private readonly ?string $deprecation; /** - * @psalm-var list + * @psalm-var array */ - private readonly array $configurableMethods; - private readonly bool $returnValueGeneration; - private ?\PHPUnit\Framework\MockObject\ReturnValueNotConfiguredException $deferredError = null; + private readonly array $defaultParameterValues; /** - * @psalm-param list $configurableMethods + * @psalm-var non-negative-int */ - public function __construct(array $configurableMethods, bool $returnValueGeneration) - { - $this->configurableMethods = $configurableMethods; - $this->returnValueGeneration = $returnValueGeneration; - } - public function hasMatchers() : bool + private readonly int $numberOfParameters; + /** + * @throws ReflectionException + * @throws RuntimeException + */ + public static function fromReflection(ReflectionMethod $method, bool $callOriginalMethod, bool $cloneArguments) : self { - foreach ($this->matchers as $matcher) { - if ($matcher->hasMatchers()) { - return \true; - } + if ($method->isPrivate()) { + $modifier = 'private'; + } elseif ($method->isProtected()) { + $modifier = 'protected'; + } else { + $modifier = 'public'; } - return \false; + if ($method->isStatic()) { + $modifier .= ' static'; + } + if ($method->returnsReference()) { + $reference = '&'; + } else { + $reference = ''; + } + $docComment = $method->getDocComment(); + if (is_string($docComment) && preg_match('#\\*[ \\t]*+@deprecated[ \\t]*+(.*?)\\r?+\\n[ \\t]*+\\*(?:[ \\t]*+@|/$)#s', $docComment, $deprecation)) { + $deprecation = trim(preg_replace('#[ \\t]*\\r?\\n[ \\t]*+\\*[ \\t]*+#', ' ', $deprecation[1])); + } else { + $deprecation = null; + } + return new self($method->getDeclaringClass()->getName(), $method->getName(), $cloneArguments, $modifier, self::methodParametersForDeclaration($method), self::methodParametersForCall($method), self::methodParametersDefaultValues($method), count($method->getParameters()), (new ReflectionMapper())->fromReturnType($method), $reference, $callOriginalMethod, $method->isStatic(), $deprecation); } /** - * Looks up the match builder with identification $id and returns it. + * @param class-string $className + * @param non-empty-string $methodName */ - public function lookupMatcher(string $id) : ?\PHPUnit\Framework\MockObject\Matcher + public static function fromName(string $className, string $methodName, bool $cloneArguments) : self { - return $this->matcherMap[$id] ?? null; + return new self($className, $methodName, $cloneArguments, 'public', '', '', [], 0, new UnknownType(), '', \false, \false, null); } /** - * Registers a matcher with the identification $id. The matcher can later be - * looked up using lookupMatcher() to figure out if it has been invoked. - * - * @throws MatcherAlreadyRegisteredException + * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName + * @psalm-param array $defaultParameterValues + * @psalm-param non-negative-int $numberOfParameters */ - public function registerMatcher(string $id, \PHPUnit\Framework\MockObject\Matcher $matcher) : void + private function __construct(string $className, string $methodName, bool $cloneArguments, string $modifier, string $argumentsForDeclaration, string $argumentsForCall, array $defaultParameterValues, int $numberOfParameters, Type $returnType, string $reference, bool $callOriginalMethod, bool $static, ?string $deprecation) { - if (isset($this->matcherMap[$id])) { - throw new \PHPUnit\Framework\MockObject\MatcherAlreadyRegisteredException($id); - } - $this->matcherMap[$id] = $matcher; + $this->className = $className; + $this->methodName = $methodName; + $this->cloneArguments = $cloneArguments; + $this->modifier = $modifier; + $this->argumentsForDeclaration = $argumentsForDeclaration; + $this->argumentsForCall = $argumentsForCall; + $this->defaultParameterValues = $defaultParameterValues; + $this->numberOfParameters = $numberOfParameters; + $this->returnType = $returnType; + $this->reference = $reference; + $this->callOriginalMethod = $callOriginalMethod; + $this->static = $static; + $this->deprecation = $deprecation; } - public function expects(InvocationOrder $rule) : InvocationMocker + /** + * @psalm-return non-empty-string + */ + public function methodName() : string { - $matcher = new \PHPUnit\Framework\MockObject\Matcher($rule); - $this->addMatcher($matcher); - return new InvocationMocker($this, $matcher, ...$this->configurableMethods); + return $this->methodName; } /** - * @throws \PHPUnit\Framework\MockObject\Exception - * @throws Exception + * @throws RuntimeException */ - public function invoke(\PHPUnit\Framework\MockObject\Invocation $invocation) : mixed + public function generateCode() : string { - $exception = null; - $hasReturnValue = \false; - $returnValue = null; - foreach ($this->matchers as $match) { - try { - if ($match->matches($invocation)) { - $value = $match->invoked($invocation); - if (!$hasReturnValue) { - $returnValue = $value; - $hasReturnValue = \true; - } - } - } catch (Exception $e) { - $exception = $e; - } + if ($this->static) { + $templateFile = 'doubled_static_method.tpl'; + } else { + $templateFile = sprintf('%s_method.tpl', $this->callOriginalMethod ? 'proxied' : 'doubled'); } - if ($exception !== null) { - throw $exception; + $deprecation = $this->deprecation; + $returnResult = ''; + if (!$this->returnType->isNever() && !$this->returnType->isVoid()) { + $returnResult = <<<'EOT' + + + return $__phpunit_result; +EOT; } - if ($hasReturnValue) { - return $returnValue; + if (null !== $this->deprecation) { + $deprecation = "The {$this->className}::{$this->methodName} method is deprecated ({$this->deprecation})."; + $deprecationTemplate = $this->loadTemplate('deprecation.tpl'); + $deprecationTemplate->setVar(['deprecation' => var_export($deprecation, \true)]); + $deprecation = $deprecationTemplate->render(); } - if (!$this->returnValueGeneration) { - $exception = new \PHPUnit\Framework\MockObject\ReturnValueNotConfiguredException($invocation); - if (strtolower($invocation->methodName()) === '__tostring') { - $this->deferredError = $exception; - return ''; + $template = $this->loadTemplate($templateFile); + $template->setVar(['arguments_decl' => $this->argumentsForDeclaration, 'arguments_call' => $this->argumentsForCall, 'return_declaration' => !empty($this->returnType->asString()) ? ': ' . $this->returnType->asString() : '', 'return_type' => $this->returnType->asString(), 'arguments_count' => !empty($this->argumentsForCall) ? substr_count($this->argumentsForCall, ',') + 1 : 0, 'class_name' => $this->className, 'method_name' => $this->methodName, 'modifier' => $this->modifier, 'reference' => $this->reference, 'clone_arguments' => $this->cloneArguments ? 'true' : 'false', 'deprecation' => $deprecation, 'return_result' => $returnResult]); + return $template->render(); + } + public function returnType() : Type + { + return $this->returnType; + } + /** + * @psalm-return array + */ + public function defaultParameterValues() : array + { + return $this->defaultParameterValues; + } + /** + * @psalm-return non-negative-int + */ + public function numberOfParameters() : int + { + return $this->numberOfParameters; + } + /** + * Returns the parameters of a function or method. + * + * @throws RuntimeException + */ + private static function methodParametersForDeclaration(ReflectionMethod $method) : string + { + $parameters = []; + $types = (new ReflectionMapper())->fromParameterTypes($method); + foreach ($method->getParameters() as $i => $parameter) { + $name = '$' . $parameter->getName(); + /* Note: PHP extensions may use empty names for reference arguments + * or "..." for methods taking a variable number of arguments. + */ + if ($name === '$' || $name === '$...') { + $name = '$arg' . $i; } - throw $exception; + $default = ''; + $reference = ''; + $typeDeclaration = ''; + if (!$types[$i]->type()->isUnknown()) { + $typeDeclaration = $types[$i]->type()->asString() . ' '; + } + if ($parameter->isPassedByReference()) { + $reference = '&'; + } + if ($parameter->isVariadic()) { + $name = '...' . $name; + } elseif ($parameter->isDefaultValueAvailable()) { + $default = ' = ' . self::exportDefaultValue($parameter); + } elseif ($parameter->isOptional()) { + $default = ' = null'; + } + $parameters[] = $typeDeclaration . $reference . $name . $default; } - return $invocation->generateReturnValue(); + return implode(', ', $parameters); } - public function matches(\PHPUnit\Framework\MockObject\Invocation $invocation) : bool + /** + * Returns the parameters of a function or method. + * + * @throws ReflectionException + */ + private static function methodParametersForCall(ReflectionMethod $method) : string { - foreach ($this->matchers as $matcher) { - if (!$matcher->matches($invocation)) { - return \false; + $parameters = []; + foreach ($method->getParameters() as $i => $parameter) { + $name = '$' . $parameter->getName(); + /* Note: PHP extensions may use empty names for reference arguments + * or "..." for methods taking a variable number of arguments. + */ + if ($name === '$' || $name === '$...') { + $name = '$arg' . $i; + } + if ($parameter->isVariadic()) { + continue; + } + if ($parameter->isPassedByReference()) { + $parameters[] = '&' . $name; + } else { + $parameters[] = $name; } } - return \true; + return implode(', ', $parameters); } /** - * @throws Throwable + * @throws ReflectionException */ - public function verify() : void + private static function exportDefaultValue(ReflectionParameter $parameter) : string { - foreach ($this->matchers as $matcher) { - $matcher->verify(); - } - if ($this->deferredError) { - throw $this->deferredError; + try { + $defaultValue = $parameter->getDefaultValue(); + if (!is_object($defaultValue)) { + return var_export($defaultValue, \true); + } + $parameterAsString = $parameter->__toString(); + return explode(' = ', substr(substr($parameterAsString, strpos($parameterAsString, ' ') + strlen(' ')), 0, -2))[1]; + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new \PHPUnit\Framework\MockObject\Generator\ReflectionException($e->getMessage(), $e->getCode(), $e); } + // @codeCoverageIgnoreEnd } - private function addMatcher(\PHPUnit\Framework\MockObject\Matcher $matcher) : void + /** + * @psalm-return array + */ + private static function methodParametersDefaultValues(ReflectionMethod $method) : array { - $this->matchers[] = $matcher; + $result = []; + foreach ($method->getParameters() as $i => $parameter) { + if (!$parameter->isDefaultValueAvailable()) { + continue; + } + $result[$i] = $parameter->getDefaultValue(); + } + return $result; } } invocationRule = $rule; - } - public function hasMatchers() : bool - { - return !$this->invocationRule instanceof AnyInvokedCount; - } - public function hasMethodNameRule() : bool - { - return $this->methodNameRule !== null; - } - public function methodNameRule() : MethodName - { - return $this->methodNameRule; - } - public function setMethodNameRule(MethodName $rule) : void - { - $this->methodNameRule = $rule; - } - public function hasParametersRule() : bool - { - return $this->parametersRule !== null; - } - public function setParametersRule(ParametersRule $rule) : void + /** + * @psalm-var array + */ + private array $methods = []; + public function addMethods(\PHPUnit\Framework\MockObject\Generator\MockMethod ...$methods) : void { - $this->parametersRule = $rule; + foreach ($methods as $method) { + $this->methods[strtolower($method->methodName())] = $method; + } } - public function setStub(Stub $stub) : void + /** + * @psalm-return list + */ + public function asArray() : array { - $this->stub = $stub; + return array_values($this->methods); } - public function setAfterMatchBuilderId(string $id) : void + public function hasMethod(string $methodName) : bool { - $this->afterMatchBuilderId = $id; + return array_key_exists(strtolower($methodName), $this->methods); } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Generator; + +use function class_exists; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5243 + */ +final class MockTrait implements \PHPUnit\Framework\MockObject\Generator\MockType +{ + private readonly string $classCode; /** - * @throws Exception - * @throws ExpectationFailedException - * @throws MatchBuilderNotFoundException - * @throws MethodNameNotConfiguredException - * @throws RuntimeException + * @psalm-var class-string */ - public function invoked(\PHPUnit\Framework\MockObject\Invocation $invocation) : mixed - { - if ($this->methodNameRule === null) { - throw new \PHPUnit\Framework\MockObject\MethodNameNotConfiguredException(); - } - if ($this->afterMatchBuilderId !== null) { - $matcher = $invocation->object()->__phpunit_getInvocationHandler()->lookupMatcher($this->afterMatchBuilderId); - if (!$matcher) { - throw new \PHPUnit\Framework\MockObject\MatchBuilderNotFoundException($this->afterMatchBuilderId); - } - } - $this->invocationRule->invoked($invocation); - try { - $this->parametersRule?->apply($invocation); - } catch (ExpectationFailedException $e) { - throw new ExpectationFailedException(sprintf("Expectation failed for %s when %s\n%s", $this->methodNameRule->toString(), $this->invocationRule->toString(), $e->getMessage()), $e->getComparisonFailure()); - } - if ($this->stub) { - return $this->stub->invoke($invocation); - } - return $invocation->generateReturnValue(); - } + private readonly string $mockName; /** - * @throws ExpectationFailedException - * @throws MatchBuilderNotFoundException - * @throws MethodNameNotConfiguredException - * @throws RuntimeException + * @psalm-param class-string $mockName */ - public function matches(\PHPUnit\Framework\MockObject\Invocation $invocation) : bool + public function __construct(string $classCode, string $mockName) { - if ($this->afterMatchBuilderId !== null) { - $matcher = $invocation->object()->__phpunit_getInvocationHandler()->lookupMatcher($this->afterMatchBuilderId); - if (!$matcher) { - throw new \PHPUnit\Framework\MockObject\MatchBuilderNotFoundException($this->afterMatchBuilderId); - } - assert($matcher instanceof self); - if (!$matcher->invocationRule->hasBeenInvoked()) { - return \false; - } - } - if ($this->methodNameRule === null) { - throw new \PHPUnit\Framework\MockObject\MethodNameNotConfiguredException(); - } - if (!$this->invocationRule->matches($invocation)) { - return \false; - } - try { - if (!$this->methodNameRule->matches($invocation)) { - return \false; - } - } catch (ExpectationFailedException $e) { - throw new ExpectationFailedException(sprintf("Expectation failed for %s when %s\n%s", $this->methodNameRule->toString(), $this->invocationRule->toString(), $e->getMessage()), $e->getComparisonFailure()); - } - return \true; + $this->classCode = $classCode; + $this->mockName = $mockName; } /** - * @throws ExpectationFailedException - * @throws MethodNameNotConfiguredException + * @psalm-return class-string */ - public function verify() : void - { - if ($this->methodNameRule === null) { - throw new \PHPUnit\Framework\MockObject\MethodNameNotConfiguredException(); - } - try { - $this->invocationRule->verify(); - if ($this->parametersRule === null) { - $this->parametersRule = new AnyParameters(); - } - $invocationIsAny = $this->invocationRule instanceof AnyInvokedCount; - $invocationIsNever = $this->invocationRule instanceof InvokedCount && $this->invocationRule->isNever(); - $invocationIsAtMost = $this->invocationRule instanceof InvokedAtMostCount; - if (!$invocationIsAny && !$invocationIsNever && !$invocationIsAtMost) { - $this->parametersRule->verify(); - } - } catch (ExpectationFailedException $e) { - throw new ExpectationFailedException(sprintf("Expectation failed for %s when %s.\n%s", $this->methodNameRule->toString(), $this->invocationRule->toString(), ThrowableToStringMapper::map($e))); - } - } - public function toString() : string + public function generate() : string { - $list = [$this->invocationRule->toString()]; - if ($this->methodNameRule !== null) { - $list[] = 'where ' . $this->methodNameRule->toString(); - } - if ($this->parametersRule !== null) { - $list[] = 'and ' . $this->parametersRule->toString(); - } - if ($this->afterMatchBuilderId !== null) { - $list[] = 'after ' . $this->afterMatchBuilderId; - } - if ($this->stub !== null) { - $list[] = 'will ' . $this->stub->toString(); + if (!class_exists($this->mockName, \false)) { + eval($this->classCode); } - return implode(' ', $list); + return $this->mockName; } } + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Generator; + +use PHPUnit\SebastianBergmann\Template\Template; +/** + * @internal This trait is not covered by the backward compatibility promise for PHPUnit + */ +trait TemplateLoader +{ + /** + * @psalm-var array + */ + private static array $templates = []; + /** + * @psalm-suppress MissingThrowsDocblock + */ + private function loadTemplate(string $template) : Template { - $this->methodName = $methodName; + $filename = __DIR__ . '/templates/' . $template; + if (!isset(self::$templates[$filename])) { + self::$templates[$filename] = new Template($filename); + } + return self::$templates[$filename]; } - public function toString() : string +} + + @trigger_error({deprecation}, E_USER_DEPRECATED); + + {modifier} function {reference}{method_name}({arguments_decl}){return_declaration} + {{deprecation} + $__phpunit_definedVariables = get_defined_vars(); + $__phpunit_namedVariadicParameters = []; + + foreach ($__phpunit_definedVariables as $__phpunit_definedVariableName => $__phpunit_definedVariableValue) { + if ((new ReflectionParameter([__CLASS__, __FUNCTION__], $__phpunit_definedVariableName))->isVariadic()) { + foreach ($__phpunit_definedVariableValue as $__phpunit_key => $__phpunit_namedValue) { + if (is_string($__phpunit_key)) { + $__phpunit_namedVariadicParameters[$__phpunit_key] = $__phpunit_namedValue; + } + } + } + } + + $__phpunit_arguments = [{arguments_call}]; + $__phpunit_count = func_num_args(); + + if ($__phpunit_count > {arguments_count}) { + $__phpunit_arguments_tmp = func_get_args(); + + for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) { + $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i]; + } + } + + $__phpunit_arguments = array_merge($__phpunit_arguments, $__phpunit_namedVariadicParameters); + + $__phpunit_result = $this->__phpunit_getInvocationHandler()->invoke( + new \PHPUnit\Framework\MockObject\Invocation( + '{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments} + ) + );{return_result} + } + + {modifier} function {reference}{method_name}({arguments_decl}){return_declaration} { - return sprintf('is "%s"', $this->methodName); + throw new \PHPUnit\Framework\MockObject\BadMethodCallException('Static method "{method_name}" cannot be invoked on mock object'); } - protected function matches(mixed $other) : bool +declare(strict_types=1); + +interface {intersection} extends {interfaces} +{ +} + + {modifier} function {reference}{method_name}({arguments_decl}){return_declaration} { - if (!is_string($other)) { - return \false; + $__phpunit_definedVariables = get_defined_vars(); + $__phpunit_namedVariadicParameters = []; + + foreach ($__phpunit_definedVariables as $__phpunit_definedVariableName => $__phpunit_definedVariableValue) { + if ((new ReflectionParameter([__CLASS__, __FUNCTION__], $__phpunit_definedVariableName))->isVariadic()) { + foreach ($__phpunit_definedVariableValue as $__phpunit_key => $__phpunit_namedValue) { + if (is_string($__phpunit_key)) { + $__phpunit_namedVariadicParameters[$__phpunit_key] = $__phpunit_namedValue; + } + } + } + } + + $__phpunit_arguments = [{arguments_call}]; + $__phpunit_count = func_num_args(); + + if ($__phpunit_count > {arguments_count}) { + $__phpunit_arguments_tmp = func_get_args(); + + for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) { + $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i]; + } } - return strtolower($this->methodName) === strtolower($other); + + $__phpunit_arguments = array_merge($__phpunit_arguments, $__phpunit_namedVariadicParameters); + + $this->__phpunit_getInvocationHandler()->invoke( + new \PHPUnit\Framework\MockObject\Invocation( + '{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments}, true + ) + ); + + $__phpunit_result = call_user_func_array([$this->__phpunit_originalObject, "{method_name}"], $__phpunit_arguments);{return_result} } +declare(strict_types=1); + +{prologue}{class_declaration} +{ +{use_statements}{mocked_methods}}{epilogue} +declare(strict_types=1); + +{prologue}class {class_name} +{ + use {trait_name}; } +declare(strict_types=1); + +{namespace}class {class_name} extends \SoapClient +{ + public function __construct($wsdl, array $options) + { + parent::__construct('{wsdl}', $options); + } +{methods}} + + public function {method_name}({arguments}) + { + } + */ + private array $methods = []; private bool $emptyMethodsArray = \false; - private string $mockClassName = ''; + /** + * @psalm-var ?class-string + */ + private ?string $mockClassName = null; private array $constructorArgs = []; private bool $originalConstructor = \true; private bool $originalClone = \true; @@ -55431,25 +59007,25 @@ final class MockBuilder private ?object $proxyTarget = null; private bool $allowMockingUnknownTypes = \true; private bool $returnValueGeneration = \true; - private readonly \PHPUnit\Framework\MockObject\Generator $generator; + private readonly Generator $generator; /** - * @psalm-param class-string $type + * @psalm-param class-string|trait-string $type */ public function __construct(TestCase $testCase, string $type) { $this->testCase = $testCase; $this->type = $type; - $this->generator = new \PHPUnit\Framework\MockObject\Generator(); + $this->generator = new Generator(); } /** * Creates a mock object using a fluent interface. * - * @throws \PHPUnit\Framework\InvalidArgumentException * @throws ClassAlreadyExistsException * @throws ClassIsEnumerationException * @throws ClassIsFinalException * @throws ClassIsReadonlyException * @throws DuplicateMethodException + * @throws InvalidArgumentException * @throws InvalidMethodNameException * @throws OriginalConstructorInvocationRequiredException * @throws ReflectionException @@ -55458,12 +59034,12 @@ final class MockBuilder * * @psalm-return MockObject&MockedType */ - public function getMock(bool $register = \true) : \PHPUnit\Framework\MockObject\MockObject + public function getMock() : \PHPUnit\Framework\MockObject\MockObject { - $object = $this->generator->getMock($this->type, !$this->emptyMethodsArray ? $this->methods : null, $this->constructorArgs, $this->mockClassName, $this->originalConstructor, $this->originalClone, $this->autoload, $this->cloneArguments, $this->callOriginalMethods, $this->proxyTarget, $this->allowMockingUnknownTypes, $this->returnValueGeneration); - if ($register) { - $this->testCase->registerMockObject($object); - } + $object = $this->generator->testDouble($this->type, \true, !$this->emptyMethodsArray ? $this->methods : null, $this->constructorArgs, $this->mockClassName ?? '', $this->originalConstructor, $this->originalClone, $this->autoload, $this->cloneArguments, $this->callOriginalMethods, $this->proxyTarget, $this->allowMockingUnknownTypes, $this->returnValueGeneration); + assert($object instanceof $this->type); + assert($object instanceof \PHPUnit\Framework\MockObject\MockObject); + $this->testCase->registerMockObject($object); return $object; } /** @@ -55474,10 +59050,13 @@ final class MockBuilder * @throws \PHPUnit\Framework\Exception * @throws ReflectionException * @throws RuntimeException + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5305 */ public function getMockForAbstractClass() : \PHPUnit\Framework\MockObject\MockObject { - $object = $this->generator->getMockForAbstractClass($this->type, $this->constructorArgs, $this->mockClassName, $this->originalConstructor, $this->originalClone, $this->autoload, $this->methods, $this->cloneArguments); + $object = $this->generator->mockObjectForAbstractClass($this->type, $this->constructorArgs, $this->mockClassName ?? '', $this->originalConstructor, $this->originalClone, $this->autoload, $this->methods, $this->cloneArguments); + assert($object instanceof \PHPUnit\Framework\MockObject\MockObject); $this->testCase->registerMockObject($object); return $object; } @@ -55489,17 +59068,21 @@ final class MockBuilder * @throws \PHPUnit\Framework\Exception * @throws ReflectionException * @throws RuntimeException + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5306 */ public function getMockForTrait() : \PHPUnit\Framework\MockObject\MockObject { - $object = $this->generator->getMockForTrait($this->type, $this->constructorArgs, $this->mockClassName, $this->originalConstructor, $this->originalClone, $this->autoload, $this->methods, $this->cloneArguments); + assert(trait_exists($this->type)); + $object = $this->generator->mockObjectForTrait($this->type, $this->constructorArgs, $this->mockClassName ?? '', $this->originalConstructor, $this->originalClone, $this->autoload, $this->methods, $this->cloneArguments); + assert($object instanceof \PHPUnit\Framework\MockObject\MockObject); $this->testCase->registerMockObject($object); return $object; } /** * Specifies the subset of methods to mock, requiring each to exist in the class. * - * @psalm-param list $methods + * @psalm-param list $methods * * @throws CannotUseOnlyMethodsException * @throws ReflectionException @@ -55516,27 +59099,29 @@ final class MockBuilder $reflector = new ReflectionClass($this->type); // @codeCoverageIgnoreStart } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); + throw new ReflectionException($e->getMessage(), $e->getCode(), $e); + // @codeCoverageIgnoreEnd } - // @codeCoverageIgnoreEnd foreach ($methods as $method) { if (!$reflector->hasMethod($method)) { throw new \PHPUnit\Framework\MockObject\CannotUseOnlyMethodsException($this->type, $method); } } - $this->methods = array_merge($this->methods ?? [], $methods); + $this->methods = array_merge($this->methods, $methods); return $this; } /** * Specifies methods that don't exist in the class which you want to mock. * - * @psalm-param list $methods + * @psalm-param list $methods * * @throws CannotUseAddMethodsException * @throws ReflectionException * @throws RuntimeException * * @return $this + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5320 */ public function addMethods(array $methods) : self { @@ -55548,15 +59133,15 @@ final class MockBuilder $reflector = new ReflectionClass($this->type); // @codeCoverageIgnoreStart } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); + throw new ReflectionException($e->getMessage(), $e->getCode(), $e); + // @codeCoverageIgnoreEnd } - // @codeCoverageIgnoreEnd foreach ($methods as $method) { if ($reflector->hasMethod($method)) { throw new \PHPUnit\Framework\MockObject\CannotUseAddMethodsException($this->type, $method); } } - $this->methods = array_merge($this->methods ?? [], $methods); + $this->methods = array_merge($this->methods, $methods); return $this; } /** @@ -55572,6 +59157,8 @@ final class MockBuilder /** * Specifies the name for the mock class. * + * @psalm-param class-string $name + * * @return $this */ public function setMockClassName(string $name) : self @@ -55623,6 +59210,8 @@ final class MockBuilder * Disables the use of class autoloading while creating the mock object. * * @return $this + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5309 */ public function disableAutoload() : self { @@ -55633,6 +59222,8 @@ final class MockBuilder * Enables the use of class autoloading while creating the mock object. * * @return $this + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5309 */ public function enableAutoload() : self { @@ -55643,6 +59234,8 @@ final class MockBuilder * Disables the cloning of arguments passed to mocked methods. * * @return $this + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5315 */ public function disableArgumentCloning() : self { @@ -55653,6 +59246,8 @@ final class MockBuilder * Enables the cloning of arguments passed to mocked methods. * * @return $this + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5315 */ public function enableArgumentCloning() : self { @@ -55663,6 +59258,8 @@ final class MockBuilder * Enables the invocation of the original methods. * * @return $this + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5307 */ public function enableProxyingToOriginalMethods() : self { @@ -55673,6 +59270,8 @@ final class MockBuilder * Disables the invocation of the original methods. * * @return $this + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5307 */ public function disableProxyingToOriginalMethods() : self { @@ -55684,6 +59283,8 @@ final class MockBuilder * Sets the proxy target. * * @return $this + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5307 */ public function setProxyTarget(object $object) : self { @@ -55692,6 +59293,8 @@ final class MockBuilder } /** * @return $this + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5308 */ public function allowMockingUnknownTypes() : self { @@ -55700,6 +59303,8 @@ final class MockBuilder } /** * @return $this + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5308 */ public function disallowMockingUnknownTypes() : self { @@ -55736,46 +59341,14 @@ declare (strict_types=1); */ namespace PHPUnit\Framework\MockObject; -use function call_user_func; -use function class_exists; /** - * @internal This class is not covered by the backward compatibility promise for PHPUnit + * @internal This trait is not covered by the backward compatibility promise for PHPUnit */ -final class MockClass implements \PHPUnit\Framework\MockObject\MockType +trait DoubledCloneMethod { - private readonly string $classCode; - /** - * @psalm-var class-string - */ - private readonly string $mockName; - /** - * @psalm-var list - */ - private readonly array $configurableMethods; - /** - * @psalm-param class-string $mockName - * @psalm-param list $configurableMethods - */ - public function __construct(string $classCode, string $mockName, array $configurableMethods) + public function __clone() : void { - $this->classCode = $classCode; - $this->mockName = $mockName; - $this->configurableMethods = $configurableMethods; - } - /** - * @psalm-return class-string - */ - public function generate() : string - { - if (!class_exists($this->mockName, \false)) { - eval($this->classCode); - call_user_func([$this->mockName, '__phpunit_initConfigurableMethods'], ...$this->configurableMethods); - } - return $this->mockName; - } - public function classCode() : string - { - return $this->classCode; + $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationHandler(); } } isPrivate()) { - $modifier = 'private'; - } elseif ($method->isProtected()) { - $modifier = 'protected'; - } else { - $modifier = 'public'; - } - if ($method->isStatic()) { - $modifier .= ' static'; - } - if ($method->returnsReference()) { - $reference = '&'; - } else { - $reference = ''; - } - $docComment = $method->getDocComment(); - if (is_string($docComment) && preg_match('#\\*[ \\t]*+@deprecated[ \\t]*+(.*?)\\r?+\\n[ \\t]*+\\*(?:[ \\t]*+@|/$)#s', $docComment, $deprecation)) { - $deprecation = trim(preg_replace('#[ \\t]*\\r?\\n[ \\t]*+\\*[ \\t]*+#', ' ', $deprecation[1])); - } else { - $deprecation = null; - } - return new self($method->getDeclaringClass()->getName(), $method->getName(), $cloneArguments, $modifier, self::methodParametersForDeclaration($method), self::methodParametersForCall($method), (new ReflectionMapper())->fromReturnType($method), $reference, $callOriginalMethod, $method->isStatic(), $deprecation); - } - public static function fromName(string $fullClassName, string $methodName, bool $cloneArguments) : self - { - return new self($fullClassName, $methodName, $cloneArguments, 'public', '', '', new UnknownType(), '', \false, \false, null); - } - public function __construct(string $className, string $methodName, bool $cloneArguments, string $modifier, string $argumentsForDeclaration, string $argumentsForCall, Type $returnType, string $reference, bool $callOriginalMethod, bool $static, ?string $deprecation) - { - $this->className = $className; - $this->methodName = $methodName; - $this->cloneArguments = $cloneArguments; - $this->modifier = $modifier; - $this->argumentsForDeclaration = $argumentsForDeclaration; - $this->argumentsForCall = $argumentsForCall; - $this->returnType = $returnType; - $this->reference = $reference; - $this->callOriginalMethod = $callOriginalMethod; - $this->static = $static; - $this->deprecation = $deprecation; - } - public function methodName() : string - { - return $this->methodName; - } - /** - * @throws RuntimeException - */ - public function generateCode() : string - { - if ($this->static) { - $templateFile = 'mocked_static_method.tpl'; - } elseif ($this->returnType->isNever() || $this->returnType->isVoid()) { - $templateFile = sprintf('%s_method_never_or_void.tpl', $this->callOriginalMethod ? 'proxied' : 'mocked'); - } else { - $templateFile = sprintf('%s_method.tpl', $this->callOriginalMethod ? 'proxied' : 'mocked'); - } - $deprecation = $this->deprecation; - if (null !== $this->deprecation) { - $deprecation = "The {$this->className}::{$this->methodName} method is deprecated ({$this->deprecation})."; - $deprecationTemplate = $this->loadTemplate('deprecation.tpl'); - $deprecationTemplate->setVar(['deprecation' => var_export($deprecation, \true)]); - $deprecation = $deprecationTemplate->render(); - } - $template = $this->loadTemplate($templateFile); - $template->setVar(['arguments_decl' => $this->argumentsForDeclaration, 'arguments_call' => $this->argumentsForCall, 'return_declaration' => !empty($this->returnType->asString()) ? ': ' . $this->returnType->asString() : '', 'return_type' => $this->returnType->asString(), 'arguments_count' => !empty($this->argumentsForCall) ? substr_count($this->argumentsForCall, ',') + 1 : 0, 'class_name' => $this->className, 'method_name' => $this->methodName, 'modifier' => $this->modifier, 'reference' => $this->reference, 'clone_arguments' => $this->cloneArguments ? 'true' : 'false', 'deprecation' => $deprecation]); - return $template->render(); - } - public function returnType() : Type - { - return $this->returnType; - } - /** - * Returns the parameters of a function or method. - * - * @throws RuntimeException - */ - private static function methodParametersForDeclaration(ReflectionMethod $method) : string - { - $parameters = []; - $types = (new ReflectionMapper())->fromParameterTypes($method); - foreach ($method->getParameters() as $i => $parameter) { - $name = '$' . $parameter->getName(); - /* Note: PHP extensions may use empty names for reference arguments - * or "..." for methods taking a variable number of arguments. - */ - if ($name === '$' || $name === '$...') { - $name = '$arg' . $i; - } - $default = ''; - $reference = ''; - $typeDeclaration = ''; - if (!$types[$i]->type()->isUnknown()) { - $typeDeclaration = $types[$i]->type()->asString() . ' '; - } - if ($parameter->isPassedByReference()) { - $reference = '&'; - } - if ($parameter->isVariadic()) { - $name = '...' . $name; - } elseif ($parameter->isDefaultValueAvailable()) { - $default = ' = ' . self::exportDefaultValue($parameter); - } elseif ($parameter->isOptional()) { - $default = ' = null'; - } - $parameters[] = $typeDeclaration . $reference . $name . $default; - } - return implode(', ', $parameters); - } - /** - * Returns the parameters of a function or method. - * - * @throws ReflectionException - */ - private static function methodParametersForCall(ReflectionMethod $method) : string - { - $parameters = []; - foreach ($method->getParameters() as $i => $parameter) { - $name = '$' . $parameter->getName(); - /* Note: PHP extensions may use empty names for reference arguments - * or "..." for methods taking a variable number of arguments. - */ - if ($name === '$' || $name === '$...') { - $name = '$arg' . $i; - } - if ($parameter->isVariadic()) { - continue; - } - if ($parameter->isPassedByReference()) { - $parameters[] = '&' . $name; - } else { - $parameters[] = $name; - } - } - return implode(', ', $parameters); - } - /** - * @throws ReflectionException - */ - private static function exportDefaultValue(ReflectionParameter $parameter) : string + public function method() : InvocationMocker { - try { - $defaultValue = $parameter->getDefaultValue(); - if (!is_object($defaultValue)) { - return var_export($defaultValue, \true); - } - $parameterAsString = $parameter->__toString(); - return explode(' = ', substr(substr($parameterAsString, strpos($parameterAsString, ' ') + strlen(' ')), 0, -2))[1]; - // @codeCoverageIgnoreStart - } catch (\ReflectionException $e) { - throw new \PHPUnit\Framework\MockObject\ReflectionException($e->getMessage(), $e->getCode(), $e); - } - // @codeCoverageIgnoreEnd + $expects = $this->expects(new AnyInvokedCount()); + return call_user_func_array([$expects, 'method'], func_get_args()); } } - */ - private array $methods = []; - public function addMethods(\PHPUnit\Framework\MockObject\MockMethod ...$methods) : void + private object $__phpunit_originalObject; + /** @noinspection MagicMethodsValidityInspection */ + public function __phpunit_hasMatchers() : bool { - foreach ($methods as $method) { - $this->methods[strtolower($method->methodName())] = $method; - } + return $this->__phpunit_getInvocationHandler()->hasMatchers(); } - /** - * @psalm-return list - */ - public function asArray() : array + /** @noinspection MagicMethodsValidityInspection */ + public function __phpunit_setOriginalObject(object $originalObject) : void { - return array_values($this->methods); + $this->__phpunit_originalObject = $originalObject; } - public function hasMethod(string $methodName) : bool + /** @noinspection MagicMethodsValidityInspection */ + public function __phpunit_verify(bool $unsetInvocationMocker = \true) : void { - return array_key_exists(strtolower($methodName), $this->methods); + $this->__phpunit_getInvocationHandler()->verify(); + if ($unsetInvocationMocker) { + $this->__phpunit_unsetInvocationMocker(); + } + } + public abstract function __phpunit_getInvocationHandler() : \PHPUnit\Framework\MockObject\InvocationHandler; + public abstract function __phpunit_unsetInvocationMocker() : void; + public function expects(InvocationOrder $matcher) : InvocationMockerBuilder + { + return $this->__phpunit_getInvocationHandler()->expects($matcher); } } __phpunit_invocationMocker = clone $this->__phpunit_getInvocationHandler(); + parent::__clone(); + } } */ - public function __construct(string $classCode, string $mockName) + private static array $__phpunit_configurableMethods; + private bool $__phpunit_returnValueGeneration = \true; + private ?\PHPUnit\Framework\MockObject\InvocationHandler $__phpunit_invocationMocker = null; + /** @noinspection MagicMethodsValidityInspection */ + public static function __phpunit_initConfigurableMethods(\PHPUnit\Framework\MockObject\ConfigurableMethod ...$configurableMethods) : void { - $this->classCode = $classCode; - $this->mockName = $mockName; + static::$__phpunit_configurableMethods = $configurableMethods; } - /** - * @psalm-return class-string - */ - public function generate() : string + /** @noinspection MagicMethodsValidityInspection */ + public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration) : void { - if (!class_exists($this->mockName, \false)) { - eval($this->classCode); + $this->__phpunit_returnValueGeneration = $returnValueGeneration; + } + /** @noinspection MagicMethodsValidityInspection */ + public function __phpunit_getInvocationHandler() : \PHPUnit\Framework\MockObject\InvocationHandler + { + if ($this->__phpunit_invocationMocker === null) { + $this->__phpunit_invocationMocker = new \PHPUnit\Framework\MockObject\InvocationHandler(static::$__phpunit_configurableMethods, $this->__phpunit_returnValueGeneration); } - return $this->mockName; + return $this->__phpunit_invocationMocker; } - public function classCode() : string + /** @noinspection MagicMethodsValidityInspection */ + public function __phpunit_unsetInvocationMocker() : void { - return $this->classCode; + $this->__phpunit_invocationMocker = null; } } + */ + private readonly array $configurableMethods; + /** + * @psalm-var ?array + */ + private ?array $configurableMethodNames = null; + public function __construct(InvocationHandler $handler, Matcher $matcher, ConfigurableMethod ...$configurableMethods) { - return 'invoked zero or more times'; + $this->invocationHandler = $handler; + $this->matcher = $matcher; + $this->configurableMethods = $configurableMethods; } - public function verify() : void + /** + * @throws MatcherAlreadyRegisteredException + * + * @return $this + */ + public function id(string $id) : self { + $this->invocationHandler->registerMatcher($id, $this->matcher); + return $this; } - public function matches(BaseInvocation $invocation) : bool + /** + * @return $this + */ + public function will(Stub $stub) : \PHPUnit\Framework\MockObject\Builder\Identity { - return \true; + $this->matcher->setStub($stub); + return $this; } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework\MockObject\Rule; - -use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class AnyParameters implements \PHPUnit\Framework\MockObject\Rule\ParametersRule -{ - public function toString() : string + /** + * @throws IncompatibleReturnValueException + */ + public function willReturn(mixed $value, mixed ...$nextValues) : self { - return 'with any parameters'; + if (count($nextValues) === 0) { + $this->ensureTypeOfReturnValues([$value]); + $stub = $value instanceof Stub ? $value : new ReturnStub($value); + return $this->will($stub); + } + $values = array_merge([$value], $nextValues); + $this->ensureTypeOfReturnValues($values); + $stub = new ConsecutiveCalls($values); + return $this->will($stub); } - public function apply(BaseInvocation $invocation) : void + public function willReturnReference(mixed &$reference) : self { + $stub = new ReturnReference($reference); + return $this->will($stub); } - public function verify() : void + public function willReturnMap(array $valueMap) : self { + $method = $this->configuredMethod(); + assert($method instanceof ConfigurableMethod); + $numberOfParameters = $method->numberOfParameters(); + $defaultValues = $method->defaultParameterValues(); + $hasDefaultValues = !empty($defaultValues); + $_valueMap = []; + foreach ($valueMap as $mapping) { + $numberOfConfiguredParameters = count($mapping) - 1; + if ($numberOfConfiguredParameters === $numberOfParameters || !$hasDefaultValues) { + $_valueMap[] = $mapping; + continue; + } + $_mapping = []; + $returnValue = array_pop($mapping); + foreach (range(0, $numberOfParameters - 1) as $i) { + if (isset($mapping[$i])) { + $_mapping[] = $mapping[$i]; + continue; + } + if (isset($defaultValues[$i])) { + $_mapping[] = $defaultValues[$i]; + } + } + $_mapping[] = $returnValue; + $_valueMap[] = $_mapping; + } + $stub = new ReturnValueMap($_valueMap); + return $this->will($stub); } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework\MockObject\Rule; - -use function count; -use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; -use PHPUnit\Framework\MockObject\Verifiable; -use PHPUnit\Framework\SelfDescribing; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -abstract class InvocationOrder implements SelfDescribing, Verifiable -{ - /** - * @psalm-var list - */ - private array $invocations = []; - public function numberOfInvocations() : int + public function willReturnArgument(int $argumentIndex) : self { - return count($this->invocations); + $stub = new ReturnArgument($argumentIndex); + return $this->will($stub); } - public function hasBeenInvoked() : bool + public function willReturnCallback(callable $callback) : self { - return count($this->invocations) > 0; + $stub = new ReturnCallback($callback); + return $this->will($stub); } - public final function invoked(BaseInvocation $invocation) : void + public function willReturnSelf() : self { - $this->invocations[] = $invocation; - $this->invokedDo($invocation); + $stub = new ReturnSelf(); + return $this->will($stub); } - public abstract function matches(BaseInvocation $invocation) : bool; - protected function invokedDo(BaseInvocation $invocation) : void + public function willReturnOnConsecutiveCalls(mixed ...$values) : self { + $stub = new ConsecutiveCalls($values); + return $this->will($stub); } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework\MockObject\Rule; - -use PHPUnit\Framework\ExpectationFailedException; -use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class InvokedAtLeastCount extends \PHPUnit\Framework\MockObject\Rule\InvocationOrder -{ - private readonly int $requiredInvocations; - public function __construct(int $requiredInvocations) + public function willThrowException(Throwable $exception) : self { - $this->requiredInvocations = $requiredInvocations; + $stub = new Exception($exception); + return $this->will($stub); } - public function toString() : string + /** + * @return $this + */ + public function after(string $id) : self { - return 'invoked at least ' . $this->requiredInvocations . ' times'; + $this->matcher->setAfterMatchBuilderId($id); + return $this; } /** - * Verifies that the current expectation is valid. If everything is OK the - * code should just return, if not it must throw an exception. + * @throws \PHPUnit\Framework\Exception + * @throws MethodNameNotConfiguredException + * @throws MethodParametersAlreadyConfiguredException * - * @throws ExpectationFailedException + * @return $this */ - public function verify() : void + public function with(mixed ...$arguments) : self { - $count = $this->numberOfInvocations(); - if ($count < $this->requiredInvocations) { - throw new ExpectationFailedException('Expected invocation at least ' . $this->requiredInvocations . ' times but it occurred ' . $count . ' time(s).'); + $this->ensureParametersCanBeConfigured(); + $this->matcher->setParametersRule(new Rule\Parameters($arguments)); + return $this; + } + /** + * @throws MethodNameNotConfiguredException + * @throws MethodParametersAlreadyConfiguredException + * + * @return $this + */ + public function withAnyParameters() : self + { + $this->ensureParametersCanBeConfigured(); + $this->matcher->setParametersRule(new Rule\AnyParameters()); + return $this; + } + /** + * @throws InvalidArgumentException + * @throws MethodCannotBeConfiguredException + * @throws MethodNameAlreadyConfiguredException + * + * @return $this + */ + public function method(Constraint|string $constraint) : self + { + if ($this->matcher->hasMethodNameRule()) { + throw new MethodNameAlreadyConfiguredException(); + } + if (is_string($constraint)) { + $this->configurableMethodNames ??= array_flip(array_map(static fn(ConfigurableMethod $configurable) => strtolower($configurable->name()), $this->configurableMethods)); + if (!array_key_exists(strtolower($constraint), $this->configurableMethodNames)) { + throw new MethodCannotBeConfiguredException($constraint); + } } + $this->matcher->setMethodNameRule(new Rule\MethodName($constraint)); + return $this; } - public function matches(BaseInvocation $invocation) : bool + /** + * @throws MethodNameNotConfiguredException + * @throws MethodParametersAlreadyConfiguredException + */ + private function ensureParametersCanBeConfigured() : void { - return \true; + if (!$this->matcher->hasMethodNameRule()) { + throw new MethodNameNotConfiguredException(); + } + if ($this->matcher->hasParametersRule()) { + throw new MethodParametersAlreadyConfiguredException(); + } + } + private function configuredMethod() : ?ConfigurableMethod + { + $configuredMethod = null; + foreach ($this->configurableMethods as $configurableMethod) { + if ($this->matcher->methodNameRule()->matchesName($configurableMethod->name())) { + if ($configuredMethod !== null) { + return null; + } + $configuredMethod = $configurableMethod; + } + } + return $configuredMethod; + } + /** + * @throws IncompatibleReturnValueException + */ + private function ensureTypeOfReturnValues(array $values) : void + { + $configuredMethod = $this->configuredMethod(); + if ($configuredMethod === null) { + return; + } + foreach ($values as $value) { + if (!$configuredMethod->mayReturn($value)) { + throw new IncompatibleReturnValueException($configuredMethod, $value); + } + } } } > $valueMap */ - public function verify() : void - { - $count = $this->numberOfInvocations(); - if ($count < 1) { - throw new ExpectationFailedException('Expected invocation at least once but it never occurred.'); - } - } - public function matches(BaseInvocation $invocation) : bool - { - return \true; - } + public function willReturnMap(array $valueMap) : self; + public function willReturnArgument(int $argumentIndex) : self; + public function willReturnCallback(callable $callback) : self; + public function willReturnSelf() : self; + public function willReturnOnConsecutiveCalls(mixed ...$values) : self; + public function willThrowException(Throwable $exception) : self; } allowedInvocations = $allowedInvocations; - } - public function toString() : string - { - return 'invoked at most ' . $this->allowedInvocations . ' times'; - } /** - * Verifies that the current expectation is valid. If everything is OK the - * code should just return, if not it must throw an exception. - * - * @throws ExpectationFailedException + * Adds a new method name match and returns the parameter match object for + * further matching possibilities. */ - public function verify() : void - { - $count = $this->numberOfInvocations(); - if ($count > $this->allowedInvocations) { - throw new ExpectationFailedException('Expected invocation at most ' . $this->allowedInvocations . ' times but it occurred ' . $count . ' time(s).'); - } - } - public function matches(BaseInvocation $invocation) : bool - { - return \true; - } + public function method(Constraint|string $constraint) : self; } expectedCount = $expectedCount; - } - public function isNever() : bool - { - return $this->expectedCount === 0; - } - public function toString() : string - { - return 'invoked ' . $this->expectedCount . ' time(s)'; - } - public function matches(BaseInvocation $invocation) : bool - { - return \true; - } /** - * Verifies that the current expectation is valid. If everything is OK the - * code should just return, if not it must throw an exception. + * Defines the expectation which must occur before the current is valid. + */ + public function after(string $id) : \PHPUnit\Framework\MockObject\Builder\Stub; + /** + * Sets the parameters to match for, each parameter to this function will + * be part of match. To perform specific matches or constraints create a + * new PHPUnit\Framework\Constraint\Constraint and use it for the parameter. + * If the parameter value is not a constraint it will use the + * PHPUnit\Framework\Constraint\IsEqual for the value. * - * @throws ExpectationFailedException + * Some examples: + * + * // match first parameter with value 2 + * $b->with(2); + * // match first parameter with value 'smock' and second identical to 42 + * $b->with('smock', new PHPUnit\Framework\Constraint\IsEqual(42)); + * */ - public function verify() : void - { - $count = $this->numberOfInvocations(); - if ($count !== $this->expectedCount) { - throw new ExpectationFailedException(sprintf('Method was expected to be called %d times, ' . 'actually called %d times.', $this->expectedCount, $count)); - } - } + public function with(mixed ...$arguments) : self; /** - * @throws ExpectationFailedException + * Sets a rule which allows any kind of parameters. + * + * Some examples: + * + * // match any number of parameters + * $b->withAnyParameters(); + * */ - protected function invokedDo(BaseInvocation $invocation) : void - { - $count = $this->numberOfInvocations(); - if ($count > $this->expectedCount) { - $message = $invocation->toString() . ' '; - $message .= match ($this->expectedCount) { - 0 => 'was not expected to be called.', - 1 => 'was not expected to be called more than once.', - default => sprintf('was not expected to be called more than %d times.', $this->expectedCount), - }; - throw new ExpectationFailedException($message); - } - } + public function withAnyParameters() : self; } constraint = $constraint; - } - public function toString() : string - { - return 'method name ' . $this->constraint->toString(); - } - /** - * @throws \PHPUnit\Framework\ExpectationFailedException - */ - public function matches(BaseInvocation $invocation) : bool - { - return $this->matchesName($invocation->methodName()); - } /** - * @throws \PHPUnit\Framework\ExpectationFailedException + * Stubs the matching method with the stub object $stub. Any invocations of + * the matched method will now be handled by the stub instead. */ - public function matchesName(string $methodName) : bool - { - return (bool) $this->constraint->evaluate($methodName, '', \true); - } + public function will(BaseStub $stub) : \PHPUnit\Framework\MockObject\Builder\Identity; } - */ - private array $parameters = []; - private ?BaseInvocation $invocation = null; - private null|bool|ExpectationFailedException $parameterVerificationResult; - /** - * @throws \PHPUnit\Framework\Exception - */ - public function __construct(array $parameters) - { - foreach ($parameters as $parameter) { - if (!$parameter instanceof Constraint) { - $parameter = new IsEqual($parameter); - } - $this->parameters[] = $parameter; - } - } - public function toString() : string - { - $text = 'with parameter'; - foreach ($this->parameters as $index => $parameter) { - if ($index > 0) { - $text .= ' and'; - } - $text .= ' ' . $index . ' ' . $parameter->toString(); - } - return $text; - } - /** - * @throws Exception - */ - public function apply(BaseInvocation $invocation) : void - { - $this->invocation = $invocation; - $this->parameterVerificationResult = null; - try { - $this->parameterVerificationResult = $this->doVerify(); - } catch (ExpectationFailedException $e) { - $this->parameterVerificationResult = $e; - throw $this->parameterVerificationResult; - } - } - /** - * Checks if the invocation $invocation matches the current rules. If it - * does the rule will get the invoked() method called which should check - * if an expectation is met. - * - * @throws ExpectationFailedException - */ - public function verify() : void - { - $this->doVerify(); - } - /** - * @throws ExpectationFailedException - */ - private function doVerify() : bool - { - if (isset($this->parameterVerificationResult)) { - return $this->guardAgainstDuplicateEvaluationOfParameterConstraints(); - } - if ($this->invocation === null) { - throw new ExpectationFailedException('Mocked method does not exist.'); - } - if (count($this->invocation->parameters()) < count($this->parameters)) { - $message = 'Parameter count for invocation %s is too low.'; - // The user called `->with($this->anything())`, but may have meant - // `->withAnyParameters()`. - // - // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/199 - if (count($this->parameters) === 1 && $this->parameters[0]::class === IsAnything::class) { - $message .= "\nTo allow 0 or more parameters with any value, omit ->with() or use ->withAnyParameters() instead."; - } - throw new ExpectationFailedException(sprintf($message, $this->invocation->toString())); - } - foreach ($this->parameters as $i => $parameter) { - $parameter->evaluate($this->invocation->parameters()[$i], sprintf('Parameter %s for invocation %s does not match expected ' . 'value.', $i, $this->invocation->toString())); - } - return \true; - } - /** - * @throws ExpectationFailedException - */ - private function guardAgainstDuplicateEvaluationOfParameterConstraints() : bool - { - if ($this->parameterVerificationResult instanceof ExpectationFailedException) { - throw $this->parameterVerificationResult; - } - return (bool) $this->parameterVerificationResult; - } + public function expects(InvocationOrder $invocationRule) : InvocationMocker; } stack = $stack; - } - public function invoke(Invocation $invocation) : mixed - { - $this->value = array_shift($this->stack); - if ($this->value instanceof \PHPUnit\Framework\MockObject\Stub\Stub) { - $this->value = $this->value->invoke($invocation); - } - return $this->value; - } - public function toString() : string - { - $exporter = new Exporter(); - return sprintf('return user-specified value %s', $exporter->export($this->value)); - } + public static function __phpunit_initConfigurableMethods(\PHPUnit\Framework\MockObject\ConfigurableMethod ...$configurableMethods) : void; + public function __phpunit_getInvocationHandler() : \PHPUnit\Framework\MockObject\InvocationHandler; + public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration) : void; + public function __phpunit_unsetInvocationMocker() : void; } exception = $exception; + $this->className = $className; + $this->methodName = $methodName; + $this->object = $object; + $this->proxiedCall = $proxiedCall; + if (strtolower($methodName) === '__tostring') { + $returnType = 'string'; + } + if (str_starts_with($returnType, '?')) { + $returnType = substr($returnType, 1); + $this->isReturnTypeNullable = \true; + } else { + $this->isReturnTypeNullable = \false; + } + $this->returnType = $returnType; + if (!$cloneObjects) { + $this->parameters = $parameters; + return; + } + foreach ($parameters as $key => $value) { + if (is_object($value)) { + $parameters[$key] = Cloner::clone($value); + } + } + $this->parameters = $parameters; } /** - * @throws Throwable + * @psalm-return class-string */ - public function invoke(Invocation $invocation) : never + public function className() : string { - throw $this->exception; + return $this->className; } - public function toString() : string + /** + * @psalm-return non-empty-string + */ + public function methodName() : string { - $exporter = new Exporter(); - return sprintf('raise user-specified exception %s', $exporter->export($this->exception)); + return $this->methodName; } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Framework\MockObject\Stub; - -use function sprintf; -use PHPUnit\Framework\MockObject\Invocation; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class ReturnArgument implements \PHPUnit\Framework\MockObject\Stub\Stub -{ - private readonly int $argumentIndex; - public function __construct(int $argumentIndex) + public function parameters() : array { - $this->argumentIndex = $argumentIndex; + return $this->parameters; } - public function invoke(Invocation $invocation) : mixed + /** + * @throws Exception + */ + public function generateReturnValue() : mixed { - return $invocation->parameters()[$this->argumentIndex] ?? null; + if ($this->returnType === 'never') { + throw new \PHPUnit\Framework\MockObject\NeverReturningMethodException($this->className, $this->methodName); + } + if ($this->isReturnTypeNullable || $this->proxiedCall) { + return null; + } + return (new \PHPUnit\Framework\MockObject\ReturnValueGenerator())->generate($this->className, $this->methodName, $this->object::class, $this->returnType); } public function toString() : string { - return sprintf('return argument #%d', $this->argumentIndex); + $exporter = new Exporter(); + return sprintf('%s::%s(%s)%s', $this->className, $this->methodName, implode(', ', array_map([$exporter, 'shortenedExport'], $this->parameters)), $this->returnType ? sprintf(': %s', $this->returnType) : ''); + } + public function object() : \PHPUnit\Framework\MockObject\MockObjectInternal|\PHPUnit\Framework\MockObject\StubInternal + { + return $this->object; } } */ - private $callback; - public function __construct(callable $callback) + private array $matchers = []; + /** + * @psalm-var array + */ + private array $matcherMap = []; + /** + * @psalm-var list + */ + private readonly array $configurableMethods; + private readonly bool $returnValueGeneration; + /** + * @psalm-param list $configurableMethods + */ + public function __construct(array $configurableMethods, bool $returnValueGeneration) { - $this->callback = $callback; + $this->configurableMethods = $configurableMethods; + $this->returnValueGeneration = $returnValueGeneration; } - public function invoke(Invocation $invocation) : mixed + public function hasMatchers() : bool { - return call_user_func_array($this->callback, $invocation->parameters()); + foreach ($this->matchers as $matcher) { + if ($matcher->hasMatchers()) { + return \true; + } + } + return \false; } - public function toString() : string + /** + * Looks up the match builder with identification $id and returns it. + */ + public function lookupMatcher(string $id) : ?\PHPUnit\Framework\MockObject\Matcher { - if (is_array($this->callback)) { - if (is_object($this->callback[0])) { - $class = $this->callback[0]::class; - $type = '->'; - } else { - $class = $this->callback[0]; - $type = '::'; + return $this->matcherMap[$id] ?? null; + } + /** + * Registers a matcher with the identification $id. The matcher can later be + * looked up using lookupMatcher() to figure out if it has been invoked. + * + * @throws MatcherAlreadyRegisteredException + */ + public function registerMatcher(string $id, \PHPUnit\Framework\MockObject\Matcher $matcher) : void + { + if (isset($this->matcherMap[$id])) { + throw new \PHPUnit\Framework\MockObject\MatcherAlreadyRegisteredException($id); + } + $this->matcherMap[$id] = $matcher; + } + public function expects(InvocationOrder $rule) : InvocationMocker + { + $matcher = new \PHPUnit\Framework\MockObject\Matcher($rule); + $this->addMatcher($matcher); + return new InvocationMocker($this, $matcher, ...$this->configurableMethods); + } + /** + * @throws \PHPUnit\Framework\MockObject\Exception + * @throws Exception + */ + public function invoke(\PHPUnit\Framework\MockObject\Invocation $invocation) : mixed + { + $exception = null; + $hasReturnValue = \false; + $returnValue = null; + foreach ($this->matchers as $match) { + try { + if ($match->matches($invocation)) { + $value = $match->invoked($invocation); + if (!$hasReturnValue) { + $returnValue = $value; + $hasReturnValue = \true; + } + } + } catch (Exception $e) { + $exception = $e; + } + } + if ($exception !== null) { + throw $exception; + } + if ($hasReturnValue) { + return $returnValue; + } + if (!$this->returnValueGeneration) { + if (strtolower($invocation->methodName()) === '__tostring') { + return ''; } - return sprintf('return result of user defined callback %s%s%s() with the ' . 'passed arguments', $class, $type, $this->callback[1]); + throw new \PHPUnit\Framework\MockObject\ReturnValueNotConfiguredException($invocation); + } + return $invocation->generateReturnValue(); + } + /** + * @throws Throwable + */ + public function verify() : void + { + foreach ($this->matchers as $matcher) { + $matcher->verify(); } - return 'return result of user defined callback ' . $this->callback . ' with the passed arguments'; + } + private function addMatcher(\PHPUnit\Framework\MockObject\Matcher $matcher) : void + { + $this->matchers[] = $matcher; } } reference =& $reference; + $this->invocationRule = $rule; } - public function invoke(Invocation $invocation) : mixed + public function hasMatchers() : bool { - return $this->reference; + return !$this->invocationRule instanceof AnyInvokedCount; } - public function toString() : string + public function hasMethodNameRule() : bool { - $exporter = new Exporter(); - return sprintf('return user-specified reference %s', $exporter->export($this->reference)); + return $this->methodNameRule !== null; + } + public function methodNameRule() : MethodName + { + return $this->methodNameRule; + } + public function setMethodNameRule(MethodName $rule) : void + { + $this->methodNameRule = $rule; + } + public function hasParametersRule() : bool + { + return $this->parametersRule !== null; + } + public function setParametersRule(ParametersRule $rule) : void + { + $this->parametersRule = $rule; + } + public function setStub(Stub $stub) : void + { + $this->stub = $stub; + } + public function setAfterMatchBuilderId(string $id) : void + { + $this->afterMatchBuilderId = $id; + } + /** + * @throws Exception + * @throws ExpectationFailedException + * @throws MatchBuilderNotFoundException + * @throws MethodNameNotConfiguredException + * @throws RuntimeException + */ + public function invoked(\PHPUnit\Framework\MockObject\Invocation $invocation) : mixed + { + if ($this->methodNameRule === null) { + throw new \PHPUnit\Framework\MockObject\MethodNameNotConfiguredException(); + } + if ($this->afterMatchBuilderId !== null) { + $matcher = $invocation->object()->__phpunit_getInvocationHandler()->lookupMatcher($this->afterMatchBuilderId); + if (!$matcher) { + throw new \PHPUnit\Framework\MockObject\MatchBuilderNotFoundException($this->afterMatchBuilderId); + } + } + $this->invocationRule->invoked($invocation); + try { + $this->parametersRule?->apply($invocation); + } catch (ExpectationFailedException $e) { + throw new ExpectationFailedException(sprintf("Expectation failed for %s when %s\n%s", $this->methodNameRule->toString(), $this->invocationRule->toString(), $e->getMessage()), $e->getComparisonFailure()); + } + if ($this->stub) { + return $this->stub->invoke($invocation); + } + return $invocation->generateReturnValue(); + } + /** + * @throws ExpectationFailedException + * @throws MatchBuilderNotFoundException + * @throws MethodNameNotConfiguredException + * @throws RuntimeException + */ + public function matches(\PHPUnit\Framework\MockObject\Invocation $invocation) : bool + { + if ($this->afterMatchBuilderId !== null) { + $matcher = $invocation->object()->__phpunit_getInvocationHandler()->lookupMatcher($this->afterMatchBuilderId); + if (!$matcher) { + throw new \PHPUnit\Framework\MockObject\MatchBuilderNotFoundException($this->afterMatchBuilderId); + } + if (!$matcher->invocationRule->hasBeenInvoked()) { + return \false; + } + } + if ($this->methodNameRule === null) { + throw new \PHPUnit\Framework\MockObject\MethodNameNotConfiguredException(); + } + if (!$this->invocationRule->matches($invocation)) { + return \false; + } + try { + if (!$this->methodNameRule->matches($invocation)) { + return \false; + } + } catch (ExpectationFailedException $e) { + throw new ExpectationFailedException(sprintf("Expectation failed for %s when %s\n%s", $this->methodNameRule->toString(), $this->invocationRule->toString(), $e->getMessage()), $e->getComparisonFailure()); + } + return \true; + } + /** + * @throws ExpectationFailedException + * @throws MethodNameNotConfiguredException + */ + public function verify() : void + { + if ($this->methodNameRule === null) { + throw new \PHPUnit\Framework\MockObject\MethodNameNotConfiguredException(); + } + try { + $this->invocationRule->verify(); + if ($this->parametersRule === null) { + $this->parametersRule = new AnyParameters(); + } + $invocationIsAny = $this->invocationRule instanceof AnyInvokedCount; + $invocationIsNever = $this->invocationRule instanceof InvokedCount && $this->invocationRule->isNever(); + $invocationIsAtMost = $this->invocationRule instanceof InvokedAtMostCount; + if (!$invocationIsAny && !$invocationIsNever && !$invocationIsAtMost) { + $this->parametersRule->verify(); + } + } catch (ExpectationFailedException $e) { + throw new ExpectationFailedException(sprintf("Expectation failed for %s when %s.\n%s", $this->methodNameRule->toString(), $this->invocationRule->toString(), ThrowableToStringMapper::map($e))); + } } } object(); + $this->methodName = $methodName; } public function toString() : string { - return 'return the current object'; + return sprintf('is "%s"', $this->methodName); + } + protected function matches(mixed $other) : bool + { + return strtolower($this->methodName) === strtolower((string) $other); } } value = $value; + $intersection = \false; + $union = \false; + if (str_contains($returnType, '|')) { + $types = explode('|', $returnType); + $union = \true; + foreach (array_keys($types) as $key) { + if (str_starts_with($types[$key], '(') && str_ends_with($types[$key], ')')) { + $types[$key] = substr($types[$key], 1, -1); + } + } + } elseif (str_contains($returnType, '&')) { + $types = explode('&', $returnType); + $intersection = \true; + } else { + $types = [$returnType]; + } + $types = array_map('strtolower', $types); + if (!$intersection) { + if (in_array('', $types, \true) || in_array('null', $types, \true) || in_array('mixed', $types, \true) || in_array('void', $types, \true)) { + return null; + } + if (in_array('true', $types, \true)) { + return \true; + } + if (in_array('false', $types, \true) || in_array('bool', $types, \true)) { + return \false; + } + if (in_array('float', $types, \true)) { + return 0.0; + } + if (in_array('int', $types, \true)) { + return 0; + } + if (in_array('string', $types, \true)) { + return ''; + } + if (in_array('array', $types, \true)) { + return []; + } + if (in_array('static', $types, \true)) { + return $this->newInstanceOf($stubClassName, $className, $methodName); + } + if (in_array('object', $types, \true)) { + return new stdClass(); + } + if (in_array('callable', $types, \true) || in_array('closure', $types, \true)) { + return static function () : void { + }; + } + if (in_array('traversable', $types, \true) || in_array('generator', $types, \true) || in_array('iterable', $types, \true)) { + $generator = static function () : \Generator { + yield from []; + }; + return $generator(); + } + if (!$union) { + return $this->testDoubleFor($returnType, $className, $methodName); + } + } + if ($union) { + foreach ($types as $type) { + if (str_contains($type, '&')) { + $_types = explode('&', $type); + if ($this->onlyInterfaces($_types)) { + return $this->testDoubleForIntersectionOfInterfaces($_types, $className, $methodName); + } + } + } + } + if ($intersection && $this->onlyInterfaces($types)) { + return $this->testDoubleForIntersectionOfInterfaces($types, $className, $methodName); + } + $reason = ''; + if ($union) { + $reason = ' because the declared return type is a union'; + } elseif ($intersection) { + $reason = ' because the declared return type is an intersection'; + } + throw new \PHPUnit\Framework\MockObject\RuntimeException(sprintf('Return value for %s::%s() cannot be generated%s, please configure a return value for this method', $className, $methodName, $reason)); } - public function invoke(Invocation $invocation) : mixed + /** + * @psalm-param non-empty-list $types + */ + private function onlyInterfaces(array $types) : bool { - return $this->value; + foreach ($types as $type) { + if (!interface_exists($type)) { + return \false; + } + } + return \true; } - public function toString() : string + /** + * @psalm-param class-string $stubClassName + * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName + * + * @throws RuntimeException + */ + private function newInstanceOf(string $stubClassName, string $className, string $methodName) : \PHPUnit\Framework\MockObject\Stub { - $exporter = new Exporter(); - return sprintf('return user-specified value %s', $exporter->export($this->value)); + try { + return (new ReflectionClass($stubClassName))->newInstanceWithoutConstructor(); + } catch (Throwable $t) { + throw new \PHPUnit\Framework\MockObject\RuntimeException(sprintf('Return value for %s::%s() cannot be generated: %s', $className, $methodName, $t->getMessage())); + } + } + /** + * @psalm-param class-string $type + * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName + * + * @throws RuntimeException + */ + private function testDoubleFor(string $type, string $className, string $methodName) : \PHPUnit\Framework\MockObject\Stub + { + try { + return (new Generator())->testDouble($type, \false, [], [], '', \false); + } catch (Throwable $t) { + throw new \PHPUnit\Framework\MockObject\RuntimeException(sprintf('Return value for %s::%s() cannot be generated: %s', $className, $methodName, $t->getMessage())); + } + } + /** + * @psalm-param non-empty-list $types + * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName + * + * @throws RuntimeException + */ + private function testDoubleForIntersectionOfInterfaces(array $types, string $className, string $methodName) : \PHPUnit\Framework\MockObject\Stub + { + try { + return (new Generator())->testDoubleForInterfaceIntersection($types, \false); + } catch (Throwable $t) { + throw new \PHPUnit\Framework\MockObject\RuntimeException(sprintf('Return value for %s::%s() cannot be generated: %s', $className, $methodName, $t->getMessage())); + } } } valueMap = $valueMap; + return 'invoked zero or more times'; } - public function invoke(Invocation $invocation) : mixed + public function verify() : void { - $parameterCount = count($invocation->parameters()); - foreach ($this->valueMap as $map) { - if (!is_array($map) || $parameterCount !== count($map) - 1) { - continue; - } - $return = array_pop($map); - if ($invocation->parameters() === $map) { - return $return; - } - } - return null; } - public function toString() : string + public function matches(BaseInvocation $invocation) : bool { - return 'return value from a map'; + return \true; } } - */ - private static array $templates = []; - /** - * @psalm-suppress MissingThrowsDocblock + * @psalm-var list */ - private function loadTemplate(string $template) : Template + private array $invocations = []; + public function numberOfInvocations() : int + { + return count($this->invocations); + } + public function hasBeenInvoked() : bool + { + return count($this->invocations) > 0; + } + public final function invoked(BaseInvocation $invocation) : void + { + $this->invocations[] = $invocation; + $this->invokedDo($invocation); + } + public abstract function matches(BaseInvocation $invocation) : bool; + public abstract function verify() : void; + protected function invokedDo(BaseInvocation $invocation) : void { - $filename = __DIR__ . '/Generator/' . $template; - if (!isset(self::$templates[$filename])) { - self::$templates[$filename] = new Template($filename); - } - return self::$templates[$filename]; } } requiredInvocations = $requiredInvocations; + } + public function toString() : string + { + return sprintf('invoked at least %d time%s', $this->requiredInvocations, $this->requiredInvocations !== 1 ? 's' : ''); + } /** * Verifies that the current expectation is valid. If everything is OK the * code should just return, if not it must throw an exception. * * @throws ExpectationFailedException */ - public function verify() : void; -} -numberOfInvocations(); + if ($actualInvocations < $this->requiredInvocations) { + throw new ExpectationFailedException(sprintf('Expected invocation at least %d time%s but it occurred %d time%s.', $this->requiredInvocations, $this->requiredInvocations !== 1 ? 's' : '', $actualInvocations, $actualInvocations !== 1 ? 's' : '')); + } + } + public function matches(BaseInvocation $invocation) : bool + { + return \true; + } +} + - */ - public function provides() : array; + public function toString() : string + { + return 'invoked at least once'; + } /** - * @psalm-return list + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws ExpectationFailedException */ - public function requires() : array; + public function verify() : void + { + $count = $this->numberOfInvocations(); + if ($count < 1) { + throw new ExpectationFailedException('Expected invocation at least once but it never occurred.'); + } + } + public function matches(BaseInvocation $invocation) : bool + { + return \true; + } } allowedInvocations = $allowedInvocations; + } + public function toString() : string + { + return sprintf('invoked at most %d time%s', $this->allowedInvocations, $this->allowedInvocations !== 1 ? 's' : ''); + } /** - * Returns a string representation of the object. + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws ExpectationFailedException */ - public function toString() : string; + public function verify() : void + { + $actualInvocations = $this->numberOfInvocations(); + if ($actualInvocations > $this->allowedInvocations) { + throw new ExpectationFailedException(sprintf('Expected invocation at most %d time%s but it occurred %d time%s.', $this->allowedInvocations, $this->allowedInvocations !== 1 ? 's' : '', $actualInvocations, $actualInvocations !== 1 ? 's' : '')); + } + } + public function matches(BaseInvocation $invocation) : bool + { + return \true; + } } expectedCount = $expectedCount; + } + public function isNever() : bool + { + return $this->expectedCount === 0; + } + public function toString() : string + { + return sprintf('invoked %d time%s', $this->expectedCount, $this->expectedCount !== 1 ? 's' : ''); + } + public function matches(BaseInvocation $invocation) : bool + { + return \true; + } + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws ExpectationFailedException + */ + public function verify() : void + { + $actualCount = $this->numberOfInvocations(); + if ($actualCount !== $this->expectedCount) { + throw new ExpectationFailedException(sprintf('Method was expected to be called %d time%s, actually called %d time%s.', $this->expectedCount, $this->expectedCount !== 1 ? 's' : '', $actualCount, $actualCount !== 1 ? 's' : '')); + } + } + /** + * @throws ExpectationFailedException + */ + protected function invokedDo(BaseInvocation $invocation) : void + { + $count = $this->numberOfInvocations(); + if ($count > $this->expectedCount) { + $message = $invocation->toString() . ' '; + $message .= match ($this->expectedCount) { + 0 => 'was not expected to be called.', + 1 => 'was not expected to be called more than once.', + default => sprintf('was not expected to be called more than %d times.', $this->expectedCount), + }; + throw new ExpectationFailedException($message); + } + } } getName(); - $data = (new DataProvider())->providedData($className, $methodName); - if ($data !== null) { - $test = $this->buildDataProviderTestSuite($methodName, $className, $data, $this->shouldTestMethodBeRunInSeparateProcess($className, $methodName), $this->shouldGlobalStateBePreserved($className, $methodName), $this->shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess($className), $this->backupSettings($className, $methodName)); - } else { - $test = new $className($methodName); - } - if ($test instanceof \PHPUnit\Framework\TestCase) { - $this->configureTestCase($test, $this->shouldTestMethodBeRunInSeparateProcess($className, $methodName), $this->shouldGlobalStateBePreserved($className, $methodName), $this->shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess($className), $this->backupSettings($className, $methodName)); + if (is_string($constraint)) { + $constraint = new MethodNameConstraint($constraint); } - return $test; + $this->constraint = $constraint; + } + public function toString() : string + { + return 'method name ' . $this->constraint->toString(); } /** - * @psalm-param class-string $className - * @psalm-param non-empty-string $methodName - * @psalm-param array{backupGlobals: ?bool, backupGlobalsExcludeList: list, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array>} $backupSettings + * @throws ExpectationFailedException */ - private function buildDataProviderTestSuite(string $methodName, string $className, array $data, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, bool $runClassInSeparateProcess, array $backupSettings) : \PHPUnit\Framework\DataProviderTestSuite + public function matches(BaseInvocation $invocation) : bool { - $dataProviderTestSuite = \PHPUnit\Framework\DataProviderTestSuite::empty($className . '::' . $methodName); - $groups = (new Groups())->groups($className, $methodName); - foreach ($data as $_dataName => $_data) { - $_test = new $className($methodName); - assert($_test instanceof \PHPUnit\Framework\TestCase); - $_test->setData($_dataName, $_data); - $this->configureTestCase($_test, $runTestInSeparateProcess, $preserveGlobalState, $runClassInSeparateProcess, $backupSettings); - $dataProviderTestSuite->addTest($_test, $groups); - } - return $dataProviderTestSuite; + return $this->matchesName($invocation->methodName()); } /** - * @psalm-param array{backupGlobals: ?bool, backupGlobalsExcludeList: list, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array>} $backupSettings + * @throws ExpectationFailedException */ - private function configureTestCase(\PHPUnit\Framework\TestCase $test, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, bool $runClassInSeparateProcess, array $backupSettings) : void + public function matchesName(string $methodName) : bool { - if ($runTestInSeparateProcess) { - $test->setRunTestInSeparateProcess(\true); - } - if ($runClassInSeparateProcess) { - $test->setRunClassInSeparateProcess(\true); - } - if ($preserveGlobalState !== null) { - $test->setPreserveGlobalState($preserveGlobalState); - } - if ($backupSettings['backupGlobals'] !== null) { - $test->setBackupGlobals($backupSettings['backupGlobals']); - } else { - $test->setBackupGlobals(ConfigurationRegistry::get()->backupGlobals()); - } - $test->setBackupGlobalsExcludeList($backupSettings['backupGlobalsExcludeList']); - if ($backupSettings['backupStaticProperties'] !== null) { - $test->setBackupStaticProperties($backupSettings['backupStaticProperties']); - } else { - $test->setBackupStaticProperties(ConfigurationRegistry::get()->backupStaticProperties()); - } - $test->setBackupStaticPropertiesExcludeList($backupSettings['backupStaticPropertiesExcludeList']); + return (bool) $this->constraint->evaluate($methodName, '', \true); } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Rule; + +use function count; +use function sprintf; +use Exception; +use PHPUnit\Framework\Constraint\Constraint; +use PHPUnit\Framework\Constraint\IsAnything; +use PHPUnit\Framework\Constraint\IsEqual; +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Parameters implements \PHPUnit\Framework\MockObject\Rule\ParametersRule +{ /** - * @psalm-param class-string $className - * @psalm-param non-empty-string $methodName - * - * @psalm-return array{backupGlobals: ?bool, backupGlobalsExcludeList: list, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array>} + * @psalm-var list */ - private function backupSettings(string $className, string $methodName) : array + private array $parameters = []; + private ?BaseInvocation $invocation = null; + private null|bool|ExpectationFailedException $parameterVerificationResult; + /** + * @throws \PHPUnit\Framework\Exception + */ + public function __construct(array $parameters) { - $metadataForClass = MetadataRegistry::parser()->forClass($className); - $metadataForMethod = MetadataRegistry::parser()->forMethod($className, $methodName); - $metadataForClassAndMethod = MetadataRegistry::parser()->forClassAndMethod($className, $methodName); - $backupGlobals = null; - $backupGlobalsExcludeList = []; - if ($metadataForMethod->isBackupGlobals()->isNotEmpty()) { - $metadata = $metadataForMethod->isBackupGlobals()->asArray()[0]; - assert($metadata instanceof BackupGlobals); - if ($metadata->enabled()) { - $backupGlobals = \true; - } - } elseif ($metadataForClass->isBackupGlobals()->isNotEmpty()) { - $metadata = $metadataForClass->isBackupGlobals()->asArray()[0]; - assert($metadata instanceof BackupGlobals); - if ($metadata->enabled()) { - $backupGlobals = \true; - } - } - foreach ($metadataForClassAndMethod->isExcludeGlobalVariableFromBackup() as $metadata) { - assert($metadata instanceof ExcludeGlobalVariableFromBackup); - $backupGlobalsExcludeList[] = $metadata->globalVariableName(); - } - $backupStaticProperties = null; - $backupStaticPropertiesExcludeList = []; - if ($metadataForMethod->isBackupStaticProperties()->isNotEmpty()) { - $metadata = $metadataForMethod->isBackupStaticProperties()->asArray()[0]; - assert($metadata instanceof BackupStaticProperties); - if ($metadata->enabled()) { - $backupStaticProperties = \true; - } - } elseif ($metadataForClass->isBackupStaticProperties()->isNotEmpty()) { - $metadata = $metadataForClass->isBackupStaticProperties()->asArray()[0]; - assert($metadata instanceof BackupStaticProperties); - if ($metadata->enabled()) { - $backupStaticProperties = \true; - } - } - foreach ($metadataForClassAndMethod->isExcludeStaticPropertyFromBackup() as $metadata) { - assert($metadata instanceof ExcludeStaticPropertyFromBackup); - if (!isset($backupStaticPropertiesExcludeList[$metadata->className()])) { - $backupStaticPropertiesExcludeList[$metadata->className()] = []; + foreach ($parameters as $parameter) { + if (!$parameter instanceof Constraint) { + $parameter = new IsEqual($parameter); } - $backupStaticPropertiesExcludeList[$metadata->className()][] = $metadata->propertyName(); + $this->parameters[] = $parameter; } - return ['backupGlobals' => $backupGlobals, 'backupGlobalsExcludeList' => $backupGlobalsExcludeList, 'backupStaticProperties' => $backupStaticProperties, 'backupStaticPropertiesExcludeList' => $backupStaticPropertiesExcludeList]; } /** - * @psalm-param class-string $className - * @psalm-param non-empty-string $methodName + * @throws Exception */ - private function shouldGlobalStateBePreserved(string $className, string $methodName) : ?bool + public function apply(BaseInvocation $invocation) : void { - $metadataForMethod = MetadataRegistry::parser()->forMethod($className, $methodName); - if ($metadataForMethod->isPreserveGlobalState()->isNotEmpty()) { - $metadata = $metadataForMethod->isPreserveGlobalState()->asArray()[0]; - assert($metadata instanceof PreserveGlobalState); - return $metadata->enabled(); - } - $metadataForClass = MetadataRegistry::parser()->forClass($className); - if ($metadataForClass->isPreserveGlobalState()->isNotEmpty()) { - $metadata = $metadataForClass->isPreserveGlobalState()->asArray()[0]; - assert($metadata instanceof PreserveGlobalState); - return $metadata->enabled(); + $this->invocation = $invocation; + $this->parameterVerificationResult = null; + try { + $this->parameterVerificationResult = $this->doVerify(); + } catch (ExpectationFailedException $e) { + $this->parameterVerificationResult = $e; + throw $this->parameterVerificationResult; } - return null; } /** - * @psalm-param class-string $className - * @psalm-param non-empty-string $methodName + * Checks if the invocation $invocation matches the current rules. If it + * does the rule will get the invoked() method called which should check + * if an expectation is met. + * + * @throws ExpectationFailedException */ - private function shouldTestMethodBeRunInSeparateProcess(string $className, string $methodName) : bool + public function verify() : void { - if (MetadataRegistry::parser()->forClass($className)->isRunTestsInSeparateProcesses()->isNotEmpty()) { - return \true; + $this->doVerify(); + } + /** + * @throws ExpectationFailedException + */ + private function doVerify() : bool + { + if (isset($this->parameterVerificationResult)) { + return $this->guardAgainstDuplicateEvaluationOfParameterConstraints(); } - if (MetadataRegistry::parser()->forMethod($className, $methodName)->isRunInSeparateProcess()->isNotEmpty()) { - return \true; + if ($this->invocation === null) { + throw new ExpectationFailedException('Mocked method does not exist.'); } - return \false; + if (count($this->invocation->parameters()) < count($this->parameters)) { + $message = 'Parameter count for invocation %s is too low.'; + // The user called `->with($this->anything())`, but may have meant + // `->withAnyParameters()`. + // + // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/199 + if (count($this->parameters) === 1 && $this->parameters[0]::class === IsAnything::class) { + $message .= "\nTo allow 0 or more parameters with any value, omit ->with() or use ->withAnyParameters() instead."; + } + throw new ExpectationFailedException(sprintf($message, $this->invocation->toString())); + } + foreach ($this->parameters as $i => $parameter) { + $parameter->evaluate($this->invocation->parameters()[$i], sprintf('Parameter %s for invocation %s does not match expected ' . 'value.', $i, $this->invocation->toString())); + } + return \true; } /** - * @psalm-param class-string $className + * @throws ExpectationFailedException */ - private function shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess(string $className) : bool + private function guardAgainstDuplicateEvaluationOfParameterConstraints() : bool { - return MetadataRegistry::parser()->forClass($className)->isRunClassInSeparateProcess()->isNotEmpty(); + if ($this->parameterVerificationResult instanceof ExpectationFailedException) { + throw $this->parameterVerificationResult; + } + return (bool) $this->parameterVerificationResult; } } - */ - private array $backupGlobalsExcludeList = []; - private ?bool $backupStaticProperties = null; - /** - * @psalm-var array> - */ - private array $backupStaticPropertiesExcludeList = []; - private ?Snapshot $snapshot = null; - private ?bool $runClassInSeparateProcess = null; - private ?bool $runTestInSeparateProcess = null; - private bool $preserveGlobalState = \false; - private bool $inIsolation = \false; - private ?string $expectedException = null; - private ?string $expectedExceptionMessage = null; - private ?string $expectedExceptionMessageRegExp = null; - private null|int|string $expectedExceptionCode = null; - /** - * @psalm-var list - */ - private array $providedTests = []; - private array $data = []; - private int|string $dataName = ''; - /** - * @psalm-var non-empty-string - */ - private string $name; - /** - * @psalm-var list - */ - private array $groups = []; - /** - * @psalm-var list - */ - private array $dependencies = []; - private array $dependencyInput = []; /** - * @psalm-var array + * @throws ExpectationFailedException if the invocation violates the rule */ - private array $iniSettings = []; - private array $locale = []; - private ?MockGenerator $mockObjectGenerator = null; - /** - * @psalm-var list - */ - private array $mockObjects = []; - private bool $registerMockObjectsFromTestArgumentsRecursively = \false; - private TestStatus $status; - private int $numberOfAssertionsPerformed = 0; - private mixed $testResult = null; - private string $output = ''; - private ?string $outputExpectedRegex = null; - private ?string $outputExpectedString = null; - private bool $outputBufferingActive = \false; - private int $outputBufferingLevel; - private bool $outputRetrievedForAssertion = \false; - private bool $doesNotPerformAssertions = \false; - /** - * @psalm-var list - */ - private array $customComparators = []; - private ?Event\Code\TestMethod $testValueObjectForEvents = null; - private bool $wasPrepared = \false; - /** - * Returns a matcher that matches when the method is executed - * zero or more times. - */ - public static final function any() : AnyInvokedCountMatcher + public function apply(BaseInvocation $invocation) : void; + public function verify() : void; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use function array_shift; +use PHPUnit\Framework\MockObject\Invocation; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ConsecutiveCalls implements \PHPUnit\Framework\MockObject\Stub\Stub +{ + private array $stack; + public function __construct(array $stack) { - return new AnyInvokedCountMatcher(); + $this->stack = $stack; } - /** - * Returns a matcher that matches when the method is never executed. - */ - public static final function never() : InvokedCountMatcher + public function invoke(Invocation $invocation) : mixed { - return new InvokedCountMatcher(0); + $value = array_shift($this->stack); + if ($value instanceof \PHPUnit\Framework\MockObject\Stub\Stub) { + $value = $value->invoke($invocation); + } + return $value; } - /** - * Returns a matcher that matches when the method is executed - * at least N times. - */ - public static final function atLeast(int $requiredInvocations) : InvokedAtLeastCountMatcher +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; +use Throwable; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Exception implements \PHPUnit\Framework\MockObject\Stub\Stub +{ + private readonly Throwable $exception; + public function __construct(Throwable $exception) { - return new InvokedAtLeastCountMatcher($requiredInvocations); + $this->exception = $exception; } /** - * Returns a matcher that matches when the method is executed at least once. + * @throws Throwable */ - public static final function atLeastOnce() : InvokedAtLeastOnceMatcher + public function invoke(Invocation $invocation) : never { - return new InvokedAtLeastOnceMatcher(); + throw $this->exception; } - /** - * Returns a matcher that matches when the method is executed exactly once. - */ - public static final function once() : InvokedCountMatcher +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ReturnArgument implements \PHPUnit\Framework\MockObject\Stub\Stub +{ + private readonly int $argumentIndex; + public function __construct(int $argumentIndex) { - return new InvokedCountMatcher(1); + $this->argumentIndex = $argumentIndex; } - /** - * Returns a matcher that matches when the method is executed - * exactly $count times. - */ - public static final function exactly(int $count) : InvokedCountMatcher + public function invoke(Invocation $invocation) : mixed { - return new InvokedCountMatcher($count); + return $invocation->parameters()[$this->argumentIndex] ?? null; } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use function call_user_func_array; +use PHPUnit\Framework\MockObject\Invocation; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ReturnCallback implements \PHPUnit\Framework\MockObject\Stub\Stub +{ /** - * Returns a matcher that matches when the method is executed - * at most N times. + * @var callable */ - public static final function atMost(int $allowedInvocations) : InvokedAtMostCountMatcher - { - return new InvokedAtMostCountMatcher($allowedInvocations); - } - public static final function returnValue(mixed $value) : ReturnStub + private $callback; + public function __construct(callable $callback) { - return new ReturnStub($value); + $this->callback = $callback; } - public static final function returnValueMap(array $valueMap) : ReturnValueMapStub + public function invoke(Invocation $invocation) : mixed { - return new ReturnValueMapStub($valueMap); + return call_user_func_array($this->callback, $invocation->parameters()); } - public static final function returnArgument(int $argumentIndex) : ReturnArgumentStub +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ReturnReference implements \PHPUnit\Framework\MockObject\Stub\Stub +{ + private mixed $reference; + public function __construct(mixed &$reference) { - return new ReturnArgumentStub($argumentIndex); + $this->reference =& $reference; } - public static final function returnCallback(callable $callback) : ReturnCallbackStub + public function invoke(Invocation $invocation) : mixed { - return new ReturnCallbackStub($callback); + return $this->reference; } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; +use PHPUnit\Framework\MockObject\RuntimeException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ReturnSelf implements \PHPUnit\Framework\MockObject\Stub\Stub +{ /** - * Returns the current object. - * - * This method is useful when mocking a fluent interface. + * @throws RuntimeException */ - public static final function returnSelf() : ReturnSelfStub + public function invoke(Invocation $invocation) : object { - return new ReturnSelfStub(); + return $invocation->object(); } - public static final function throwException(Throwable $exception) : ExceptionStub +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ReturnStub implements \PHPUnit\Framework\MockObject\Stub\Stub +{ + private readonly mixed $value; + public function __construct(mixed $value) { - return new ExceptionStub($exception); + $this->value = $value; } - public static final function onConsecutiveCalls(mixed ...$arguments) : ConsecutiveCallsStub + public function invoke(Invocation $invocation) : mixed { - return new ConsecutiveCallsStub($arguments); + return $this->value; } - /** - * @psalm-param non-empty-string $name - * - * @internal This method is not covered by the backward compatibility promise for PHPUnit - */ - public function __construct(string $name) +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use function array_pop; +use function count; +use function is_array; +use PHPUnit\Framework\MockObject\Invocation; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ReturnValueMap implements \PHPUnit\Framework\MockObject\Stub\Stub +{ + private readonly array $valueMap; + public function __construct(array $valueMap) { - $this->setName($name); - $this->status = TestStatus::unknown(); + $this->valueMap = $valueMap; } - /** - * This method is called before the first test of this test class is run. - */ - public static function setUpBeforeClass() : void + public function invoke(Invocation $invocation) : mixed { + $parameterCount = count($invocation->parameters()); + foreach ($this->valueMap as $map) { + if (!is_array($map) || $parameterCount !== count($map) - 1) { + continue; + } + $return = array_pop($map); + if ($invocation->parameters() === $map) { + return $return; + } + } + return null; } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface Stub +{ /** - * This method is called after the last test of this test class is run. + * Fakes the processing of the invocation $invocation by returning a + * specific value. */ - public static function tearDownAfterClass() : void - { - } + public function invoke(Invocation $invocation) : mixed; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface Reorderable +{ + public function sortId() : string; /** - * This method is called before each test. + * @psalm-return list */ - protected function setUp() : void - { - } + public function provides() : array; /** - * Performs assertions shared by all tests of a test case. - * - * This method is called between setUp() and test. + * @psalm-return list */ - protected function assertPreConditions() : void - { - } + public function requires() : array; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface SelfDescribing +{ /** - * Performs assertions shared by all tests of a test case. + * Returns a string representation of the object. + */ + public function toString() : string; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use Countable; +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +interface Test extends Countable +{ + public function run() : void; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use function assert; +use PHPUnit\Metadata\Api\DataProvider; +use PHPUnit\Metadata\Api\Groups; +use PHPUnit\Metadata\BackupGlobals; +use PHPUnit\Metadata\BackupStaticProperties; +use PHPUnit\Metadata\ExcludeGlobalVariableFromBackup; +use PHPUnit\Metadata\ExcludeStaticPropertyFromBackup; +use PHPUnit\Metadata\Parser\Registry as MetadataRegistry; +use PHPUnit\Metadata\PreserveGlobalState; +use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry; +use ReflectionClass; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestBuilder +{ + /** + * @psalm-param non-empty-string $methodName * - * This method is called between test and tearDown(). + * @throws InvalidDataProviderException */ - protected function assertPostConditions() : void + public function build(ReflectionClass $theClass, string $methodName) : \PHPUnit\Framework\Test { + $className = $theClass->getName(); + $data = (new DataProvider())->providedData($className, $methodName); + if ($data !== null) { + return $this->buildDataProviderTestSuite($methodName, $className, $data, $this->shouldTestMethodBeRunInSeparateProcess($className, $methodName), $this->shouldGlobalStateBePreserved($className, $methodName), $this->shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess($className), $this->backupSettings($className, $methodName)); + } + $test = new $className($methodName); + assert($test instanceof \PHPUnit\Framework\TestCase); + $this->configureTestCase($test, $this->shouldTestMethodBeRunInSeparateProcess($className, $methodName), $this->shouldGlobalStateBePreserved($className, $methodName), $this->shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess($className), $this->backupSettings($className, $methodName)); + return $test; } /** - * This method is called after each test. + * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName + * @psalm-param array{backupGlobals: ?bool, backupGlobalsExcludeList: list, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array>} $backupSettings */ - protected function tearDown() : void + private function buildDataProviderTestSuite(string $methodName, string $className, array $data, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, bool $runClassInSeparateProcess, array $backupSettings) : \PHPUnit\Framework\DataProviderTestSuite { + $dataProviderTestSuite = \PHPUnit\Framework\DataProviderTestSuite::empty($className . '::' . $methodName); + $groups = (new Groups())->groups($className, $methodName); + foreach ($data as $_dataName => $_data) { + $_test = new $className($methodName); + assert($_test instanceof \PHPUnit\Framework\TestCase); + $_test->setData($_dataName, $_data); + $this->configureTestCase($_test, $runTestInSeparateProcess, $preserveGlobalState, $runClassInSeparateProcess, $backupSettings); + $dataProviderTestSuite->addTest($_test, $groups); + } + return $dataProviderTestSuite; } /** - * Returns a string representation of the test case. - * - * @throws Exception - * - * @internal This method is not covered by the backward compatibility promise for PHPUnit + * @psalm-param array{backupGlobals: ?bool, backupGlobalsExcludeList: list, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array>} $backupSettings */ - public function toString() : string + private function configureTestCase(\PHPUnit\Framework\TestCase $test, bool $runTestInSeparateProcess, ?bool $preserveGlobalState, bool $runClassInSeparateProcess, array $backupSettings) : void { - $buffer = sprintf('%s::%s', (new ReflectionClass($this))->getName(), $this->name); - return $buffer . $this->dataSetAsStringWithData(); + if ($runTestInSeparateProcess) { + $test->setRunTestInSeparateProcess(\true); + } + if ($runClassInSeparateProcess) { + $test->setRunClassInSeparateProcess(\true); + } + if ($preserveGlobalState !== null) { + $test->setPreserveGlobalState($preserveGlobalState); + } + if ($backupSettings['backupGlobals'] !== null) { + $test->setBackupGlobals($backupSettings['backupGlobals']); + } else { + $test->setBackupGlobals(ConfigurationRegistry::get()->backupGlobals()); + } + $test->setBackupGlobalsExcludeList($backupSettings['backupGlobalsExcludeList']); + if ($backupSettings['backupStaticProperties'] !== null) { + $test->setBackupStaticProperties($backupSettings['backupStaticProperties']); + } else { + $test->setBackupStaticProperties(ConfigurationRegistry::get()->backupStaticProperties()); + } + $test->setBackupStaticPropertiesExcludeList($backupSettings['backupStaticPropertiesExcludeList']); } /** - * @internal This method is not covered by the backward compatibility promise for PHPUnit + * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName + * + * @psalm-return array{backupGlobals: ?bool, backupGlobalsExcludeList: list, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array>} */ - public final function count() : int - { - return 1; - } - public final function getActualOutputForAssertion() : string + private function backupSettings(string $className, string $methodName) : array { - $this->outputRetrievedForAssertion = \true; - return $this->output(); - } + $metadataForClass = MetadataRegistry::parser()->forClass($className); + $metadataForMethod = MetadataRegistry::parser()->forMethod($className, $methodName); + $metadataForClassAndMethod = MetadataRegistry::parser()->forClassAndMethod($className, $methodName); + $backupGlobals = null; + $backupGlobalsExcludeList = []; + if ($metadataForMethod->isBackupGlobals()->isNotEmpty()) { + $metadata = $metadataForMethod->isBackupGlobals()->asArray()[0]; + assert($metadata instanceof BackupGlobals); + if ($metadata->enabled()) { + $backupGlobals = \true; + } + } elseif ($metadataForClass->isBackupGlobals()->isNotEmpty()) { + $metadata = $metadataForClass->isBackupGlobals()->asArray()[0]; + assert($metadata instanceof BackupGlobals); + if ($metadata->enabled()) { + $backupGlobals = \true; + } + } + foreach ($metadataForClassAndMethod->isExcludeGlobalVariableFromBackup() as $metadata) { + assert($metadata instanceof ExcludeGlobalVariableFromBackup); + $backupGlobalsExcludeList[] = $metadata->globalVariableName(); + } + $backupStaticProperties = null; + $backupStaticPropertiesExcludeList = []; + if ($metadataForMethod->isBackupStaticProperties()->isNotEmpty()) { + $metadata = $metadataForMethod->isBackupStaticProperties()->asArray()[0]; + assert($metadata instanceof BackupStaticProperties); + if ($metadata->enabled()) { + $backupStaticProperties = \true; + } + } elseif ($metadataForClass->isBackupStaticProperties()->isNotEmpty()) { + $metadata = $metadataForClass->isBackupStaticProperties()->asArray()[0]; + assert($metadata instanceof BackupStaticProperties); + if ($metadata->enabled()) { + $backupStaticProperties = \true; + } + } + foreach ($metadataForClassAndMethod->isExcludeStaticPropertyFromBackup() as $metadata) { + assert($metadata instanceof ExcludeStaticPropertyFromBackup); + if (!isset($backupStaticPropertiesExcludeList[$metadata->className()])) { + $backupStaticPropertiesExcludeList[$metadata->className()] = []; + } + $backupStaticPropertiesExcludeList[$metadata->className()][] = $metadata->propertyName(); + } + return ['backupGlobals' => $backupGlobals, 'backupGlobalsExcludeList' => $backupGlobalsExcludeList, 'backupStaticProperties' => $backupStaticProperties, 'backupStaticPropertiesExcludeList' => $backupStaticPropertiesExcludeList]; + } + /** + * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName + */ + private function shouldGlobalStateBePreserved(string $className, string $methodName) : ?bool + { + $metadataForMethod = MetadataRegistry::parser()->forMethod($className, $methodName); + if ($metadataForMethod->isPreserveGlobalState()->isNotEmpty()) { + $metadata = $metadataForMethod->isPreserveGlobalState()->asArray()[0]; + assert($metadata instanceof PreserveGlobalState); + return $metadata->enabled(); + } + $metadataForClass = MetadataRegistry::parser()->forClass($className); + if ($metadataForClass->isPreserveGlobalState()->isNotEmpty()) { + $metadata = $metadataForClass->isPreserveGlobalState()->asArray()[0]; + assert($metadata instanceof PreserveGlobalState); + return $metadata->enabled(); + } + return null; + } + /** + * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName + */ + private function shouldTestMethodBeRunInSeparateProcess(string $className, string $methodName) : bool + { + if (MetadataRegistry::parser()->forClass($className)->isRunTestsInSeparateProcesses()->isNotEmpty()) { + return \true; + } + if (MetadataRegistry::parser()->forMethod($className, $methodName)->isRunInSeparateProcess()->isNotEmpty()) { + return \true; + } + return \false; + } + /** + * @psalm-param class-string $className + */ + private function shouldAllTestMethodsOfTestClassBeRunInSingleSeparateProcess(string $className) : bool + { + return MetadataRegistry::parser()->forClass($className)->isRunClassInSeparateProcess()->isNotEmpty(); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use const LC_ALL; +use const LC_COLLATE; +use const LC_CTYPE; +use const LC_MONETARY; +use const LC_NUMERIC; +use const LC_TIME; +use const PATHINFO_FILENAME; +use const PHP_EOL; +use const PHP_URL_PATH; +use function array_keys; +use function array_merge; +use function array_values; +use function assert; +use function basename; +use function chdir; +use function class_exists; +use function clearstatcache; +use function count; +use function defined; +use function explode; +use function getcwd; +use function implode; +use function in_array; +use function ini_set; +use function is_array; +use function is_callable; +use function is_int; +use function is_object; +use function is_string; +use function libxml_clear_errors; +use function method_exists; +use function ob_end_clean; +use function ob_get_clean; +use function ob_get_contents; +use function ob_get_level; +use function ob_start; +use function parse_url; +use function pathinfo; +use function preg_replace; +use function setlocale; +use function sprintf; +use function str_contains; +use function trim; +use AssertionError; +use PHPUnit\DeepCopy\DeepCopy; +use PHPUnit\Event; +use PHPUnit\Event\NoPreviousThrowableException; +use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException; +use PHPUnit\Framework\Constraint\Exception as ExceptionConstraint; +use PHPUnit\Framework\Constraint\ExceptionCode; +use PHPUnit\Framework\Constraint\ExceptionMessageIsOrContains; +use PHPUnit\Framework\Constraint\ExceptionMessageMatchesRegularExpression; +use PHPUnit\Framework\MockObject\Exception as MockObjectException; +use PHPUnit\Framework\MockObject\Generator\Generator as MockGenerator; +use PHPUnit\Framework\MockObject\MockBuilder; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\MockObject\MockObjectInternal; +use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount as AnyInvokedCountMatcher; +use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastCount as InvokedAtLeastCountMatcher; +use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastOnce as InvokedAtLeastOnceMatcher; +use PHPUnit\Framework\MockObject\Rule\InvokedAtMostCount as InvokedAtMostCountMatcher; +use PHPUnit\Framework\MockObject\Rule\InvokedCount as InvokedCountMatcher; +use PHPUnit\Framework\MockObject\Stub; +use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls as ConsecutiveCallsStub; +use PHPUnit\Framework\MockObject\Stub\Exception as ExceptionStub; +use PHPUnit\Framework\MockObject\Stub\ReturnArgument as ReturnArgumentStub; +use PHPUnit\Framework\MockObject\Stub\ReturnCallback as ReturnCallbackStub; +use PHPUnit\Framework\MockObject\Stub\ReturnSelf as ReturnSelfStub; +use PHPUnit\Framework\MockObject\Stub\ReturnStub; +use PHPUnit\Framework\MockObject\Stub\ReturnValueMap as ReturnValueMapStub; +use PHPUnit\Framework\TestSize\TestSize; +use PHPUnit\Framework\TestStatus\TestStatus; +use PHPUnit\Metadata\Api\Groups; +use PHPUnit\Metadata\Api\HookMethods; +use PHPUnit\Metadata\Api\Requirements; +use PHPUnit\Metadata\Parser\Registry as MetadataRegistry; +use PHPUnit\TestRunner\TestResult\PassedTests; +use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry; +use PHPUnit\Util\Cloner; +use PHPUnit\Util\Test as TestUtil; +use ReflectionClass; +use ReflectionException; +use ReflectionObject; +use PHPUnit\SebastianBergmann\CodeCoverage\StaticAnalysisCacheNotConfiguredException; +use PHPUnit\SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException; +use PHPUnit\SebastianBergmann\Comparator\Comparator; +use PHPUnit\SebastianBergmann\Comparator\Factory as ComparatorFactory; +use PHPUnit\SebastianBergmann\Diff\Differ; +use PHPUnit\SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder; +use PHPUnit\SebastianBergmann\Exporter\Exporter; +use PHPUnit\SebastianBergmann\GlobalState\ExcludeList as GlobalStateExcludeList; +use PHPUnit\SebastianBergmann\GlobalState\Restorer; +use PHPUnit\SebastianBergmann\GlobalState\Snapshot; +use PHPUnit\SebastianBergmann\Invoker\TimeoutException; +use PHPUnit\SebastianBergmann\ObjectEnumerator\Enumerator; +use PHPUnit\SebastianBergmann\RecursionContext\Context; +use Throwable; +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Framework\Reorderable, \PHPUnit\Framework\SelfDescribing, \PHPUnit\Framework\Test +{ + private const LOCALE_CATEGORIES = [LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME]; + private ?bool $backupGlobals = null; + /** + * @psalm-var list + */ + private array $backupGlobalsExcludeList = []; + private ?bool $backupStaticProperties = null; + /** + * @psalm-var array> + */ + private array $backupStaticPropertiesExcludeList = []; + private ?Snapshot $snapshot = null; + private ?bool $runClassInSeparateProcess = null; + private ?bool $runTestInSeparateProcess = null; + private bool $preserveGlobalState = \false; + private bool $inIsolation = \false; + private ?string $expectedException = null; + private ?string $expectedExceptionMessage = null; + private ?string $expectedExceptionMessageRegExp = null; + private null|int|string $expectedExceptionCode = null; + /** + * @psalm-var list + */ + private array $providedTests = []; + private array $data = []; + private int|string $dataName = ''; + /** + * @psalm-var non-empty-string + */ + private string $name; + /** + * @psalm-var list + */ + private array $groups = []; + /** + * @psalm-var list + */ + private array $dependencies = []; + private array $dependencyInput = []; + /** + * @psalm-var array + */ + private array $iniSettings = []; + private array $locale = []; + /** + * @psalm-var list + */ + private array $mockObjects = []; + private bool $registerMockObjectsFromTestArgumentsRecursively = \false; + private TestStatus $status; + private int $numberOfAssertionsPerformed = 0; + private mixed $testResult = null; + private string $output = ''; + private ?string $outputExpectedRegex = null; + private ?string $outputExpectedString = null; + private bool $outputBufferingActive = \false; + private int $outputBufferingLevel; + private bool $outputRetrievedForAssertion = \false; + private bool $doesNotPerformAssertions = \false; + /** + * @psalm-var list + */ + private array $customComparators = []; + private ?Event\Code\TestMethod $testValueObjectForEvents = null; + private bool $wasPrepared = \false; + /** + * @psalm-var array + */ + private array $failureTypes = []; + /** + * Returns a matcher that matches when the method is executed + * zero or more times. + */ + public static final function any() : AnyInvokedCountMatcher + { + return new AnyInvokedCountMatcher(); + } + /** + * Returns a matcher that matches when the method is never executed. + */ + public static final function never() : InvokedCountMatcher + { + return new InvokedCountMatcher(0); + } + /** + * Returns a matcher that matches when the method is executed + * at least N times. + */ + public static final function atLeast(int $requiredInvocations) : InvokedAtLeastCountMatcher + { + return new InvokedAtLeastCountMatcher($requiredInvocations); + } + /** + * Returns a matcher that matches when the method is executed at least once. + */ + public static final function atLeastOnce() : InvokedAtLeastOnceMatcher + { + return new InvokedAtLeastOnceMatcher(); + } + /** + * Returns a matcher that matches when the method is executed exactly once. + */ + public static final function once() : InvokedCountMatcher + { + return new InvokedCountMatcher(1); + } + /** + * Returns a matcher that matches when the method is executed + * exactly $count times. + */ + public static final function exactly(int $count) : InvokedCountMatcher + { + return new InvokedCountMatcher($count); + } + /** + * Returns a matcher that matches when the method is executed + * at most N times. + */ + public static final function atMost(int $allowedInvocations) : InvokedAtMostCountMatcher + { + return new InvokedAtMostCountMatcher($allowedInvocations); + } + /** + * @deprecated Use $double->willReturn() instead of $double->will($this->returnValue()) + * @see https://github.com/sebastianbergmann/phpunit/issues/5423 + */ + public static final function returnValue(mixed $value) : ReturnStub + { + return new ReturnStub($value); + } + /** + * @deprecated Use $double->willReturnMap() instead of $double->will($this->returnValueMap()) + * @see https://github.com/sebastianbergmann/phpunit/issues/5423 + */ + public static final function returnValueMap(array $valueMap) : ReturnValueMapStub + { + return new ReturnValueMapStub($valueMap); + } + /** + * @deprecated Use $double->willReturnArgument() instead of $double->will($this->returnArgument()) + * @see https://github.com/sebastianbergmann/phpunit/issues/5423 + */ + public static final function returnArgument(int $argumentIndex) : ReturnArgumentStub + { + return new ReturnArgumentStub($argumentIndex); + } + /** + * @deprecated Use $double->willReturnCallback() instead of $double->will($this->returnCallback()) + * @see https://github.com/sebastianbergmann/phpunit/issues/5423 + */ + public static final function returnCallback(callable $callback) : ReturnCallbackStub + { + return new ReturnCallbackStub($callback); + } + /** + * @deprecated Use $double->willReturnSelf() instead of $double->will($this->returnSelf()) + * @see https://github.com/sebastianbergmann/phpunit/issues/5423 + */ + public static final function returnSelf() : ReturnSelfStub + { + return new ReturnSelfStub(); + } + public static final function throwException(Throwable $exception) : ExceptionStub + { + return new ExceptionStub($exception); + } + /** + * @deprecated Use $double->willReturn() instead of $double->will($this->onConsecutiveCalls()) + * @see https://github.com/sebastianbergmann/phpunit/issues/5423 + * @see https://github.com/sebastianbergmann/phpunit/issues/5425 + */ + public static final function onConsecutiveCalls(mixed ...$arguments) : ConsecutiveCallsStub + { + return new ConsecutiveCallsStub($arguments); + } + /** + * @psalm-param non-empty-string $name + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function __construct(string $name) + { + $this->setName($name); + $this->status = TestStatus::unknown(); + } + /** + * This method is called before the first test of this test class is run. + */ + public static function setUpBeforeClass() : void + { + } + /** + * This method is called after the last test of this test class is run. + */ + public static function tearDownAfterClass() : void + { + } + /** + * This method is called before each test. + */ + protected function setUp() : void + { + } + /** + * Performs assertions shared by all tests of a test case. + * + * This method is called between setUp() and test. + */ + protected function assertPreConditions() : void + { + } + /** + * Performs assertions shared by all tests of a test case. + * + * This method is called between test and tearDown(). + */ + protected function assertPostConditions() : void + { + } + /** + * This method is called after each test. + */ + protected function tearDown() : void + { + } + /** + * Returns a string representation of the test case. + * + * @throws Exception + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function toString() : string + { + $buffer = sprintf('%s::%s', (new ReflectionClass($this))->getName(), $this->name); + return $buffer . $this->dataSetAsStringWithData(); + } + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public final function count() : int + { + return 1; + } + public final function getActualOutputForAssertion() : string + { + $this->outputRetrievedForAssertion = \true; + return $this->output(); + } public final function expectOutputRegex(string $expectedRegex) : void { $this->outputExpectedRegex = $expectedRegex; @@ -57719,7 +62069,6 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr * @throws CodeCoverageException * @throws Exception * @throws MoreThanOneDataSetFromDataProviderException - * @throws NoDataSetFromDataProviderException * @throws NoPreviousThrowableException * @throws ProcessIsolationException * @throws StaticAnalysisCacheNotConfiguredException @@ -57751,12 +62100,6 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr { return new MockBuilder($this, $className); } - public final function registerComparator(Comparator $comparator) : void - { - ComparatorFactory::getInstance()->register($comparator); - Event\Facade::emitter()->testRegisteredComparator($comparator::class); - $this->customComparators[] = $comparator; - } /** * @internal This method is not covered by the backward compatibility promise for PHPUnit */ @@ -57802,7 +62145,7 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr if ($this->output === '') { return \false; } - if ($this->hasExpectationOnOutput()) { + if ($this->expectsOutput()) { return \false; } return \true; @@ -57827,12 +62170,14 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr /** * @internal This method is not covered by the backward compatibility promise for PHPUnit */ - public final function hasExpectationOnOutput() : bool + public final function expectsOutput() : bool { - return is_string($this->outputExpectedString) || is_string($this->outputExpectedRegex) || $this->outputRetrievedForAssertion; + return $this->hasExpectationOnOutput() || $this->outputRetrievedForAssertion; } /** * @internal This method is not covered by the backward compatibility promise for PHPUnit + * + * @deprecated */ public final function registerMockObjectsFromTestArgumentsRecursively() : void { @@ -57860,7 +62205,7 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr if ($this->inIsolation) { $this->invokeBeforeClassHookMethods($hookMethods, $emitter); } - if (method_exists(static::class, $this->name) && MetadataRegistry::parser()->forMethod(static::class, $this->name)->isDoesNotPerformAssertions()->isNotEmpty()) { + if (method_exists(static::class, $this->name) && MetadataRegistry::parser()->forClassAndMethod(static::class, $this->name)->isDoesNotPerformAssertions()->isNotEmpty()) { $this->doesNotPerformAssertions = \true; } $this->invokeBeforeTestHookMethods($hookMethods, $emitter); @@ -57878,25 +62223,40 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr $this->status = TestStatus::skipped($e->getMessage()); $emitter->testSkipped($this->valueObjectForEvents(), $e->getMessage()); } catch (AssertionError|\PHPUnit\Framework\AssertionFailedError $e) { + if (!$this->wasPrepared) { + $this->wasPrepared = \true; + $emitter->testPreparationFailed($this->valueObjectForEvents()); + } $this->status = TestStatus::failure($e->getMessage()); $emitter->testFailed($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($e), Event\Code\ComparisonFailureBuilder::from($e)); } catch (TimeoutException $e) { $this->status = TestStatus::risky($e->getMessage()); } catch (Throwable $_e) { - $e = $_e; - $this->status = TestStatus::error($_e->getMessage()); - $emitter->testErrored($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($_e)); + if ($this->isRegisteredFailure($_e)) { + $this->status = TestStatus::failure($_e->getMessage()); + $emitter->testFailed($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($_e), null); + } else { + $e = $this->transformException($_e); + $this->status = TestStatus::error($e->getMessage()); + $emitter->testErrored($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($e)); + } } - if ($this->stopOutputBuffering() && !isset($e)) { + $outputBufferingStopped = \false; + if (!isset($e) && $this->hasExpectationOnOutput() && $this->stopOutputBuffering()) { + $outputBufferingStopped = \true; $this->performAssertionsOnOutput(); } if ($this->status->isSuccess()) { - Event\Facade::emitter()->testPassed($this->valueObjectForEvents()); + $emitter->testPassed($this->valueObjectForEvents()); if (!$this->usesDataProvider()) { PassedTests::instance()->testMethodPassed($this->valueObjectForEvents(), $this->testResult); } } - $this->mockObjects = []; + try { + $this->mockObjects = []; + } catch (Throwable $t) { + Event\Facade::emitter()->testErrored($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($t)); + } // Tear down the fixture. An exception raised in tearDown() will be // caught and passed on when no exception was raised before. try { @@ -57906,6 +62266,9 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr $this->invokeAfterClassHookMethods($hookMethods, $emitter); } } + } catch (AssertionError|\PHPUnit\Framework\AssertionFailedError $e) { + $this->status = TestStatus::failure($e->getMessage()); + $emitter->testFailed($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($e), Event\Code\ComparisonFailureBuilder::from($e)); } catch (Throwable $exceptionRaisedDuringTearDown) { if (!isset($e)) { $this->status = TestStatus::error($exceptionRaisedDuringTearDown->getMessage()); @@ -57913,6 +62276,9 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr $emitter->testErrored($this->valueObjectForEvents(), Event\Code\ThrowableBuilder::from($exceptionRaisedDuringTearDown)); } } + if (!$outputBufferingStopped) { + $this->stopOutputBuffering(); + } clearstatcache(); if ($currentWorkingDirectory !== getcwd()) { chdir($currentWorkingDirectory); @@ -58053,6 +62419,7 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr */ public final function registerMockObject(MockObject $mockObject) : void { + assert($mockObject instanceof MockObjectInternal); $this->mockObjects[] = $mockObject; } /** @@ -58175,6 +62542,19 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr { return $this->wasPrepared; } + protected final function registerComparator(Comparator $comparator) : void + { + ComparatorFactory::getInstance()->register($comparator); + Event\Facade::emitter()->testRegisteredComparator($comparator::class); + $this->customComparators[] = $comparator; + } + /** + * @psalm-param class-string $classOrInterface + */ + protected final function registerFailureType(string $classOrInterface) : void + { + $this->failureTypes[$classOrInterface] = \true; + } /** * @throws AssertionFailedError * @throws Exception @@ -58205,6 +62585,8 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr * test is run. * * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5214 */ protected function iniSet(string $varName, string $newValue) : void { @@ -58220,6 +62602,8 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr * resets the locale to its original value after the test is run. * * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5216 */ protected function setLocale(mixed ...$arguments) : void { @@ -58239,36 +62623,6 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr throw new \PHPUnit\Framework\Exception('The locale functionality is not implemented on your platform, ' . 'the specified locale does not exist or the category name is ' . 'invalid.'); } } - /** - * Creates a test stub for the specified interface or class. - * - * @psalm-template RealInstanceType of object - * - * @psalm-param class-string $originalClassName - * - * @psalm-return Stub&RealInstanceType - * - * @throws \PHPUnit\Framework\MockObject\Exception - * @throws InvalidArgumentException - * @throws NoPreviousThrowableException - */ - protected function createStub(string $originalClassName) : Stub - { - $stub = $this->createTestDouble($originalClassName, \false); - Event\Facade::emitter()->testCreatedStub($originalClassName); - return $stub; - } - /** - * @psalm-param list $interfaces - * - * @throws \PHPUnit\Framework\MockObject\Exception - */ - protected function createStubForIntersectionOfInterfaces(array $interfaces) : Stub - { - $stub = $this->mockObjectGenerator()->getMockForInterfaces($interfaces); - Event\Facade::emitter()->testCreatedStubForIntersectionOfInterfaces($interfaces); - return $stub; - } /** * Creates a mock object for the specified interface or class. * @@ -58278,24 +62632,29 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr * * @psalm-return MockObject&RealInstanceType * - * @throws \PHPUnit\Framework\MockObject\Exception * @throws InvalidArgumentException + * @throws MockObjectException * @throws NoPreviousThrowableException */ protected function createMock(string $originalClassName) : MockObject { - $mock = $this->createTestDouble($originalClassName); + $mock = (new MockGenerator())->testDouble($originalClassName, \true, callOriginalConstructor: \false, callOriginalClone: \false, cloneArguments: \false, allowMockingUnknownTypes: \false); + assert($mock instanceof $originalClassName); + assert($mock instanceof MockObject); + $this->registerMockObject($mock); Event\Facade::emitter()->testCreatedMockObject($originalClassName); return $mock; } /** * @psalm-param list $interfaces * - * @throws \PHPUnit\Framework\MockObject\Exception + * @throws MockObjectException */ protected function createMockForIntersectionOfInterfaces(array $interfaces) : MockObject { - $mock = $this->mockObjectGenerator()->getMockForInterfaces($interfaces); + $mock = (new MockGenerator())->testDoubleForInterfaceIntersection($interfaces, \true); + assert($mock instanceof MockObject); + $this->registerMockObject($mock); Event\Facade::emitter()->testCreatedMockObjectForIntersectionOfInterfaces($interfaces); return $mock; } @@ -58308,8 +62667,8 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr * * @psalm-return MockObject&RealInstanceType * - * @throws \PHPUnit\Framework\MockObject\Exception * @throws InvalidArgumentException + * @throws MockObjectException * @throws NoPreviousThrowableException */ protected function createConfiguredMock(string $originalClassName, array $configuration) : MockObject @@ -58323,7 +62682,7 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr /** * Creates a partial mock object for the specified interface or class. * - * @psalm-param list $methods + * @psalm-param list $methods * * @psalm-template RealInstanceType of object * @@ -58331,8 +62690,8 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr * * @psalm-return MockObject&RealInstanceType * - * @throws \PHPUnit\Framework\MockObject\Exception * @throws InvalidArgumentException + * @throws MockObjectException */ protected function createPartialMock(string $originalClassName, array $methods) : MockObject { @@ -58349,8 +62708,10 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr * * @psalm-return MockObject&RealInstanceType * - * @throws \PHPUnit\Framework\MockObject\Exception * @throws InvalidArgumentException + * @throws MockObjectException + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5240 */ protected function createTestProxy(string $originalClassName, array $constructorArguments = []) : MockObject { @@ -58369,26 +62730,26 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr * * @psalm-return MockObject&RealInstanceType * - * @throws \PHPUnit\Framework\MockObject\Exception * @throws InvalidArgumentException + * @throws MockObjectException + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5241 */ protected function getMockForAbstractClass(string $originalClassName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, array $mockedMethods = [], bool $cloneArguments = \false) : MockObject { - $mockObject = $this->mockObjectGenerator()->getMockForAbstractClass($originalClassName, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments); + $mockObject = (new MockGenerator())->mockObjectForAbstractClass($originalClassName, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments); $this->registerMockObject($mockObject); Event\Facade::emitter()->testCreatedMockObjectForAbstractClass($originalClassName); + assert($mockObject instanceof $originalClassName); + assert($mockObject instanceof MockObject); return $mockObject; } /** * Creates a mock object based on the given WSDL file. * - * @psalm-template RealInstanceType of object - * - * @psalm-param class-string|string $originalClassName - * - * @psalm-return MockObject&RealInstanceType + * @throws MockObjectException * - * @throws \PHPUnit\Framework\MockObject\Exception + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5242 */ protected function getMockFromWsdl(string $wsdlFile, string $originalClassName = '', string $mockClassName = '', array $methods = [], bool $callOriginalConstructor = \true, array $options = []) : MockObject { @@ -58397,10 +62758,11 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr $originalClassName = preg_replace('/\\W/', '', $fileName); } if (!class_exists($originalClassName)) { - eval($this->mockObjectGenerator()->generateClassFromWsdl($wsdlFile, $originalClassName, $methods, $options)); + eval((new MockGenerator())->generateClassFromWsdl($wsdlFile, $originalClassName, $methods, $options)); } - $mockObject = $this->mockObjectGenerator()->getMock($originalClassName, $methods, ['', $options], $mockClassName, $callOriginalConstructor, \false, \false); + $mockObject = (new MockGenerator())->testDouble($originalClassName, \true, $methods, ['', $options], $mockClassName, $callOriginalConstructor, \false, \false); Event\Facade::emitter()->testCreatedMockObjectFromWsdl($wsdlFile, $originalClassName, $mockClassName, $methods, $callOriginalConstructor, $options); + assert($mockObject instanceof MockObject); $this->registerMockObject($mockObject); return $mockObject; } @@ -58411,12 +62773,14 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr * * @psalm-param trait-string $traitName * - * @throws \PHPUnit\Framework\MockObject\Exception * @throws InvalidArgumentException + * @throws MockObjectException + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5243 */ protected function getMockForTrait(string $traitName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true, array $mockedMethods = [], bool $cloneArguments = \false) : MockObject { - $mockObject = $this->mockObjectGenerator()->getMockForTrait($traitName, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments); + $mockObject = (new MockGenerator())->mockObjectForTrait($traitName, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments); $this->registerMockObject($mockObject); Event\Facade::emitter()->testCreatedMockObjectForTrait($traitName); return $mockObject; @@ -58426,11 +62790,17 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr * * @psalm-param trait-string $traitName * - * @throws \PHPUnit\Framework\MockObject\Exception + * @throws MockObjectException + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5244 */ protected function getObjectForTrait(string $traitName, array $arguments = [], string $traitClassName = '', bool $callOriginalConstructor = \true, bool $callOriginalClone = \true, bool $callAutoload = \true) : object { - return $this->mockObjectGenerator()->getObjectForTrait($traitName, $traitClassName, $callAutoload, $callOriginalConstructor, $arguments); + return (new MockGenerator())->objectForTrait($traitName, $traitClassName, $callAutoload, $callOriginalConstructor, $arguments); + } + protected function transformException(Throwable $t) : Throwable + { + return $t; } /** * This method is called when a test method did not execute successfully. @@ -58540,13 +62910,6 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr Event\Facade::emitter()->testSkipped($this->valueObjectForEvents(), $message); $this->status = TestStatus::skipped($message); } - private function mockObjectGenerator() : MockGenerator - { - if ($this->mockObjectGenerator === null) { - $this->mockObjectGenerator = new MockGenerator(); - } - return $this->mockObjectGenerator; - } private function startOutputBuffering() : void { ob_start(); @@ -58558,11 +62921,16 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr */ private function stopOutputBuffering() : bool { - if (ob_get_level() !== $this->outputBufferingLevel) { - while (ob_get_level() >= $this->outputBufferingLevel) { + $bufferingLevel = ob_get_level(); + if ($bufferingLevel !== $this->outputBufferingLevel) { + if ($bufferingLevel > $this->outputBufferingLevel) { + $message = 'Test code or tested code did not close its own output buffers'; + } else { + $message = 'Test code or tested code closed output buffers other than its own'; + } + while (ob_get_level() >= $this->outputBufferingLevel) { ob_end_clean(); } - $message = 'Test code or tested code did not (only) close its own output buffers'; Event\Facade::emitter()->testConsideredRisky($this->valueObjectForEvents(), $message); $this->status = TestStatus::risky($message); return \false; @@ -58658,6 +63026,9 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr } return !in_array($mock, $enumerator->enumerate($this->testResult), \true); } + /** + * @deprecated + */ private function registerMockObjectsFromTestArguments(array $testArguments, Context $context = new Context()) : void { if ($this->registerMockObjectsFromTestArgumentsRecursively) { @@ -58667,13 +63038,14 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr } } } else { - foreach ($testArguments as $testArgument) { + foreach ($testArguments as &$testArgument) { if ($testArgument instanceof MockObject) { $testArgument = Cloner::clone($testArgument); $this->registerMockObject($testArgument); } elseif (is_array($testArgument) && !$context->contains($testArgument)) { + $testArgumentCopy = $testArgument; $context->add($testArgument); - $this->registerMockObjectsFromTestArguments($testArgument, $context); + $this->registerMockObjectsFromTestArguments($testArgumentCopy, $context); } } } @@ -58754,21 +63126,6 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr } return TestUtil::isTestMethod($class->getMethod($methodName)); } - /** - * @psalm-template RealInstanceType of object - * - * @psalm-param class-string $originalClassName - * - * @psalm-return MockObject&RealInstanceType - * - * @throws \PHPUnit\Framework\MockObject\Exception - * @throws InvalidArgumentException - * @throws NoPreviousThrowableException - */ - private function createTestDouble(string $originalClassName, bool $register = \true) : MockObject - { - return $this->getMockBuilder($originalClassName)->disableOriginalConstructor()->disableOriginalClone()->disableArgumentCloning()->disallowMockingUnknownTypes()->getMock($register); - } /** * @throws Exception * @throws ExpectationFailedException @@ -58781,7 +63138,7 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr if ($this->outputExpectedRegex !== null) { $this->assertMatchesRegularExpression($this->outputExpectedRegex, $this->output); } elseif ($this->outputExpectedString !== null) { - $this->assertEquals($this->outputExpectedString, $this->output); + $this->assertSame($this->outputExpectedString, $this->output); } } catch (\PHPUnit\Framework\ExpectationFailedException $e) { $this->status = TestStatus::failure($e->getMessage()); @@ -58789,26 +63146,44 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr throw $e; } } + /** + * @throws Throwable + */ private function invokeBeforeClassHookMethods(array $hookMethods, Event\Emitter $emitter) : void { $this->invokeHookMethods($hookMethods['beforeClass'], $emitter, 'testBeforeFirstTestMethodCalled', 'testBeforeFirstTestMethodFinished'); } + /** + * @throws Throwable + */ private function invokeBeforeTestHookMethods(array $hookMethods, Event\Emitter $emitter) : void { $this->invokeHookMethods($hookMethods['before'], $emitter, 'testBeforeTestMethodCalled', 'testBeforeTestMethodFinished'); } + /** + * @throws Throwable + */ private function invokePreConditionHookMethods(array $hookMethods, Event\Emitter $emitter) : void { $this->invokeHookMethods($hookMethods['preCondition'], $emitter, 'testPreConditionCalled', 'testPreConditionFinished'); } + /** + * @throws Throwable + */ private function invokePostConditionHookMethods(array $hookMethods, Event\Emitter $emitter) : void { $this->invokeHookMethods($hookMethods['postCondition'], $emitter, 'testPostConditionCalled', 'testPostConditionFinished'); } + /** + * @throws Throwable + */ private function invokeAfterTestHookMethods(array $hookMethods, Event\Emitter $emitter) : void { $this->invokeHookMethods($hookMethods['after'], $emitter, 'testAfterTestMethodCalled', 'testAfterTestMethodFinished'); } + /** + * @throws Throwable + */ private function invokeAfterClassHookMethods(array $hookMethods, Event\Emitter $emitter) : void { $this->invokeHookMethods($hookMethods['afterClass'], $emitter, 'testAfterLastTestMethodCalled', 'testAfterLastTestMethodFinished'); @@ -58817,6 +63192,8 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr * @psalm-param list $hookMethods * @psalm-param 'testBeforeFirstTestMethodCalled'|'testBeforeTestMethodCalled'|'testPreConditionCalled'|'testPostConditionCalled'|'testAfterTestMethodCalled'|'testAfterLastTestMethodCalled' $calledMethod * @psalm-param 'testBeforeFirstTestMethodFinished'|'testBeforeTestMethodFinished'|'testPreConditionFinished'|'testPostConditionFinished'|'testAfterTestMethodFinished'|'testAfterLastTestMethodFinished' $finishedMethod + * + * @throws Throwable */ private function invokeHookMethods(array $hookMethods, Event\Emitter $emitter, string $calledMethod, string $finishedMethod) : void { @@ -58825,14 +63202,23 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr if ($this->methodDoesNotExistOrIsDeclaredInTestCase($methodName)) { continue; } - $this->{$methodName}(); + try { + $this->{$methodName}(); + } catch (Throwable $t) { + } $methodInvoked = new Event\Code\ClassMethod(static::class, $methodName); $emitter->{$calledMethod}(static::class, $methodInvoked); $methodsInvoked[] = $methodInvoked; + if (isset($t)) { + break; + } } if (!empty($methodsInvoked)) { $emitter->{$finishedMethod}(static::class, ...$methodsInvoked); } + if (isset($t)) { + throw $t; + } } private function methodDoesNotExistOrIsDeclaredInTestCase(string $methodName) : bool { @@ -58842,7 +63228,7 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr /** * @throws ExpectationFailedException */ - private function verifyExceptionExpectations(Throwable|\Exception $exception) : void + private function verifyExceptionExpectations(\Exception|Throwable $exception) : void { if ($this->expectedException !== null) { $this->assertThat($exception, new ExceptionConstraint($this->expectedException)); @@ -58875,6 +63261,75 @@ abstract class TestCase extends \PHPUnit\Framework\Assert implements \PHPUnit\Fr throw new \PHPUnit\Framework\AssertionFailedError(sprintf('Failed asserting that exception with code "%s" is thrown', $this->expectedExceptionCode)); } } + private function isRegisteredFailure(Throwable $t) : bool + { + foreach (array_keys($this->failureTypes) as $failureType) { + if ($t instanceof $failureType) { + return \true; + } + } + return \false; + } + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + private function hasExpectationOnOutput() : bool + { + return is_string($this->outputExpectedString) || is_string($this->outputExpectedRegex); + } + /** + * Creates a test stub for the specified interface or class. + * + * @psalm-template RealInstanceType of object + * + * @psalm-param class-string $originalClassName + * + * @psalm-return Stub&RealInstanceType + * + * @throws InvalidArgumentException + * @throws MockObjectException + * @throws NoPreviousThrowableException + */ + protected static function createStub(string $originalClassName) : Stub + { + $stub = (new MockGenerator())->testDouble($originalClassName, \true, callOriginalConstructor: \false, callOriginalClone: \false, cloneArguments: \false, allowMockingUnknownTypes: \false); + Event\Facade::emitter()->testCreatedStub($originalClassName); + assert($stub instanceof $originalClassName); + assert($stub instanceof Stub); + return $stub; + } + /** + * @psalm-param list $interfaces + * + * @throws MockObjectException + */ + protected static function createStubForIntersectionOfInterfaces(array $interfaces) : Stub + { + $stub = (new MockGenerator())->testDoubleForInterfaceIntersection($interfaces, \false); + Event\Facade::emitter()->testCreatedStubForIntersectionOfInterfaces($interfaces); + return $stub; + } + /** + * Creates (and configures) a test stub for the specified interface or class. + * + * @psalm-template RealInstanceType of object + * + * @psalm-param class-string $originalClassName + * + * @psalm-return Stub&RealInstanceType + * + * @throws InvalidArgumentException + * @throws MockObjectException + * @throws NoPreviousThrowableException + */ + protected static final function createConfiguredStub(string $originalClassName, array $configuration) : Stub + { + $o = self::createStub($originalClassName); + foreach ($configuration as $method => $return) { + $o->method($method)->willReturn($return); + } + return $o; + } } enable(); + error_clear_last(); + if ($this->shouldErrorHandlerBeUsed($test)) { + ErrorHandler::instance()->enable(); + } $collectCodeCoverage = CodeCoverage::instance()->isActive() && $shouldCodeCoverageBeCollected; if ($collectCodeCoverage) { CodeCoverage::instance()->start($test); @@ -58983,7 +63440,7 @@ final class TestRunner $error = \true; } $test->addToAssertionCount(\PHPUnit\Framework\Assert::getCount()); - if ($this->configuration->reportUselessTests() && $test->numberOfAssertionsPerformed() === 0) { + if ($this->configuration->reportUselessTests() && !$test->doesNotPerformAssertions() && $test->numberOfAssertionsPerformed() === 0) { $risky = \true; } if (!$error && !$failure && !$incomplete && !$skipped && !$risky && $this->configuration->requireCoverageMetadata() && !$this->hasCoverageMetadata($test::class, $test->name())) { @@ -59012,17 +63469,11 @@ final class TestRunner } } ErrorHandler::instance()->disable(); - if (isset($e)) { - if ($test->wasPrepared()) { - Event\Facade::emitter()->testFinished($test->valueObjectForEvents(), $test->numberOfAssertionsPerformed()); - } - return; - } - if ($this->configuration->reportUselessTests() && !$test->doesNotPerformAssertions() && $test->numberOfAssertionsPerformed() === 0) { + if (!$error && !$incomplete && !$skipped && $this->configuration->reportUselessTests() && !$test->doesNotPerformAssertions() && $test->numberOfAssertionsPerformed() === 0) { Event\Facade::emitter()->testConsideredRisky($test->valueObjectForEvents(), 'This test did not perform any assertions'); } if ($test->doesNotPerformAssertions() && $test->numberOfAssertionsPerformed() > 0) { - Event\Facade::emitter()->testConsideredRisky($test->valueObjectForEvents(), sprintf('This test is not expected to perform assertions but performed %d assertions', $test->numberOfAssertionsPerformed())); + Event\Facade::emitter()->testConsideredRisky($test->valueObjectForEvents(), sprintf('This test is not expected to perform assertions but performed %d assertion%s', $test->numberOfAssertionsPerformed(), $test->numberOfAssertionsPerformed() > 1 ? 's' : '')); } if ($test->hasUnexpectedOutput()) { Event\Facade::emitter()->testPrintedUnexpectedOutput($test->output()); @@ -59066,7 +63517,9 @@ final class TestRunner $includedFiles = GlobalState::getIncludedFilesAsString(); $iniSettings = GlobalState::getIniSettingsAsString(); } + $exportObjects = Event\Facade::emitter()->exportsObjects() ? 'true' : 'false'; $coverage = CodeCoverage::instance()->isActive() ? 'true' : 'false'; + $linesToBeIgnored = var_export(CodeCoverage::instance()->linesToBeIgnored(), \true); if (defined('PHPUNIT_COMPOSER_INSTALL')) { $composerAutoload = var_export(PHPUNIT_COMPOSER_INSTALL, \true); } else { @@ -59089,13 +63542,14 @@ final class TestRunner $includePath = "'." . $includePath . ".'"; $offset = hrtime(); $serializedConfiguration = $this->saveConfigurationForChildProcess(); - $var = ['bootstrap' => $bootstrap, 'composerAutoload' => $composerAutoload, 'phar' => $phar, 'filename' => $class->getFileName(), 'className' => $class->getName(), 'collectCodeCoverageInformation' => $coverage, 'data' => $data, 'dataName' => $dataName, 'dependencyInput' => $dependencyInput, 'constants' => $constants, 'globals' => $globals, 'include_path' => $includePath, 'included_files' => $includedFiles, 'iniSettings' => $iniSettings, 'name' => $test->name(), 'offsetSeconds' => $offset[0], 'offsetNanoseconds' => $offset[1], 'serializedConfiguration' => $serializedConfiguration]; + $processResultFile = tempnam(sys_get_temp_dir(), 'phpunit_'); + $var = ['bootstrap' => $bootstrap, 'composerAutoload' => $composerAutoload, 'phar' => $phar, 'filename' => $class->getFileName(), 'className' => $class->getName(), 'collectCodeCoverageInformation' => $coverage, 'linesToBeIgnored' => $linesToBeIgnored, 'data' => $data, 'dataName' => $dataName, 'dependencyInput' => $dependencyInput, 'constants' => $constants, 'globals' => $globals, 'include_path' => $includePath, 'included_files' => $includedFiles, 'iniSettings' => $iniSettings, 'name' => $test->name(), 'offsetSeconds' => $offset[0], 'offsetNanoseconds' => $offset[1], 'serializedConfiguration' => $serializedConfiguration, 'processResultFile' => $processResultFile, 'exportObjects' => $exportObjects]; if (!$runEntireClass) { $var['methodName'] = $test->name(); } $template->setVar($var); $php = AbstractPhpProcess::factory(); - $php->runTestJob($template->render(), $test); + $php->runTestJob($template->render(), $test, $processResultFile); @unlink($serializedConfiguration); } /** @@ -59170,7 +63624,7 @@ final class TestRunner */ private function saveConfigurationForChildProcess() : string { - $path = tempnam(sys_get_temp_dir(), 'PHPUnit'); + $path = tempnam(sys_get_temp_dir(), 'phpunit_'); if (!$path) { throw new \PHPUnit\Framework\ProcessIsolationException(); } @@ -59179,6 +63633,13 @@ final class TestRunner } return $path; } + private function shouldErrorHandlerBeUsed(\PHPUnit\Framework\TestCase $test) : bool + { + if (MetadataRegistry::parser()->forMethod($test::class, $test->name())->isWithoutErrorHandler()->isNotEmpty()) { + return \false; + } + return \true; + } } > */ - protected array $groups = []; - protected ?array $requiredTests = null; + private array $groups = []; + private ?array $requiredTests = null; /** * @psalm-var list */ private array $tests = []; private ?array $providedTests = null; private ?Factory $iteratorFilter = null; - private readonly bool $stopOnError; - private readonly bool $stopOnFailure; - private readonly bool $stopOnWarning; - private readonly bool $stopOnRisky; - private readonly bool $stopOnIncomplete; - private readonly bool $stopOnSkipped; - private readonly bool $stopOnDefect; - public static function empty(string $name = null) : static + /** + * @psalm-param non-empty-string $name + */ + public static function empty(string $name) : static { - if ($name === null) { - $name = ''; - } return new static($name); } /** @@ -60079,7 +64535,7 @@ class TestSuite implements IteratorAggregate, \PHPUnit\Framework\Reorderable, \P Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('Class "%s" has no public constructor.', $class->getName())); return $testSuite; } - foreach ((new Reflection())->publicMethodsInTestClass($class) as $method) { + foreach (Reflection::publicMethodsInTestClass($class) as $method) { if ($method->getDeclaringClass()->getName() === \PHPUnit\Framework\Assert::class) { continue; } @@ -60096,24 +64552,19 @@ class TestSuite implements IteratorAggregate, \PHPUnit\Framework\Reorderable, \P } return $testSuite; } + /** + * @psalm-param non-empty-string $name + */ private final function __construct(string $name) { $this->name = $name; - $configuration = Registry::get(); - $this->stopOnError = $configuration->stopOnError(); - $this->stopOnFailure = $configuration->stopOnFailure(); - $this->stopOnWarning = $configuration->stopOnWarning(); - $this->stopOnRisky = $configuration->stopOnRisky(); - $this->stopOnIncomplete = $configuration->stopOnIncomplete(); - $this->stopOnSkipped = $configuration->stopOnSkipped(); - $this->stopOnDefect = $configuration->stopOnDefect(); } /** * Returns a string representation of the test suite. */ public function toString() : string { - return $this->getName(); + return $this->name(); } /** * Adds a test to the suite. @@ -60125,7 +64576,7 @@ class TestSuite implements IteratorAggregate, \PHPUnit\Framework\Reorderable, \P $this->tests[] = $test; $this->clearCaches(); if ($test instanceof self && empty($groups)) { - $groups = $test->getGroups(); + $groups = $test->groups(); } if ($this->containsOnlyVirtualGroups($groups)) { $groups[] = 'default'; @@ -60210,9 +64661,9 @@ class TestSuite implements IteratorAggregate, \PHPUnit\Framework\Reorderable, \P return empty($this->tests); } /** - * Returns the name of the suite. + * @psalm-return non-empty-string */ - public function getName() : string + public function name() : string { return $this->name; } @@ -60221,11 +64672,11 @@ class TestSuite implements IteratorAggregate, \PHPUnit\Framework\Reorderable, \P * * @psalm-return list */ - public function getGroups() : array + public function groups() : array { return array_map('strval', array_keys($this->groups)); } - public function getGroupDetails() : array + public function groupDetails() : array { return $this->groups; } @@ -60249,7 +64700,8 @@ class TestSuite implements IteratorAggregate, \PHPUnit\Framework\Reorderable, \P return; } foreach ($this as $test) { - if ($this->shouldStop()) { + if (TestResultFacade::shouldStop()) { + $emitter->testRunnerExecutionAborted(); break; } $test->run(); @@ -60316,9 +64768,7 @@ class TestSuite implements IteratorAggregate, \PHPUnit\Framework\Reorderable, \P } foreach ($this->tests as $test) { if (!$test instanceof \PHPUnit\Framework\Reorderable) { - // @codeCoverageIgnoreStart continue; - // @codeCoverageIgnoreEnd } $this->providedTests = \PHPUnit\Framework\ExecutionOrderDependency::mergeUnique($this->providedTests, $test->provides()); } @@ -60334,9 +64784,7 @@ class TestSuite implements IteratorAggregate, \PHPUnit\Framework\Reorderable, \P $this->requiredTests = []; foreach ($this->tests as $test) { if (!$test instanceof \PHPUnit\Framework\Reorderable) { - // @codeCoverageIgnoreStart continue; - // @codeCoverageIgnoreEnd } $this->requiredTests = \PHPUnit\Framework\ExecutionOrderDependency::mergeUnique(\PHPUnit\Framework\ExecutionOrderDependency::filterInvalid($this->requiredTests), $test->requires()); } @@ -60346,7 +64794,7 @@ class TestSuite implements IteratorAggregate, \PHPUnit\Framework\Reorderable, \P } public function sortId() : string { - return $this->getName() . '::class'; + return $this->name() . '::class'; } /** * @psalm-assert-if-true class-string $this->name @@ -60356,7 +64804,7 @@ class TestSuite implements IteratorAggregate, \PHPUnit\Framework\Reorderable, \P return class_exists($this->name, \false) && is_subclass_of($this->name, \PHPUnit\Framework\TestCase::class); } /** - * @throws \PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException + * @throws Event\TestData\MoreThanOneDataSetFromDataProviderException * @throws Exception */ protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method) : void @@ -60394,28 +64842,6 @@ class TestSuite implements IteratorAggregate, \PHPUnit\Framework\Reorderable, \P $reflector = new ReflectionClass($this->name); return !$reflector->hasMethod($methodName) || $reflector->getMethod($methodName)->getDeclaringClass()->getName() === \PHPUnit\Framework\TestCase::class; } - private function shouldStop() : bool - { - if (($this->stopOnDefect || $this->stopOnError) && Facade::hasTestErroredEvents()) { - return \true; - } - if (($this->stopOnDefect || $this->stopOnFailure) && Facade::hasTestFailedEvents()) { - return \true; - } - if (($this->stopOnDefect || $this->stopOnWarning) && Facade::hasWarningEvents()) { - return \true; - } - if (($this->stopOnDefect || $this->stopOnRisky) && Facade::hasTestConsideredRiskyEvents()) { - return \true; - } - if ($this->stopOnSkipped && Facade::hasTestSkippedEvents()) { - return \true; - } - if ($this->stopOnIncomplete && Facade::hasTestMarkedIncompleteEvents()) { - return \true; - } - return \false; - } /** * @throws Exception */ @@ -60454,7 +64880,7 @@ class TestSuite implements IteratorAggregate, \PHPUnit\Framework\Reorderable, \P $methodsCalledBeforeFirstTest[] = $methodCalledBeforeFirstTest; call_user_func([$this->name, $beforeClassMethod]); } - } catch (\PHPUnit\Framework\SkippedTestSuiteError|\PHPUnit\Framework\SkippedTest $e) { + } catch (\PHPUnit\Framework\SkippedTest|\PHPUnit\Framework\SkippedTestSuiteError $e) { $emitter->testSuiteSkipped($testSuiteValueObjectForEvents, $e->getMessage()); return \false; } catch (Throwable $t) { @@ -60580,9 +65006,9 @@ namespace PHPUnit\Logging; use const FILE_APPEND; use const LOCK_EX; use const PHP_EOL; -use function explode; use function file_put_contents; use function implode; +use function preg_split; use function str_repeat; use function strlen; use PHPUnit\Event\Event; @@ -60603,7 +65029,7 @@ final class EventLogger implements Tracer { $telemetryInfo = $this->telemetryInfo($event); $indentation = PHP_EOL . str_repeat(' ', strlen($telemetryInfo)); - $lines = explode(PHP_EOL, $event->asString()); + $lines = preg_split('/\\r\\n|\\r|\\n/', $event->asString()); file_put_contents($this->path, $telemetryInfo . implode($indentation, $lines) . PHP_EOL, FILE_APPEND | LOCK_EX); } private function telemetryInfo(Event $event) : string @@ -60666,9 +65092,9 @@ use PHPUnit\Event\Test\Errored; use PHPUnit\Event\Test\Failed; use PHPUnit\Event\Test\Finished; use PHPUnit\Event\Test\MarkedIncomplete; +use PHPUnit\Event\Test\PreparationStarted; use PHPUnit\Event\Test\Prepared; use PHPUnit\Event\Test\Skipped; -use PHPUnit\Event\TestData\NoDataSetFromDataProviderException; use PHPUnit\Event\TestSuite\Started; use PHPUnit\Event\UnknownSubscriberTypeException; use PHPUnit\TextUI\Output\Printer; @@ -60713,14 +65139,15 @@ final class JunitXmlLogger private ?DOMElement $currentTestCase = null; private ?HRTime $time = null; private bool $prepared = \false; + private bool $preparationFailed = \false; /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ - public function __construct(Printer $printer) + public function __construct(Printer $printer, Facade $facade) { $this->printer = $printer; - $this->registerSubscribers(); + $this->registerSubscribers($facade); $this->createDocument(); } public function flush() : void @@ -60769,11 +65196,23 @@ final class JunitXmlLogger } /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException */ - public function testPrepared(Prepared $event) : void + public function testPreparationStarted(PreparationStarted $event) : void { $this->createTestCase($event); + } + /** + * @throws InvalidArgumentException + */ + public function testPreparationFailed() : void + { + $this->preparationFailed = \true; + } + /** + * @throws InvalidArgumentException + */ + public function testPrepared() : void + { $this->prepared = \true; } /** @@ -60781,11 +65220,13 @@ final class JunitXmlLogger */ public function testFinished(Finished $event) : void { + if ($this->preparationFailed) { + return; + } $this->handleFinish($event->telemetryInfo(), $event->numberOfAssertionsPerformed()); } /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException */ public function testMarkedIncomplete(MarkedIncomplete $event) : void { @@ -60793,7 +65234,6 @@ final class JunitXmlLogger } /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException */ public function testSkipped(Skipped $event) : void { @@ -60801,7 +65241,6 @@ final class JunitXmlLogger } /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException */ public function testErrored(Errored $event) : void { @@ -60810,7 +65249,6 @@ final class JunitXmlLogger } /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException */ public function testFailed(Failed $event) : void { @@ -60839,9 +65277,9 @@ final class JunitXmlLogger * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ - private function registerSubscribers() : void + private function registerSubscribers(Facade $facade) : void { - Facade::registerSubscribers(new \PHPUnit\Logging\JUnit\TestSuiteStartedSubscriber($this), new \PHPUnit\Logging\JUnit\TestSuiteFinishedSubscriber($this), new \PHPUnit\Logging\JUnit\TestPreparedSubscriber($this), new \PHPUnit\Logging\JUnit\TestFinishedSubscriber($this), new \PHPUnit\Logging\JUnit\TestErroredSubscriber($this), new \PHPUnit\Logging\JUnit\TestFailedSubscriber($this), new \PHPUnit\Logging\JUnit\TestMarkedIncompleteSubscriber($this), new \PHPUnit\Logging\JUnit\TestSkippedSubscriber($this), new \PHPUnit\Logging\JUnit\TestRunnerExecutionFinishedSubscriber($this)); + $facade->registerSubscribers(new \PHPUnit\Logging\JUnit\TestSuiteStartedSubscriber($this), new \PHPUnit\Logging\JUnit\TestSuiteFinishedSubscriber($this), new \PHPUnit\Logging\JUnit\TestPreparationStartedSubscriber($this), new \PHPUnit\Logging\JUnit\TestPreparationFailedSubscriber($this), new \PHPUnit\Logging\JUnit\TestPreparedSubscriber($this), new \PHPUnit\Logging\JUnit\TestFinishedSubscriber($this), new \PHPUnit\Logging\JUnit\TestErroredSubscriber($this), new \PHPUnit\Logging\JUnit\TestFailedSubscriber($this), new \PHPUnit\Logging\JUnit\TestMarkedIncompleteSubscriber($this), new \PHPUnit\Logging\JUnit\TestSkippedSubscriber($this), new \PHPUnit\Logging\JUnit\TestRunnerExecutionFinishedSubscriber($this)); } private function createDocument() : void { @@ -60852,7 +65290,6 @@ final class JunitXmlLogger } /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException */ private function handleFault(Errored|Failed $event, string $type) : void { @@ -60872,7 +65309,6 @@ final class JunitXmlLogger } /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException */ private function handleIncompleteOrSkipped(MarkedIncomplete|Skipped $event) : void { @@ -60889,7 +65325,6 @@ final class JunitXmlLogger } /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException */ private function testAsString(Test $test) : string { @@ -60901,7 +65336,6 @@ final class JunitXmlLogger } /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException */ private function name(Test $test) : string { @@ -60920,11 +65354,10 @@ final class JunitXmlLogger } /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException * * @psalm-assert !null $this->currentTestCase */ - private function createTestCase(Prepared|MarkedIncomplete|Skipped|Errored|Failed $event) : void + private function createTestCase(Errored|Failed|MarkedIncomplete|PreparationStarted|Prepared|Skipped $event) : void { $testCase = $this->document->createElement('testcase'); $test = $event->test(); @@ -60984,7 +65417,6 @@ namespace PHPUnit\Logging\JUnit; use PHPUnit\Event\InvalidArgumentException; use PHPUnit\Event\Test\Errored; use PHPUnit\Event\Test\ErroredSubscriber; -use PHPUnit\Event\TestData\NoDataSetFromDataProviderException; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ @@ -60992,7 +65424,6 @@ final class TestErroredSubscriber extends \PHPUnit\Logging\JUnit\Subscriber impl { /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException */ public function notify(Errored $event) : void { @@ -61015,7 +65446,6 @@ namespace PHPUnit\Logging\JUnit; use PHPUnit\Event\InvalidArgumentException; use PHPUnit\Event\Test\Failed; use PHPUnit\Event\Test\FailedSubscriber; -use PHPUnit\Event\TestData\NoDataSetFromDataProviderException; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ @@ -61023,7 +65453,6 @@ final class TestFailedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber imple { /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException */ public function notify(Failed $event) : void { @@ -61046,7 +65475,6 @@ namespace PHPUnit\Logging\JUnit; use PHPUnit\Event\InvalidArgumentException; use PHPUnit\Event\Test\Finished; use PHPUnit\Event\Test\FinishedSubscriber; -use PHPUnit\Event\TestData\NoDataSetFromDataProviderException; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ @@ -61054,7 +65482,6 @@ final class TestFinishedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber imp { /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException */ public function notify(Finished $event) : void { @@ -61077,7 +65504,6 @@ namespace PHPUnit\Logging\JUnit; use PHPUnit\Event\InvalidArgumentException; use PHPUnit\Event\Test\MarkedIncomplete; use PHPUnit\Event\Test\MarkedIncompleteSubscriber; -use PHPUnit\Event\TestData\NoDataSetFromDataProviderException; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ @@ -61085,7 +65511,6 @@ final class TestMarkedIncompleteSubscriber extends \PHPUnit\Logging\JUnit\Subscr { /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException */ public function notify(MarkedIncomplete $event) : void { @@ -61105,10 +65530,67 @@ declare (strict_types=1); */ namespace PHPUnit\Logging\JUnit; +use PHPUnit\Event\InvalidArgumentException; +use PHPUnit\Event\Test\PreparationFailed; +use PHPUnit\Event\Test\PreparationFailedSubscriber; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestPreparationFailedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements PreparationFailedSubscriber +{ + /** + * @throws InvalidArgumentException + */ + public function notify(PreparationFailed $event) : void + { + $this->logger()->testPreparationFailed(); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Logging\JUnit; + +use PHPUnit\Event\InvalidArgumentException; +use PHPUnit\Event\Test\PreparationStarted; +use PHPUnit\Event\Test\PreparationStartedSubscriber; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestPreparationStartedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber implements PreparationStartedSubscriber +{ + /** + * @throws InvalidArgumentException + */ + public function notify(PreparationStarted $event) : void + { + $this->logger()->testPreparationStarted($event); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Logging\JUnit; + use PHPUnit\Event\InvalidArgumentException; use PHPUnit\Event\Test\Prepared; use PHPUnit\Event\Test\PreparedSubscriber; -use PHPUnit\Event\TestData\NoDataSetFromDataProviderException; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ @@ -61116,11 +65598,10 @@ final class TestPreparedSubscriber extends \PHPUnit\Logging\JUnit\Subscriber imp { /** * @throws InvalidArgumentException - * @throws NoDataSetFromDataProviderException */ public function notify(Prepared $event) : void { - $this->logger()->testPrepared($event); + $this->logger()->testPrepared(); } } printer = $printer; - $this->registerSubscribers(); + $this->registerSubscribers($facade); $this->setFlowId(); } public function testSuiteStarted(TestSuiteStarted $event) : void @@ -61599,9 +66078,6 @@ final class TeamCityLogger $this->isSummaryTestCountPrinted = \true; $this->writeMessage('testCount', ['count' => $testSuite->count()]); } - if ($testSuite->isWithName() && $testSuite->name() === '') { - return; - } $parameters = ['name' => $testSuite->name()]; if ($testSuite->isForTestClass()) { assert($testSuite instanceof TestSuiteForTestClass); @@ -61616,9 +66092,6 @@ final class TeamCityLogger public function testSuiteFinished(TestSuiteFinished $event) : void { $testSuite = $event->testSuite(); - if ($testSuite->isWithName() && $testSuite->name() === '') { - return; - } $parameters = ['name' => $testSuite->name()]; if ($testSuite->isForTestMethodWithDataProvider()) { assert($testSuite instanceof TestSuiteForTestMethodWithDataProvider); @@ -61632,7 +66105,7 @@ final class TeamCityLogger $parameters = ['name' => $test->name()]; if ($test->isTestMethod()) { assert($test instanceof TestMethod); - $parameters['locationHint'] = sprintf('php_qn://%s::\\%s::%s', $test->file(), $test->className(), $test->methodName()); + $parameters['locationHint'] = sprintf('php_qn://%s::\\%s::%s', $test->file(), $test->className(), $test->name()); } $this->writeMessage('testStarted', $parameters); $this->time = $event->telemetryInfo()->time(); @@ -61711,9 +66184,9 @@ final class TeamCityLogger * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ - private function registerSubscribers() : void + private function registerSubscribers(Facade $facade) : void { - Facade::registerSubscribers(new \PHPUnit\Logging\TeamCity\TestSuiteStartedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestSuiteFinishedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestPreparedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestFinishedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestErroredSubscriber($this), new \PHPUnit\Logging\TeamCity\TestFailedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestMarkedIncompleteSubscriber($this), new \PHPUnit\Logging\TeamCity\TestSkippedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestConsideredRiskySubscriber($this), new \PHPUnit\Logging\TeamCity\TestRunnerExecutionFinishedSubscriber($this)); + $facade->registerSubscribers(new \PHPUnit\Logging\TeamCity\TestSuiteStartedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestSuiteFinishedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestPreparedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestFinishedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestErroredSubscriber($this), new \PHPUnit\Logging\TeamCity\TestFailedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestMarkedIncompleteSubscriber($this), new \PHPUnit\Logging\TeamCity\TestSkippedSubscriber($this), new \PHPUnit\Logging\TeamCity\TestConsideredRiskySubscriber($this), new \PHPUnit\Logging\TeamCity\TestRunnerExecutionFinishedSubscriber($this)); } private function setFlowId() : void { @@ -61951,6 +66424,7 @@ use PHPUnit\Framework\TestCase; use PHPUnit\Metadata\Parser\Registry as MetadataRegistry; use PHPUnit\Metadata\TestDox; use PHPUnit\Util\Color; +use ReflectionEnum; use ReflectionMethod; use ReflectionObject; use PHPUnit\SebastianBergmann\Exporter\Exporter; @@ -62093,7 +66567,12 @@ final class NamePrettifier if (is_object($value)) { $reflector = new ReflectionObject($value); if ($reflector->isEnum()) { - $value = $value->value; + $enumReflector = new ReflectionEnum($value); + if ($enumReflector->isBacked()) { + $value = $value->value; + } else { + $value = $value->name; + } } elseif ($reflector->hasMethod('__toString')) { $value = (string) $value; } else { @@ -62102,6 +66581,9 @@ final class NamePrettifier } if (!is_scalar($value)) { $value = gettype($value); + if ($value === 'NULL') { + $value = 'null'; + } } if (is_bool($value) || is_int($value) || is_float($value)) { $value = (new Exporter())->export($value); @@ -62163,11 +66645,15 @@ final class PlainTextRenderer $result = []; foreach ($tests as $test) { $prettifiedMethodName = $test->test()->testDox()->prettifiedMethodName(); + $success = \true; + if ($test->status()->isError() || $test->status()->isFailure() || $test->status()->isIncomplete() || $test->status()->isSkipped()) { + $success = \false; + } if (!isset($result[$prettifiedMethodName])) { - $result[$prettifiedMethodName] = $test->status()->isSuccess() ? 'x' : ' '; + $result[$prettifiedMethodName] = $success ? 'x' : ' '; continue; } - if ($test->status()->isSuccess()) { + if ($success) { continue; } $result[$prettifiedMethodName] = ' '; @@ -62241,16 +66727,16 @@ declare (strict_types=1); */ namespace PHPUnit\Logging\TestDox; -use PHPUnit\Event\Test\MockObjectForAbstractClassCreated; -use PHPUnit\Event\Test\MockObjectForAbstractClassCreatedSubscriber; +use PHPUnit\Event\Test\Errored; +use PHPUnit\Event\Test\ErroredSubscriber; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ -final class TestCreatedMockObjectForAbstractClassSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements MockObjectForAbstractClassCreatedSubscriber +final class TestErroredSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements ErroredSubscriber { - public function notify(MockObjectForAbstractClassCreated $event) : void + public function notify(Errored $event) : void { - $this->collector()->testCreatedTestDouble($event); + $this->collector()->testErrored($event); } } collector()->testCreatedTestDouble($event); + $this->collector()->testFailed($event); } } collector()->testCreatedTestDouble($event); + $this->collector()->testFinished($event); } } collector()->testCreatedTestDouble($event); + $this->collector()->testMarkedIncomplete($event); } } collector()->testCreatedTestDouble($event); + $this->collector()->testPassed($event); } } collector()->testCreatedTestDouble($event); + $this->collector()->testPrepared($event); } } collector()->testCreatedTestDouble($event); + $this->collector()->testSkipped($event); } } collector()->testErrored($event); + $this->collector()->testTriggeredDeprecation($event); } } collector()->testFailed($event); + $this->collector()->testTriggeredNotice($event); } } collector()->testFinished($event); + $this->collector()->testTriggeredPhpDeprecation($event); } } collector()->testMarkedIncomplete($event); + $this->collector()->testTriggeredPhpNotice($event); } } collector()->testPassed($event); + $this->collector()->testTriggeredPhpWarning($event); } } collector()->testPrepared($event); + $this->collector()->testTriggeredPhpunitDeprecation($event); } } collector()->testSkipped($event); + $this->collector()->testTriggeredPhpunitError($event); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Logging\TestDox; + +use PHPUnit\Event\Test\PhpunitWarningTriggered; +use PHPUnit\Event\Test\PhpunitWarningTriggeredSubscriber; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestTriggeredPhpunitWarningSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements PhpunitWarningTriggeredSubscriber +{ + public function notify(PhpunitWarningTriggered $event) : void + { + $this->collector()->testTriggeredPhpunitWarning($event); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Logging\TestDox; + +use PHPUnit\Event\Test\WarningTriggered; +use PHPUnit\Event\Test\WarningTriggeredSubscriber; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestTriggeredWarningSubscriber extends \PHPUnit\Logging\TestDox\Subscriber implements WarningTriggeredSubscriber +{ + public function notify(WarningTriggered $event) : void + { + $this->collector()->testTriggeredWarning($event); } } - */ - private readonly array $testDoubles; - /** - * @psalm-param list $testDoubles - */ - public function __construct(TestMethod $test, Duration $duration, TestStatus $status, ?Throwable $throwable, array $testDoubles) + public function __construct(TestMethod $test, TestStatus $status, ?Throwable $throwable) { $this->test = $test; - $this->duration = $duration; $this->status = $status; $this->throwable = $throwable; - $this->testDoubles = $testDoubles; } public function test() : TestMethod { return $this->test; } - public function duration() : Duration - { - return $this->duration; - } public function status() : TestStatus { return $this->status; @@ -62648,13 +67169,6 @@ final class TestResult { return $this->throwable; } - /** - * @psalm-return list - */ - public function testDoubles() : array - { - return $this->testDoubles; - } } > */ private array $tests = []; - private ?HRTime $time = null; private ?TestStatus $status = null; private ?Throwable $throwable = null; - /** - * @psalm-var list - */ - private array $testDoubles = []; /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ - public function __construct() + public function __construct(Facade $facade) { - $this->registerSubscribers(); + $this->registerSubscribers($facade); } /** * @psalm-return array @@ -62828,8 +67344,42 @@ final class TestResultCollector { $result = []; foreach ($this->tests as $prettifiedClassName => $tests) { + $testsByDeclaringClass = []; + foreach ($tests as $test) { + $declaringClassName = (new ReflectionMethod($test->test()->className(), $test->test()->methodName()))->getDeclaringClass()->getName(); + if (!isset($testsByDeclaringClass[$declaringClassName])) { + $testsByDeclaringClass[$declaringClassName] = []; + } + $testsByDeclaringClass[$declaringClassName][] = $test; + } + foreach (array_keys($testsByDeclaringClass) as $declaringClassName) { + usort($testsByDeclaringClass[$declaringClassName], static function (TestDoxTestMethod $a, TestDoxTestMethod $b) : int { + return $a->test()->line() <=> $b->test()->line(); + }); + } + uksort( + $testsByDeclaringClass, + /** + * @psalm-param class-string $a + * @psalm-param class-string $b + */ + static function (string $a, string $b) : int { + if (is_subclass_of($b, $a)) { + return -1; + } + if (is_subclass_of($a, $b)) { + return 1; + } + return 0; + } + ); + $tests = []; + foreach ($testsByDeclaringClass as $_tests) { + $tests = array_merge($tests, $_tests); + } $result[$prettifiedClassName] = \PHPUnit\Logging\TestDox\TestResultCollection::fromArray($tests); } + ksort($result); return $result; } public function testPrepared(Prepared $event) : void @@ -62837,10 +67387,8 @@ final class TestResultCollector if (!$event->test()->isTestMethod()) { return; } - $this->time = $event->telemetryInfo()->time(); $this->status = TestStatus::unknown(); $this->throwable = null; - $this->testDoubles = []; } public function testErrored(Errored $event) : void { @@ -62863,32 +67411,92 @@ final class TestResultCollector if (!$event->test()->isTestMethod()) { return; } - $this->status = TestStatus::success(); + $this->updateTestStatus(TestStatus::success()); } public function testSkipped(Skipped $event) : void { - $this->status = TestStatus::skipped($event->message()); + if (!$event->test()->isTestMethod()) { + return; + } + $this->updateTestStatus(TestStatus::skipped($event->message())); } public function testMarkedIncomplete(MarkedIncomplete $event) : void { - $this->status = TestStatus::incomplete($event->throwable()->message()); + if (!$event->test()->isTestMethod()) { + return; + } + $this->updateTestStatus(TestStatus::incomplete($event->throwable()->message())); $this->throwable = $event->throwable(); } public function testConsideredRisky(ConsideredRisky $event) : void { - $this->status = TestStatus::risky($event->message()); + if (!$event->test()->isTestMethod()) { + return; + } + $this->updateTestStatus(TestStatus::risky()); + } + public function testTriggeredDeprecation(DeprecationTriggered $event) : void + { + if (!$event->test()->isTestMethod()) { + return; + } + $this->updateTestStatus(TestStatus::deprecation()); + } + public function testTriggeredNotice(NoticeTriggered $event) : void + { + if (!$event->test()->isTestMethod()) { + return; + } + $this->updateTestStatus(TestStatus::notice()); + } + public function testTriggeredWarning(WarningTriggered $event) : void + { + if (!$event->test()->isTestMethod()) { + return; + } + $this->updateTestStatus(TestStatus::warning()); + } + public function testTriggeredPhpDeprecation(PhpDeprecationTriggered $event) : void + { + if (!$event->test()->isTestMethod()) { + return; + } + $this->updateTestStatus(TestStatus::deprecation()); + } + public function testTriggeredPhpNotice(PhpNoticeTriggered $event) : void + { + if (!$event->test()->isTestMethod()) { + return; + } + $this->updateTestStatus(TestStatus::notice()); + } + public function testTriggeredPhpWarning(PhpWarningTriggered $event) : void + { + if (!$event->test()->isTestMethod()) { + return; + } + $this->updateTestStatus(TestStatus::warning()); + } + public function testTriggeredPhpunitDeprecation(PhpunitDeprecationTriggered $event) : void + { + if (!$event->test()->isTestMethod()) { + return; + } + $this->updateTestStatus(TestStatus::deprecation()); } - public function testCreatedTestDouble(MockObjectCreated|MockObjectForAbstractClassCreated|MockObjectForTraitCreated|MockObjectFromWsdlCreated|PartialMockObjectCreated|TestProxyCreated|TestStubCreated $event) : void + public function testTriggeredPhpunitError(PhpunitErrorTriggered $event) : void { - if ($event instanceof MockObjectForTraitCreated) { - $this->testDoubles[] = $event->traitName(); + if (!$event->test()->isTestMethod()) { return; } - if ($event instanceof MockObjectFromWsdlCreated) { - $this->testDoubles[] = SoapClient::class; + $this->updateTestStatus(TestStatus::error()); + } + public function testTriggeredPhpunitWarning(PhpunitWarningTriggered $event) : void + { + if (!$event->test()->isTestMethod()) { return; } - $this->testDoubles[] = $event->className(); + $this->updateTestStatus(TestStatus::warning()); } /** * @throws InvalidArgumentException @@ -62903,19 +67511,24 @@ final class TestResultCollector if (!isset($this->tests[$test->testDox()->prettifiedClassName()])) { $this->tests[$test->testDox()->prettifiedClassName()] = []; } - $this->tests[$test->testDox()->prettifiedClassName()][] = new TestDoxTestMethod($test, $event->telemetryInfo()->time()->duration($this->time), $this->status, $this->throwable, $this->testDoubles); - $this->time = null; + $this->tests[$test->testDox()->prettifiedClassName()][] = new TestDoxTestMethod($test, $this->status, $this->throwable); $this->status = null; $this->throwable = null; - $this->testDoubles = []; } /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ - private function registerSubscribers() : void + private function registerSubscribers(Facade $facade) : void + { + $facade->registerSubscribers(new \PHPUnit\Logging\TestDox\TestConsideredRiskySubscriber($this), new \PHPUnit\Logging\TestDox\TestErroredSubscriber($this), new \PHPUnit\Logging\TestDox\TestFailedSubscriber($this), new \PHPUnit\Logging\TestDox\TestFinishedSubscriber($this), new \PHPUnit\Logging\TestDox\TestMarkedIncompleteSubscriber($this), new \PHPUnit\Logging\TestDox\TestPassedSubscriber($this), new \PHPUnit\Logging\TestDox\TestPreparedSubscriber($this), new \PHPUnit\Logging\TestDox\TestSkippedSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredDeprecationSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredNoticeSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredPhpDeprecationSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredPhpNoticeSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredPhpunitDeprecationSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredPhpunitErrorSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredPhpunitWarningSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredPhpWarningSubscriber($this), new \PHPUnit\Logging\TestDox\TestTriggeredWarningSubscriber($this)); + } + private function updateTestStatus(TestStatus $status) : void { - Facade::registerSubscribers(new \PHPUnit\Logging\TestDox\TestConsideredRiskySubscriber($this), new \PHPUnit\Logging\TestDox\TestCreatedMockObjectForAbstractClassSubscriber($this), new \PHPUnit\Logging\TestDox\TestCreatedMockObjectForTraitSubscriber($this), new \PHPUnit\Logging\TestDox\TestCreatedMockObjectFromWsdlSubscriber($this), new \PHPUnit\Logging\TestDox\TestCreatedMockObjectSubscriber($this), new \PHPUnit\Logging\TestDox\TestCreatedPartialMockObjectSubscriber($this), new \PHPUnit\Logging\TestDox\TestCreatedTestProxySubscriber($this), new \PHPUnit\Logging\TestDox\TestCreatedTestStubSubscriber($this), new \PHPUnit\Logging\TestDox\TestErroredSubscriber($this), new \PHPUnit\Logging\TestDox\TestFailedSubscriber($this), new \PHPUnit\Logging\TestDox\TestFinishedSubscriber($this), new \PHPUnit\Logging\TestDox\TestMarkedIncompleteSubscriber($this), new \PHPUnit\Logging\TestDox\TestPassedSubscriber($this), new \PHPUnit\Logging\TestDox\TestPreparedSubscriber($this), new \PHPUnit\Logging\TestDox\TestSkippedSubscriber($this)); + if ($this->status !== null && $this->status->isMoreImportantThan($status)) { + return; + } + $this->status = $status; } } codeUnitsToSourceLines($codeUnits); } + /** + * @psalm-return array> + */ + public function linesToBeIgnored(TestSuite $testSuite) : array + { + $codeUnits = CodeUnitCollection::fromList(); + $mapper = new Mapper(); + foreach ($this->testCaseClassesIn($testSuite) as $testCaseClassName) { + $codeUnits = $codeUnits->mergeWith($this->codeUnitsIgnoredBy($testCaseClassName)); + } + return $mapper->codeUnitsToSourceLines($codeUnits); + } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName @@ -63130,6 +67768,37 @@ final class CodeCoverage } return \true; } + /** + * @psalm-return list + */ + private function testCaseClassesIn(TestSuite $testSuite) : array + { + $classNames = []; + foreach (new RecursiveIteratorIterator($testSuite) as $test) { + $classNames[] = $test::class; + } + return array_values(array_unique($classNames)); + } + /** + * @psalm-param class-string $className + */ + private function codeUnitsIgnoredBy(string $className) : CodeUnitCollection + { + $codeUnits = CodeUnitCollection::fromList(); + $mapper = new Mapper(); + foreach (Registry::parser()->forClass($className) as $metadata) { + if ($metadata instanceof IgnoreClassForCodeCoverage) { + $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits($metadata->className())); + } + if ($metadata instanceof IgnoreMethodForCodeCoverage) { + $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits($metadata->className() . '::' . $metadata->methodName())); + } + if ($metadata instanceof IgnoreFunctionForCodeCoverage) { + $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits('::' . $metadata->functionName())); + } + } + return $codeUnits; + } } className(), $_dataProvider->methodName()); + Event\Facade::emitter()->dataProviderMethodCalled($testMethod, $dataProviderMethod); + $methodsCalled[] = $dataProviderMethod; try { $class = new ReflectionClass($_dataProvider->className()); $method = $class->getMethod($_dataProvider->methodName()); @@ -63237,6 +67911,7 @@ final class DataProvider $data = $method->invoke($object, $_dataProvider->methodName()); } } catch (Throwable $e) { + Event\Facade::emitter()->dataProviderMethodFinished($testMethod, ...$methodsCalled); throw new InvalidDataProviderException($e->getMessage(), $e->getCode(), $e); } if ($data instanceof Traversable) { @@ -63246,6 +67921,7 @@ final class DataProvider if (is_int($key)) { $data[] = $value; } elseif (array_key_exists($key, $data)) { + Event\Facade::emitter()->dataProviderMethodFinished($testMethod, ...$methodsCalled); throw new InvalidDataProviderException(sprintf('The key "%s" has already been defined by a previous data provider', $key)); } else { $data[$key] = $value; @@ -63256,6 +67932,7 @@ final class DataProvider $result = array_merge($result, $data); } } + Event\Facade::emitter()->dataProviderMethodFinished($testMethod, ...$methodsCalled); return $result; } private function dataProvidedByMetadata(MetadataCollection $testWith) : array @@ -63279,13 +67956,13 @@ final class DataProvider return null; } $docComment = str_replace("\r\n", "\n", $docComment); - $docComment = preg_replace('/' . '\\n' . '\\s*' . '\\*' . '\\s?' . '/', "\n", $docComment); + $docComment = preg_replace('/\\n\\s*\\*\\s?/', "\n", $docComment); $docComment = substr($docComment, 0, -1); $docComment = rtrim($docComment, "\n"); if (!preg_match('/@testWith\\s+/', $docComment, $matches, \PREG_OFFSET_CAPTURE)) { return null; } - $offset = strlen($matches[0][0]) + $matches[0][1]; + $offset = strlen($matches[0][0]) + (int) $matches[0][1]; $annotationContent = substr($docComment, $offset); $data = []; foreach (explode("\n", $annotationContent) as $candidateRow) { @@ -63313,7 +67990,7 @@ final class DataProvider private function valueObjectForTestMethodWithoutTestData(string $className, string $methodName) : TestMethod { $location = Reflection::sourceLocationFor($className, $methodName); - return new TestMethod($className, $methodName, $location['file'], $location['line'], Event\Code\TestDoxBuilder::fromClassNameAndMethodName($className, $methodName), MetadataRegistry::parser()->for($className, $methodName), TestDataCollection::fromArray([])); + return new TestMethod($className, $methodName, $location['file'], $location['line'], Event\Code\TestDoxBuilder::fromClassNameAndMethodName($className, $methodName), MetadataRegistry::parser()->forClassAndMethod($className, $methodName), TestDataCollection::fromArray([])); } } methodsInTestClass(new ReflectionClass($className)) as $method) { + foreach (Reflection::methodsInTestClass(new ReflectionClass($className)) as $method) { $methodName = $method->getName(); assert(!empty($methodName)); $metadata = Registry::parser()->forMethod($className, $methodName); @@ -63662,11 +68339,17 @@ namespace PHPUnit\Metadata; final class BackupGlobals extends \PHPUnit\Metadata\Metadata { private readonly bool $enabled; + /** + * @psalm-param 0|1 $level + */ protected function __construct(int $level, bool $enabled) { parent::__construct($level); $this->enabled = $enabled; } + /** + * @psalm-assert-if-true BackupGlobals $this + */ public function isBackupGlobals() : bool { return \true; @@ -63697,11 +68380,17 @@ namespace PHPUnit\Metadata; final class BackupStaticProperties extends \PHPUnit\Metadata\Metadata { private readonly bool $enabled; + /** + * @psalm-param 0|1 $level + */ protected function __construct(int $level, bool $enabled) { parent::__construct($level); $this->enabled = $enabled; } + /** + * @psalm-assert-if-true BackupStaticProperties $this + */ public function isBackupStaticProperties() : bool { return \true; @@ -63731,6 +68420,9 @@ namespace PHPUnit\Metadata; */ final class Before extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-assert-if-true Before $this + */ public function isBefore() : bool { return \true; @@ -63756,6 +68448,9 @@ namespace PHPUnit\Metadata; */ final class BeforeClass extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-assert-if-true BeforeClass $this + */ public function isBeforeClass() : bool { return \true; @@ -63781,16 +68476,29 @@ namespace PHPUnit\Metadata; */ final class Covers extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-var non-empty-string + */ private readonly string $target; + /** + * @psalm-param 0|1 $level + * @psalm-param non-empty-string $target + */ protected function __construct(int $level, string $target) { parent::__construct($level); $this->target = $target; } + /** + * @psalm-assert-if-true Covers $this + */ public function isCovers() : bool { return \true; } + /** + * @psalm-return non-empty-string + */ public function target() : string { return $this->target; @@ -63821,6 +68529,7 @@ final class CoversClass extends \PHPUnit\Metadata\Metadata */ private readonly string $className; /** + * @psalm-param 0|1 $level * @psalm-param class-string $className */ protected function __construct(int $level, string $className) @@ -63828,6 +68537,9 @@ final class CoversClass extends \PHPUnit\Metadata\Metadata parent::__construct($level); $this->className = $className; } + /** + * @psalm-assert-if-true CoversClass $this + */ public function isCoversClass() : bool { return \true; @@ -63874,6 +68586,7 @@ final class CoversDefaultClass extends \PHPUnit\Metadata\Metadata */ private readonly string $className; /** + * @psalm-param 0|1 $level * @psalm-param class-string $className */ protected function __construct(int $level, string $className) @@ -63881,6 +68594,9 @@ final class CoversDefaultClass extends \PHPUnit\Metadata\Metadata parent::__construct($level); $this->className = $className; } + /** + * @psalm-assert-if-true CoversDefaultClass $this + */ public function isCoversDefaultClass() : bool { return \true; @@ -63913,16 +68629,29 @@ namespace PHPUnit\Metadata; */ final class CoversFunction extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-var non-empty-string + */ private readonly string $functionName; + /** + * @psalm-param 0|1 $level + * @psalm-param non-empty-string $functionName + */ protected function __construct(int $level, string $functionName) { parent::__construct($level); $this->functionName = $functionName; } + /** + * @psalm-assert-if-true CoversFunction $this + */ public function isCoversFunction() : bool { return \true; } + /** + * @psalm-return non-empty-string + */ public function functionName() : string { return $this->functionName; @@ -63955,6 +68684,9 @@ namespace PHPUnit\Metadata; */ final class CoversNothing extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-assert-if-true CoversNothing $this + */ public function isCoversNothing() : bool { return \true; @@ -63984,9 +68716,14 @@ final class DataProvider extends \PHPUnit\Metadata\Metadata * @psalm-var class-string */ private readonly string $className; + /** + * @psalm-var non-empty-string + */ private readonly string $methodName; /** + * @psalm-param 0|1 $level * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName */ protected function __construct(int $level, string $className, string $methodName) { @@ -63994,6 +68731,9 @@ final class DataProvider extends \PHPUnit\Metadata\Metadata $this->className = $className; $this->methodName = $methodName; } + /** + * @psalm-assert-if-true DataProvider $this + */ public function isDataProvider() : bool { return \true; @@ -64005,6 +68745,9 @@ final class DataProvider extends \PHPUnit\Metadata\Metadata { return $this->className; } + /** + * @psalm-return non-empty-string + */ public function methodName() : string { return $this->methodName; @@ -64037,6 +68780,7 @@ final class DependsOnClass extends \PHPUnit\Metadata\Metadata private readonly bool $deepClone; private readonly bool $shallowClone; /** + * @psalm-param 0|1 $level * @psalm-param class-string $className */ protected function __construct(int $level, string $className, bool $deepClone, bool $shallowClone) @@ -64046,6 +68790,9 @@ final class DependsOnClass extends \PHPUnit\Metadata\Metadata $this->deepClone = $deepClone; $this->shallowClone = $shallowClone; } + /** + * @psalm-assert-if-true DependsOnClass $this + */ public function isDependsOnClass() : bool { return \true; @@ -64090,11 +68837,16 @@ final class DependsOnMethod extends \PHPUnit\Metadata\Metadata * @psalm-var class-string */ private readonly string $className; + /** + * @psalm-var non-empty-string + */ private readonly string $methodName; private readonly bool $deepClone; private readonly bool $shallowClone; /** + * @psalm-param 0|1 $level * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName */ protected function __construct(int $level, string $className, string $methodName, bool $deepClone, bool $shallowClone) { @@ -64104,6 +68856,9 @@ final class DependsOnMethod extends \PHPUnit\Metadata\Metadata $this->deepClone = $deepClone; $this->shallowClone = $shallowClone; } + /** + * @psalm-assert-if-true DependsOnMethod $this + */ public function isDependsOnMethod() : bool { return \true; @@ -64115,6 +68870,9 @@ final class DependsOnMethod extends \PHPUnit\Metadata\Metadata { return $this->className; } + /** + * @psalm-return non-empty-string + */ public function methodName() : string { return $this->methodName; @@ -64148,6 +68906,9 @@ namespace PHPUnit\Metadata; */ final class DoesNotPerformAssertions extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-assert-if-true DoesNotPerformAssertions $this + */ public function isDoesNotPerformAssertions() : bool { return \true; @@ -64271,16 +69032,29 @@ namespace PHPUnit\Metadata; */ final class ExcludeGlobalVariableFromBackup extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-var non-empty-string + */ private readonly string $globalVariableName; + /** + * @psalm-param 0|1 $level + * @psalm-param non-empty-string $globalVariableName + */ protected function __construct(int $level, string $globalVariableName) { parent::__construct($level); $this->globalVariableName = $globalVariableName; } + /** + * @psalm-assert-if-true ExcludeGlobalVariableFromBackup $this + */ public function isExcludeGlobalVariableFromBackup() : bool { return \true; } + /** + * @psalm-return non-empty-string + */ public function globalVariableName() : string { return $this->globalVariableName; @@ -64310,9 +69084,14 @@ final class ExcludeStaticPropertyFromBackup extends \PHPUnit\Metadata\Metadata * @psalm-var class-string */ private readonly string $className; + /** + * @psalm-var non-empty-string + */ private readonly string $propertyName; /** + * @psalm-param 0|1 $level * @psalm-param class-string $className + * @psalm-param non-empty-string $propertyName */ protected function __construct(int $level, string $className, string $propertyName) { @@ -64320,6 +69099,9 @@ final class ExcludeStaticPropertyFromBackup extends \PHPUnit\Metadata\Metadata $this->className = $className; $this->propertyName = $propertyName; } + /** + * @psalm-assert-if-true ExcludeStaticPropertyFromBackup $this + */ public function isExcludeStaticPropertyFromBackup() : bool { return \true; @@ -64331,6 +69113,9 @@ final class ExcludeStaticPropertyFromBackup extends \PHPUnit\Metadata\Metadata { return $this->className; } + /** + * @psalm-return non-empty-string + */ public function propertyName() : string { return $this->propertyName; @@ -64356,16 +69141,29 @@ namespace PHPUnit\Metadata; */ final class Group extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-var non-empty-string + */ private readonly string $groupName; + /** + * @psalm-param 0|1 $level + * @psalm-param non-empty-string $groupName + */ protected function __construct(int $level, string $groupName) { parent::__construct($level); $this->groupName = $groupName; } + /** + * @psalm-assert-if-true Group $this + */ public function isGroup() : bool { return \true; } + /** + * @psalm-return non-empty-string + */ public function groupName() : string { return $this->groupName; @@ -64384,6 +69182,197 @@ declare (strict_types=1); */ namespace PHPUnit\Metadata; +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513 + */ +final class IgnoreClassForCodeCoverage extends \PHPUnit\Metadata\Metadata +{ + /** + * @psalm-var class-string + */ + private readonly string $className; + /** + * @psalm-param 0|1 $level + * @psalm-param class-string $className + */ + protected function __construct(int $level, string $className) + { + parent::__construct($level); + $this->className = $className; + } + /** + * @psalm-assert-if-true IgnoreClassForCodeCoverage $this + */ + public function isIgnoreClassForCodeCoverage() : bool + { + return \true; + } + /** + * @psalm-return class-string + */ + public function className() : string + { + return $this->className; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Metadata; + +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +final class IgnoreDeprecations extends \PHPUnit\Metadata\Metadata +{ + /** + * @psalm-assert-if-true IgnoreDeprecations $this + */ + public function isIgnoreDeprecations() : bool + { + return \true; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Metadata; + +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513 + */ +final class IgnoreFunctionForCodeCoverage extends \PHPUnit\Metadata\Metadata +{ + /** + * @psalm-var non-empty-string + */ + private readonly string $functionName; + /** + * @psalm-param 0|1 $level + * @psalm-param non-empty-string $functionName + */ + protected function __construct(int $level, string $functionName) + { + parent::__construct($level); + $this->functionName = $functionName; + } + /** + * @psalm-assert-if-true IgnoreFunctionForCodeCoverage $this + */ + public function isIgnoreFunctionForCodeCoverage() : bool + { + return \true; + } + /** + * @psalm-return non-empty-string + */ + public function functionName() : string + { + return $this->functionName; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Metadata; + +/** + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513 + */ +final class IgnoreMethodForCodeCoverage extends \PHPUnit\Metadata\Metadata +{ + /** + * @psalm-var class-string + */ + private readonly string $className; + /** + * @psalm-var non-empty-string + */ + private readonly string $methodName; + /** + * @psalm-param 0|1 $level + * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName + */ + protected function __construct(int $level, string $className, string $methodName) + { + parent::__construct($level); + $this->className = $className; + $this->methodName = $methodName; + } + /** + * @psalm-assert-if-true IgnoreMethodForCodeCoverage $this + */ + public function isIgnoreMethodForCodeCoverage() : bool + { + return \true; + } + /** + * @psalm-return class-string + */ + public function className() : string + { + return $this->className; + } + /** + * @psalm-return non-empty-string + */ + public function methodName() : string + { + return $this->methodName; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Metadata; + use PHPUnit\Metadata\Version\Requirement; /** * @psalm-immutable @@ -64394,6 +69383,9 @@ abstract class Metadata { private const CLASS_LEVEL = 0; private const METHOD_LEVEL = 1; + /** + * @psalm-var 0|1 + */ private readonly int $level; public static function after() : \PHPUnit\Metadata\After { @@ -64434,14 +69426,23 @@ abstract class Metadata { return new \PHPUnit\Metadata\CoversClass(self::CLASS_LEVEL, $className); } + /** + * @psalm-param non-empty-string $functionName + */ public static function coversFunction(string $functionName) : \PHPUnit\Metadata\CoversFunction { return new \PHPUnit\Metadata\CoversFunction(self::CLASS_LEVEL, $functionName); } + /** + * @psalm-param non-empty-string $target + */ public static function coversOnClass(string $target) : \PHPUnit\Metadata\Covers { return new \PHPUnit\Metadata\Covers(self::CLASS_LEVEL, $target); } + /** + * @psalm-param non-empty-string $target + */ public static function coversOnMethod(string $target) : \PHPUnit\Metadata\Covers { return new \PHPUnit\Metadata\Covers(self::METHOD_LEVEL, $target); @@ -64463,15 +69464,23 @@ abstract class Metadata } /** * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName */ public static function dataProvider(string $className, string $methodName) : \PHPUnit\Metadata\DataProvider { return new \PHPUnit\Metadata\DataProvider(self::METHOD_LEVEL, $className, $methodName); } + /** + * @psalm-param class-string $className + */ public static function dependsOnClass(string $className, bool $deepClone, bool $shallowClone) : \PHPUnit\Metadata\DependsOnClass { return new \PHPUnit\Metadata\DependsOnClass(self::METHOD_LEVEL, $className, $deepClone, $shallowClone); } + /** + * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName + */ public static function dependsOnMethod(string $className, string $methodName, bool $deepClone, bool $shallowClone) : \PHPUnit\Metadata\DependsOnMethod { return new \PHPUnit\Metadata\DependsOnMethod(self::METHOD_LEVEL, $className, $methodName, $deepClone, $shallowClone); @@ -64484,16 +69493,23 @@ abstract class Metadata { return new \PHPUnit\Metadata\DoesNotPerformAssertions(self::METHOD_LEVEL); } + /** + * @psalm-param non-empty-string $globalVariableName + */ public static function excludeGlobalVariableFromBackupOnClass(string $globalVariableName) : \PHPUnit\Metadata\ExcludeGlobalVariableFromBackup { return new \PHPUnit\Metadata\ExcludeGlobalVariableFromBackup(self::CLASS_LEVEL, $globalVariableName); } + /** + * @psalm-param non-empty-string $globalVariableName + */ public static function excludeGlobalVariableFromBackupOnMethod(string $globalVariableName) : \PHPUnit\Metadata\ExcludeGlobalVariableFromBackup { return new \PHPUnit\Metadata\ExcludeGlobalVariableFromBackup(self::METHOD_LEVEL, $globalVariableName); } /** * @psalm-param class-string $className + * @psalm-param non-empty-string $propertyName */ public static function excludeStaticPropertyFromBackupOnClass(string $className, string $propertyName) : \PHPUnit\Metadata\ExcludeStaticPropertyFromBackup { @@ -64501,19 +69517,56 @@ abstract class Metadata } /** * @psalm-param class-string $className + * @psalm-param non-empty-string $propertyName */ public static function excludeStaticPropertyFromBackupOnMethod(string $className, string $propertyName) : \PHPUnit\Metadata\ExcludeStaticPropertyFromBackup { return new \PHPUnit\Metadata\ExcludeStaticPropertyFromBackup(self::METHOD_LEVEL, $className, $propertyName); } + /** + * @psalm-param non-empty-string $groupName + */ public static function groupOnClass(string $groupName) : \PHPUnit\Metadata\Group { return new \PHPUnit\Metadata\Group(self::CLASS_LEVEL, $groupName); } + /** + * @psalm-param non-empty-string $groupName + */ public static function groupOnMethod(string $groupName) : \PHPUnit\Metadata\Group { return new \PHPUnit\Metadata\Group(self::METHOD_LEVEL, $groupName); } + public static function ignoreDeprecationsOnClass() : \PHPUnit\Metadata\IgnoreDeprecations + { + return new \PHPUnit\Metadata\IgnoreDeprecations(self::CLASS_LEVEL); + } + public static function ignoreDeprecationsOnMethod() : \PHPUnit\Metadata\IgnoreDeprecations + { + return new \PHPUnit\Metadata\IgnoreDeprecations(self::METHOD_LEVEL); + } + /** + * @psalm-param class-string $className + */ + public static function ignoreClassForCodeCoverage(string $className) : \PHPUnit\Metadata\IgnoreClassForCodeCoverage + { + return new \PHPUnit\Metadata\IgnoreClassForCodeCoverage(self::CLASS_LEVEL, $className); + } + /** + * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName + */ + public static function ignoreMethodForCodeCoverage(string $className, string $methodName) : \PHPUnit\Metadata\IgnoreMethodForCodeCoverage + { + return new \PHPUnit\Metadata\IgnoreMethodForCodeCoverage(self::CLASS_LEVEL, $className, $methodName); + } + /** + * @psalm-param non-empty-string $functionName + */ + public static function ignoreFunctionForCodeCoverage(string $functionName) : \PHPUnit\Metadata\IgnoreFunctionForCodeCoverage + { + return new \PHPUnit\Metadata\IgnoreFunctionForCodeCoverage(self::CLASS_LEVEL, $functionName); + } public static function postCondition() : \PHPUnit\Metadata\PostCondition { return new \PHPUnit\Metadata\PostCondition(self::METHOD_LEVEL); @@ -64530,16 +69583,23 @@ abstract class Metadata { return new \PHPUnit\Metadata\PreserveGlobalState(self::METHOD_LEVEL, $enabled); } + /** + * @psalm-param non-empty-string $functionName + */ public static function requiresFunctionOnClass(string $functionName) : \PHPUnit\Metadata\RequiresFunction { return new \PHPUnit\Metadata\RequiresFunction(self::CLASS_LEVEL, $functionName); } + /** + * @psalm-param non-empty-string $functionName + */ public static function requiresFunctionOnMethod(string $functionName) : \PHPUnit\Metadata\RequiresFunction { return new \PHPUnit\Metadata\RequiresFunction(self::METHOD_LEVEL, $functionName); } /** * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName */ public static function requiresMethodOnClass(string $className, string $methodName) : \PHPUnit\Metadata\RequiresMethod { @@ -64547,23 +69607,36 @@ abstract class Metadata } /** * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName */ public static function requiresMethodOnMethod(string $className, string $methodName) : \PHPUnit\Metadata\RequiresMethod { return new \PHPUnit\Metadata\RequiresMethod(self::METHOD_LEVEL, $className, $methodName); } + /** + * @psalm-param non-empty-string $operatingSystem + */ public static function requiresOperatingSystemOnClass(string $operatingSystem) : \PHPUnit\Metadata\RequiresOperatingSystem { return new \PHPUnit\Metadata\RequiresOperatingSystem(self::CLASS_LEVEL, $operatingSystem); } + /** + * @psalm-param non-empty-string $operatingSystem + */ public static function requiresOperatingSystemOnMethod(string $operatingSystem) : \PHPUnit\Metadata\RequiresOperatingSystem { return new \PHPUnit\Metadata\RequiresOperatingSystem(self::METHOD_LEVEL, $operatingSystem); } + /** + * @psalm-param non-empty-string $operatingSystemFamily + */ public static function requiresOperatingSystemFamilyOnClass(string $operatingSystemFamily) : \PHPUnit\Metadata\RequiresOperatingSystemFamily { return new \PHPUnit\Metadata\RequiresOperatingSystemFamily(self::CLASS_LEVEL, $operatingSystemFamily); } + /** + * @psalm-param non-empty-string $operatingSystemFamily + */ public static function requiresOperatingSystemFamilyOnMethod(string $operatingSystemFamily) : \PHPUnit\Metadata\RequiresOperatingSystemFamily { return new \PHPUnit\Metadata\RequiresOperatingSystemFamily(self::METHOD_LEVEL, $operatingSystemFamily); @@ -64576,10 +69649,16 @@ abstract class Metadata { return new \PHPUnit\Metadata\RequiresPhp(self::METHOD_LEVEL, $versionRequirement); } + /** + * @psalm-param non-empty-string $extension + */ public static function requiresPhpExtensionOnClass(string $extension, ?Requirement $versionRequirement) : \PHPUnit\Metadata\RequiresPhpExtension { return new \PHPUnit\Metadata\RequiresPhpExtension(self::CLASS_LEVEL, $extension, $versionRequirement); } + /** + * @psalm-param non-empty-string $extension + */ public static function requiresPhpExtensionOnMethod(string $extension, ?Requirement $versionRequirement) : \PHPUnit\Metadata\RequiresPhpExtension { return new \PHPUnit\Metadata\RequiresPhpExtension(self::METHOD_LEVEL, $extension, $versionRequirement); @@ -64592,10 +69671,18 @@ abstract class Metadata { return new \PHPUnit\Metadata\RequiresPhpunit(self::METHOD_LEVEL, $versionRequirement); } + /** + * @psalm-param non-empty-string $setting + * @psalm-param non-empty-string $value + */ public static function requiresSettingOnClass(string $setting, string $value) : \PHPUnit\Metadata\RequiresSetting { return new \PHPUnit\Metadata\RequiresSetting(self::CLASS_LEVEL, $setting, $value); } + /** + * @psalm-param non-empty-string $setting + * @psalm-param non-empty-string $value + */ public static function requiresSettingOnMethod(string $setting, string $value) : \PHPUnit\Metadata\RequiresSetting { return new \PHPUnit\Metadata\RequiresSetting(self::METHOD_LEVEL, $setting, $value); @@ -64616,10 +69703,16 @@ abstract class Metadata { return new \PHPUnit\Metadata\Test(self::METHOD_LEVEL); } + /** + * @psalm-param non-empty-string $text + */ public static function testDoxOnClass(string $text) : \PHPUnit\Metadata\TestDox { return new \PHPUnit\Metadata\TestDox(self::CLASS_LEVEL, $text); } + /** + * @psalm-param non-empty-string $text + */ public static function testDoxOnMethod(string $text) : \PHPUnit\Metadata\TestDox { return new \PHPUnit\Metadata\TestDox(self::METHOD_LEVEL, $text); @@ -64635,14 +69728,23 @@ abstract class Metadata { return new \PHPUnit\Metadata\UsesClass(self::CLASS_LEVEL, $className); } + /** + * @psalm-param non-empty-string $functionName + */ public static function usesFunction(string $functionName) : \PHPUnit\Metadata\UsesFunction { return new \PHPUnit\Metadata\UsesFunction(self::CLASS_LEVEL, $functionName); } + /** + * @psalm-param non-empty-string $target + */ public static function usesOnClass(string $target) : \PHPUnit\Metadata\Uses { return new \PHPUnit\Metadata\Uses(self::CLASS_LEVEL, $target); } + /** + * @psalm-param non-empty-string $target + */ public static function usesOnMethod(string $target) : \PHPUnit\Metadata\Uses { return new \PHPUnit\Metadata\Uses(self::METHOD_LEVEL, $target); @@ -64654,6 +69756,13 @@ abstract class Metadata { return new \PHPUnit\Metadata\UsesDefaultClass(self::CLASS_LEVEL, $className); } + public static function withoutErrorHandler() : \PHPUnit\Metadata\WithoutErrorHandler + { + return new \PHPUnit\Metadata\WithoutErrorHandler(self::METHOD_LEVEL); + } + /** + * @psalm-param 0|1 $level + */ protected function __construct(int $level) { $this->level = $level; @@ -64771,10 +69880,16 @@ abstract class Metadata { return \false; } + /** + * @psalm-assert-if-true ExcludeGlobalVariableFromBackup $this + */ public function isExcludeGlobalVariableFromBackup() : bool { return \false; } + /** + * @psalm-assert-if-true ExcludeStaticPropertyFromBackup $this + */ public function isExcludeStaticPropertyFromBackup() : bool { return \false; @@ -64786,6 +69901,34 @@ abstract class Metadata { return \false; } + /** + * @psalm-assert-if-true IgnoreDeprecations $this + */ + public function isIgnoreDeprecations() : bool + { + return \false; + } + /** + * @psalm-assert-if-true IgnoreClassForCodeCoverage $this + */ + public function isIgnoreClassForCodeCoverage() : bool + { + return \false; + } + /** + * @psalm-assert-if-true IgnoreMethodForCodeCoverage $this + */ + public function isIgnoreMethodForCodeCoverage() : bool + { + return \false; + } + /** + * @psalm-assert-if-true IgnoreFunctionForCodeCoverage $this + */ + public function isIgnoreFunctionForCodeCoverage() : bool + { + return \false; + } /** * @psalm-assert-if-true RunClassInSeparateProcess $this */ @@ -64933,6 +70076,13 @@ abstract class Metadata { return \false; } + /** + * @psalm-assert-if-true WithoutErrorHandler $this + */ + public function isWithoutErrorHandler() : bool + { + return \false; + } } metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isGroup())); } + public function isIgnoreDeprecations() : self + { + return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isIgnoreDeprecations())); + } + /** + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513 + */ + public function isIgnoreClassForCodeCoverage() : self + { + return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isIgnoreClassForCodeCoverage())); + } + /** + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513 + */ + public function isIgnoreMethodForCodeCoverage() : self + { + return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isIgnoreMethodForCodeCoverage())); + } + /** + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513 + */ + public function isIgnoreFunctionForCodeCoverage() : self + { + return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isIgnoreFunctionForCodeCoverage())); + } public function isRunClassInSeparateProcess() : self { return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isRunClassInSeparateProcess())); @@ -65171,6 +70346,10 @@ final class MetadataCollection implements Countable, IteratorAggregate { return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isUsesFunction())); } + public function isWithoutErrorHandler() : self + { + return new self(...array_filter($this->metadata, static fn(\PHPUnit\Metadata\Metadata $metadata): bool => $metadata->isWithoutErrorHandler())); + } } className()); + break; + case IgnoreDeprecations::class: + assert($attributeInstance instanceof IgnoreDeprecations); + $result[] = Metadata::ignoreDeprecationsOnClass(); + break; + case IgnoreMethodForCodeCoverage::class: + assert($attributeInstance instanceof IgnoreMethodForCodeCoverage); + $result[] = Metadata::ignoreMethodForCodeCoverage($attributeInstance->className(), $attributeInstance->methodName()); + break; + case IgnoreFunctionForCodeCoverage::class: + assert($attributeInstance instanceof IgnoreFunctionForCodeCoverage); + $result[] = Metadata::ignoreFunctionForCodeCoverage($attributeInstance->functionName()); + break; case PreserveGlobalState::class: assert($attributeInstance instanceof PreserveGlobalState); $result[] = Metadata::preserveGlobalStateOnClass($attributeInstance->enabled()); @@ -66171,6 +71376,10 @@ final class AttributeParser implements \PHPUnit\Metadata\Parser\Parser assert($attributeInstance instanceof Group); $result[] = Metadata::groupOnMethod($attributeInstance->name()); break; + case IgnoreDeprecations::class: + assert($attributeInstance instanceof IgnoreDeprecations); + $result[] = Metadata::ignoreDeprecationsOnMethod(); + break; case PostCondition::class: $result[] = Metadata::postCondition(); break; @@ -66240,6 +71449,10 @@ final class AttributeParser implements \PHPUnit\Metadata\Parser\Parser assert($attributeInstance instanceof Ticket); $result[] = Metadata::groupOnMethod($attributeInstance->text()); break; + case WithoutErrorHandler::class: + assert($attributeInstance instanceof WithoutErrorHandler); + $result[] = Metadata::withoutErrorHandler(); + break; } } return MetadataCollection::fromArray($result); @@ -66266,8 +71479,6 @@ declare (strict_types=1); */ namespace PHPUnit\Metadata\Parser; -use function class_exists; -use function method_exists; use PHPUnit\Metadata\MetadataCollection; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit @@ -66319,20 +71530,6 @@ final class CachingParser implements \PHPUnit\Metadata\Parser\Parser $this->classAndMethodCache[$key] = $this->forClass($className)->mergeWith($this->forMethod($className, $methodName)); return $this->classAndMethodCache[$key]; } - /** - * @psalm-param class-string $className - * @psalm-param non-empty-string $methodName - */ - public function for(string $className, string $methodName) : MetadataCollection - { - if (!class_exists($className)) { - return MetadataCollection::fromArray([]); - } - if (method_exists($className, $methodName)) { - return $this->forClassAndMethod($className, $methodName); - } - return $this->forClass($className); - } } enabled = $enabled; } + /** + * @psalm-assert-if-true PreserveGlobalState $this + */ public function isPreserveGlobalState() : bool { return \true; @@ -66565,16 +71774,29 @@ namespace PHPUnit\Metadata; */ final class RequiresFunction extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-var non-empty-string + */ private readonly string $functionName; + /** + * @psalm-param 0|1 $level + * @psalm-param non-empty-string $functionName + */ protected function __construct(int $level, string $functionName) { parent::__construct($level); $this->functionName = $functionName; } + /** + * @psalm-assert-if-true RequiresFunction $this + */ public function isRequiresFunction() : bool { return \true; } + /** + * @psalm-return non-empty-string + */ public function functionName() : string { return $this->functionName; @@ -66604,9 +71826,14 @@ final class RequiresMethod extends \PHPUnit\Metadata\Metadata * @psalm-var class-string */ private readonly string $className; + /** + * @psalm-var non-empty-string + */ private readonly string $methodName; /** + * @psalm-param 0|1 $level * @psalm-param class-string $className + * @psalm-param non-empty-string $methodName */ protected function __construct(int $level, string $className, string $methodName) { @@ -66614,7 +71841,10 @@ final class RequiresMethod extends \PHPUnit\Metadata\Metadata $this->className = $className; $this->methodName = $methodName; } - public function isrequiresMethod() : bool + /** + * @psalm-assert-if-true RequiresMethod $this + */ + public function isRequiresMethod() : bool { return \true; } @@ -66625,6 +71855,9 @@ final class RequiresMethod extends \PHPUnit\Metadata\Metadata { return $this->className; } + /** + * @psalm-return non-empty-string + */ public function methodName() : string { return $this->methodName; @@ -66650,16 +71883,29 @@ namespace PHPUnit\Metadata; */ final class RequiresOperatingSystem extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-var non-empty-string + */ private readonly string $operatingSystem; + /** + * @psalm-param 0|1 $level + * @psalm-param non-empty-string $operatingSystem + */ public function __construct(int $level, string $operatingSystem) { parent::__construct($level); $this->operatingSystem = $operatingSystem; } + /** + * @psalm-assert-if-true RequiresOperatingSystem $this + */ public function isRequiresOperatingSystem() : bool { return \true; } + /** + * @psalm-return non-empty-string + */ public function operatingSystem() : string { return $this->operatingSystem; @@ -66685,16 +71931,29 @@ namespace PHPUnit\Metadata; */ final class RequiresOperatingSystemFamily extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-var non-empty-string + */ private readonly string $operatingSystemFamily; + /** + * @psalm-param 0|1 $level + * @psalm-param non-empty-string $operatingSystemFamily + */ protected function __construct(int $level, string $operatingSystemFamily) { parent::__construct($level); $this->operatingSystemFamily = $operatingSystemFamily; } + /** + * @psalm-assert-if-true RequiresOperatingSystemFamily $this + */ public function isRequiresOperatingSystemFamily() : bool { return \true; } + /** + * @psalm-return non-empty-string + */ public function operatingSystemFamily() : string { return $this->operatingSystemFamily; @@ -66722,11 +71981,17 @@ use PHPUnit\Metadata\Version\Requirement; final class RequiresPhp extends \PHPUnit\Metadata\Metadata { private readonly Requirement $versionRequirement; + /** + * @psalm-param 0|1 $level + */ protected function __construct(int $level, Requirement $versionRequirement) { parent::__construct($level); $this->versionRequirement = $versionRequirement; } + /** + * @psalm-assert-if-true RequiresPhp $this + */ public function isRequiresPhp() : bool { return \true; @@ -66757,18 +72022,31 @@ use PHPUnit\Metadata\Version\Requirement; */ final class RequiresPhpExtension extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-var non-empty-string + */ private readonly string $extension; private readonly ?Requirement $versionRequirement; + /** + * @psalm-param 0|1 $level + * @psalm-param non-empty-string $extension + */ protected function __construct(int $level, string $extension, ?Requirement $versionRequirement) { parent::__construct($level); $this->extension = $extension; $this->versionRequirement = $versionRequirement; } + /** + * @psalm-assert-if-true RequiresPhpExtension $this + */ public function isRequiresPhpExtension() : bool { return \true; } + /** + * @psalm-return non-empty-string + */ public function extension() : string { return $this->extension; @@ -66813,11 +72091,17 @@ use PHPUnit\Metadata\Version\Requirement; final class RequiresPhpunit extends \PHPUnit\Metadata\Metadata { private readonly Requirement $versionRequirement; + /** + * @psalm-param 0|1 $level + */ protected function __construct(int $level, Requirement $versionRequirement) { parent::__construct($level); $this->versionRequirement = $versionRequirement; } + /** + * @psalm-assert-if-true RequiresPhpunit $this + */ public function isRequiresPhpunit() : bool { return \true; @@ -66847,22 +72131,42 @@ namespace PHPUnit\Metadata; */ final class RequiresSetting extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-var non-empty-string + */ private readonly string $setting; + /** + * @psalm-var non-empty-string + */ private readonly string $value; + /** + * @psalm-param 0|1 $level + * @psalm-param non-empty-string $setting + * @psalm-param non-empty-string $value + */ protected function __construct(int $level, string $setting, string $value) { parent::__construct($level); $this->setting = $setting; $this->value = $value; } + /** + * @psalm-assert-if-true RequiresSetting $this + */ public function isRequiresSetting() : bool { return \true; } + /** + * @psalm-return non-empty-string + */ public function setting() : string { return $this->setting; } + /** + * @psalm-return non-empty-string + */ public function value() : string { return $this->value; @@ -66888,6 +72192,9 @@ namespace PHPUnit\Metadata; */ final class RunClassInSeparateProcess extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-assert-if-true RunClassInSeparateProcess $this + */ public function isRunClassInSeparateProcess() : bool { return \true; @@ -66913,6 +72220,9 @@ namespace PHPUnit\Metadata; */ final class RunInSeparateProcess extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-assert-if-true RunInSeparateProcess $this + */ public function isRunInSeparateProcess() : bool { return \true; @@ -66938,6 +72248,9 @@ namespace PHPUnit\Metadata; */ final class RunTestsInSeparateProcesses extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-assert-if-true RunTestsInSeparateProcesses $this + */ public function isRunTestsInSeparateProcesses() : bool { return \true; @@ -66963,6 +72276,9 @@ namespace PHPUnit\Metadata; */ final class Test extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-assert-if-true Test $this + */ public function isTest() : bool { return \true; @@ -66988,16 +72304,29 @@ namespace PHPUnit\Metadata; */ final class TestDox extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-var non-empty-string + */ private readonly string $text; + /** + * @psalm-param 0|1 $level + * @psalm-param non-empty-string $text + */ protected function __construct(int $level, string $text) { parent::__construct($level); $this->text = $text; } + /** + * @psalm-assert-if-true TestDox $this + */ public function isTestDox() : bool { return \true; } + /** + * @psalm-return non-empty-string + */ public function text() : string { return $this->text; @@ -67024,11 +72353,17 @@ namespace PHPUnit\Metadata; final class TestWith extends \PHPUnit\Metadata\Metadata { private readonly array $data; + /** + * @psalm-param 0|1 $level + */ protected function __construct(int $level, array $data) { parent::__construct($level); $this->data = $data; } + /** + * @psalm-assert-if-true TestWith $this + */ public function isTestWith() : bool { return \true; @@ -67058,16 +72393,29 @@ namespace PHPUnit\Metadata; */ final class Uses extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-var non-empty-string + */ private readonly string $target; + /** + * @psalm-param 0|1 $level + * @psalm-param non-empty-string $target + */ protected function __construct(int $level, string $target) { parent::__construct($level); $this->target = $target; } + /** + * @psalm-assert-if-true Uses $this + */ public function isUses() : bool { return \true; } + /** + * @psalm-return non-empty-string + */ public function target() : string { return $this->target; @@ -67098,6 +72446,7 @@ final class UsesClass extends \PHPUnit\Metadata\Metadata */ private readonly string $className; /** + * @psalm-param 0|1 $level * @psalm-param class-string $className */ protected function __construct(int $level, string $className) @@ -67105,6 +72454,9 @@ final class UsesClass extends \PHPUnit\Metadata\Metadata parent::__construct($level); $this->className = $className; } + /** + * @psalm-assert-if-true UsesClass $this + */ public function isUsesClass() : bool { return \true; @@ -67151,6 +72503,7 @@ final class UsesDefaultClass extends \PHPUnit\Metadata\Metadata */ private readonly string $className; /** + * @psalm-param 0|1 $level * @psalm-param class-string $className */ protected function __construct(int $level, string $className) @@ -67158,6 +72511,9 @@ final class UsesDefaultClass extends \PHPUnit\Metadata\Metadata parent::__construct($level); $this->className = $className; } + /** + * @psalm-assert-if-true UsesDefaultClass $this + */ public function isUsesDefaultClass() : bool { return \true; @@ -67190,16 +72546,29 @@ namespace PHPUnit\Metadata; */ final class UsesFunction extends \PHPUnit\Metadata\Metadata { + /** + * @psalm-var non-empty-string + */ private readonly string $functionName; + /** + * @psalm-param 0|1 $level + * @psalm-param non-empty-string $functionName + */ public function __construct(int $level, string $functionName) { parent::__construct($level); $this->functionName = $functionName; } + /** + * @psalm-assert-if-true UsesFunction $this + */ public function isUsesFunction() : bool { return \true; } + /** + * @psalm-return non-empty-string + */ public function functionName() : string { return $this->functionName; @@ -67353,278 +72722,74 @@ declare (strict_types=1); * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -namespace PHPUnit\Runner; +namespace PHPUnit\Metadata; -use function file_put_contents; -use function sprintf; -use PHPUnit\Event\Facade as EventFacade; -use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException; -use PHPUnit\Event\TestData\NoDataSetFromDataProviderException; -use PHPUnit\Framework\TestCase; -use PHPUnit\TextUI\Configuration\CodeCoverageFilterRegistry; -use PHPUnit\TextUI\Configuration\Configuration; -use PHPUnit\TextUI\Output\Printer; -use PHPUnit\SebastianBergmann\CodeCoverage\Driver\Driver; -use PHPUnit\SebastianBergmann\CodeCoverage\Driver\Selector; -use PHPUnit\SebastianBergmann\CodeCoverage\Exception as CodeCoverageException; -use PHPUnit\SebastianBergmann\CodeCoverage\Filter; -use PHPUnit\SebastianBergmann\CodeCoverage\Report\Clover as CloverReport; -use PHPUnit\SebastianBergmann\CodeCoverage\Report\Cobertura as CoberturaReport; -use PHPUnit\SebastianBergmann\CodeCoverage\Report\Crap4j as Crap4jReport; -use PHPUnit\SebastianBergmann\CodeCoverage\Report\Html\Colors; -use PHPUnit\SebastianBergmann\CodeCoverage\Report\Html\CustomCssFile; -use PHPUnit\SebastianBergmann\CodeCoverage\Report\Html\Facade as HtmlReport; -use PHPUnit\SebastianBergmann\CodeCoverage\Report\PHP as PhpReport; -use PHPUnit\SebastianBergmann\CodeCoverage\Report\Text as TextReport; -use PHPUnit\SebastianBergmann\CodeCoverage\Report\Thresholds; -use PHPUnit\SebastianBergmann\CodeCoverage\Report\Xml\Facade as XmlReport; -use PHPUnit\SebastianBergmann\CodeCoverage\Test\TestSize\TestSize; -use PHPUnit\SebastianBergmann\CodeCoverage\Test\TestStatus\TestStatus; -use PHPUnit\SebastianBergmann\Comparator\Comparator; -use PHPUnit\SebastianBergmann\Timer\NoActiveTimerException; -use PHPUnit\SebastianBergmann\Timer\Timer; /** - * @internal This class is not covered by the backward compatibility promise for PHPUnit + * @psalm-immutable + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ -final class CodeCoverage +final class WithoutErrorHandler extends \PHPUnit\Metadata\Metadata { - private static ?self $instance = null; - private ?\PHPUnit\SebastianBergmann\CodeCoverage\CodeCoverage $codeCoverage = null; - private ?Driver $driver = null; - private bool $collecting = \false; - private ?TestCase $test = null; - private ?Timer $timer = null; - public static function instance() : self - { - if (self::$instance === null) { - self::$instance = new self(); - } - return self::$instance; - } - public function init(Configuration $configuration, CodeCoverageFilterRegistry $codeCoverageFilterRegistry) : void - { - $codeCoverageFilterRegistry->init($configuration); - if (!$configuration->hasCoverageReport()) { - return; - } - $this->activate($codeCoverageFilterRegistry->get(), $configuration->pathCoverage()); - if (!$this->isActive()) { - return; - } - if ($configuration->hasCoverageCacheDirectory()) { - $this->codeCoverage()->cacheStaticAnalysis($configuration->coverageCacheDirectory()); - } - $this->codeCoverage()->excludeSubclassesOfThisClassFromUnintentionallyCoveredCodeCheck(Comparator::class); - if ($configuration->strictCoverage()) { - $this->codeCoverage()->enableCheckForUnintentionallyCoveredCode(); - } - if ($configuration->ignoreDeprecatedCodeUnitsFromCodeCoverage()) { - $this->codeCoverage()->ignoreDeprecatedCode(); - } else { - $this->codeCoverage()->doNotIgnoreDeprecatedCode(); - } - if ($configuration->disableCodeCoverageIgnore()) { - $this->codeCoverage()->disableAnnotationsForIgnoringCode(); - } else { - $this->codeCoverage()->enableAnnotationsForIgnoringCode(); - } - if ($configuration->includeUncoveredFiles()) { - $this->codeCoverage()->includeUncoveredFiles(); - } else { - $this->codeCoverage()->excludeUncoveredFiles(); - } - if ($codeCoverageFilterRegistry->get()->isEmpty()) { - if (!$codeCoverageFilterRegistry->configured()) { - EventFacade::emitter()->testRunnerTriggeredWarning('No filter is configured, code coverage will not be processed'); - } else { - EventFacade::emitter()->testRunnerTriggeredWarning('Incorrect filter configuration, code coverage will not be processed'); - } - $this->deactivate(); - } - } /** - * @psalm-assert-if-true !null $this->instance + * @psalm-assert-if-true WithoutErrorHandler $this */ - public function isActive() : bool - { - return $this->codeCoverage !== null; - } - public function codeCoverage() : \PHPUnit\SebastianBergmann\CodeCoverage\CodeCoverage - { - return $this->codeCoverage; - } - public function driver() : Driver + public function isWithoutErrorHandler() : bool { - return $this->driver; + return \true; } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\Baseline; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Baseline +{ + public const VERSION = 1; /** - * @throws MoreThanOneDataSetFromDataProviderException - * @throws NoDataSetFromDataProviderException + * @psalm-var array>> */ - public function start(TestCase $test) : void - { - if ($this->collecting) { - return; - } - $size = TestSize::unknown(); - if ($test->size()->isSmall()) { - $size = TestSize::small(); - } elseif ($test->size()->isMedium()) { - $size = TestSize::medium(); - } elseif ($test->size()->isLarge()) { - $size = TestSize::large(); - } - $this->test = $test; - $this->codeCoverage->start($test->valueObjectForEvents()->id(), $size); - $this->collecting = \true; - } - public function stop(bool $append = \true, array|false $linesToBeCovered = [], array $linesToBeUsed = []) : void + private array $issues = []; + public function add(\PHPUnit\Runner\Baseline\Issue $issue) : void { - if (!$this->collecting) { - return; + if (!isset($this->issues[$issue->file()])) { + $this->issues[$issue->file()] = []; } - $status = TestStatus::unknown(); - if ($this->test !== null) { - if ($this->test->status()->isSuccess()) { - $status = TestStatus::success(); - } else { - $status = TestStatus::failure(); - } + if (!isset($this->issues[$issue->file()][$issue->line()])) { + $this->issues[$issue->file()][$issue->line()] = []; } - /* @noinspection UnusedFunctionResultInspection */ - $this->codeCoverage->stop($append, $status, $linesToBeCovered, $linesToBeUsed); - $this->test = null; - $this->collecting = \false; - } - public function deactivate() : void - { - $this->driver = null; - $this->codeCoverage = null; - $this->test = null; + $this->issues[$issue->file()][$issue->line()][] = $issue; } - public function generateReports(Printer $printer, Configuration $configuration) : void + public function has(\PHPUnit\Runner\Baseline\Issue $issue) : bool { - if (!$this->isActive()) { - return; - } - if ($configuration->hasCoverageClover()) { - $this->codeCoverageGenerationStart($printer, 'Clover XML'); - try { - $writer = new CloverReport(); - $writer->process($this->codeCoverage(), $configuration->coverageClover()); - $this->codeCoverageGenerationSucceeded($printer); - unset($writer); - } catch (CodeCoverageException $e) { - $this->codeCoverageGenerationFailed($printer, $e); - } - } - if ($configuration->hasCoverageCobertura()) { - $this->codeCoverageGenerationStart($printer, 'Cobertura XML'); - try { - $writer = new CoberturaReport(); - $writer->process($this->codeCoverage(), $configuration->coverageCobertura()); - $this->codeCoverageGenerationSucceeded($printer); - unset($writer); - } catch (CodeCoverageException $e) { - $this->codeCoverageGenerationFailed($printer, $e); - } - } - if ($configuration->hasCoverageCrap4j()) { - $this->codeCoverageGenerationStart($printer, 'Crap4J XML'); - try { - $writer = new Crap4jReport($configuration->coverageCrap4jThreshold()); - $writer->process($this->codeCoverage(), $configuration->coverageCrap4j()); - $this->codeCoverageGenerationSucceeded($printer); - unset($writer); - } catch (CodeCoverageException $e) { - $this->codeCoverageGenerationFailed($printer, $e); - } - } - if ($configuration->hasCoverageHtml()) { - $this->codeCoverageGenerationStart($printer, 'HTML'); - try { - $customCssFile = CustomCssFile::default(); - if ($configuration->hasCoverageHtmlCustomCssFile()) { - $customCssFile = CustomCssFile::from($configuration->coverageHtmlCustomCssFile()); - } - $writer = new HtmlReport(sprintf(' and PHPUnit %s', \PHPUnit\Runner\Version::id()), Colors::from($configuration->coverageHtmlColorSuccessLow(), $configuration->coverageHtmlColorSuccessMedium(), $configuration->coverageHtmlColorSuccessHigh(), $configuration->coverageHtmlColorWarning(), $configuration->coverageHtmlColorDanger()), Thresholds::from($configuration->coverageHtmlLowUpperBound(), $configuration->coverageHtmlHighLowerBound()), $customCssFile); - $writer->process($this->codeCoverage(), $configuration->coverageHtml()); - $this->codeCoverageGenerationSucceeded($printer); - unset($writer); - } catch (CodeCoverageException $e) { - $this->codeCoverageGenerationFailed($printer, $e); - } - } - if ($configuration->hasCoveragePhp()) { - $this->codeCoverageGenerationStart($printer, 'PHP'); - try { - $writer = new PhpReport(); - $writer->process($this->codeCoverage(), $configuration->coveragePhp()); - $this->codeCoverageGenerationSucceeded($printer); - unset($writer); - } catch (CodeCoverageException $e) { - $this->codeCoverageGenerationFailed($printer, $e); - } - } - if ($configuration->hasCoverageText()) { - $processor = new TextReport(Thresholds::default(), $configuration->coverageTextShowUncoveredFiles(), $configuration->coverageTextShowOnlySummary()); - $textReport = $processor->process($this->codeCoverage(), $configuration->colors()); - if ($configuration->coverageText() === 'php://stdout') { - $printer->print($textReport); - } else { - file_put_contents($configuration->coverageText(), $textReport); - } - } - if ($configuration->hasCoverageXml()) { - $this->codeCoverageGenerationStart($printer, 'PHPUnit XML'); - try { - $writer = new XmlReport(\PHPUnit\Runner\Version::id()); - $writer->process($this->codeCoverage(), $configuration->coverageXml()); - $this->codeCoverageGenerationSucceeded($printer); - unset($writer); - } catch (CodeCoverageException $e) { - $this->codeCoverageGenerationFailed($printer, $e); - } + if (!isset($this->issues[$issue->file()][$issue->line()])) { + return \false; } - } - private function activate(Filter $filter, bool $pathCoverage) : void - { - try { - if ($pathCoverage) { - $this->driver = (new Selector())->forLineAndPathCoverage($filter); - } else { - $this->driver = (new Selector())->forLineCoverage($filter); + foreach ($this->issues[$issue->file()][$issue->line()] as $_issue) { + if ($_issue->equals($issue)) { + return \true; } - $this->codeCoverage = new \PHPUnit\SebastianBergmann\CodeCoverage\CodeCoverage($this->driver, $filter); - } catch (CodeCoverageException $e) { - EventFacade::emitter()->testRunnerTriggeredWarning($e->getMessage()); } - } - private function codeCoverageGenerationStart(Printer $printer, string $format) : void - { - $printer->print(sprintf("\nGenerating code coverage report in %s format ... ", $format)); - $this->timer()->start(); - } - /** - * @throws NoActiveTimerException - */ - private function codeCoverageGenerationSucceeded(Printer $printer) : void - { - $printer->print(sprintf("done [%s]\n", $this->timer()->stop()->asString())); + return \false; } /** - * @throws NoActiveTimerException + * @psalm-return array>> */ - private function codeCoverageGenerationFailed(Printer $printer, CodeCoverageException $e) : void - { - $printer->print(sprintf("failed [%s]\n%s\n", $this->timer()->stop()->asString(), $e->getMessage())); - } - private function timer() : Timer + public function groupedByFileAndLine() : array { - if ($this->timer === null) { - $this->timer = new Timer(); - } - return $this->timer; + return $this->issues; } } getMessage()), $previous->getCode(), $previous); + parent::__construct(sprintf('File "%s" does not have line %d', $file, $line)); } } registerSubscribers(new \PHPUnit\Runner\Baseline\TestTriggeredDeprecationSubscriber($this), new \PHPUnit\Runner\Baseline\TestTriggeredNoticeSubscriber($this), new \PHPUnit\Runner\Baseline\TestTriggeredPhpDeprecationSubscriber($this), new \PHPUnit\Runner\Baseline\TestTriggeredPhpNoticeSubscriber($this), new \PHPUnit\Runner\Baseline\TestTriggeredPhpWarningSubscriber($this), new \PHPUnit\Runner\Baseline\TestTriggeredWarningSubscriber($this)); + $this->baseline = new \PHPUnit\Runner\Baseline\Baseline(); + $this->source = $source; + } + public function baseline() : \PHPUnit\Runner\Baseline\Baseline + { + return $this->baseline; + } + /** + * @throws FileDoesNotExistException + * @throws FileDoesNotHaveLineException + */ + public function testTriggeredIssue(DeprecationTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpWarningTriggered|WarningTriggered $event) : void + { + if (!$this->source->ignoreSuppressionOfPhpWarnings() && $event->wasSuppressed()) { + return; + } + if ($this->source->restrictWarnings() && !(new SourceFilter())->includes($this->source, $event->file())) { + return; + } + $this->baseline->add(\PHPUnit\Runner\Baseline\Issue::from($event->file(), $event->line(), null, $event->message())); } } file = $file; + $this->line = $line; + $this->hash = $hash; + $this->description = $description; + } + /** + * @psalm-return non-empty-string + */ + public function file() : string + { + return $this->file; + } + /** + * @psalm-return positive-int + */ + public function line() : int { - parent::__construct(sprintf('Class "%s" does not implement interface %s', $className, Extension::class)); + return $this->line; + } + /** + * @psalm-return non-empty-string + */ + public function hash() : string + { + return $this->hash; + } + /** + * @psalm-return non-empty-string + */ + public function description() : string + { + return $this->description; + } + public function equals(self $other) : bool + { + return $this->file() === $other->file() && $this->line() === $other->line() && $this->hash() === $other->hash() && $this->description() === $other->description(); + } + /** + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + * + * @psalm-return non-empty-string + * + * @throws FileDoesNotExistException + * @throws FileDoesNotHaveLineException + */ + private static function calculateHash(string $file, int $line) : string + { + if (!is_file($file)) { + throw new FileDoesNotExistException($file); + } + $lines = file($file, \FILE_IGNORE_NEW_LINES); + $key = $line - 1; + if (!isset($lines[$key])) { + throw new \PHPUnit\Runner\Baseline\FileDoesNotHaveLineException($file, $line); + } + $hash = sha1($lines[$key]); + assert(!empty($hash)); + return $hash; } } loadFile($baselineFile); + } catch (XmlException $e) { + throw new \PHPUnit\Runner\Baseline\CannotLoadBaselineException(sprintf('Cannot read baseline: %s', trim($e->getMessage()))); + } + $version = (int) $document->documentElement->getAttribute('version'); + if ($version !== \PHPUnit\Runner\Baseline\Baseline::VERSION) { + throw new \PHPUnit\Runner\Baseline\CannotLoadBaselineException(sprintf('Cannot read baseline %s, version %d is not supported', $baselineFile, $version)); + } + $baseline = new \PHPUnit\Runner\Baseline\Baseline(); + $baselineDirectory = dirname(realpath($baselineFile)); + $xpath = new DOMXPath($document); + foreach ($xpath->query('file') as $fileElement) { + assert($fileElement instanceof DOMElement); + $file = $baselineDirectory . \DIRECTORY_SEPARATOR . str_replace('/', \DIRECTORY_SEPARATOR, $fileElement->getAttribute('path')); + foreach ($xpath->query('line', $fileElement) as $lineElement) { + assert($lineElement instanceof DOMElement); + $line = (int) $lineElement->getAttribute('number'); + $hash = $lineElement->getAttribute('hash'); + foreach ($xpath->query('issue', $lineElement) as $issueElement) { + assert($issueElement instanceof DOMElement); + $description = $issueElement->textContent; + assert(!empty($file)); + assert($line > 0); + assert(!empty($hash)); + assert(!empty($description)); + $baseline->add(\PHPUnit\Runner\Baseline\Issue::from($file, $line, $hash, $description)); + } + } + } + return $baseline; } } baselineDirectory = $baselineDirectory; + } + /** + * @psalm-param non-empty-string $filename + * + * @psalm-return non-empty-string + */ + public function calculate(string $filename) : string + { + $result = implode('/', $this->parts($filename)); + assert($result !== ''); + return $result; + } + /** + * @psalm-param non-empty-string $filename + * + * @psalm-return list + */ + public function parts(string $filename) : array + { + $schemePosition = strpos($filename, '://'); + if ($schemePosition !== \false) { + $filename = substr($filename, $schemePosition + 3); + assert($filename !== ''); + } + $parentParts = explode('/', trim(str_replace('\\', '/', $this->baselineDirectory), '/')); + $parentPartsCount = count($parentParts); + $filenameParts = explode('/', trim(str_replace('\\', '/', $filename), '/')); + $filenamePartsCount = count($filenameParts); + $i = 0; + for (; $i < $filenamePartsCount; $i++) { + if ($parentPartsCount < $i + 1) { + break; + } + $parentPath = implode('/', array_slice($parentParts, 0, $i + 1)); + $filenamePath = implode('/', array_slice($filenameParts, 0, $i + 1)); + if ($parentPath !== $filenamePath) { + break; + } + } + if ($i === 0) { + return [$filename]; + } + $dotsCount = $parentPartsCount - $i; + assert($dotsCount >= 0); + return array_merge(array_fill(0, $dotsCount, '..'), array_slice($filenameParts, $i)); } } generator = $generator; + } + protected function generator() : \PHPUnit\Runner\Baseline\Generator + { + return $this->generator; + } } generator()->testTriggeredIssue($event); } } generator()->testTriggeredIssue($event); + } } generator()->testTriggeredIssue($event); + } } generator()->testTriggeredIssue($event); + } } generator()->testTriggeredIssue($event); } } generator()->testTriggeredIssue($event); } } openMemory(); + $writer->setIndent(\true); + $writer->startDocument(); + $writer->startElement('files'); + $writer->writeAttribute('version', (string) \PHPUnit\Runner\Baseline\Baseline::VERSION); + foreach ($baseline->groupedByFileAndLine() as $file => $lines) { + assert(!empty($file)); + $writer->startElement('file'); + $writer->writeAttribute('path', $pathCalculator->calculate($file)); + foreach ($lines as $line => $issues) { + $writer->startElement('line'); + $writer->writeAttribute('number', (string) $line); + $writer->writeAttribute('hash', $issues[0]->hash()); + foreach ($issues as $issue) { + $writer->startElement('issue'); + $writer->writeCData($issue->description()); + $writer->endElement(); + } + $writer->endElement(); + } + $writer->endElement(); + } + $writer->endElement(); + file_put_contents($baselineFile, $writer->outputMemory()); + } } > + */ + private array $linesToBeIgnored = []; + public static function instance() : self { - parent::__construct(sprintf('PHPUnit does not support PHPT %s sections', $section)); + if (self::$instance === null) { + self::$instance = new self(); + } + return self::$instance; + } + public function init(Configuration $configuration, CodeCoverageFilterRegistry $codeCoverageFilterRegistry, bool $extensionRequiresCodeCoverageCollection) : void + { + $codeCoverageFilterRegistry->init($configuration); + if (!$configuration->hasCoverageReport() && !$extensionRequiresCodeCoverageCollection) { + return; + } + $this->activate($codeCoverageFilterRegistry->get(), $configuration->pathCoverage()); + if (!$this->isActive()) { + return; + } + if ($configuration->hasCoverageCacheDirectory()) { + $this->codeCoverage()->cacheStaticAnalysis($configuration->coverageCacheDirectory()); + } + $this->codeCoverage()->excludeSubclassesOfThisClassFromUnintentionallyCoveredCodeCheck(Comparator::class); + if ($configuration->strictCoverage()) { + $this->codeCoverage()->enableCheckForUnintentionallyCoveredCode(); + } + if ($configuration->ignoreDeprecatedCodeUnitsFromCodeCoverage()) { + $this->codeCoverage()->ignoreDeprecatedCode(); + } else { + $this->codeCoverage()->doNotIgnoreDeprecatedCode(); + } + if ($configuration->disableCodeCoverageIgnore()) { + $this->codeCoverage()->disableAnnotationsForIgnoringCode(); + } else { + $this->codeCoverage()->enableAnnotationsForIgnoringCode(); + } + if ($configuration->includeUncoveredFiles()) { + $this->codeCoverage()->includeUncoveredFiles(); + } else { + $this->codeCoverage()->excludeUncoveredFiles(); + } + if ($codeCoverageFilterRegistry->get()->isEmpty()) { + if (!$codeCoverageFilterRegistry->configured()) { + EventFacade::emitter()->testRunnerTriggeredWarning('No filter is configured, code coverage will not be processed'); + } else { + EventFacade::emitter()->testRunnerTriggeredWarning('Incorrect filter configuration, code coverage will not be processed'); + } + $this->deactivate(); + } + } + /** + * @psalm-assert-if-true !null $this->instance + */ + public function isActive() : bool + { + return $this->codeCoverage !== null; + } + public function codeCoverage() : \PHPUnit\SebastianBergmann\CodeCoverage\CodeCoverage + { + return $this->codeCoverage; + } + public function driver() : Driver + { + return $this->driver; + } + /** + * @throws MoreThanOneDataSetFromDataProviderException + */ + public function start(TestCase $test) : void + { + if ($this->collecting) { + return; + } + $size = TestSize::unknown(); + if ($test->size()->isSmall()) { + $size = TestSize::small(); + } elseif ($test->size()->isMedium()) { + $size = TestSize::medium(); + } elseif ($test->size()->isLarge()) { + $size = TestSize::large(); + } + $this->test = $test; + $this->codeCoverage->start($test->valueObjectForEvents()->id(), $size); + $this->collecting = \true; + } + public function stop(bool $append = \true, array|false $linesToBeCovered = [], array $linesToBeUsed = []) : void + { + if (!$this->collecting) { + return; + } + $status = TestStatus::unknown(); + if ($this->test !== null) { + if ($this->test->status()->isSuccess()) { + $status = TestStatus::success(); + } else { + $status = TestStatus::failure(); + } + } + /* @noinspection UnusedFunctionResultInspection */ + $this->codeCoverage->stop($append, $status, $linesToBeCovered, $linesToBeUsed, $this->linesToBeIgnored); + $this->test = null; + $this->collecting = \false; + } + public function deactivate() : void + { + $this->driver = null; + $this->codeCoverage = null; + $this->test = null; + } + public function generateReports(Printer $printer, Configuration $configuration) : void + { + if (!$this->isActive()) { + return; + } + if ($configuration->hasCoveragePhp()) { + $this->codeCoverageGenerationStart($printer, 'PHP'); + try { + $writer = new PhpReport(); + $writer->process($this->codeCoverage(), $configuration->coveragePhp()); + $this->codeCoverageGenerationSucceeded($printer); + unset($writer); + } catch (CodeCoverageException $e) { + $this->codeCoverageGenerationFailed($printer, $e); + } + } + if ($configuration->hasCoverageClover()) { + $this->codeCoverageGenerationStart($printer, 'Clover XML'); + try { + $writer = new CloverReport(); + $writer->process($this->codeCoverage(), $configuration->coverageClover()); + $this->codeCoverageGenerationSucceeded($printer); + unset($writer); + } catch (CodeCoverageException $e) { + $this->codeCoverageGenerationFailed($printer, $e); + } + } + if ($configuration->hasCoverageCobertura()) { + $this->codeCoverageGenerationStart($printer, 'Cobertura XML'); + try { + $writer = new CoberturaReport(); + $writer->process($this->codeCoverage(), $configuration->coverageCobertura()); + $this->codeCoverageGenerationSucceeded($printer); + unset($writer); + } catch (CodeCoverageException $e) { + $this->codeCoverageGenerationFailed($printer, $e); + } + } + if ($configuration->hasCoverageCrap4j()) { + $this->codeCoverageGenerationStart($printer, 'Crap4J XML'); + try { + $writer = new Crap4jReport($configuration->coverageCrap4jThreshold()); + $writer->process($this->codeCoverage(), $configuration->coverageCrap4j()); + $this->codeCoverageGenerationSucceeded($printer); + unset($writer); + } catch (CodeCoverageException $e) { + $this->codeCoverageGenerationFailed($printer, $e); + } + } + if ($configuration->hasCoverageHtml()) { + $this->codeCoverageGenerationStart($printer, 'HTML'); + try { + $customCssFile = CustomCssFile::default(); + if ($configuration->hasCoverageHtmlCustomCssFile()) { + $customCssFile = CustomCssFile::from($configuration->coverageHtmlCustomCssFile()); + } + $writer = new HtmlReport(sprintf(' and PHPUnit %s', \PHPUnit\Runner\Version::id()), Colors::from($configuration->coverageHtmlColorSuccessLow(), $configuration->coverageHtmlColorSuccessMedium(), $configuration->coverageHtmlColorSuccessHigh(), $configuration->coverageHtmlColorWarning(), $configuration->coverageHtmlColorDanger()), Thresholds::from($configuration->coverageHtmlLowUpperBound(), $configuration->coverageHtmlHighLowerBound()), $customCssFile); + $writer->process($this->codeCoverage(), $configuration->coverageHtml()); + $this->codeCoverageGenerationSucceeded($printer); + unset($writer); + } catch (CodeCoverageException $e) { + $this->codeCoverageGenerationFailed($printer, $e); + } + } + if ($configuration->hasCoverageText()) { + $processor = new TextReport(Thresholds::default(), $configuration->coverageTextShowUncoveredFiles(), $configuration->coverageTextShowOnlySummary()); + $textReport = $processor->process($this->codeCoverage(), $configuration->colors()); + if ($configuration->coverageText() === 'php://stdout') { + $printer->print($textReport); + } else { + file_put_contents($configuration->coverageText(), $textReport); + } + } + if ($configuration->hasCoverageXml()) { + $this->codeCoverageGenerationStart($printer, 'PHPUnit XML'); + try { + $writer = new XmlReport(\PHPUnit\Runner\Version::id()); + $writer->process($this->codeCoverage(), $configuration->coverageXml()); + $this->codeCoverageGenerationSucceeded($printer); + unset($writer); + } catch (CodeCoverageException $e) { + $this->codeCoverageGenerationFailed($printer, $e); + } + } + } + /** + * @psalm-param array> $linesToBeIgnored + */ + public function ignoreLines(array $linesToBeIgnored) : void + { + $this->linesToBeIgnored = $linesToBeIgnored; + } + /** + * @psalm-return array> + */ + public function linesToBeIgnored() : array + { + return $this->linesToBeIgnored; + } + private function activate(Filter $filter, bool $pathCoverage) : void + { + try { + if ($pathCoverage) { + $this->driver = (new Selector())->forLineAndPathCoverage($filter); + } else { + $this->driver = (new Selector())->forLineCoverage($filter); + } + $this->codeCoverage = new \PHPUnit\SebastianBergmann\CodeCoverage\CodeCoverage($this->driver, $filter); + } catch (CodeCoverageException $e) { + EventFacade::emitter()->testRunnerTriggeredWarning($e->getMessage()); + } + } + private function codeCoverageGenerationStart(Printer $printer, string $format) : void + { + $printer->print(sprintf("\nGenerating code coverage report in %s format ... ", $format)); + $this->timer()->start(); + } + /** + * @throws NoActiveTimerException + */ + private function codeCoverageGenerationSucceeded(Printer $printer) : void + { + $printer->print(sprintf("done [%s]\n", $this->timer()->stop()->asString())); + } + /** + * @throws NoActiveTimerException + */ + private function codeCoverageGenerationFailed(Printer $printer, CodeCoverageException $e) : void + { + $printer->print(sprintf("failed [%s]\n%s\n", $this->timer()->stop()->asString(), $e->getMessage())); + } + private function timer() : Timer + { + if ($this->timer === null) { + $this->timer = new Timer(); + } + return $this->timer; } } isExcluded($errorFile)) { + return \false; + } + $test = Event\Code\TestMethodBuilder::fromCallStack(); + $ignoredByBaseline = $this->ignoredByBaseline($errorFile, $errorLine, $errorString); + $ignoredByTest = $test->metadata()->isIgnoreDeprecations()->isNotEmpty(); + switch ($errorNumber) { + case E_NOTICE: + case E_STRICT: + Event\Facade::emitter()->testTriggeredPhpNotice($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline); + break; + case E_USER_NOTICE: + Event\Facade::emitter()->testTriggeredNotice($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline); + break; + case E_WARNING: + Event\Facade::emitter()->testTriggeredPhpWarning($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline); + break; + case E_USER_WARNING: + Event\Facade::emitter()->testTriggeredWarning($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline); + break; + case E_DEPRECATED: + Event\Facade::emitter()->testTriggeredPhpDeprecation($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline, $ignoredByTest); + break; + case E_USER_DEPRECATED: + Event\Facade::emitter()->testTriggeredDeprecation($test, $errorString, $errorFile, $errorLine, $suppressed, $ignoredByBaseline, $ignoredByTest); + break; + case E_USER_ERROR: + Event\Facade::emitter()->testTriggeredError($test, $errorString, $errorFile, $errorLine, $suppressed); + throw new \PHPUnit\Runner\ErrorException('E_USER_ERROR was triggered'); + default: + return \false; + } + return \false; + } + public function enable() : void + { + if ($this->enabled) { + return; + } + set_error_handler($this); + $this->enabled = \true; + $this->originalErrorReportingLevel = error_reporting(); + error_reporting($this->originalErrorReportingLevel & self::UNHANDLEABLE_LEVELS); + } + public function disable() : void + { + if (!$this->enabled) { + return; + } + restore_error_handler(); + error_reporting(error_reporting() | $this->originalErrorReportingLevel); + $this->enabled = \false; + $this->originalErrorReportingLevel = null; + } + public function use(Baseline $baseline) : void + { + $this->baseline = $baseline; + } + /** + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + * @psalm-param non-empty-string $description + */ + private function ignoredByBaseline(string $file, int $line, string $description) : bool + { + if ($this->baseline === null) { + return \false; + } + return $this->baseline->has(Issue::from($file, $line, null, $description)); + } } configuration = $configuration; - $this->facade = $facade; - } - /** - * @psalm-param class-string $className - * @psalm-param array $parameters - * - * @throws Exception - */ - public function bootstrap(string $className, array $parameters) : void + public function __construct(string $className, string $file) { - if (!class_exists($className)) { - throw new ClassDoesNotExistException($className); - } - if (!in_array(\PHPUnit\Runner\Extension\Extension::class, class_implements($className), \true)) { - throw new ClassDoesNotImplementExtensionInterfaceException($className); - } - try { - $instance = (new ReflectionClass($className))->newInstance(); - } catch (ReflectionException $e) { - throw new ClassCannotBeInstantiatedException($className, $e); - } - assert($instance instanceof \PHPUnit\Runner\Extension\Extension); - $instance->bootstrap($this->configuration, $this->facade, \PHPUnit\Runner\Extension\ParameterCollection::fromArray($parameters)); - Event\Facade::emitter()->testRunnerBootstrappedExtension($className, $parameters); + parent::__construct(sprintf('Class %s cannot be found in %s', $className, $file)); } } + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use function sprintf; +use RuntimeException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class DirectoryCannotBeCreatedException extends RuntimeException implements \PHPUnit\Runner\Exception +{ + public function __construct(string $directory) + { + parent::__construct(sprintf('Cannot create directory "%s"', $directory)); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use Error; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ErrorException extends Error implements \PHPUnit\Runner\Exception +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface Exception extends \PHPUnit\Exception +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use function sprintf; +use RuntimeException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class FileDoesNotExistException extends RuntimeException implements \PHPUnit\Runner\Exception +{ + public function __construct(string $file) + { + parent::__construct(sprintf('File "%s" does not exist', $file)); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use RuntimeException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class InvalidOrderException extends RuntimeException implements \PHPUnit\Runner\Exception +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use RuntimeException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class InvalidPhptFileException extends RuntimeException implements \PHPUnit\Runner\Exception +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use RuntimeException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class NoIgnoredEventException extends RuntimeException implements \PHPUnit\Runner\Exception +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use function sprintf; +use RuntimeException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ParameterDoesNotExistException extends RuntimeException implements \PHPUnit\Runner\Exception +{ + public function __construct(string $name) + { + parent::__construct(sprintf('Parameter "%s" does not exist', $name)); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use function sprintf; +use RuntimeException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class PhptExternalFileCannotBeLoadedException extends RuntimeException implements \PHPUnit\Runner\Exception +{ + public function __construct(string $section, string $file) + { + parent::__construct(sprintf('Could not load --%s-- %s for PHPT file', $section . '_EXTERNAL', $file)); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use RuntimeException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ReflectionException extends RuntimeException implements \PHPUnit\Runner\Exception +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use function sprintf; +use RuntimeException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class UnsupportedPhptSectionException extends RuntimeException implements \PHPUnit\Runner\Exception +{ + public function __construct(string $section) + { + parent::__construct(sprintf('PHPUnit does not support PHPT %s sections', $section)); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\Extension; + +use PHPUnit\TextUI\Configuration\Configuration; +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +interface Extension +{ + public function bootstrap(Configuration $configuration, \PHPUnit\Runner\Extension\Facade $facade, \PHPUnit\Runner\Extension\ParameterCollection $parameters) : void; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\Extension; + +use function assert; +use function class_exists; +use function class_implements; +use function in_array; +use function sprintf; +use PHPUnit\Event\Facade as EventFacade; +use PHPUnit\TextUI\Configuration\Configuration; +use ReflectionClass; +use Throwable; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ExtensionBootstrapper +{ + private readonly Configuration $configuration; + private readonly \PHPUnit\Runner\Extension\Facade $facade; + public function __construct(Configuration $configuration, \PHPUnit\Runner\Extension\Facade $facade) + { + $this->configuration = $configuration; + $this->facade = $facade; + } + /** + * @psalm-param class-string $className + * @psalm-param array $parameters + */ + public function bootstrap(string $className, array $parameters) : void + { + if (!class_exists($className)) { + EventFacade::emitter()->testRunnerTriggeredWarning(sprintf('Cannot bootstrap extension because class %s does not exist', $className)); + return; + } + if (!in_array(\PHPUnit\Runner\Extension\Extension::class, class_implements($className), \true)) { + EventFacade::emitter()->testRunnerTriggeredWarning(sprintf('Cannot bootstrap extension because class %s does not implement interface %s', $className, \PHPUnit\Runner\Extension\Extension::class)); + return; + } + try { + $instance = (new ReflectionClass($className))->newInstance(); + assert($instance instanceof \PHPUnit\Runner\Extension\Extension); + $instance->bootstrap($this->configuration, $this->facade, \PHPUnit\Runner\Extension\ParameterCollection::fromArray($parameters)); + } catch (Throwable $t) { + EventFacade::emitter()->testRunnerTriggeredWarning(sprintf('Bootstrapping of extension %s failed: %s%s%s', $className, $t->getMessage(), \PHP_EOL, $t->getTraceAsString())); + return; + } + EventFacade::emitter()->testRunnerBootstrappedExtension($className, $parameters); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\Extension; + +use PHPUnit\Event\EventFacadeIsSealedException; +use PHPUnit\Event\Facade as EventFacade; +use PHPUnit\Event\Subscriber; +use PHPUnit\Event\Tracer\Tracer; +use PHPUnit\Event\UnknownSubscriberTypeException; +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + */ +final class Facade +{ + private bool $replacesOutput = \false; + private bool $replacesProgressOutput = \false; + private bool $replacesResultOutput = \false; + private bool $requiresCodeCoverageCollection = \false; + private bool $requiresExportOfObjects = \false; + /** + * @throws EventFacadeIsSealedException + * @throws UnknownSubscriberTypeException + */ + public function registerSubscribers(Subscriber ...$subscribers) : void + { + EventFacade::instance()->registerSubscribers(...$subscribers); + } + /** + * @throws EventFacadeIsSealedException + * @throws UnknownSubscriberTypeException + */ + public function registerSubscriber(Subscriber $subscriber) : void + { + EventFacade::instance()->registerSubscriber($subscriber); + } + /** + * @throws EventFacadeIsSealedException + */ + public function registerTracer(Tracer $tracer) : void + { + EventFacade::instance()->registerTracer($tracer); + } + public function replaceOutput() : void + { + $this->replacesOutput = \true; + } + public function replacesOutput() : bool + { + return $this->replacesOutput; + } + public function replaceProgressOutput() : void + { + $this->replacesProgressOutput = \true; + } + public function replacesProgressOutput() : bool + { + return $this->replacesOutput || $this->replacesProgressOutput; + } + public function replaceResultOutput() : void + { + $this->replacesResultOutput = \true; + } + public function replacesResultOutput() : bool + { + return $this->replacesOutput || $this->replacesResultOutput; + } + public function requireCodeCoverageCollection() : void + { + $this->requiresCodeCoverageCollection = \true; + } + public function requiresCodeCoverageCollection() : bool + { + return $this->requiresCodeCoverageCollection; + } + /** + * @deprecated + */ + public function requireExportOfObjects() : void + { + $this->requiresExportOfObjects = \true; + } + /** + * @deprecated + */ + public function requiresExportOfObjects() : bool + { + return $this->requiresExportOfObjects; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\Extension; + +use function array_key_exists; +use PHPUnit\Runner\ParameterDoesNotExistException; /** * @psalm-immutable * @@ -68169,8 +74435,13 @@ declare (strict_types=1); */ namespace PHPUnit\Runner\Extension; +use function count; +use function explode; use function extension_loaded; +use function implode; use function is_file; +use function sprintf; +use function str_contains; use PHPUnit\PharIo\Manifest\ApplicationName; use PHPUnit\PharIo\Manifest\Exception as ManifestException; use PHPUnit\PharIo\Manifest\ManifestLoader; @@ -68178,55 +74449,69 @@ use PHPUnit\PharIo\Version\Version as PharIoVersion; use PHPUnit\Event; use PHPUnit\Runner\Version; use PHPUnit\SebastianBergmann\FileIterator\Facade as FileIteratorFacade; +use Throwable; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class PharLoader { /** - * @psalm-return array{loadedExtensions: list, notLoadedExtensions: list} + * @psalm-param non-empty-string $directory + * + * @psalm-return list */ public function loadPharExtensionsInDirectory(string $directory) : array { $pharExtensionLoaded = extension_loaded('phar'); - if (!$pharExtensionLoaded) { - Event\Facade::emitter()->testRunnerTriggeredWarning('Loading PHPUnit extension(s) from PHP archive(s) failed, PHAR extension not loaded'); - } $loadedExtensions = []; - $notLoadedExtensions = []; foreach ((new FileIteratorFacade())->getFilesAsArray($directory, '.phar') as $file) { if (!$pharExtensionLoaded) { - $notLoadedExtensions[] = $file . ' cannot be loaded'; + Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('Cannot load extension from %s because the PHAR extension is not available', $file)); continue; } if (!is_file('phar://' . $file . '/manifest.xml')) { - $notLoadedExtensions[] = $file . ' is not an extension for PHPUnit'; + Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('%s is not an extension for PHPUnit', $file)); continue; } try { $applicationName = new ApplicationName('phpunit/phpunit'); - $version = new PharIoVersion(Version::series()); + $version = new PharIoVersion($this->phpunitVersion()); $manifest = ManifestLoader::fromFile('phar://' . $file . '/manifest.xml'); if (!$manifest->isExtensionFor($applicationName)) { - $notLoadedExtensions[] = $file . ' is not an extension for PHPUnit'; + Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('%s is not an extension for PHPUnit', $file)); continue; } if (!$manifest->isExtensionFor($applicationName, $version)) { - $notLoadedExtensions[] = $file . ' is not compatible with this version of PHPUnit'; + Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('%s is not compatible with PHPUnit %s', $file, Version::series())); continue; } } catch (ManifestException $e) { - $notLoadedExtensions[] = $file . ': ' . $e->getMessage(); + Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('Cannot load extension from %s: %s', $file, $e->getMessage())); + continue; + } + try { + /** @psalm-suppress UnresolvableInclude */ + @(require $file); + } catch (Throwable $t) { + Event\Facade::emitter()->testRunnerTriggeredWarning(sprintf('Cannot load extension from %s: %s', $file, $t->getMessage())); continue; } - /** - * @psalm-suppress UnresolvableInclude - */ - require $file; $loadedExtensions[] = $manifest->getName()->asString() . ' ' . $manifest->getVersion()->getVersionString(); Event\Facade::emitter()->testRunnerLoadedExtensionFromPhar($file, $manifest->getName()->asString(), $manifest->getVersion()->getVersionString()); } - return ['loadedExtensions' => $loadedExtensions, 'notLoadedExtensions' => $notLoadedExtensions]; + return $loadedExtensions; + } + private function phpunitVersion() : string + { + $version = Version::id(); + if (!str_contains($version, '-')) { + return $version; + } + $parts = explode('.', explode('-', $version)[0]); + if (count($parts) === 2) { + $parts[] = 0; + } + return implode('.', $parts); } } */ private array $filters = []; + /** + * @psalm-param list $testIds + */ + public function addTestIdFilter(array $testIds) : void + { + $this->filters[] = [new ReflectionClass(\PHPUnit\Runner\Filter\TestIdFilterIterator::class), $testIds]; + } + /** + * @psalm-param list $groups + */ public function addExcludeGroupFilter(array $groups) : void { $this->filters[] = [new ReflectionClass(\PHPUnit\Runner\Filter\ExcludeGroupFilterIterator::class), $groups]; } + /** + * @psalm-param list $groups + */ public function addIncludeGroupFilter(array $groups) : void { $this->filters[] = [new ReflectionClass(\PHPUnit\Runner\Filter\IncludeGroupFilterIterator::class), $groups]; } + /** + * @psalm-param non-empty-string $name + */ public function addNameFilter(string $name) : void { $this->filters[] = [new ReflectionClass(\PHPUnit\Runner\Filter\NameFilterIterator::class), $name]; @@ -68319,6 +74620,7 @@ use function array_map; use function array_push; use function in_array; use function spl_object_id; +use PHPUnit\Framework\Test; use PHPUnit\Framework\TestSuite; use RecursiveFilterIterator; use RecursiveIterator; @@ -68331,10 +74633,14 @@ abstract class GroupFilterIterator extends RecursiveFilterIterator * @psalm-var list */ protected array $groupTests = []; + /** + * @psalm-param RecursiveIterator $iterator + * @psalm-param list $groups + */ public function __construct(RecursiveIterator $iterator, array $groups, TestSuite $suite) { parent::__construct($iterator); - foreach ($suite->getGroupDetails() as $group => $tests) { + foreach ($suite->groupDetails() as $group => $tests) { if (in_array((string) $group, $groups, \true)) { $testHashes = array_map('spl_object_id', $tests); array_push($this->groupTests, ...$testHashes); @@ -68409,6 +74715,9 @@ final class NameFilterIterator extends RecursiveFilterIterator private ?int $filterMin = null; private ?int $filterMax = null; /** + * @psalm-param RecursiveIterator $iterator + * @psalm-param non-empty-string $filter + * * @throws Exception */ public function __construct(RecursiveIterator $iterator, string $filter) @@ -68486,74 +74795,322 @@ declare (strict_types=1); * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -namespace PHPUnit\Runner; +namespace PHPUnit\Runner\Filter; -use const DEBUG_BACKTRACE_IGNORE_ARGS; -use const DIRECTORY_SEPARATOR; -use function array_merge; -use function basename; -use function debug_backtrace; -use function defined; -use function dirname; -use function explode; -use function extension_loaded; -use function file; -use function file_get_contents; -use function file_put_contents; -use function is_array; -use function is_file; -use function is_readable; -use function is_string; -use function ltrim; -use function preg_match; -use function preg_replace; -use function preg_split; -use function realpath; -use function rtrim; -use function str_contains; -use function str_replace; -use function str_starts_with; -use function strncasecmp; -use function substr; -use function trim; -use function unlink; -use function unserialize; -use function var_export; -use PHPUnit\Event\Code\Phpt; -use PHPUnit\Event\Code\ThrowableBuilder; -use PHPUnit\Event\Facade as EventFacade; -use PHPUnit\Event\NoPreviousThrowableException; -use PHPUnit\Framework\Assert; -use PHPUnit\Framework\AssertionFailedError; -use PHPUnit\Framework\ExecutionOrderDependency; -use PHPUnit\Framework\ExpectationFailedException; -use PHPUnit\Framework\IncompleteTestError; -use PHPUnit\Framework\PhptAssertionFailedError; -use PHPUnit\Framework\Reorderable; -use PHPUnit\Framework\SelfDescribing; +use function in_array; +use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException; +use PHPUnit\Event\TestData\NoDataSetFromDataProviderException; use PHPUnit\Framework\Test; -use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry; -use PHPUnit\Util\PHP\AbstractPhpProcess; -use PHPUnit\SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData; -use PHPUnit\SebastianBergmann\CodeCoverage\InvalidArgumentException; -use PHPUnit\SebastianBergmann\CodeCoverage\StaticAnalysisCacheNotConfiguredException; -use PHPUnit\SebastianBergmann\CodeCoverage\Test\TestSize\TestSize; -use PHPUnit\SebastianBergmann\CodeCoverage\Test\TestStatus\TestStatus; -use PHPUnit\SebastianBergmann\CodeCoverage\TestIdMissingException; -use PHPUnit\SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException; -use PHPUnit\SebastianBergmann\Template\Template; -use Throwable; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\TestSuite; +use PHPUnit\Runner\PhptTestCase; +use RecursiveFilterIterator; +use RecursiveIterator; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestIdFilterIterator extends RecursiveFilterIterator +{ + /** + * @psalm-var non-empty-list + */ + private readonly array $testIds; + /** + * @psalm-param RecursiveIterator $iterator + * @psalm-param non-empty-list $testIds + */ + public function __construct(RecursiveIterator $iterator, array $testIds) + { + parent::__construct($iterator); + $this->testIds = $testIds; + } + public function accept() : bool + { + $test = $this->getInnerIterator()->current(); + if ($test instanceof TestSuite) { + return \true; + } + if (!$test instanceof TestCase && !$test instanceof PhptTestCase) { + return \false; + } + try { + return in_array($test->valueObjectForEvents()->id(), $this->testIds, \true); + } catch (MoreThanOneDataSetFromDataProviderException|NoDataSetFromDataProviderException) { + return \false; + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\GarbageCollection; + +use function gc_collect_cycles; +use function gc_disable; +use function gc_enable; +use PHPUnit\Event\EventFacadeIsSealedException; +use PHPUnit\Event\Facade; +use PHPUnit\Event\UnknownSubscriberTypeException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class GarbageCollectionHandler +{ + private readonly Facade $facade; + private readonly int $threshold; + private int $tests = 0; + /** + * @throws EventFacadeIsSealedException + * @throws UnknownSubscriberTypeException + */ + public function __construct(Facade $facade, int $threshold) + { + $this->facade = $facade; + $this->threshold = $threshold; + $this->registerSubscribers(); + } + public function executionStarted() : void + { + gc_disable(); + $this->facade->emitter()->testRunnerDisabledGarbageCollection(); + gc_collect_cycles(); + $this->facade->emitter()->testRunnerTriggeredGarbageCollection(); + } + public function executionFinished() : void + { + gc_collect_cycles(); + $this->facade->emitter()->testRunnerTriggeredGarbageCollection(); + gc_enable(); + $this->facade->emitter()->testRunnerEnabledGarbageCollection(); + } + public function testFinished() : void + { + $this->tests++; + if ($this->tests === $this->threshold) { + gc_collect_cycles(); + $this->facade->emitter()->testRunnerTriggeredGarbageCollection(); + $this->tests = 0; + } + } + /** + * @throws EventFacadeIsSealedException + * @throws UnknownSubscriberTypeException + */ + private function registerSubscribers() : void + { + $this->facade->registerSubscribers(new \PHPUnit\Runner\GarbageCollection\ExecutionStartedSubscriber($this), new \PHPUnit\Runner\GarbageCollection\ExecutionFinishedSubscriber($this), new \PHPUnit\Runner\GarbageCollection\TestFinishedSubscriber($this)); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\GarbageCollection; + +use PHPUnit\Event\InvalidArgumentException; +use PHPUnit\Event\TestRunner\ExecutionFinished; +use PHPUnit\Event\TestRunner\ExecutionFinishedSubscriber as TestRunnerExecutionFinishedSubscriber; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ExecutionFinishedSubscriber extends \PHPUnit\Runner\GarbageCollection\Subscriber implements TestRunnerExecutionFinishedSubscriber +{ + /** + * @throws \PHPUnit\Framework\InvalidArgumentException + * @throws InvalidArgumentException + */ + public function notify(ExecutionFinished $event) : void + { + $this->handler()->executionFinished(); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\GarbageCollection; + +use PHPUnit\Event\InvalidArgumentException; +use PHPUnit\Event\TestRunner\ExecutionStarted; +use PHPUnit\Event\TestRunner\ExecutionStartedSubscriber as TestRunnerExecutionStartedSubscriber; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ExecutionStartedSubscriber extends \PHPUnit\Runner\GarbageCollection\Subscriber implements TestRunnerExecutionStartedSubscriber +{ + /** + * @throws \PHPUnit\Framework\InvalidArgumentException + * @throws InvalidArgumentException + */ + public function notify(ExecutionStarted $event) : void + { + $this->handler()->executionStarted(); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\GarbageCollection; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +abstract class Subscriber +{ + private readonly \PHPUnit\Runner\GarbageCollection\GarbageCollectionHandler $handler; + public function __construct(\PHPUnit\Runner\GarbageCollection\GarbageCollectionHandler $handler) + { + $this->handler = $handler; + } + protected function handler() : \PHPUnit\Runner\GarbageCollection\GarbageCollectionHandler + { + return $this->handler; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\GarbageCollection; + +use PHPUnit\Event\InvalidArgumentException; +use PHPUnit\Event\Test\Finished; +use PHPUnit\Event\Test\FinishedSubscriber; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestFinishedSubscriber extends \PHPUnit\Runner\GarbageCollection\Subscriber implements FinishedSubscriber +{ + /** + * @throws \PHPUnit\Framework\InvalidArgumentException + * @throws InvalidArgumentException + */ + public function notify(Finished $event) : void + { + $this->handler()->testFinished(); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use const DEBUG_BACKTRACE_IGNORE_ARGS; +use const DIRECTORY_SEPARATOR; +use function array_merge; +use function basename; +use function debug_backtrace; +use function defined; +use function dirname; +use function explode; +use function extension_loaded; +use function file; +use function file_get_contents; +use function file_put_contents; +use function is_array; +use function is_file; +use function is_readable; +use function is_string; +use function ltrim; +use function preg_match; +use function preg_replace; +use function preg_split; +use function realpath; +use function rtrim; +use function str_contains; +use function str_replace; +use function str_starts_with; +use function strncasecmp; +use function substr; +use function trim; +use function unlink; +use function unserialize; +use function var_export; +use PHPUnit\Event\Code\Phpt; +use PHPUnit\Event\Code\ThrowableBuilder; +use PHPUnit\Event\Facade as EventFacade; +use PHPUnit\Event\NoPreviousThrowableException; +use PHPUnit\Framework\Assert; +use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\ExecutionOrderDependency; +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\IncompleteTestError; +use PHPUnit\Framework\PhptAssertionFailedError; +use PHPUnit\Framework\Reorderable; +use PHPUnit\Framework\SelfDescribing; +use PHPUnit\Framework\Test; +use PHPUnit\TextUI\Configuration\Registry as ConfigurationRegistry; +use PHPUnit\Util\PHP\AbstractPhpProcess; +use PHPUnit\SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData; +use PHPUnit\SebastianBergmann\CodeCoverage\InvalidArgumentException; +use PHPUnit\SebastianBergmann\CodeCoverage\StaticAnalysisCacheNotConfiguredException; +use PHPUnit\SebastianBergmann\CodeCoverage\Test\TestSize\TestSize; +use PHPUnit\SebastianBergmann\CodeCoverage\Test\TestStatus\TestStatus; +use PHPUnit\SebastianBergmann\CodeCoverage\TestIdMissingException; +use PHPUnit\SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException; +use PHPUnit\SebastianBergmann\Template\Template; +use Throwable; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ final class PhptTestCase implements Reorderable, SelfDescribing, Test { + /** + * @psalm-var non-empty-string + */ private readonly string $filename; private readonly AbstractPhpProcess $phpUtil; private string $output = ''; /** * Constructs a test case with the given filename. * + * @psalm-param non-empty-string $filename + * * @throws Exception */ public function __construct(string $filename, AbstractPhpProcess $phpUtil = null) @@ -68610,9 +75167,6 @@ final class PhptTestCase implements Reorderable, SelfDescribing, Test $this->phpUtil->setEnv($env); } $this->phpUtil->setUseStderrRedirection(\true); - if (ConfigurationRegistry::get()->enforceTimeLimit()) { - $this->phpUtil->setTimeout(ConfigurationRegistry::get()->timeoutForLargeTests()); - } if ($this->shouldTestBeSkipped($sections, $settings)) { return; } @@ -68636,7 +75190,7 @@ final class PhptTestCase implements Reorderable, SelfDescribing, Test $this->output = $jobResult['stdout'] ?? ''; if (\PHPUnit\Runner\CodeCoverage::instance()->isActive() && ($coverage = $this->cleanupForCoverage())) { \PHPUnit\Runner\CodeCoverage::instance()->codeCoverage()->start($this->filename, TestSize::large()); - \PHPUnit\Runner\CodeCoverage::instance()->codeCoverage()->append($coverage, $this->filename, \true, TestStatus::unknown(), [], []); + \PHPUnit\Runner\CodeCoverage::instance()->codeCoverage()->append($coverage, $this->filename, \true, TestStatus::unknown()); } try { $this->assertPhptExpectation($sections, $this->output); @@ -69260,10 +75814,10 @@ final class ResultCacheHandler * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ - public function __construct(\PHPUnit\Runner\ResultCache\ResultCache $cache) + public function __construct(\PHPUnit\Runner\ResultCache\ResultCache $cache, Facade $facade) { $this->cache = $cache; - $this->registerSubscribers(); + $this->registerSubscribers($facade); } public function testSuiteStarted() : void { @@ -69329,9 +75883,9 @@ final class ResultCacheHandler * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ - private function registerSubscribers() : void + private function registerSubscribers(Facade $facade) : void { - Facade::registerSubscribers(new \PHPUnit\Runner\ResultCache\TestSuiteStartedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestSuiteFinishedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestPreparedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestMarkedIncompleteSubscriber($this), new \PHPUnit\Runner\ResultCache\TestConsideredRiskySubscriber($this), new \PHPUnit\Runner\ResultCache\TestErroredSubscriber($this), new \PHPUnit\Runner\ResultCache\TestFailedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestSkippedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestFinishedSubscriber($this)); + $facade->registerSubscribers(new \PHPUnit\Runner\ResultCache\TestSuiteStartedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestSuiteFinishedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestPreparedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestMarkedIncompleteSubscriber($this), new \PHPUnit\Runner\ResultCache\TestConsideredRiskySubscriber($this), new \PHPUnit\Runner\ResultCache\TestErroredSubscriber($this), new \PHPUnit\Runner\ResultCache\TestFailedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestSkippedSubscriber($this), new \PHPUnit\Runner\ResultCache\TestFinishedSubscriber($this)); } } */ @@ -69677,95 +76240,65 @@ final class Collector */ private array $testConsideredRiskyEvents = []; /** - * @psalm-var array> + * @psalm-var array> */ - private array $testTriggeredDeprecationEvents = []; + private array $testTriggeredPhpunitDeprecationEvents = []; /** - * @psalm-var array> + * @psalm-var array> */ - private array $testTriggeredPhpDeprecationEvents = []; + private array $testTriggeredPhpunitErrorEvents = []; /** - * @psalm-var array> + * @psalm-var array> */ - private array $testTriggeredPhpunitDeprecationEvents = []; + private array $testTriggeredPhpunitWarningEvents = []; /** - * @psalm-var array> + * @psalm-var list */ - private array $testTriggeredErrorEvents = []; + private array $testRunnerTriggeredWarningEvents = []; /** - * @psalm-var array> + * @psalm-var list */ - private array $testTriggeredNoticeEvents = []; + private array $testRunnerTriggeredDeprecationEvents = []; /** - * @psalm-var array> + * @psalm-var array */ - private array $testTriggeredPhpNoticeEvents = []; + private array $errors = []; /** - * @psalm-var array> + * @psalm-var array */ - private array $testTriggeredWarningEvents = []; + private array $deprecations = []; /** - * @psalm-var array> + * @psalm-var array */ - private array $testTriggeredPhpWarningEvents = []; + private array $notices = []; /** - * @psalm-var array> + * @psalm-var array */ - private array $testTriggeredPhpunitErrorEvents = []; + private array $warnings = []; /** - * @psalm-var array> + * @psalm-var array */ - private array $testTriggeredPhpunitWarningEvents = []; + private array $phpDeprecations = []; /** - * @psalm-var list + * @psalm-var array */ - private array $testRunnerTriggeredWarningEvents = []; + private array $phpNotices = []; /** - * @psalm-var list + * @psalm-var array */ - private array $testRunnerTriggeredDeprecationEvents = []; + private array $phpWarnings = []; /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ - public function __construct() + public function __construct(Facade $facade, Source $source) { - Facade::registerSubscribers(new \PHPUnit\TestRunner\TestResult\ExecutionStartedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestSuiteSkippedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestSuiteStartedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestSuiteFinishedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestPreparedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestFinishedSubscriber($this), new \PHPUnit\TestRunner\TestResult\BeforeTestClassMethodErroredSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestErroredSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestFailedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestMarkedIncompleteSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestSkippedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestConsideredRiskySubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredDeprecationSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredErrorSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredNoticeSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpDeprecationSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpNoticeSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpunitDeprecationSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpunitErrorSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpunitWarningSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpWarningSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredWarningSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestRunnerTriggeredDeprecationSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestRunnerTriggeredWarningSubscriber($this)); + $facade->registerSubscribers(new \PHPUnit\TestRunner\TestResult\ExecutionStartedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestSuiteSkippedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestSuiteStartedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestSuiteFinishedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestPreparedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestFinishedSubscriber($this), new \PHPUnit\TestRunner\TestResult\BeforeTestClassMethodErroredSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestErroredSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestFailedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestMarkedIncompleteSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestSkippedSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestConsideredRiskySubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredDeprecationSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredErrorSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredNoticeSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpDeprecationSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpNoticeSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpunitDeprecationSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpunitErrorSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpunitWarningSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredPhpWarningSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestTriggeredWarningSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestRunnerTriggeredDeprecationSubscriber($this), new \PHPUnit\TestRunner\TestResult\TestRunnerTriggeredWarningSubscriber($this)); + $this->source = $source; } public function result() : \PHPUnit\TestRunner\TestResult\TestResult { - return new \PHPUnit\TestRunner\TestResult\TestResult($this->numberOfTests, $this->numberOfTestsRun, $this->numberOfAssertions, $this->testErroredEvents, $this->testFailedEvents, $this->testConsideredRiskyEvents, $this->testSuiteSkippedEvents, $this->testSkippedEvents, $this->testMarkedIncompleteEvents, $this->testTriggeredDeprecationEvents, $this->testTriggeredPhpDeprecationEvents, $this->testTriggeredPhpunitDeprecationEvents, $this->testTriggeredErrorEvents, $this->testTriggeredNoticeEvents, $this->testTriggeredPhpNoticeEvents, $this->testTriggeredWarningEvents, $this->testTriggeredPhpWarningEvents, $this->testTriggeredPhpunitErrorEvents, $this->testTriggeredPhpunitWarningEvents, $this->testRunnerTriggeredDeprecationEvents, $this->testRunnerTriggeredWarningEvents); - } - public function hasTestErroredEvents() : bool - { - return !empty($this->testErroredEvents); - } - public function hasTestFailedEvents() : bool - { - return !empty($this->testFailedEvents); - } - public function hasTestConsideredRiskyEvents() : bool - { - return !empty($this->testConsideredRiskyEvents); - } - public function hasTestSkippedEvents() : bool - { - return !empty($this->testSkippedEvents); - } - public function hasTestMarkedIncompleteEvents() : bool - { - return !empty($this->testMarkedIncompleteEvents); - } - public function hasTestRunnerTriggeredWarningEvents() : bool - { - return !empty($this->testRunnerTriggeredWarningEvents); - } - /** - * @psalm-return list - */ - public function testRunnerTriggeredWarningEvents() : array - { - return $this->testRunnerTriggeredWarningEvents; + return new \PHPUnit\TestRunner\TestResult\TestResult($this->numberOfTests, $this->numberOfTestsRun, $this->numberOfAssertions, $this->testErroredEvents, $this->testFailedEvents, $this->testConsideredRiskyEvents, $this->testSuiteSkippedEvents, $this->testSkippedEvents, $this->testMarkedIncompleteEvents, $this->testTriggeredPhpunitDeprecationEvents, $this->testTriggeredPhpunitErrorEvents, $this->testTriggeredPhpunitWarningEvents, $this->testRunnerTriggeredDeprecationEvents, $this->testRunnerTriggeredWarningEvents, array_values($this->errors), array_values($this->deprecations), array_values($this->notices), array_values($this->warnings), array_values($this->phpDeprecations), array_values($this->phpNotices), array_values($this->phpWarnings), $this->numberOfIssuesIgnoredByBaseline); } public function executionStarted(ExecutionStarted $event) : void { @@ -69787,9 +76320,6 @@ final class Collector } $this->currentTestSuiteForTestClassFailed = \false; } - /** - * @throws NoDataSetFromDataProviderException - */ public function testSuiteFinished(TestSuiteFinished $event) : void { if ($this->currentTestSuiteForTestClassFailed) { @@ -69863,17 +76393,47 @@ final class Collector } public function testTriggeredDeprecation(DeprecationTriggered $event) : void { - if (!isset($this->testTriggeredDeprecationEvents[$event->test()->id()])) { - $this->testTriggeredDeprecationEvents[$event->test()->id()] = []; + if ($event->ignoredByTest()) { + return; + } + if ($event->ignoredByBaseline()) { + $this->numberOfIssuesIgnoredByBaseline++; + return; + } + if (!$this->source->ignoreSuppressionOfDeprecations() && $event->wasSuppressed()) { + return; + } + if ($this->source->restrictDeprecations() && !(new SourceFilter())->includes($this->source, $event->file())) { + return; } - $this->testTriggeredDeprecationEvents[$event->test()->id()][] = $event; + $id = $this->issueId($event); + if (!isset($this->deprecations[$id])) { + $this->deprecations[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test()); + return; + } + $this->deprecations[$id]->triggeredBy($event->test()); } public function testTriggeredPhpDeprecation(PhpDeprecationTriggered $event) : void { - if (!isset($this->testTriggeredPhpDeprecationEvents[$event->test()->id()])) { - $this->testTriggeredPhpDeprecationEvents[$event->test()->id()] = []; + if ($event->ignoredByTest()) { + return; + } + if ($event->ignoredByBaseline()) { + $this->numberOfIssuesIgnoredByBaseline++; + return; + } + if (!$this->source->ignoreSuppressionOfPhpDeprecations() && $event->wasSuppressed()) { + return; + } + if ($this->source->restrictDeprecations() && !(new SourceFilter())->includes($this->source, $event->file())) { + return; + } + $id = $this->issueId($event); + if (!isset($this->phpDeprecations[$id])) { + $this->phpDeprecations[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test()); + return; } - $this->testTriggeredPhpDeprecationEvents[$event->test()->id()][] = $event; + $this->phpDeprecations[$id]->triggeredBy($event->test()); } public function testTriggeredPhpunitDeprecation(PhpunitDeprecationTriggered $event) : void { @@ -69884,38 +76444,91 @@ final class Collector } public function testTriggeredError(ErrorTriggered $event) : void { - if (!isset($this->testTriggeredErrorEvents[$event->test()->id()])) { - $this->testTriggeredErrorEvents[$event->test()->id()] = []; + if (!$this->source->ignoreSuppressionOfErrors() && $event->wasSuppressed()) { + return; } - $this->testTriggeredErrorEvents[$event->test()->id()][] = $event; + $id = $this->issueId($event); + if (!isset($this->errors[$id])) { + $this->errors[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test()); + return; + } + $this->errors[$id]->triggeredBy($event->test()); } public function testTriggeredNotice(NoticeTriggered $event) : void { - if (!isset($this->testTriggeredNoticeEvents[$event->test()->id()])) { - $this->testTriggeredNoticeEvents[$event->test()->id()] = []; + if ($event->ignoredByBaseline()) { + $this->numberOfIssuesIgnoredByBaseline++; + return; + } + if (!$this->source->ignoreSuppressionOfNotices() && $event->wasSuppressed()) { + return; + } + if ($this->source->restrictNotices() && !(new SourceFilter())->includes($this->source, $event->file())) { + return; + } + $id = $this->issueId($event); + if (!isset($this->notices[$id])) { + $this->notices[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test()); + return; } - $this->testTriggeredNoticeEvents[$event->test()->id()][] = $event; + $this->notices[$id]->triggeredBy($event->test()); } public function testTriggeredPhpNotice(PhpNoticeTriggered $event) : void { - if (!isset($this->testTriggeredPhpNoticeEvents[$event->test()->id()])) { - $this->testTriggeredPhpNoticeEvents[$event->test()->id()] = []; + if ($event->ignoredByBaseline()) { + $this->numberOfIssuesIgnoredByBaseline++; + return; + } + if (!$this->source->ignoreSuppressionOfPhpNotices() && $event->wasSuppressed()) { + return; } - $this->testTriggeredPhpNoticeEvents[$event->test()->id()][] = $event; + if ($this->source->restrictNotices() && !(new SourceFilter())->includes($this->source, $event->file())) { + return; + } + $id = $this->issueId($event); + if (!isset($this->phpNotices[$id])) { + $this->phpNotices[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test()); + return; + } + $this->phpNotices[$id]->triggeredBy($event->test()); } public function testTriggeredWarning(WarningTriggered $event) : void { - if (!isset($this->testTriggeredWarningEvents[$event->test()->id()])) { - $this->testTriggeredWarningEvents[$event->test()->id()] = []; + if ($event->ignoredByBaseline()) { + $this->numberOfIssuesIgnoredByBaseline++; + return; + } + if (!$this->source->ignoreSuppressionOfWarnings() && $event->wasSuppressed()) { + return; + } + if ($this->source->restrictWarnings() && !(new SourceFilter())->includes($this->source, $event->file())) { + return; + } + $id = $this->issueId($event); + if (!isset($this->warnings[$id])) { + $this->warnings[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test()); + return; } - $this->testTriggeredWarningEvents[$event->test()->id()][] = $event; + $this->warnings[$id]->triggeredBy($event->test()); } public function testTriggeredPhpWarning(PhpWarningTriggered $event) : void { - if (!isset($this->testTriggeredPhpWarningEvents[$event->test()->id()])) { - $this->testTriggeredPhpWarningEvents[$event->test()->id()] = []; + if ($event->ignoredByBaseline()) { + $this->numberOfIssuesIgnoredByBaseline++; + return; + } + if (!$this->source->ignoreSuppressionOfPhpWarnings() && $event->wasSuppressed()) { + return; + } + if ($this->source->restrictWarnings() && !(new SourceFilter())->includes($this->source, $event->file())) { + return; } - $this->testTriggeredPhpWarningEvents[$event->test()->id()][] = $event; + $id = $this->issueId($event); + if (!isset($this->phpWarnings[$id])) { + $this->phpWarnings[$id] = Issue::from($event->file(), $event->line(), $event->message(), $event->test()); + return; + } + $this->phpWarnings[$id]->triggeredBy($event->test()); } public function testTriggeredPhpunitError(PhpunitErrorTriggered $event) : void { @@ -69939,9 +76552,44 @@ final class Collector { $this->testRunnerTriggeredWarningEvents[] = $event; } - public function hasWarningEvents() : bool + public function hasErroredTests() : bool + { + return !empty($this->testErroredEvents); + } + public function hasFailedTests() : bool + { + return !empty($this->testFailedEvents); + } + public function hasRiskyTests() : bool + { + return !empty($this->testConsideredRiskyEvents); + } + public function hasSkippedTests() : bool + { + return !empty($this->testSkippedEvents); + } + public function hasIncompleteTests() : bool + { + return !empty($this->testMarkedIncompleteEvents); + } + public function hasDeprecations() : bool + { + return !empty($this->deprecations) || !empty($this->phpDeprecations) || !empty($this->testTriggeredPhpunitDeprecationEvents) || !empty($this->testRunnerTriggeredDeprecationEvents); + } + public function hasNotices() : bool + { + return !empty($this->notices) || !empty($this->phpNotices); + } + public function hasWarnings() : bool + { + return !empty($this->warnings) || !empty($this->phpWarnings) || !empty($this->testTriggeredPhpunitWarningEvents) || !empty($this->testRunnerTriggeredWarningEvents); + } + /** + * @psalm-return non-empty-string + */ + private function issueId(DeprecationTriggered|ErrorTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpWarningTriggered|WarningTriggered $event) : string { - return !empty($this->testTriggeredWarningEvents) || !empty($this->testTriggeredPhpWarningEvents) || !empty($this->testTriggeredPhpunitWarningEvents) || !empty($this->testRunnerTriggeredWarningEvents); + return implode(':', [$event->file(), $event->line(), $event->message()]); } } hasTestErroredEvents(); + $configuration = ConfigurationRegistry::get(); + $collector = self::collector(); + if (($configuration->stopOnDefect() || $configuration->stopOnError()) && $collector->hasErroredTests()) { + return \true; + } + if (($configuration->stopOnDefect() || $configuration->stopOnFailure()) && $collector->hasFailedTests()) { + return \true; + } + if (($configuration->stopOnDefect() || $configuration->stopOnWarning()) && $collector->hasWarnings()) { + return \true; + } + if (($configuration->stopOnDefect() || $configuration->stopOnRisky()) && $collector->hasRiskyTests()) { + return \true; + } + if ($configuration->stopOnDeprecation() && $collector->hasDeprecations()) { + return \true; + } + if ($configuration->stopOnNotice() && $collector->hasNotices()) { + return \true; + } + if ($configuration->stopOnIncomplete() && $collector->hasIncompleteTests()) { + return \true; + } + if ($configuration->stopOnSkipped() && $collector->hasSkippedTests()) { + return \true; + } + return \false; } /** * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ - public static function hasTestFailedEvents() : bool + private static function collector() : \PHPUnit\TestRunner\TestResult\Collector { - return self::collector()->hasTestFailedEvents(); + if (self::$collector === null) { + $configuration = ConfigurationRegistry::get(); + self::$collector = new \PHPUnit\TestRunner\TestResult\Collector(EventFacade::instance(), $configuration->source()); + } + return self::$collector; } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TestRunner\TestResult\Issues; + +use PHPUnit\Event\Code\Test; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Issue +{ /** - * @throws EventFacadeIsSealedException - * @throws UnknownSubscriberTypeException + * @psalm-var non-empty-string + */ + private readonly string $file; + /** + * @psalm-var positive-int + */ + private readonly int $line; + /** + * @psalm-var non-empty-string + */ + private readonly string $description; + /** + * @psalm-var non-empty-array */ - public static function hasWarningEvents() : bool + private array $triggeringTests; + /** + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + * @psalm-param non-empty-string $description + */ + public static function from(string $file, int $line, string $description, Test $triggeringTest) : self { - return self::collector()->hasWarningEvents(); + return new self($file, $line, $description, $triggeringTest); } /** - * @throws EventFacadeIsSealedException - * @throws UnknownSubscriberTypeException + * @psalm-param non-empty-string $file + * @psalm-param positive-int $line + * @psalm-param non-empty-string $description */ - public static function hasTestConsideredRiskyEvents() : bool + private function __construct(string $file, int $line, string $description, Test $triggeringTest) { - return self::collector()->hasTestConsideredRiskyEvents(); + $this->file = $file; + $this->line = $line; + $this->description = $description; + $this->triggeringTests = [$triggeringTest->id() => ['test' => $triggeringTest, 'count' => 1]]; + } + public function triggeredBy(Test $test) : void + { + if (isset($this->triggeringTests[$test->id()])) { + $this->triggeringTests[$test->id()]['count']++; + return; + } + $this->triggeringTests[$test->id()] = ['test' => $test, 'count' => 1]; } /** - * @throws EventFacadeIsSealedException - * @throws UnknownSubscriberTypeException + * @psalm-return non-empty-string */ - public static function hasTestSkippedEvents() : bool + public function file() : string { - return self::collector()->hasTestSkippedEvents(); + return $this->file; } /** - * @throws EventFacadeIsSealedException - * @throws UnknownSubscriberTypeException + * @psalm-return positive-int */ - public static function hasTestMarkedIncompleteEvents() : bool + public function line() : int { - return self::collector()->hasTestMarkedIncompleteEvents(); + return $this->line; } /** - * @throws EventFacadeIsSealedException - * @throws UnknownSubscriberTypeException + * @psalm-return non-empty-string */ - private static function collector() : \PHPUnit\TestRunner\TestResult\Collector + public function description() : string { - if (self::$collector === null) { - self::$collector = new \PHPUnit\TestRunner\TestResult\Collector(); - } - return self::$collector; + return $this->description; + } + /** + * @psalm-return non-empty-array + */ + public function triggeringTests() : array + { + return $this->triggeringTests; } } passedTestClasses[] = $className; } - /** - * @throws NoDataSetFromDataProviderException - */ public function testMethodPassed(TestMethod $test, mixed $returnValue) : void { $size = (new Groups())->size($test->className(), $test->methodName()); @@ -70452,7 +77178,6 @@ declare (strict_types=1); */ namespace PHPUnit\TestRunner\TestResult; -use PHPUnit\Event\TestData\NoDataSetFromDataProviderException; use PHPUnit\Event\TestSuite\Finished; use PHPUnit\Event\TestSuite\FinishedSubscriber; /** @@ -70460,9 +77185,6 @@ use PHPUnit\Event\TestSuite\FinishedSubscriber; */ final class TestSuiteFinishedSubscriber extends \PHPUnit\TestRunner\TestResult\Subscriber implements FinishedSubscriber { - /** - * @throws NoDataSetFromDataProviderException - */ public function notify(Finished $event) : void { $this->collector()->testSuiteFinished($event); @@ -70784,23 +77506,17 @@ namespace PHPUnit\TestRunner\TestResult; use function count; use PHPUnit\Event\Test\BeforeFirstTestMethodErrored; use PHPUnit\Event\Test\ConsideredRisky; -use PHPUnit\Event\Test\DeprecationTriggered; use PHPUnit\Event\Test\Errored; -use PHPUnit\Event\Test\ErrorTriggered; use PHPUnit\Event\Test\Failed; use PHPUnit\Event\Test\MarkedIncomplete; -use PHPUnit\Event\Test\NoticeTriggered; -use PHPUnit\Event\Test\PhpDeprecationTriggered; -use PHPUnit\Event\Test\PhpNoticeTriggered; use PHPUnit\Event\Test\PhpunitDeprecationTriggered; use PHPUnit\Event\Test\PhpunitErrorTriggered; use PHPUnit\Event\Test\PhpunitWarningTriggered; -use PHPUnit\Event\Test\PhpWarningTriggered; use PHPUnit\Event\Test\Skipped as TestSkipped; -use PHPUnit\Event\Test\WarningTriggered; use PHPUnit\Event\TestRunner\DeprecationTriggered as TestRunnerDeprecationTriggered; use PHPUnit\Event\TestRunner\WarningTriggered as TestRunnerWarningTriggered; use PHPUnit\Event\TestSuite\Skipped as TestSuiteSkipped; +use PHPUnit\TestRunner\TestResult\Issues\Issue; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ @@ -70834,53 +77550,57 @@ final class TestResult */ private readonly array $testConsideredRiskyEvents; /** - * @psalm-var array> + * @psalm-var array> */ - private readonly array $testTriggeredDeprecationEvents; + private readonly array $testTriggeredPhpunitDeprecationEvents; /** - * @psalm-var array> + * @psalm-var array> */ - private readonly array $testTriggeredPhpDeprecationEvents; + private readonly array $testTriggeredPhpunitErrorEvents; /** - * @psalm-var array> + * @psalm-var array> */ - private readonly array $testTriggeredPhpunitDeprecationEvents; + private readonly array $testTriggeredPhpunitWarningEvents; /** - * @psalm-var array> + * @psalm-var list */ - private readonly array $testTriggeredErrorEvents; + private readonly array $testRunnerTriggeredDeprecationEvents; /** - * @psalm-var array> + * @psalm-var list */ - private readonly array $testTriggeredNoticeEvents; + private readonly array $testRunnerTriggeredWarningEvents; /** - * @psalm-var array> + * @psalm-var list */ - private readonly array $testTriggeredPhpNoticeEvents; + private readonly array $errors; /** - * @psalm-var array> + * @psalm-var list */ - private readonly array $testTriggeredWarningEvents; + private readonly array $deprecations; /** - * @psalm-var array> + * @psalm-var list */ - private readonly array $testTriggeredPhpWarningEvents; + private readonly array $notices; /** - * @psalm-var array> + * @psalm-var list */ - private readonly array $testTriggeredPhpunitErrorEvents; + private readonly array $warnings; /** - * @psalm-var array> + * @psalm-var list */ - private readonly array $testTriggeredPhpunitWarningEvents; + private readonly array $phpDeprecations; /** - * @psalm-var list + * @psalm-var list */ - private readonly array $testRunnerTriggeredDeprecationEvents; + private readonly array $phpNotices; /** - * @psalm-var list + * @psalm-var list */ - private readonly array $testRunnerTriggeredWarningEvents; + private readonly array $phpWarnings; + /** + * @psalm-var non-negative-int + */ + private readonly int $numberOfIssuesIgnoredByBaseline; /** * @psalm-param list $testErroredEvents * @psalm-param list $testFailedEvents @@ -70888,20 +77608,21 @@ final class TestResult * @psalm-param list $testSuiteSkippedEvents * @psalm-param list $testSkippedEvents * @psalm-param list $testMarkedIncompleteEvents - * @psalm-param array> $testTriggeredDeprecationEvents - * @psalm-param array> $testTriggeredPhpDeprecationEvents * @psalm-param array> $testTriggeredPhpunitDeprecationEvents - * @psalm-param array> $testTriggeredErrorEvents - * @psalm-param array> $testTriggeredNoticeEvents - * @psalm-param array> $testTriggeredPhpNoticeEvents - * @psalm-param array> $testTriggeredWarningEvents - * @psalm-param array> $testTriggeredPhpWarningEvents * @psalm-param array> $testTriggeredPhpunitErrorEvents * @psalm-param array> $testTriggeredPhpunitWarningEvents * @psalm-param list $testRunnerTriggeredDeprecationEvents * @psalm-param list $testRunnerTriggeredWarningEvents + * @psalm-param list $errors + * @psalm-param list $deprecations + * @psalm-param list $notices + * @psalm-param list $warnings + * @psalm-param list $phpDeprecations + * @psalm-param list $phpNotices + * @psalm-param list $phpWarnings + * @psalm-param non-negative-int $numberOfIssuesIgnoredByBaseline */ - public function __construct(int $numberOfTests, int $numberOfTestsRun, int $numberOfAssertions, array $testErroredEvents, array $testFailedEvents, array $testConsideredRiskyEvents, array $testSuiteSkippedEvents, array $testSkippedEvents, array $testMarkedIncompleteEvents, array $testTriggeredDeprecationEvents, array $testTriggeredPhpDeprecationEvents, array $testTriggeredPhpunitDeprecationEvents, array $testTriggeredErrorEvents, array $testTriggeredNoticeEvents, array $testTriggeredPhpNoticeEvents, array $testTriggeredWarningEvents, array $testTriggeredPhpWarningEvents, array $testTriggeredPhpunitErrorEvents, array $testTriggeredPhpunitWarningEvents, array $testRunnerTriggeredDeprecationEvents, array $testRunnerTriggeredWarningEvents) + public function __construct(int $numberOfTests, int $numberOfTestsRun, int $numberOfAssertions, array $testErroredEvents, array $testFailedEvents, array $testConsideredRiskyEvents, array $testSuiteSkippedEvents, array $testSkippedEvents, array $testMarkedIncompleteEvents, array $testTriggeredPhpunitDeprecationEvents, array $testTriggeredPhpunitErrorEvents, array $testTriggeredPhpunitWarningEvents, array $testRunnerTriggeredDeprecationEvents, array $testRunnerTriggeredWarningEvents, array $errors, array $deprecations, array $notices, array $warnings, array $phpDeprecations, array $phpNotices, array $phpWarnings, int $numberOfIssuesIgnoredByBaseline) { $this->numberOfTests = $numberOfTests; $this->numberOfTestsRun = $numberOfTestsRun; @@ -70912,22 +77633,19 @@ final class TestResult $this->testSuiteSkippedEvents = $testSuiteSkippedEvents; $this->testSkippedEvents = $testSkippedEvents; $this->testMarkedIncompleteEvents = $testMarkedIncompleteEvents; - $this->testTriggeredDeprecationEvents = $testTriggeredDeprecationEvents; - $this->testTriggeredPhpDeprecationEvents = $testTriggeredPhpDeprecationEvents; $this->testTriggeredPhpunitDeprecationEvents = $testTriggeredPhpunitDeprecationEvents; - $this->testTriggeredErrorEvents = $testTriggeredErrorEvents; - $this->testTriggeredNoticeEvents = $testTriggeredNoticeEvents; - $this->testTriggeredPhpNoticeEvents = $testTriggeredPhpNoticeEvents; - $this->testTriggeredWarningEvents = $testTriggeredWarningEvents; - $this->testTriggeredPhpWarningEvents = $testTriggeredPhpWarningEvents; $this->testTriggeredPhpunitErrorEvents = $testTriggeredPhpunitErrorEvents; $this->testTriggeredPhpunitWarningEvents = $testTriggeredPhpunitWarningEvents; $this->testRunnerTriggeredDeprecationEvents = $testRunnerTriggeredDeprecationEvents; $this->testRunnerTriggeredWarningEvents = $testRunnerTriggeredWarningEvents; - } - public function numberOfTests() : int - { - return $this->numberOfTests; + $this->errors = $errors; + $this->deprecations = $deprecations; + $this->notices = $notices; + $this->warnings = $warnings; + $this->phpDeprecations = $phpDeprecations; + $this->phpNotices = $phpNotices; + $this->phpWarnings = $phpWarnings; + $this->numberOfIssuesIgnoredByBaseline = $numberOfIssuesIgnoredByBaseline; } public function numberOfTestsRun() : int { @@ -71027,36 +77745,6 @@ final class TestResult { return $this->numberOfTestMarkedIncompleteEvents() > 0; } - /** - * @psalm-return array> - */ - public function testTriggeredDeprecationEvents() : array - { - return $this->testTriggeredDeprecationEvents; - } - public function numberOfTestsWithTestTriggeredDeprecationEvents() : int - { - return count($this->testTriggeredDeprecationEvents); - } - public function hasTestTriggeredDeprecationEvents() : bool - { - return $this->numberOfTestsWithTestTriggeredDeprecationEvents() > 0; - } - /** - * @psalm-return array> - */ - public function testTriggeredPhpDeprecationEvents() : array - { - return $this->testTriggeredPhpDeprecationEvents; - } - public function numberOfTestsWithTestTriggeredPhpDeprecationEvents() : int - { - return count($this->testTriggeredPhpDeprecationEvents); - } - public function hasTestTriggeredPhpDeprecationEvents() : bool - { - return $this->numberOfTestsWithTestTriggeredPhpDeprecationEvents() > 0; - } /** * @psalm-return array> */ @@ -71073,179 +77761,188 @@ final class TestResult return $this->numberOfTestsWithTestTriggeredPhpunitDeprecationEvents() > 0; } /** - * @psalm-return array> + * @psalm-return array> */ - public function testTriggeredErrorEvents() : array + public function testTriggeredPhpunitErrorEvents() : array { - return $this->testTriggeredErrorEvents; + return $this->testTriggeredPhpunitErrorEvents; } - public function numberOfTestsWithTestTriggeredErrorEvents() : int + public function numberOfTestsWithTestTriggeredPhpunitErrorEvents() : int { - return count($this->testTriggeredErrorEvents); + return count($this->testTriggeredPhpunitErrorEvents); } - public function hasTestTriggeredErrorEvents() : bool + public function hasTestTriggeredPhpunitErrorEvents() : bool { - return $this->numberOfTestsWithTestTriggeredErrorEvents() > 0; + return $this->numberOfTestsWithTestTriggeredPhpunitErrorEvents() > 0; } /** - * @psalm-return array> + * @psalm-return array> */ - public function testTriggeredNoticeEvents() : array + public function testTriggeredPhpunitWarningEvents() : array { - return $this->testTriggeredNoticeEvents; + return $this->testTriggeredPhpunitWarningEvents; } - public function numberOfTestsWithTestTriggeredNoticeEvents() : int + public function numberOfTestsWithTestTriggeredPhpunitWarningEvents() : int { - return count($this->testTriggeredNoticeEvents); + return count($this->testTriggeredPhpunitWarningEvents); } - public function hasTestTriggeredNoticeEvents() : bool + public function hasTestTriggeredPhpunitWarningEvents() : bool { - return $this->numberOfTestsWithTestTriggeredNoticeEvents() > 0; + return $this->numberOfTestsWithTestTriggeredPhpunitWarningEvents() > 0; } /** - * @psalm-return array> + * @psalm-return list */ - public function testTriggeredPhpNoticeEvents() : array + public function testRunnerTriggeredDeprecationEvents() : array { - return $this->testTriggeredPhpNoticeEvents; + return $this->testRunnerTriggeredDeprecationEvents; } - public function numberOfTestsWithTestTriggeredPhpNoticeEvents() : int + public function numberOfTestRunnerTriggeredDeprecationEvents() : int { - return count($this->testTriggeredPhpNoticeEvents); + return count($this->testRunnerTriggeredDeprecationEvents); } - public function hasTestTriggeredPhpNoticeEvents() : bool + public function hasTestRunnerTriggeredDeprecationEvents() : bool { - return $this->numberOfTestsWithTestTriggeredPhpNoticeEvents() > 0; + return $this->numberOfTestRunnerTriggeredDeprecationEvents() > 0; } /** - * @psalm-return array> + * @psalm-return list */ - public function testTriggeredWarningEvents() : array + public function testRunnerTriggeredWarningEvents() : array + { + return $this->testRunnerTriggeredWarningEvents; + } + public function numberOfTestRunnerTriggeredWarningEvents() : int { - return $this->testTriggeredWarningEvents; + return count($this->testRunnerTriggeredWarningEvents); } - public function numberOfTestsWithTestTriggeredWarningEvents() : int + public function hasTestRunnerTriggeredWarningEvents() : bool { - return count($this->testTriggeredWarningEvents); + return $this->numberOfTestRunnerTriggeredWarningEvents() > 0; } - public function hasTestTriggeredWarningEvents() : bool + public function wasSuccessful() : bool { - return $this->numberOfTestsWithTestTriggeredWarningEvents() > 0; + return $this->wasSuccessfulIgnoringPhpunitWarnings() && !$this->hasTestTriggeredPhpunitErrorEvents() && !$this->hasTestRunnerTriggeredWarningEvents() && !$this->hasTestTriggeredPhpunitWarningEvents(); } - /** - * @psalm-return array> - */ - public function testTriggeredPhpWarningEvents() : array + public function wasSuccessfulIgnoringPhpunitWarnings() : bool { - return $this->testTriggeredPhpWarningEvents; + return !$this->hasTestErroredEvents() && !$this->hasTestFailedEvents(); } - public function numberOfTestsWithTestTriggeredPhpWarningEvents() : int + public function wasSuccessfulAndNoTestHasIssues() : bool { - return count($this->testTriggeredPhpWarningEvents); + return $this->wasSuccessful() && !$this->hasTestsWithIssues(); } - public function hasTestTriggeredPhpWarningEvents() : bool + public function hasTestsWithIssues() : bool { - return $this->numberOfTestsWithTestTriggeredPhpWarningEvents() > 0; + return $this->hasRiskyTests() || $this->hasIncompleteTests() || $this->hasDeprecations() || !empty($this->errors) || $this->hasNotices() || $this->hasWarnings(); } /** - * @psalm-return array> + * @psalm-return list */ - public function testTriggeredPhpunitErrorEvents() : array - { - return $this->testTriggeredPhpunitErrorEvents; - } - public function numberOfTestsWithTestTriggeredPhpunitErrorEvents() : int + public function errors() : array { - return count($this->testTriggeredPhpunitErrorEvents); + return $this->errors; } - public function hasTestTriggeredPhpunitErrorEvents() : bool + /** + * @psalm-return list + */ + public function deprecations() : array { - return $this->numberOfTestsWithTestTriggeredPhpunitErrorEvents() > 0; + return $this->deprecations; } /** - * @psalm-return array> + * @psalm-return list */ - public function testTriggeredPhpunitWarningEvents() : array + public function notices() : array { - return $this->testTriggeredPhpunitWarningEvents; + return $this->notices; } - public function numberOfTestsWithTestTriggeredPhpunitWarningEvents() : int + /** + * @psalm-return list + */ + public function warnings() : array { - return count($this->testTriggeredPhpunitWarningEvents); + return $this->warnings; } - public function hasTestTriggeredPhpunitWarningEvents() : bool + /** + * @psalm-return list + */ + public function phpDeprecations() : array { - return $this->numberOfTestsWithTestTriggeredPhpunitWarningEvents() > 0; + return $this->phpDeprecations; } /** - * @psalm-return list + * @psalm-return list */ - public function testRunnerTriggeredDeprecationEvents() : array + public function phpNotices() : array { - return $this->testRunnerTriggeredDeprecationEvents; + return $this->phpNotices; } - public function numberOfTestRunnerTriggeredDeprecationEvents() : int + /** + * @psalm-return list + */ + public function phpWarnings() : array { - return count($this->testRunnerTriggeredDeprecationEvents); + return $this->phpWarnings; } - public function hasTestRunnerTriggeredDeprecationEvents() : bool + public function hasTests() : bool { - return $this->numberOfTestRunnerTriggeredDeprecationEvents() > 0; + return $this->numberOfTests > 0; } - /** - * @psalm-return list - */ - public function testRunnerTriggeredWarningEvents() : array + public function hasErrors() : bool { - return $this->testRunnerTriggeredWarningEvents; + return $this->numberOfErrors() > 0; } - public function numberOfTestRunnerTriggeredWarningEvents() : int + public function numberOfErrors() : int { - return count($this->testRunnerTriggeredWarningEvents); + return $this->numberOfTestErroredEvents() + count($this->errors) + $this->numberOfTestsWithTestTriggeredPhpunitErrorEvents(); } - public function hasTestRunnerTriggeredWarningEvents() : bool + public function hasDeprecations() : bool { - return $this->numberOfTestRunnerTriggeredWarningEvents() > 0; + return $this->numberOfDeprecations() > 0; } - public function hasDeprecationEvents() : bool + public function numberOfDeprecations() : int { - return $this->numberOfDeprecationEvents() > 0; + return count($this->deprecations) + count($this->phpDeprecations) + count($this->testTriggeredPhpunitDeprecationEvents) + count($this->testRunnerTriggeredDeprecationEvents); } - public function numberOfDeprecationEvents() : int + public function hasNotices() : bool { - return $this->numberOfTestsWithTestTriggeredDeprecationEvents() + $this->numberOfTestsWithTestTriggeredPhpDeprecationEvents() + $this->numberOfTestRunnerTriggeredDeprecationEvents() + $this->numberOfTestsWithTestTriggeredPhpunitDeprecationEvents(); + return $this->numberOfNotices() > 0; } - public function hasNoticeEvents() : bool + public function numberOfNotices() : int { - return $this->numberOfNoticeEvents() > 0; + return count($this->notices) + count($this->phpNotices); } - public function numberOfNoticeEvents() : int + public function hasWarnings() : bool { - return $this->numberOfTestsWithTestTriggeredNoticeEvents() + $this->numberOfTestsWithTestTriggeredPhpNoticeEvents(); + return $this->numberOfWarnings() > 0; } - public function hasWarningEvents() : bool + public function numberOfWarnings() : int { - return $this->numberOfWarningEvents() > 0; + return count($this->warnings) + count($this->phpWarnings) + count($this->testTriggeredPhpunitWarningEvents) + count($this->testRunnerTriggeredWarningEvents); } - public function numberOfWarningEvents() : int + public function hasIncompleteTests() : bool { - return $this->numberOfTestsWithTestTriggeredWarningEvents() + $this->numberOfTestsWithTestTriggeredPhpWarningEvents() + $this->numberOfTestsWithTestTriggeredPhpunitWarningEvents() + $this->numberOfTestRunnerTriggeredWarningEvents(); + return !empty($this->testMarkedIncompleteEvents); } - public function wasSuccessful() : bool + public function hasRiskyTests() : bool { - return $this->wasSuccessfulIgnoringPhpunitWarnings() && !$this->hasTestRunnerTriggeredWarningEvents() && !$this->hasTestTriggeredPhpunitWarningEvents(); + return !empty($this->testConsideredRiskyEvents); } - public function wasSuccessfulIgnoringPhpunitWarnings() : bool + public function hasSkippedTests() : bool { - return !$this->hasTestErroredEvents() && !$this->hasTestFailedEvents(); + return !empty($this->testSkippedEvents); } - public function wasSuccessfulAndNoTestHasIssues() : bool + public function hasIssuesIgnoredByBaseline() : bool { - return $this->wasSuccessful() && !$this->hasTestsWithIssues(); + return $this->numberOfIssuesIgnoredByBaseline > 0; } - public function hasTestsWithIssues() : bool + /** + * @psalm-return non-negative-int + */ + public function numberOfIssuesIgnoredByBaseline() : int { - return $this->hasTestConsideredRiskyEvents() || $this->hasTestMarkedIncompleteEvents() || $this->hasDeprecationEvents() || $this->hasTestTriggeredErrorEvents() || $this->hasNoticeEvents() || $this->hasWarningEvents(); + return $this->numberOfIssuesIgnoredByBaseline; } } */ - private static array $loadedClasses = []; + private static array $declaredClasses = []; /** - * @psalm-var list + * @psalm-var array> */ - private static array $declaredClasses = []; - public function __construct() - { - if (empty(self::$declaredClasses)) { - self::$declaredClasses = get_declared_classes(); - } - } + private static array $fileToClassesMap = []; /** * @throws Exception */ public function load(string $suiteClassFile) : ReflectionClass { + $suiteClassFile = realpath($suiteClassFile); $suiteClassName = $this->classNameFromFileName($suiteClassFile); - if (!class_exists($suiteClassName, \false)) { - include_once $suiteClassFile; - $loadedClasses = array_values(array_diff(get_declared_classes(), array_merge(self::$declaredClasses, self::$loadedClasses))); - self::$loadedClasses = array_merge($loadedClasses, self::$loadedClasses); - if (empty(self::$loadedClasses)) { - throw new \PHPUnit\Runner\ClassCannotBeFoundException($suiteClassName, $suiteClassFile); - } - } - if (!class_exists($suiteClassName, \false)) { - $offset = 0 - strlen($suiteClassName); - foreach (self::$loadedClasses as $loadedClass) { - if (stripos(substr($loadedClass, $offset - 1), '\\' . $suiteClassName) === 0 || stripos(substr($loadedClass, $offset - 1), '_' . $suiteClassName) === 0) { - $suiteClassName = $loadedClass; - break; - } + $loadedClasses = $this->loadSuiteClassFile($suiteClassFile); + foreach ($loadedClasses as $className) { + /** @noinspection PhpUnhandledExceptionInspection */ + $class = new ReflectionClass($className); + if ($class->isAnonymous()) { + continue; + } + if ($class->getFileName() !== $suiteClassFile) { + continue; + } + if (!$class->isSubclassOf(TestCase::class)) { + continue; } + if (!str_ends_with(strtolower($class->getShortName()), strtolower($suiteClassName))) { + continue; + } + if (!$class->isAbstract()) { + return $class; + } + $e = new \PHPUnit\Runner\ClassIsAbstractException($class->getName(), $suiteClassFile); } - if (!class_exists($suiteClassName, \false)) { - throw new \PHPUnit\Runner\ClassCannotBeFoundException($suiteClassName, $suiteClassFile); + if (isset($e)) { + throw $e; } - $class = new ReflectionClass($suiteClassName); - if ($class->isSubclassOf(TestCase::class)) { - if ($class->isAbstract()) { - throw new \PHPUnit\Runner\ClassIsAbstractException($suiteClassName, $suiteClassFile); - } - return $class; + if (!class_exists($suiteClassName)) { + throw new \PHPUnit\Runner\ClassCannotBeFoundException($suiteClassName, $suiteClassFile); } - throw new \PHPUnit\Runner\ClassCannotBeFoundException($suiteClassName, $suiteClassFile); + throw new \PHPUnit\Runner\ClassDoesNotExtendTestCaseException($suiteClassName, $suiteClassFile); } private function classNameFromFileName(string $suiteClassFile) : string { @@ -71336,6 +78028,33 @@ final class TestSuiteLoader } return $className; } + /** + * @psalm-return list + */ + private function loadSuiteClassFile(string $suiteClassFile) : array + { + if (isset(self::$fileToClassesMap[$suiteClassFile])) { + return self::$fileToClassesMap[$suiteClassFile]; + } + if (empty(self::$declaredClasses)) { + self::$declaredClasses = get_declared_classes(); + } + require_once $suiteClassFile; + $loadedClasses = array_values(array_diff(get_declared_classes(), self::$declaredClasses)); + foreach ($loadedClasses as $loadedClass) { + /** @noinspection PhpUnhandledExceptionInspection */ + $class = new ReflectionClass($loadedClass); + if (!isset(self::$fileToClassesMap[$class->getFileName()])) { + self::$fileToClassesMap[$class->getFileName()] = []; + } + self::$fileToClassesMap[$class->getFileName()][] = $class->getName(); + } + self::$declaredClasses = get_declared_classes(); + if (empty($loadedClasses)) { + return self::$declaredClasses; + } + return $loadedClasses; + } } setTests($this->reverse($suite->tests())); } elseif ($order === self::ORDER_RANDOMIZED) { $suite->setTests($this->randomize($suite->tests())); - } elseif ($order === self::ORDER_DURATION && $this->cache !== null) { + } elseif ($order === self::ORDER_DURATION) { $suite->setTests($this->sortByDuration($suite->tests())); } elseif ($order === self::ORDER_SIZE) { $suite->setTests($this->sortBySize($suite->tests())); } - if ($orderDefects === self::ORDER_DEFECTS_FIRST && $this->cache !== null) { + if ($orderDefects === self::ORDER_DEFECTS_FIRST) { $suite->setTests($this->sortDefectsFirst($suite->tests())); } if ($resolveDependencies && !$suite instanceof DataProviderTestSuite) { @@ -71634,7 +78353,7 @@ final class Version return self::$pharVersion; } if (self::$version === '') { - self::$version = (new VersionId('10.0.16', dirname(__DIR__, 2)))->asString(); + self::$version = (new VersionId('10.5.8', dirname(__DIR__, 2)))->asString(); } return self::$version; } @@ -71673,7 +78392,9 @@ use function realpath; use function sprintf; use function trim; use function unlink; +use PHPUnit\Event\EventFacadeIsSealedException; use PHPUnit\Event\Facade as EventFacade; +use PHPUnit\Event\UnknownSubscriberTypeException; use PHPUnit\Framework\TestSuite; use PHPUnit\Logging\EventLogger; use PHPUnit\Logging\JUnit\JunitXmlLogger; @@ -71681,10 +78402,17 @@ use PHPUnit\Logging\TeamCity\TeamCityLogger; use PHPUnit\Logging\TestDox\HtmlRenderer as TestDoxHtmlRenderer; use PHPUnit\Logging\TestDox\PlainTextRenderer as TestDoxTextRenderer; use PHPUnit\Logging\TestDox\TestResultCollector as TestDoxResultCollector; +use PHPUnit\Metadata\Api\CodeCoverage as CodeCoverageMetadataApi; +use PHPUnit\Runner\Baseline\CannotLoadBaselineException; +use PHPUnit\Runner\Baseline\Generator as BaselineGenerator; +use PHPUnit\Runner\Baseline\Reader; +use PHPUnit\Runner\Baseline\Writer; use PHPUnit\Runner\CodeCoverage; +use PHPUnit\Runner\ErrorHandler; use PHPUnit\Runner\Extension\ExtensionBootstrapper; use PHPUnit\Runner\Extension\Facade as ExtensionFacade; use PHPUnit\Runner\Extension\PharLoader; +use PHPUnit\Runner\GarbageCollection\GarbageCollectionHandler; use PHPUnit\Runner\ResultCache\DefaultResultCache; use PHPUnit\Runner\ResultCache\NullResultCache; use PHPUnit\Runner\ResultCache\ResultCache; @@ -71744,23 +78472,48 @@ final class Application $this->executeCommandsThatRequireCliConfigurationAndTestSuite($cliConfiguration, $testSuite); $this->executeHelpCommandWhenThereIsNothingElseToDo($configuration, $testSuite); $pharExtensions = null; + $extensionRequiresCodeCoverageCollection = \false; + $extensionReplacesOutput = \false; + $extensionReplacesProgressOutput = \false; + $extensionReplacesResultOutput = \false; + $extensionRequiresExportOfObjects = \false; if (!$configuration->noExtensions()) { if ($configuration->hasPharExtensionDirectory()) { $pharExtensions = (new PharLoader())->loadPharExtensionsInDirectory($configuration->pharExtensionDirectory()); } - $this->bootstrapExtensions($configuration); - } - CodeCoverage::instance()->init($configuration, CodeCoverageFilterRegistry::instance()); - $printer = OutputFacade::init($configuration); - $this->writeRuntimeInformation($printer, $configuration); - $this->writePharExtensionInformation($printer, $pharExtensions); - $this->writeRandomSeedInformation($printer, $configuration); - $printer->print(PHP_EOL); + $bootstrappedExtensions = $this->bootstrapExtensions($configuration); + $extensionRequiresCodeCoverageCollection = $bootstrappedExtensions['requiresCodeCoverageCollection']; + $extensionReplacesOutput = $bootstrappedExtensions['replacesOutput']; + $extensionReplacesProgressOutput = $bootstrappedExtensions['replacesProgressOutput']; + $extensionReplacesResultOutput = $bootstrappedExtensions['replacesResultOutput']; + $extensionRequiresExportOfObjects = $bootstrappedExtensions['requiresExportOfObjects']; + } + if ($extensionRequiresExportOfObjects) { + EventFacade::emitter()->exportObjects(); + } + CodeCoverage::instance()->init($configuration, CodeCoverageFilterRegistry::instance(), $extensionRequiresCodeCoverageCollection); + if (CodeCoverage::instance()->isActive()) { + CodeCoverage::instance()->ignoreLines((new CodeCoverageMetadataApi())->linesToBeIgnored($testSuite)); + } + $printer = OutputFacade::init($configuration, $extensionReplacesProgressOutput, $extensionReplacesResultOutput); + if (!$configuration->debug() && !$extensionReplacesOutput) { + $this->writeRuntimeInformation($printer, $configuration); + $this->writePharExtensionInformation($printer, $pharExtensions); + $this->writeRandomSeedInformation($printer, $configuration); + $printer->print(PHP_EOL); + } + if ($configuration->debug()) { + EventFacade::instance()->registerTracer(new EventLogger('php://stdout', \false)); + } $this->registerLogfileWriters($configuration); $testDoxResultCollector = $this->testDoxResultCollector($configuration); TestResultFacade::init(); $resultCache = $this->initializeTestResultCache($configuration); - EventFacade::seal(); + if ($configuration->controlGarbageCollector()) { + new GarbageCollectionHandler(EventFacade::instance(), $configuration->numberOfTestsBeforeGarbageCollection()); + } + $baselineGenerator = $this->configureBaseline($configuration); + EventFacade::instance()->seal(); $timer = new Timer(); $timer->start(); $runner = new \PHPUnit\TextUI\TestRunner(); @@ -71777,33 +78530,22 @@ final class Application OutputFacade::printerFor($configuration->logfileTestdoxText())->print((new TestDoxTextRenderer())->render($testDoxResult)); } $result = TestResultFacade::result(); - OutputFacade::printResult($result, $testDoxResult, $duration); + if (!$extensionReplacesResultOutput) { + OutputFacade::printResult($result, $testDoxResult, $duration); + } CodeCoverage::instance()->generateReports($printer, $configuration); - $shellExitCode = (new \PHPUnit\TextUI\ShellExitCodeCalculator())->calculate($configuration->failOnEmptyTestSuite(), $configuration->failOnRisky(), $configuration->failOnWarning(), $configuration->failOnIncomplete(), $configuration->failOnSkipped(), $result); + if (isset($baselineGenerator)) { + (new Writer())->write($configuration->generateBaseline(), $baselineGenerator->baseline()); + $printer->print(sprintf(PHP_EOL . 'Baseline written to %s.' . PHP_EOL, realpath($configuration->generateBaseline()))); + } + $shellExitCode = (new \PHPUnit\TextUI\ShellExitCodeCalculator())->calculate($configuration->failOnDeprecation(), $configuration->failOnEmptyTestSuite(), $configuration->failOnIncomplete(), $configuration->failOnNotice(), $configuration->failOnRisky(), $configuration->failOnSkipped(), $configuration->failOnWarning(), $result); EventFacade::emitter()->applicationFinished($shellExitCode); return $shellExitCode; + // @codeCoverageIgnoreStart } catch (Throwable $t) { $this->exitWithCrashMessage($t); } - } - private function exitWithCrashMessage(Throwable $t) : never - { - $message = $t->getMessage(); - if (empty(trim($message))) { - $message = '(no message)'; - } - printf('%s%sAn error occurred inside PHPUnit.%s%sMessage: %s', PHP_EOL, PHP_EOL, PHP_EOL, PHP_EOL, $message); - $first = \true; - do { - printf('%s%s: %s:%d%s%s%s%s', PHP_EOL, $first ? 'Location' : 'Caused by', $t->getFile(), $t->getLine(), PHP_EOL, PHP_EOL, $t->getTraceAsString(), PHP_EOL); - $first = \false; - } while ($t = $t->getPrevious()); - exit(Result::CRASH); - } - private function exitWithErrorMessage(string $message) : never - { - print Version::getVersionString() . PHP_EOL . PHP_EOL . $message . PHP_EOL; - exit(Result::EXCEPTION); + // @codeCoverageIgnoreEnd } private function execute(\PHPUnit\TextUI\Command\Command $command) : never { @@ -71820,7 +78562,11 @@ final class Application try { include_once $filename; } catch (Throwable $t) { - $this->exitWithErrorMessage(sprintf('Error in bootstrap script: %s:%s%s%s%s', $t::class, PHP_EOL, $t->getMessage(), PHP_EOL, $t->getTraceAsString())); + $message = sprintf('Error in bootstrap script: %s:%s%s%s%s', $t::class, PHP_EOL, $t->getMessage(), PHP_EOL, $t->getTraceAsString()); + while ($t = $t->getPrevious()) { + $message .= sprintf('%s%sPrevious error: %s:%s%s%s%s', PHP_EOL, PHP_EOL, $t::class, PHP_EOL, $t->getMessage(), PHP_EOL, $t->getTraceAsString()); + } + $this->exitWithErrorMessage($message); } EventFacade::emitter()->testRunnerBootstrapFinished($filename); } @@ -71833,7 +78579,7 @@ final class Application } return $cliConfiguration; } - private function loadXmlConfiguration(string|false $configurationFile) : XmlConfiguration + private function loadXmlConfiguration(false|string $configurationFile) : XmlConfiguration { if (!$configurationFile) { return DefaultConfiguration::create(); @@ -71852,18 +78598,19 @@ final class Application $this->exitWithErrorMessage($e->getMessage()); } } - private function bootstrapExtensions(Configuration $configuration) : void + /** + * @psalm-return array{requiresCodeCoverageCollection: bool, replacesOutput: bool, replacesProgressOutput: bool, replacesResultOutput: bool, requiresExportOfObjects: bool} + */ + private function bootstrapExtensions(Configuration $configuration) : array { - $extensionBootstrapper = new ExtensionBootstrapper($configuration, new ExtensionFacade()); + $facade = new ExtensionFacade(); + $extensionBootstrapper = new ExtensionBootstrapper($configuration, $facade); foreach ($configuration->extensionBootstrappers() as $bootstrapper) { - try { - $extensionBootstrapper->bootstrap($bootstrapper['className'], $bootstrapper['parameters']); - } catch (\PHPUnit\Runner\Exception $e) { - $this->exitWithErrorMessage(sprintf('Error while bootstrapping extension: %s', $e->getMessage())); - } + $extensionBootstrapper->bootstrap($bootstrapper['className'], $bootstrapper['parameters']); } + return ['requiresCodeCoverageCollection' => $facade->requiresCodeCoverageCollection(), 'replacesOutput' => $facade->replacesOutput(), 'replacesProgressOutput' => $facade->replacesProgressOutput(), 'replacesResultOutput' => $facade->replacesResultOutput(), 'requiresExportOfObjects' => $facade->requiresExportOfObjects()]; } - private function executeCommandsThatOnlyRequireCliConfiguration(CliConfiguration $cliConfiguration, string|false $configurationFile) : void + private function executeCommandsThatOnlyRequireCliConfiguration(CliConfiguration $cliConfiguration, false|string $configurationFile) : void { if ($cliConfiguration->generateConfiguration()) { $this->execute(new GenerateConfigurationCommand()); @@ -71910,7 +78657,7 @@ final class Application } private function executeHelpCommandWhenThereIsNothingElseToDo(Configuration $configuration, TestSuite $testSuite) : void { - if ($testSuite->isEmpty() && !$configuration->hasCliArgument() && $configuration->testSuite()->isEmpty()) { + if ($testSuite->isEmpty() && !$configuration->hasCliArguments() && $configuration->testSuite()->isEmpty()) { $this->execute(new ShowHelpCommand(Result::FAILURE)); } } @@ -71927,17 +78674,14 @@ final class Application } } /** - * @psalm-param ?array{loadedExtensions: list, notLoadedExtensions: list} $pharExtensions + * @psalm-param ?list $pharExtensions */ private function writePharExtensionInformation(Printer $printer, ?array $pharExtensions) : void { if ($pharExtensions === null) { return; } - foreach ($pharExtensions['loadedExtensions'] as $extension) { - $this->writeMessage($printer, 'Extension', $extension); - } - foreach ($pharExtensions['notLoadedExtensions'] as $extension) { + foreach ($pharExtensions as $extension) { $this->writeMessage($printer, 'Extension', $extension); } } @@ -71951,43 +78695,105 @@ final class Application $this->writeMessage($printer, 'Random Seed', (string) $configuration->randomOrderSeed()); } } + /** + * @throws EventFacadeIsSealedException + * @throws UnknownSubscriberTypeException + */ private function registerLogfileWriters(Configuration $configuration) : void { if ($configuration->hasLogEventsText()) { if (is_file($configuration->logEventsText())) { unlink($configuration->logEventsText()); } - EventFacade::registerTracer(new EventLogger($configuration->logEventsText(), \false)); + EventFacade::instance()->registerTracer(new EventLogger($configuration->logEventsText(), \false)); } if ($configuration->hasLogEventsVerboseText()) { if (is_file($configuration->logEventsVerboseText())) { unlink($configuration->logEventsVerboseText()); } - EventFacade::registerTracer(new EventLogger($configuration->logEventsVerboseText(), \true)); + EventFacade::instance()->registerTracer(new EventLogger($configuration->logEventsVerboseText(), \true)); + EventFacade::emitter()->exportObjects(); } if ($configuration->hasLogfileJunit()) { - new JunitXmlLogger(OutputFacade::printerFor($configuration->logfileJunit())); + new JunitXmlLogger(OutputFacade::printerFor($configuration->logfileJunit()), EventFacade::instance()); } if ($configuration->hasLogfileTeamcity()) { - new TeamCityLogger(DefaultPrinter::from($configuration->logfileTeamcity())); + new TeamCityLogger(DefaultPrinter::from($configuration->logfileTeamcity()), EventFacade::instance()); } } + /** + * @throws EventFacadeIsSealedException + * @throws UnknownSubscriberTypeException + */ private function testDoxResultCollector(Configuration $configuration) : ?TestDoxResultCollector { if ($configuration->hasLogfileTestdoxHtml() || $configuration->hasLogfileTestdoxText() || $configuration->outputIsTestDox()) { - return new TestDoxResultCollector(); + return new TestDoxResultCollector(EventFacade::instance()); } return null; } + /** + * @throws EventFacadeIsSealedException + * @throws UnknownSubscriberTypeException + */ private function initializeTestResultCache(Configuration $configuration) : ResultCache { if ($configuration->cacheResult()) { $cache = new DefaultResultCache($configuration->testResultCacheFile()); - new ResultCacheHandler($cache); + new ResultCacheHandler($cache, EventFacade::instance()); return $cache; } return new NullResultCache(); } + /** + * @throws EventFacadeIsSealedException + * @throws UnknownSubscriberTypeException + */ + private function configureBaseline(Configuration $configuration) : ?BaselineGenerator + { + if ($configuration->hasGenerateBaseline()) { + return new BaselineGenerator(EventFacade::instance(), $configuration->source()); + } + if ($configuration->source()->useBaseline()) { + /** @psalm-suppress MissingThrowsDocblock */ + $baselineFile = $configuration->source()->baseline(); + $baseline = null; + try { + $baseline = (new Reader())->read($baselineFile); + } catch (CannotLoadBaselineException $e) { + EventFacade::emitter()->testRunnerTriggeredWarning($e->getMessage()); + } + if ($baseline !== null) { + ErrorHandler::instance()->use($baseline); + } + } + return null; + } + /** + * @codeCoverageIgnore + */ + private function exitWithCrashMessage(Throwable $t) : never + { + $message = $t->getMessage(); + if (empty(trim($message))) { + $message = '(no message)'; + } + printf('%s%sAn error occurred inside PHPUnit.%s%sMessage: %s', PHP_EOL, PHP_EOL, PHP_EOL, PHP_EOL, $message); + $first = \true; + if ($t->getPrevious()) { + $t = $t->getPrevious(); + } + do { + printf('%s%s: %s:%d%s%s%s%s', PHP_EOL, $first ? 'Location' : 'Caused by', $t->getFile(), $t->getLine(), PHP_EOL, PHP_EOL, $t->getTraceAsString(), PHP_EOL); + $first = \false; + } while ($t = $t->getPrevious()); + exit(Result::CRASH); + } + private function exitWithErrorMessage(string $message) : never + { + print Version::getVersionString() . PHP_EOL . PHP_EOL . $message . PHP_EOL; + exit(Result::EXCEPTION); + } } warnAboutConflictingOptions(); $buffer .= 'Available test group(s):' . \PHP_EOL; - $groups = $this->suite->getGroups(); + $groups = $this->suite->groups(); sort($groups); foreach ($groups as $group) { if (str_starts_with($group, '__phpunit_')) { @@ -72342,13 +79148,19 @@ final class ListTestsAsXmlCommand implements \PHPUnit\TextUI\Command\Command $currentTestCase = $test::class; } $writer->startElement('testCaseMethod'); + $writer->writeAttribute('id', $test->valueObjectForEvents()->id()); $writer->writeAttribute('name', $test->name()); $writer->writeAttribute('groups', implode(',', $test->groups())); + /** + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5481 + */ if (!empty($test->dataSetAsString())) { $writer->writeAttribute('dataSet', str_replace(' with data set ', '', $test->dataSetAsString())); } $writer->endElement(); - } elseif ($test instanceof PhptTestCase) { + continue; + } + if ($test instanceof PhptTestCase) { if ($currentTestCase !== null) { $writer->endElement(); $currentTestCase = null; @@ -72400,6 +79212,7 @@ namespace PHPUnit\TextUI\Command; use function copy; use function file_put_contents; +use function sprintf; use PHPUnit\TextUI\XmlConfiguration\Migrator; use Throwable; /** @@ -72414,17 +79227,14 @@ final class MigrateConfigurationCommand implements \PHPUnit\TextUI\Command\Comma } public function execute() : \PHPUnit\TextUI\Command\Result { - copy($this->filename, $this->filename . '.bak'); - $buffer = 'Created backup: ' . $this->filename . '.bak' . \PHP_EOL; - $shellExitCode = \PHPUnit\TextUI\Command\Result::SUCCESS; try { - file_put_contents($this->filename, (new Migrator())->migrate($this->filename)); - $buffer .= 'Migrated configuration: ' . $this->filename . \PHP_EOL; + $migrated = (new Migrator())->migrate($this->filename); + copy($this->filename, $this->filename . '.bak'); + file_put_contents($this->filename, $migrated); + return \PHPUnit\TextUI\Command\Result::from(sprintf('Created backup: %s.bak%sMigrated configuration: %s%s', $this->filename, \PHP_EOL, $this->filename, \PHP_EOL)); } catch (Throwable $t) { - $buffer .= 'Migration failed: ' . $t->getMessage() . \PHP_EOL; - $shellExitCode = \PHPUnit\TextUI\Command\Result::FAILURE; + return \PHPUnit\TextUI\Command\Result::from(sprintf('Migration of %s failed:%s%s%s', $this->filename, \PHP_EOL, $t->getMessage(), \PHP_EOL), \PHPUnit\TextUI\Command\Result::FAILURE); } - return \PHPUnit\TextUI\Command\Result::from($buffer, $shellExitCode); } } configuration->hasCoverageCacheDirectory()) { - return \PHPUnit\TextUI\Command\Result::from('Cache for static analysis has not been configured' . \PHP_EOL, \PHPUnit\TextUI\Command\Result::FAILURE); + return \PHPUnit\TextUI\Command\Result::from('Cache for static analysis has not been configured' . PHP_EOL, \PHPUnit\TextUI\Command\Result::FAILURE); } - $this->codeCoverageFilterRegistry->init($this->configuration); + $this->codeCoverageFilterRegistry->init($this->configuration, \true); if (!$this->codeCoverageFilterRegistry->configured()) { - return \PHPUnit\TextUI\Command\Result::from('Filter for code coverage has not been configured' . \PHP_EOL, \PHPUnit\TextUI\Command\Result::FAILURE); + return \PHPUnit\TextUI\Command\Result::from('Filter for code coverage has not been configured' . PHP_EOL, \PHPUnit\TextUI\Command\Result::FAILURE); } $timer = new Timer(); $timer->start(); print 'Warming cache for static analysis ... '; (new CacheWarmer())->warmCache($this->configuration->coverageCacheDirectory(), !$this->configuration->disableCodeCoverageIgnore(), $this->configuration->ignoreDeprecatedCodeUnitsFromCodeCoverage(), $this->codeCoverageFilterRegistry->get()); - printf('[%s]%s', $timer->stop()->asString(), \PHP_EOL); + printf('[%s]%s', $timer->stop()->asString(), PHP_EOL); return \PHPUnit\TextUI\Command\Result::from(); } } @@ -72629,6 +79442,8 @@ use PHPUnit\TextUI\XmlConfiguration\Exception as XmlConfigurationException; use PHPUnit\TextUI\XmlConfiguration\Loader; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + * + * @codeCoverageIgnore */ final class Builder { @@ -72664,10 +79479,14 @@ declare (strict_types=1); namespace PHPUnit\TextUI\CliArguments; use function array_map; +use function basename; use function explode; +use function getcwd; +use function is_file; use function is_numeric; use function sprintf; use PHPUnit\Runner\TestSuiteSorter; +use PHPUnit\Util\Filesystem; use PHPUnit\SebastianBergmann\CliParser\Exception as CliParserException; use PHPUnit\SebastianBergmann\CliParser\Parser as CliParser; /** @@ -72675,8 +79494,8 @@ use PHPUnit\SebastianBergmann\CliParser\Parser as CliParser; */ final class Builder { - private const LONG_OPTIONS = ['atleast-version=', 'bootstrap=', 'cache-result', 'do-not-cache-result', 'cache-directory=', 'cache-result-file=', 'check-version', 'colors==', 'columns=', 'configuration=', 'coverage-cache=', 'warm-coverage-cache', 'coverage-filter=', 'coverage-clover=', 'coverage-cobertura=', 'coverage-crap4j=', 'coverage-html=', 'coverage-php=', 'coverage-text==', 'coverage-xml=', 'path-coverage', 'disallow-test-output', 'display-incomplete', 'display-skipped', 'display-deprecations', 'display-errors', 'display-notices', 'display-warnings', 'default-time-limit=', 'enforce-time-limit', 'exclude-group=', 'filter=', 'generate-configuration', 'globals-backup', 'group=', 'covers=', 'uses=', 'help', 'resolve-dependencies', 'ignore-dependencies', 'include-path=', 'list-groups', 'list-suites', 'list-tests', 'list-tests-xml=', 'log-junit=', 'log-teamcity=', 'migrate-configuration', 'no-configuration', 'no-coverage', 'no-logging', 'no-extensions', 'no-output', 'no-progress', 'no-results', 'order-by=', 'process-isolation', 'dont-report-useless-tests', 'random-order', 'random-order-seed=', 'reverse-order', 'reverse-list', 'static-backup', 'stderr', 'stop-on-defect', 'stop-on-error', 'stop-on-failure', 'stop-on-warning', 'stop-on-incomplete', 'stop-on-risky', 'stop-on-skipped', 'fail-on-empty-test-suite', 'fail-on-incomplete', 'fail-on-risky', 'fail-on-skipped', 'fail-on-warning', 'strict-coverage', 'disable-coverage-ignore', 'strict-global-state', 'teamcity', 'testdox', 'testdox-html=', 'testdox-text=', 'test-suffix=', 'testsuite=', 'exclude-testsuite=', 'log-events-text=', 'log-events-verbose-text=', 'version']; - private const SHORT_OPTIONS = 'd:c:hv'; + private const LONG_OPTIONS = ['atleast-version=', 'bootstrap=', 'cache-result', 'do-not-cache-result', 'cache-directory=', 'cache-result-file=', 'check-version', 'colors==', 'columns=', 'configuration=', 'coverage-cache=', 'warm-coverage-cache', 'coverage-filter=', 'coverage-clover=', 'coverage-cobertura=', 'coverage-crap4j=', 'coverage-html=', 'coverage-php=', 'coverage-text==', 'coverage-xml=', 'path-coverage', 'disallow-test-output', 'display-incomplete', 'display-skipped', 'display-deprecations', 'display-errors', 'display-notices', 'display-warnings', 'default-time-limit=', 'enforce-time-limit', 'exclude-group=', 'filter=', 'generate-baseline=', 'use-baseline=', 'ignore-baseline', 'generate-configuration', 'globals-backup', 'group=', 'covers=', 'uses=', 'help', 'resolve-dependencies', 'ignore-dependencies', 'include-path=', 'list-groups', 'list-suites', 'list-tests', 'list-tests-xml=', 'log-junit=', 'log-teamcity=', 'migrate-configuration', 'no-configuration', 'no-coverage', 'no-logging', 'no-extensions', 'no-output', 'no-progress', 'no-results', 'order-by=', 'process-isolation', 'dont-report-useless-tests', 'random-order', 'random-order-seed=', 'reverse-order', 'reverse-list', 'static-backup', 'stderr', 'fail-on-deprecation', 'fail-on-empty-test-suite', 'fail-on-incomplete', 'fail-on-notice', 'fail-on-risky', 'fail-on-skipped', 'fail-on-warning', 'stop-on-defect', 'stop-on-deprecation', 'stop-on-error', 'stop-on-failure', 'stop-on-incomplete', 'stop-on-notice', 'stop-on-risky', 'stop-on-skipped', 'stop-on-warning', 'strict-coverage', 'disable-coverage-ignore', 'strict-global-state', 'teamcity', 'testdox', 'testdox-html=', 'testdox-text=', 'test-suffix=', 'testsuite=', 'exclude-testsuite=', 'log-events-text=', 'log-events-verbose-text=', 'version', 'debug']; + private const SHORT_OPTIONS = 'd:c:h'; /** * @throws Exception */ @@ -72687,7 +79506,6 @@ final class Builder } catch (CliParserException $e) { throw new \PHPUnit\TextUI\CliArguments\Exception($e->getMessage(), $e->getCode(), $e); } - $argument = null; $atLeastVersion = null; $backupGlobals = null; $backupStaticProperties = null; @@ -72726,12 +79544,26 @@ final class Builder $excludeGroups = null; $executionOrder = null; $executionOrderDefects = null; + $failOnDeprecation = null; $failOnEmptyTestSuite = null; $failOnIncomplete = null; + $failOnNotice = null; $failOnRisky = null; $failOnSkipped = null; $failOnWarning = null; + $stopOnDefect = null; + $stopOnDeprecation = null; + $stopOnError = null; + $stopOnFailure = null; + $stopOnIncomplete = null; + $stopOnNotice = null; + $stopOnRisky = null; + $stopOnSkipped = null; + $stopOnWarning = null; $filter = null; + $generateBaseline = null; + $useBaseline = null; + $ignoreBaseline = \false; $generateConfiguration = \false; $migrateConfiguration = \false; $groups = null; @@ -72758,13 +79590,6 @@ final class Builder $reverseList = null; $stderr = null; $strictCoverage = null; - $stopOnDefect = null; - $stopOnError = null; - $stopOnFailure = null; - $stopOnIncomplete = null; - $stopOnRisky = null; - $stopOnSkipped = null; - $stopOnWarning = null; $teamcityLogfile = null; $testdoxHtmlFile = null; $testdoxTextFile = null; @@ -72777,9 +79602,7 @@ final class Builder $logEventsVerboseText = null; $printerTeamCity = null; $printerTestDox = null; - if (isset($options[1][0])) { - $argument = $options[1][0]; - } + $debug = \false; foreach ($options[0] as $option) { switch ($option[0]) { case '--colors': @@ -72869,6 +79692,21 @@ final class Builder case '--exclude-testsuite': $excludeTestSuite = $option[1]; break; + case '--generate-baseline': + $generateBaseline = $option[1]; + if (basename($generateBaseline) === $generateBaseline) { + $generateBaseline = getcwd() . \DIRECTORY_SEPARATOR . $generateBaseline; + } + break; + case '--use-baseline': + $useBaseline = $option[1]; + if (!is_file($useBaseline) && basename($useBaseline) === $useBaseline) { + $useBaseline = getcwd() . \DIRECTORY_SEPARATOR . $useBaseline; + } + break; + case '--ignore-baseline': + $ignoreBaseline = \true; + break; case '--generate-configuration': $generateConfiguration = \true; break; @@ -72951,41 +79789,53 @@ final class Builder case '--stderr': $stderr = \true; break; + case '--fail-on-deprecation': + $failOnDeprecation = \true; + break; + case '--fail-on-empty-test-suite': + $failOnEmptyTestSuite = \true; + break; + case '--fail-on-incomplete': + $failOnIncomplete = \true; + break; + case '--fail-on-notice': + $failOnNotice = \true; + break; + case '--fail-on-risky': + $failOnRisky = \true; + break; + case '--fail-on-skipped': + $failOnSkipped = \true; + break; + case '--fail-on-warning': + $failOnWarning = \true; + break; case '--stop-on-defect': $stopOnDefect = \true; break; + case '--stop-on-deprecation': + $stopOnDeprecation = \true; + break; case '--stop-on-error': $stopOnError = \true; break; case '--stop-on-failure': $stopOnFailure = \true; break; - case '--stop-on-warning': - $stopOnWarning = \true; - break; case '--stop-on-incomplete': $stopOnIncomplete = \true; break; + case '--stop-on-notice': + $stopOnNotice = \true; + break; case '--stop-on-risky': $stopOnRisky = \true; break; case '--stop-on-skipped': $stopOnSkipped = \true; break; - case '--fail-on-empty-test-suite': - $failOnEmptyTestSuite = \true; - break; - case '--fail-on-incomplete': - $failOnIncomplete = \true; - break; - case '--fail-on-risky': - $failOnRisky = \true; - break; - case '--fail-on-skipped': - $failOnSkipped = \true; - break; - case '--fail-on-warning': - $failOnWarning = \true; + case '--stop-on-warning': + $stopOnWarning = \true; break; case '--teamcity': $printerTeamCity = \true; @@ -73099,10 +79949,19 @@ final class Builder $executionOrder = TestSuiteSorter::ORDER_REVERSED; break; case '--log-events-text': - $logEventsText = $option[1]; + $logEventsText = Filesystem::resolvePathOrStream($option[1]); + if (!$logEventsText) { + throw new \PHPUnit\TextUI\CliArguments\Exception(sprintf('The path "%s" specified for the --log-events-text option could not be resolved', $option[1])); + } break; case '--log-events-verbose-text': - $logEventsVerboseText = $option[1]; + $logEventsVerboseText = Filesystem::resolvePathOrStream($option[1]); + if (!$logEventsVerboseText) { + throw new \PHPUnit\TextUI\CliArguments\Exception(sprintf('The path "%s" specified for the --log-events-verbose-text option could not be resolved', $option[1])); + } + break; + case '--debug': + $debug = \true; break; } } @@ -73112,7 +79971,7 @@ final class Builder if (empty($coverageFilter)) { $coverageFilter = null; } - return new \PHPUnit\TextUI\CliArguments\Configuration($argument, $atLeastVersion, $backupGlobals, $backupStaticProperties, $beStrictAboutChangesToGlobalState, $bootstrap, $cacheDirectory, $cacheResult, $cacheResultFile, $checkVersion, $colors, $columns, $configuration, $coverageClover, $coverageCobertura, $coverageCrap4J, $coverageHtml, $coveragePhp, $coverageText, $coverageTextShowUncoveredFiles, $coverageTextShowOnlySummary, $coverageXml, $pathCoverage, $coverageCacheDirectory, $warmCoverageCache, $defaultTimeLimit, $disableCodeCoverageIgnore, $disallowTestOutput, $enforceTimeLimit, $excludeGroups, $executionOrder, $executionOrderDefects, $failOnEmptyTestSuite, $failOnIncomplete, $failOnRisky, $failOnSkipped, $failOnWarning, $filter, $generateConfiguration, $migrateConfiguration, $groups, $testsCovering, $testsUsing, $help, $includePath, $iniSettings, $junitLogfile, $listGroups, $listSuites, $listTests, $listTestsXml, $noCoverage, $noExtensions, $noOutput, $noProgress, $noResults, $noLogging, $processIsolation, $randomOrderSeed, $reportUselessTests, $resolveDependencies, $reverseList, $stderr, $strictCoverage, $stopOnDefect, $stopOnError, $stopOnFailure, $stopOnIncomplete, $stopOnRisky, $stopOnSkipped, $stopOnWarning, $teamcityLogfile, $testdoxHtmlFile, $testdoxTextFile, $testSuffixes, $testSuite, $excludeTestSuite, $useDefaultConfiguration, $displayIncomplete, $displaySkipped, $displayDeprecations, $displayErrors, $displayNotices, $displayWarnings, $version, $coverageFilter, $logEventsText, $logEventsVerboseText, $printerTeamCity, $printerTestDox); + return new \PHPUnit\TextUI\CliArguments\Configuration($options[1], $atLeastVersion, $backupGlobals, $backupStaticProperties, $beStrictAboutChangesToGlobalState, $bootstrap, $cacheDirectory, $cacheResult, $cacheResultFile, $checkVersion, $colors, $columns, $configuration, $coverageClover, $coverageCobertura, $coverageCrap4J, $coverageHtml, $coveragePhp, $coverageText, $coverageTextShowUncoveredFiles, $coverageTextShowOnlySummary, $coverageXml, $pathCoverage, $coverageCacheDirectory, $warmCoverageCache, $defaultTimeLimit, $disableCodeCoverageIgnore, $disallowTestOutput, $enforceTimeLimit, $excludeGroups, $executionOrder, $executionOrderDefects, $failOnDeprecation, $failOnEmptyTestSuite, $failOnIncomplete, $failOnNotice, $failOnRisky, $failOnSkipped, $failOnWarning, $stopOnDefect, $stopOnDeprecation, $stopOnError, $stopOnFailure, $stopOnIncomplete, $stopOnNotice, $stopOnRisky, $stopOnSkipped, $stopOnWarning, $filter, $generateBaseline, $useBaseline, $ignoreBaseline, $generateConfiguration, $migrateConfiguration, $groups, $testsCovering, $testsUsing, $help, $includePath, $iniSettings, $junitLogfile, $listGroups, $listSuites, $listTests, $listTestsXml, $noCoverage, $noExtensions, $noOutput, $noProgress, $noResults, $noLogging, $processIsolation, $randomOrderSeed, $reportUselessTests, $resolveDependencies, $reverseList, $stderr, $strictCoverage, $teamcityLogfile, $testdoxHtmlFile, $testdoxTextFile, $testSuffixes, $testSuite, $excludeTestSuite, $useDefaultConfiguration, $displayIncomplete, $displaySkipped, $displayDeprecations, $displayErrors, $displayNotices, $displayWarnings, $version, $coverageFilter, $logEventsText, $logEventsVerboseText, $printerTeamCity, $printerTestDox, $debug); } } + */ + private readonly array $arguments; private readonly ?string $atLeastVersion; private readonly ?bool $backupGlobals; private readonly ?bool $backupStaticProperties; @@ -73168,12 +80030,26 @@ final class Configuration private readonly ?array $excludeGroups; private readonly ?int $executionOrder; private readonly ?int $executionOrderDefects; + private readonly ?bool $failOnDeprecation; private readonly ?bool $failOnEmptyTestSuite; private readonly ?bool $failOnIncomplete; + private readonly ?bool $failOnNotice; private readonly ?bool $failOnRisky; private readonly ?bool $failOnSkipped; private readonly ?bool $failOnWarning; + private readonly ?bool $stopOnDefect; + private readonly ?bool $stopOnDeprecation; + private readonly ?bool $stopOnError; + private readonly ?bool $stopOnFailure; + private readonly ?bool $stopOnIncomplete; + private readonly ?bool $stopOnNotice; + private readonly ?bool $stopOnRisky; + private readonly ?bool $stopOnSkipped; + private readonly ?bool $stopOnWarning; private readonly ?string $filter; + private readonly ?string $generateBaseline; + private readonly ?string $useBaseline; + private readonly bool $ignoreBaseline; private readonly bool $generateConfiguration; private readonly bool $migrateConfiguration; private readonly ?array $groups; @@ -73200,20 +80076,13 @@ final class Configuration private readonly ?bool $reverseList; private readonly ?bool $stderr; private readonly ?bool $strictCoverage; - private readonly ?bool $stopOnDefect; - private readonly ?bool $stopOnError; - private readonly ?bool $stopOnFailure; - private readonly ?bool $stopOnIncomplete; - private readonly ?bool $stopOnRisky; - private readonly ?bool $stopOnSkipped; - private readonly ?bool $stopOnWarning; private readonly ?string $teamcityLogfile; private readonly ?bool $teamCityPrinter; private readonly ?string $testdoxHtmlFile; private readonly ?string $testdoxTextFile; private readonly ?bool $testdoxPrinter; /** - * @psalm-var ?non-empty-list + * @psalm-var ?non-empty-list */ private readonly ?array $testSuffixes; private readonly ?string $testSuite; @@ -73228,12 +80097,14 @@ final class Configuration private readonly bool $version; private readonly ?string $logEventsText; private readonly ?string $logEventsVerboseText; + private readonly bool $debug; /** - * @psalm-param ?non-empty-list $testSuffixes + * @psalm-param list $arguments + * @psalm-param ?non-empty-list $testSuffixes */ - public function __construct(?string $argument, ?string $atLeastVersion, ?bool $backupGlobals, ?bool $backupStaticProperties, ?bool $beStrictAboutChangesToGlobalState, ?string $bootstrap, ?string $cacheDirectory, ?bool $cacheResult, ?string $cacheResultFile, bool $checkVersion, ?string $colors, null|int|string $columns, ?string $configurationFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4J, ?string $coverageHtml, ?string $coveragePhp, ?string $coverageText, ?bool $coverageTextShowUncoveredFiles, ?bool $coverageTextShowOnlySummary, ?string $coverageXml, ?bool $pathCoverage, ?string $coverageCacheDirectory, bool $warmCoverageCache, ?int $defaultTimeLimit, ?bool $disableCodeCoverageIgnore, ?bool $disallowTestOutput, ?bool $enforceTimeLimit, ?array $excludeGroups, ?int $executionOrder, ?int $executionOrderDefects, ?bool $failOnEmptyTestSuite, ?bool $failOnIncomplete, ?bool $failOnRisky, ?bool $failOnSkipped, ?bool $failOnWarning, ?string $filter, bool $generateConfiguration, bool $migrateConfiguration, ?array $groups, ?array $testsCovering, ?array $testsUsing, bool $help, ?string $includePath, ?array $iniSettings, ?string $junitLogfile, bool $listGroups, bool $listSuites, bool $listTests, ?string $listTestsXml, ?bool $noCoverage, ?bool $noExtensions, ?bool $noOutput, ?bool $noProgress, ?bool $noResults, ?bool $noLogging, ?bool $processIsolation, ?int $randomOrderSeed, ?bool $reportUselessTests, ?bool $resolveDependencies, ?bool $reverseList, ?bool $stderr, ?bool $strictCoverage, ?bool $stopOnDefect, ?bool $stopOnError, ?bool $stopOnFailure, ?bool $stopOnIncomplete, ?bool $stopOnRisky, ?bool $stopOnSkipped, ?bool $stopOnWarning, ?string $teamcityLogfile, ?string $testdoxHtmlFile, ?string $testdoxTextFile, ?array $testSuffixes, ?string $testSuite, ?string $excludeTestSuite, bool $useDefaultConfiguration, ?bool $displayDetailsOnIncompleteTests, ?bool $displayDetailsOnSkippedTests, ?bool $displayDetailsOnTestsThatTriggerDeprecations, ?bool $displayDetailsOnTestsThatTriggerErrors, ?bool $displayDetailsOnTestsThatTriggerNotices, ?bool $displayDetailsOnTestsThatTriggerWarnings, bool $version, ?array $coverageFilter, ?string $logEventsText, ?string $logEventsVerboseText, ?bool $printerTeamCity, ?bool $printerTestDox) + public function __construct(array $arguments, ?string $atLeastVersion, ?bool $backupGlobals, ?bool $backupStaticProperties, ?bool $beStrictAboutChangesToGlobalState, ?string $bootstrap, ?string $cacheDirectory, ?bool $cacheResult, ?string $cacheResultFile, bool $checkVersion, ?string $colors, null|int|string $columns, ?string $configurationFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4J, ?string $coverageHtml, ?string $coveragePhp, ?string $coverageText, ?bool $coverageTextShowUncoveredFiles, ?bool $coverageTextShowOnlySummary, ?string $coverageXml, ?bool $pathCoverage, ?string $coverageCacheDirectory, bool $warmCoverageCache, ?int $defaultTimeLimit, ?bool $disableCodeCoverageIgnore, ?bool $disallowTestOutput, ?bool $enforceTimeLimit, ?array $excludeGroups, ?int $executionOrder, ?int $executionOrderDefects, ?bool $failOnDeprecation, ?bool $failOnEmptyTestSuite, ?bool $failOnIncomplete, ?bool $failOnNotice, ?bool $failOnRisky, ?bool $failOnSkipped, ?bool $failOnWarning, ?bool $stopOnDefect, ?bool $stopOnDeprecation, ?bool $stopOnError, ?bool $stopOnFailure, ?bool $stopOnIncomplete, ?bool $stopOnNotice, ?bool $stopOnRisky, ?bool $stopOnSkipped, ?bool $stopOnWarning, ?string $filter, ?string $generateBaseline, ?string $useBaseline, bool $ignoreBaseline, bool $generateConfiguration, bool $migrateConfiguration, ?array $groups, ?array $testsCovering, ?array $testsUsing, bool $help, ?string $includePath, ?array $iniSettings, ?string $junitLogfile, bool $listGroups, bool $listSuites, bool $listTests, ?string $listTestsXml, ?bool $noCoverage, ?bool $noExtensions, ?bool $noOutput, ?bool $noProgress, ?bool $noResults, ?bool $noLogging, ?bool $processIsolation, ?int $randomOrderSeed, ?bool $reportUselessTests, ?bool $resolveDependencies, ?bool $reverseList, ?bool $stderr, ?bool $strictCoverage, ?string $teamcityLogfile, ?string $testdoxHtmlFile, ?string $testdoxTextFile, ?array $testSuffixes, ?string $testSuite, ?string $excludeTestSuite, bool $useDefaultConfiguration, ?bool $displayDetailsOnIncompleteTests, ?bool $displayDetailsOnSkippedTests, ?bool $displayDetailsOnTestsThatTriggerDeprecations, ?bool $displayDetailsOnTestsThatTriggerErrors, ?bool $displayDetailsOnTestsThatTriggerNotices, ?bool $displayDetailsOnTestsThatTriggerWarnings, bool $version, ?array $coverageFilter, ?string $logEventsText, ?string $logEventsVerboseText, ?bool $printerTeamCity, ?bool $printerTestDox, bool $debug) { - $this->argument = $argument; + $this->arguments = $arguments; $this->atLeastVersion = $atLeastVersion; $this->backupGlobals = $backupGlobals; $this->backupStaticProperties = $backupStaticProperties; @@ -73266,12 +80137,26 @@ final class Configuration $this->excludeGroups = $excludeGroups; $this->executionOrder = $executionOrder; $this->executionOrderDefects = $executionOrderDefects; + $this->failOnDeprecation = $failOnDeprecation; $this->failOnEmptyTestSuite = $failOnEmptyTestSuite; $this->failOnIncomplete = $failOnIncomplete; + $this->failOnNotice = $failOnNotice; $this->failOnRisky = $failOnRisky; $this->failOnSkipped = $failOnSkipped; $this->failOnWarning = $failOnWarning; + $this->stopOnDefect = $stopOnDefect; + $this->stopOnDeprecation = $stopOnDeprecation; + $this->stopOnError = $stopOnError; + $this->stopOnFailure = $stopOnFailure; + $this->stopOnIncomplete = $stopOnIncomplete; + $this->stopOnNotice = $stopOnNotice; + $this->stopOnRisky = $stopOnRisky; + $this->stopOnSkipped = $stopOnSkipped; + $this->stopOnWarning = $stopOnWarning; $this->filter = $filter; + $this->generateBaseline = $generateBaseline; + $this->useBaseline = $useBaseline; + $this->ignoreBaseline = $ignoreBaseline; $this->generateConfiguration = $generateConfiguration; $this->migrateConfiguration = $migrateConfiguration; $this->groups = $groups; @@ -73298,13 +80183,6 @@ final class Configuration $this->reverseList = $reverseList; $this->stderr = $stderr; $this->strictCoverage = $strictCoverage; - $this->stopOnDefect = $stopOnDefect; - $this->stopOnError = $stopOnError; - $this->stopOnFailure = $stopOnFailure; - $this->stopOnIncomplete = $stopOnIncomplete; - $this->stopOnRisky = $stopOnRisky; - $this->stopOnSkipped = $stopOnSkipped; - $this->stopOnWarning = $stopOnWarning; $this->teamcityLogfile = $teamcityLogfile; $this->testdoxHtmlFile = $testdoxHtmlFile; $this->testdoxTextFile = $testdoxTextFile; @@ -73323,23 +80201,14 @@ final class Configuration $this->logEventsVerboseText = $logEventsVerboseText; $this->teamCityPrinter = $printerTeamCity; $this->testdoxPrinter = $printerTestDox; + $this->debug = $debug; } /** - * @psalm-assert-if-true !null $this->argument - */ - public function hasArgument() : bool - { - return $this->argument !== null; - } - /** - * @throws Exception + * @psalm-return list */ - public function argument() : string + public function arguments() : array { - if (!$this->hasArgument()) { - throw new \PHPUnit\TextUI\CliArguments\Exception(); - } - return $this->argument; + return $this->arguments; } /** * @psalm-assert-if-true !null $this->atLeastVersion @@ -73462,6 +80331,8 @@ final class Configuration } /** * @psalm-assert-if-true !null $this->cacheResultFile + * + * @deprecated */ public function hasCacheResultFile() : bool { @@ -73469,6 +80340,8 @@ final class Configuration } /** * @throws Exception + * + * @deprecated */ public function cacheResultFile() : string { @@ -73721,6 +80594,8 @@ final class Configuration } /** * @psalm-assert-if-true !null $this->coverageCacheDirectory + * + * @deprecated */ public function hasCoverageCacheDirectory() : bool { @@ -73728,6 +80603,8 @@ final class Configuration } /** * @throws Exception + * + * @deprecated */ public function coverageCacheDirectory() : string { @@ -73859,6 +80736,23 @@ final class Configuration } return $this->executionOrderDefects; } + /** + * @psalm-assert-if-true !null $this->failOnDeprecation + */ + public function hasFailOnDeprecation() : bool + { + return $this->failOnDeprecation !== null; + } + /** + * @throws Exception + */ + public function failOnDeprecation() : bool + { + if (!$this->hasFailOnDeprecation()) { + throw new \PHPUnit\TextUI\CliArguments\Exception(); + } + return $this->failOnDeprecation; + } /** * @psalm-assert-if-true !null $this->failOnEmptyTestSuite */ @@ -73893,6 +80787,23 @@ final class Configuration } return $this->failOnIncomplete; } + /** + * @psalm-assert-if-true !null $this->failOnNotice + */ + public function hasFailOnNotice() : bool + { + return $this->failOnNotice !== null; + } + /** + * @throws Exception + */ + public function failOnNotice() : bool + { + if (!$this->hasFailOnNotice()) { + throw new \PHPUnit\TextUI\CliArguments\Exception(); + } + return $this->failOnNotice; + } /** * @psalm-assert-if-true !null $this->failOnRisky */ @@ -73944,6 +80855,159 @@ final class Configuration } return $this->failOnWarning; } + /** + * @psalm-assert-if-true !null $this->stopOnDefect + */ + public function hasStopOnDefect() : bool + { + return $this->stopOnDefect !== null; + } + /** + * @throws Exception + */ + public function stopOnDefect() : bool + { + if (!$this->hasStopOnDefect()) { + throw new \PHPUnit\TextUI\CliArguments\Exception(); + } + return $this->stopOnDefect; + } + /** + * @psalm-assert-if-true !null $this->stopOnDeprecation + */ + public function hasStopOnDeprecation() : bool + { + return $this->stopOnDeprecation !== null; + } + /** + * @throws Exception + */ + public function stopOnDeprecation() : bool + { + if (!$this->hasStopOnDeprecation()) { + throw new \PHPUnit\TextUI\CliArguments\Exception(); + } + return $this->stopOnDeprecation; + } + /** + * @psalm-assert-if-true !null $this->stopOnError + */ + public function hasStopOnError() : bool + { + return $this->stopOnError !== null; + } + /** + * @throws Exception + */ + public function stopOnError() : bool + { + if (!$this->hasStopOnError()) { + throw new \PHPUnit\TextUI\CliArguments\Exception(); + } + return $this->stopOnError; + } + /** + * @psalm-assert-if-true !null $this->stopOnFailure + */ + public function hasStopOnFailure() : bool + { + return $this->stopOnFailure !== null; + } + /** + * @throws Exception + */ + public function stopOnFailure() : bool + { + if (!$this->hasStopOnFailure()) { + throw new \PHPUnit\TextUI\CliArguments\Exception(); + } + return $this->stopOnFailure; + } + /** + * @psalm-assert-if-true !null $this->stopOnIncomplete + */ + public function hasStopOnIncomplete() : bool + { + return $this->stopOnIncomplete !== null; + } + /** + * @throws Exception + */ + public function stopOnIncomplete() : bool + { + if (!$this->hasStopOnIncomplete()) { + throw new \PHPUnit\TextUI\CliArguments\Exception(); + } + return $this->stopOnIncomplete; + } + /** + * @psalm-assert-if-true !null $this->stopOnNotice + */ + public function hasStopOnNotice() : bool + { + return $this->stopOnNotice !== null; + } + /** + * @throws Exception + */ + public function stopOnNotice() : bool + { + if (!$this->hasStopOnNotice()) { + throw new \PHPUnit\TextUI\CliArguments\Exception(); + } + return $this->stopOnNotice; + } + /** + * @psalm-assert-if-true !null $this->stopOnRisky + */ + public function hasStopOnRisky() : bool + { + return $this->stopOnRisky !== null; + } + /** + * @throws Exception + */ + public function stopOnRisky() : bool + { + if (!$this->hasStopOnRisky()) { + throw new \PHPUnit\TextUI\CliArguments\Exception(); + } + return $this->stopOnRisky; + } + /** + * @psalm-assert-if-true !null $this->stopOnSkipped + */ + public function hasStopOnSkipped() : bool + { + return $this->stopOnSkipped !== null; + } + /** + * @throws Exception + */ + public function stopOnSkipped() : bool + { + if (!$this->hasStopOnSkipped()) { + throw new \PHPUnit\TextUI\CliArguments\Exception(); + } + return $this->stopOnSkipped; + } + /** + * @psalm-assert-if-true !null $this->stopOnWarning + */ + public function hasStopOnWarning() : bool + { + return $this->stopOnWarning !== null; + } + /** + * @throws Exception + */ + public function stopOnWarning() : bool + { + if (!$this->hasStopOnWarning()) { + throw new \PHPUnit\TextUI\CliArguments\Exception(); + } + return $this->stopOnWarning; + } /** * @psalm-assert-if-true !null $this->filter */ @@ -73961,6 +81025,44 @@ final class Configuration } return $this->filter; } + /** + * @psalm-assert-if-true !null $this->generateBaseline + */ + public function hasGenerateBaseline() : bool + { + return $this->generateBaseline !== null; + } + /** + * @throws Exception + */ + public function generateBaseline() : string + { + if (!$this->hasGenerateBaseline()) { + throw new \PHPUnit\TextUI\CliArguments\Exception(); + } + return $this->generateBaseline; + } + /** + * @psalm-assert-if-true !null $this->useBaseline + */ + public function hasUseBaseline() : bool + { + return $this->useBaseline !== null; + } + /** + * @throws Exception + */ + public function useBaseline() : string + { + if (!$this->hasUseBaseline()) { + throw new \PHPUnit\TextUI\CliArguments\Exception(); + } + return $this->useBaseline; + } + public function ignoreBaseline() : bool + { + return $this->ignoreBaseline; + } public function generateConfiguration() : bool { return $this->generateConfiguration; @@ -74325,125 +81427,6 @@ final class Configuration } return $this->strictCoverage; } - /** - * @psalm-assert-if-true !null $this->stopOnDefect - */ - public function hasStopOnDefect() : bool - { - return $this->stopOnDefect !== null; - } - /** - * @throws Exception - */ - public function stopOnDefect() : bool - { - if (!$this->hasStopOnDefect()) { - throw new \PHPUnit\TextUI\CliArguments\Exception(); - } - return $this->stopOnDefect; - } - /** - * @psalm-assert-if-true !null $this->stopOnError - */ - public function hasStopOnError() : bool - { - return $this->stopOnError !== null; - } - /** - * @throws Exception - */ - public function stopOnError() : bool - { - if (!$this->hasStopOnError()) { - throw new \PHPUnit\TextUI\CliArguments\Exception(); - } - return $this->stopOnError; - } - /** - * @psalm-assert-if-true !null $this->stopOnFailure - */ - public function hasStopOnFailure() : bool - { - return $this->stopOnFailure !== null; - } - /** - * @throws Exception - */ - public function stopOnFailure() : bool - { - if (!$this->hasStopOnFailure()) { - throw new \PHPUnit\TextUI\CliArguments\Exception(); - } - return $this->stopOnFailure; - } - /** - * @psalm-assert-if-true !null $this->stopOnIncomplete - */ - public function hasStopOnIncomplete() : bool - { - return $this->stopOnIncomplete !== null; - } - /** - * @throws Exception - */ - public function stopOnIncomplete() : bool - { - if (!$this->hasStopOnIncomplete()) { - throw new \PHPUnit\TextUI\CliArguments\Exception(); - } - return $this->stopOnIncomplete; - } - /** - * @psalm-assert-if-true !null $this->stopOnRisky - */ - public function hasStopOnRisky() : bool - { - return $this->stopOnRisky !== null; - } - /** - * @throws Exception - */ - public function stopOnRisky() : bool - { - if (!$this->hasStopOnRisky()) { - throw new \PHPUnit\TextUI\CliArguments\Exception(); - } - return $this->stopOnRisky; - } - /** - * @psalm-assert-if-true !null $this->stopOnSkipped - */ - public function hasStopOnSkipped() : bool - { - return $this->stopOnSkipped !== null; - } - /** - * @throws Exception - */ - public function stopOnSkipped() : bool - { - if (!$this->hasStopOnSkipped()) { - throw new \PHPUnit\TextUI\CliArguments\Exception(); - } - return $this->stopOnSkipped; - } - /** - * @psalm-assert-if-true !null $this->stopOnWarning - */ - public function hasStopOnWarning() : bool - { - return $this->stopOnWarning !== null; - } - /** - * @throws Exception - */ - public function stopOnWarning() : bool - { - if (!$this->hasStopOnWarning()) { - throw new \PHPUnit\TextUI\CliArguments\Exception(); - } - return $this->stopOnWarning; - } /** * @psalm-assert-if-true !null $this->teamcityLogfile */ @@ -74537,7 +81520,7 @@ final class Configuration return $this->testSuffixes !== null; } /** - * @psalm-return non-empty-list + * @psalm-return non-empty-list * * @throws Exception */ @@ -74726,6 +81709,10 @@ final class Configuration } return $this->logEventsVerboseText; } + public function debug() : bool + { + return $this->debug; + } } useDefaultConfiguration(); if ($configuration->hasConfigurationFile()) { @@ -74790,7 +81777,7 @@ final class XmlConfigurationFileFinder } return \false; } - private function configurationFileInDirectory(string $directory) : string|false + private function configurationFileInDirectory(string $directory) : false|string { $candidates = [$directory . '/phpunit.xml', $directory . '/phpunit.dist.xml', $directory . '/phpunit.xml.dist']; foreach ($candidates as $candidate) { @@ -74814,6 +81801,7 @@ declare (strict_types=1); */ namespace PHPUnit\TextUI\Configuration; +use function array_keys; use function assert; use PHPUnit\SebastianBergmann\CodeCoverage\Filter; /** @@ -74839,28 +81827,17 @@ final class CodeCoverageFilterRegistry assert($this->filter !== null); return $this->filter; } - public function init(\PHPUnit\TextUI\Configuration\Configuration $configuration) : void + public function init(\PHPUnit\TextUI\Configuration\Configuration $configuration, bool $force = \false) : void { - if (!$configuration->hasCoverageReport()) { + if (!$configuration->hasCoverageReport() && !$force) { return; } - if ($this->configured) { + if ($this->configured && !$force) { return; } $this->filter = new Filter(); - if ($configuration->hasNonEmptyListOfFilesToBeIncludedInCodeCoverageReport()) { - foreach ($configuration->coverageIncludeDirectories() as $directory) { - $this->filter->includeDirectory($directory->path(), $directory->suffix(), $directory->prefix()); - } - foreach ($configuration->coverageIncludeFiles() as $file) { - $this->filter->includeFile($file->path()); - } - foreach ($configuration->coverageExcludeDirectories() as $directory) { - $this->filter->excludeDirectory($directory->path(), $directory->suffix(), $directory->prefix()); - } - foreach ($configuration->coverageExcludeFiles() as $file) { - $this->filter->excludeFile($file->path()); - } + if ($configuration->source()->notEmpty()) { + $this->filter->includeFiles(array_keys((new \PHPUnit\TextUI\Configuration\SourceMapper())->map($configuration->source()))); $this->configured = \true; } } @@ -74893,16 +81870,16 @@ final class Configuration public const COLOR_AUTO = 'auto'; public const COLOR_ALWAYS = 'always'; public const COLOR_DEFAULT = self::COLOR_NEVER; - private readonly ?string $cliArgument; + /** + * @psalm-var list + */ + private readonly array $cliArguments; private readonly ?string $configurationFile; private readonly ?string $bootstrap; private readonly bool $cacheResult; private readonly ?string $cacheDirectory; private readonly ?string $coverageCacheDirectory; - private readonly \PHPUnit\TextUI\Configuration\FilterDirectoryCollection $coverageIncludeDirectories; - private readonly \PHPUnit\TextUI\Configuration\FileCollection $coverageIncludeFiles; - private readonly \PHPUnit\TextUI\Configuration\FilterDirectoryCollection $coverageExcludeDirectories; - private readonly \PHPUnit\TextUI\Configuration\FileCollection $coverageExcludeFiles; + private readonly \PHPUnit\TextUI\Configuration\Source $source; private readonly bool $pathCoverage; private readonly ?string $coverageClover; private readonly ?string $coverageCobertura; @@ -74925,14 +81902,28 @@ final class Configuration private readonly string $testResultCacheFile; private readonly bool $ignoreDeprecatedCodeUnitsFromCodeCoverage; private readonly bool $disableCodeCoverageIgnore; + private readonly bool $failOnDeprecation; private readonly bool $failOnEmptyTestSuite; private readonly bool $failOnIncomplete; + private readonly bool $failOnNotice; private readonly bool $failOnRisky; private readonly bool $failOnSkipped; private readonly bool $failOnWarning; + private readonly bool $stopOnDefect; + private readonly bool $stopOnDeprecation; + private readonly bool $stopOnError; + private readonly bool $stopOnFailure; + private readonly bool $stopOnIncomplete; + private readonly bool $stopOnNotice; + private readonly bool $stopOnRisky; + private readonly bool $stopOnSkipped; + private readonly bool $stopOnWarning; private readonly bool $outputToStandardErrorStream; private readonly int $columns; private readonly bool $noExtensions; + /** + * @psalm-var ?non-empty-string + */ private readonly ?string $pharExtensionDirectory; /** * @psalm-var list}> @@ -74943,13 +81934,6 @@ final class Configuration private readonly bool $beStrictAboutChangesToGlobalState; private readonly bool $colors; private readonly bool $processIsolation; - private readonly bool $stopOnDefect; - private readonly bool $stopOnError; - private readonly bool $stopOnFailure; - private readonly bool $stopOnWarning; - private readonly bool $stopOnIncomplete; - private readonly bool $stopOnRisky; - private readonly bool $stopOnSkipped; private readonly bool $enforceTimeLimit; private readonly int $defaultTimeLimit; private readonly int $timeoutForSmallTests; @@ -74993,26 +81977,29 @@ final class Configuration private readonly string $excludeTestSuite; private readonly ?string $defaultTestSuite; /** - * @psalm-var non-empty-list + * @psalm-var non-empty-list */ private readonly array $testSuffixes; private readonly \PHPUnit\TextUI\Configuration\Php $php; - /** - * @psalm-param non-empty-list $testSuffixes + private readonly bool $controlGarbageCollector; + private readonly int $numberOfTestsBeforeGarbageCollection; + private readonly ?string $generateBaseline; + private readonly bool $debug; + /** + * @psalm-param list $cliArguments + * @psalm-param ?non-empty-string $pharExtensionDirectory + * @psalm-param non-empty-list $testSuffixes * @psalm-param list}> $extensionBootstrappers */ - public function __construct(?string $cliArgument, ?string $configurationFile, ?string $bootstrap, bool $cacheResult, ?string $cacheDirectory, ?string $coverageCacheDirectory, \PHPUnit\TextUI\Configuration\FilterDirectoryCollection $coverageIncludeDirectories, \PHPUnit\TextUI\Configuration\FileCollection $coverageIncludeFiles, \PHPUnit\TextUI\Configuration\FilterDirectoryCollection $coverageExcludeDirectories, \PHPUnit\TextUI\Configuration\FileCollection $coverageExcludeFiles, string $testResultCacheFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4j, int $coverageCrap4jThreshold, ?string $coverageHtml, int $coverageHtmlLowUpperBound, int $coverageHtmlHighLowerBound, string $coverageHtmlColorSuccessLow, string $coverageHtmlColorSuccessMedium, string $coverageHtmlColorSuccessHigh, string $coverageHtmlColorWarning, string $coverageHtmlColorDanger, ?string $coverageHtmlCustomCssFile, ?string $coveragePhp, ?string $coverageText, bool $coverageTextShowUncoveredFiles, bool $coverageTextShowOnlySummary, ?string $coverageXml, bool $pathCoverage, bool $ignoreDeprecatedCodeUnitsFromCodeCoverage, bool $disableCodeCoverageIgnore, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $outputToStandardErrorStream, int|string $columns, bool $noExtensions, ?string $pharExtensionDirectory, array $extensionBootstrappers, bool $backupGlobals, bool $backupStaticProperties, bool $beStrictAboutChangesToGlobalState, bool $colors, bool $processIsolation, bool $stopOnDefect, bool $stopOnError, bool $stopOnFailure, bool $stopOnWarning, bool $stopOnIncomplete, bool $stopOnRisky, bool $stopOnSkipped, bool $enforceTimeLimit, int $defaultTimeLimit, int $timeoutForSmallTests, int $timeoutForMediumTests, int $timeoutForLargeTests, bool $reportUselessTests, bool $strictCoverage, bool $disallowTestOutput, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $reverseDefectList, bool $requireCoverageMetadata, bool $registerMockObjectsFromTestArgumentsRecursively, bool $noProgress, bool $noResults, bool $noOutput, int $executionOrder, int $executionOrderDefects, bool $resolveDependencies, ?string $logfileTeamcity, ?string $logfileJunit, ?string $logfileTestdoxHtml, ?string $logfileTestdoxText, ?string $logEventsText, ?string $logEventsVerboseText, bool $teamCityOutput, bool $testDoxOutput, ?array $testsCovering, ?array $testsUsing, ?string $filter, ?array $groups, ?array $excludeGroups, int $randomOrderSeed, bool $includeUncoveredFiles, \PHPUnit\TextUI\Configuration\TestSuiteCollection $testSuite, string $includeTestSuite, string $excludeTestSuite, ?string $defaultTestSuite, array $testSuffixes, \PHPUnit\TextUI\Configuration\Php $php) + public function __construct(array $cliArguments, ?string $configurationFile, ?string $bootstrap, bool $cacheResult, ?string $cacheDirectory, ?string $coverageCacheDirectory, \PHPUnit\TextUI\Configuration\Source $source, string $testResultCacheFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4j, int $coverageCrap4jThreshold, ?string $coverageHtml, int $coverageHtmlLowUpperBound, int $coverageHtmlHighLowerBound, string $coverageHtmlColorSuccessLow, string $coverageHtmlColorSuccessMedium, string $coverageHtmlColorSuccessHigh, string $coverageHtmlColorWarning, string $coverageHtmlColorDanger, ?string $coverageHtmlCustomCssFile, ?string $coveragePhp, ?string $coverageText, bool $coverageTextShowUncoveredFiles, bool $coverageTextShowOnlySummary, ?string $coverageXml, bool $pathCoverage, bool $ignoreDeprecatedCodeUnitsFromCodeCoverage, bool $disableCodeCoverageIgnore, bool $failOnDeprecation, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnNotice, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $stopOnDefect, bool $stopOnDeprecation, bool $stopOnError, bool $stopOnFailure, bool $stopOnIncomplete, bool $stopOnNotice, bool $stopOnRisky, bool $stopOnSkipped, bool $stopOnWarning, bool $outputToStandardErrorStream, int|string $columns, bool $noExtensions, ?string $pharExtensionDirectory, array $extensionBootstrappers, bool $backupGlobals, bool $backupStaticProperties, bool $beStrictAboutChangesToGlobalState, bool $colors, bool $processIsolation, bool $enforceTimeLimit, int $defaultTimeLimit, int $timeoutForSmallTests, int $timeoutForMediumTests, int $timeoutForLargeTests, bool $reportUselessTests, bool $strictCoverage, bool $disallowTestOutput, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $reverseDefectList, bool $requireCoverageMetadata, bool $registerMockObjectsFromTestArgumentsRecursively, bool $noProgress, bool $noResults, bool $noOutput, int $executionOrder, int $executionOrderDefects, bool $resolveDependencies, ?string $logfileTeamcity, ?string $logfileJunit, ?string $logfileTestdoxHtml, ?string $logfileTestdoxText, ?string $logEventsText, ?string $logEventsVerboseText, bool $teamCityOutput, bool $testDoxOutput, ?array $testsCovering, ?array $testsUsing, ?string $filter, ?array $groups, ?array $excludeGroups, int $randomOrderSeed, bool $includeUncoveredFiles, \PHPUnit\TextUI\Configuration\TestSuiteCollection $testSuite, string $includeTestSuite, string $excludeTestSuite, ?string $defaultTestSuite, array $testSuffixes, \PHPUnit\TextUI\Configuration\Php $php, bool $controlGarbageCollector, int $numberOfTestsBeforeGarbageCollection, ?string $generateBaseline, bool $debug) { - $this->cliArgument = $cliArgument; + $this->cliArguments = $cliArguments; $this->configurationFile = $configurationFile; $this->bootstrap = $bootstrap; $this->cacheResult = $cacheResult; $this->cacheDirectory = $cacheDirectory; $this->coverageCacheDirectory = $coverageCacheDirectory; - $this->coverageIncludeDirectories = $coverageIncludeDirectories; - $this->coverageIncludeFiles = $coverageIncludeFiles; - $this->coverageExcludeDirectories = $coverageExcludeDirectories; - $this->coverageExcludeFiles = $coverageExcludeFiles; + $this->source = $source; $this->testResultCacheFile = $testResultCacheFile; $this->coverageClover = $coverageClover; $this->coverageCobertura = $coverageCobertura; @@ -75035,11 +82022,22 @@ final class Configuration $this->pathCoverage = $pathCoverage; $this->ignoreDeprecatedCodeUnitsFromCodeCoverage = $ignoreDeprecatedCodeUnitsFromCodeCoverage; $this->disableCodeCoverageIgnore = $disableCodeCoverageIgnore; + $this->failOnDeprecation = $failOnDeprecation; $this->failOnEmptyTestSuite = $failOnEmptyTestSuite; $this->failOnIncomplete = $failOnIncomplete; + $this->failOnNotice = $failOnNotice; $this->failOnRisky = $failOnRisky; $this->failOnSkipped = $failOnSkipped; $this->failOnWarning = $failOnWarning; + $this->stopOnDefect = $stopOnDefect; + $this->stopOnDeprecation = $stopOnDeprecation; + $this->stopOnError = $stopOnError; + $this->stopOnFailure = $stopOnFailure; + $this->stopOnIncomplete = $stopOnIncomplete; + $this->stopOnNotice = $stopOnNotice; + $this->stopOnRisky = $stopOnRisky; + $this->stopOnSkipped = $stopOnSkipped; + $this->stopOnWarning = $stopOnWarning; $this->outputToStandardErrorStream = $outputToStandardErrorStream; $this->columns = $columns; $this->noExtensions = $noExtensions; @@ -75050,13 +82048,6 @@ final class Configuration $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState; $this->colors = $colors; $this->processIsolation = $processIsolation; - $this->stopOnDefect = $stopOnDefect; - $this->stopOnError = $stopOnError; - $this->stopOnFailure = $stopOnFailure; - $this->stopOnWarning = $stopOnWarning; - $this->stopOnIncomplete = $stopOnIncomplete; - $this->stopOnRisky = $stopOnRisky; - $this->stopOnSkipped = $stopOnSkipped; $this->enforceTimeLimit = $enforceTimeLimit; $this->defaultTimeLimit = $defaultTimeLimit; $this->timeoutForSmallTests = $timeoutForSmallTests; @@ -75101,23 +82092,47 @@ final class Configuration $this->defaultTestSuite = $defaultTestSuite; $this->testSuffixes = $testSuffixes; $this->php = $php; + $this->controlGarbageCollector = $controlGarbageCollector; + $this->numberOfTestsBeforeGarbageCollection = $numberOfTestsBeforeGarbageCollection; + $this->generateBaseline = $generateBaseline; + $this->debug = $debug; + } + /** + * @psalm-assert-if-true !empty $this->cliArguments + */ + public function hasCliArguments() : bool + { + return !empty($this->cliArguments); } /** - * @psalm-assert-if-true !null $this->cliArgument + * @psalm-return list + */ + public function cliArguments() : array + { + return $this->cliArguments; + } + /** + * @psalm-assert-if-true !empty $this->cliArguments + * + * @deprecated Use hasCliArguments() instead */ public function hasCliArgument() : bool { - return $this->cliArgument !== null; + return !empty($this->cliArguments); } /** * @throws NoCliArgumentException + * + * @return non-empty-string + * + * @deprecated Use cliArguments()[0] instead */ public function cliArgument() : string { - if (!$this->hasCliArgument()) { + if (!$this->hasCliArguments()) { throw new \PHPUnit\TextUI\Configuration\NoCliArgumentException(); } - return $this->cliArgument; + return $this->cliArguments[0]; } /** * @psalm-assert-if-true !null $this->configurationFile @@ -75191,25 +82206,65 @@ final class Configuration } return $this->coverageCacheDirectory; } + public function source() : \PHPUnit\TextUI\Configuration\Source + { + return $this->source; + } + /** + * @deprecated Use source()->restrictDeprecations() instead + */ + public function restrictDeprecations() : bool + { + return $this->source()->restrictDeprecations(); + } + /** + * @deprecated Use source()->restrictNotices() instead + */ + public function restrictNotices() : bool + { + return $this->source()->restrictNotices(); + } + /** + * @deprecated Use source()->restrictWarnings() instead + */ + public function restrictWarnings() : bool + { + return $this->source()->restrictWarnings(); + } + /** + * @deprecated Use source()->notEmpty() instead + */ public function hasNonEmptyListOfFilesToBeIncludedInCodeCoverageReport() : bool { - return $this->coverageIncludeDirectories->notEmpty() || $this->coverageIncludeFiles->notEmpty(); + return $this->source->notEmpty(); } + /** + * @deprecated Use source()->includeDirectories() instead + */ public function coverageIncludeDirectories() : \PHPUnit\TextUI\Configuration\FilterDirectoryCollection { - return $this->coverageIncludeDirectories; + return $this->source()->includeDirectories(); } + /** + * @deprecated Use source()->includeFiles() instead + */ public function coverageIncludeFiles() : \PHPUnit\TextUI\Configuration\FileCollection { - return $this->coverageIncludeFiles; + return $this->source()->includeFiles(); } + /** + * @deprecated Use source()->excludeDirectories() instead + */ public function coverageExcludeDirectories() : \PHPUnit\TextUI\Configuration\FilterDirectoryCollection { - return $this->coverageExcludeDirectories; + return $this->source()->excludeDirectories(); } + /** + * @deprecated Use source()->excludeFiles() instead + */ public function coverageExcludeFiles() : \PHPUnit\TextUI\Configuration\FileCollection { - return $this->coverageExcludeFiles; + return $this->source()->excludeFiles(); } public function testResultCacheFile() : string { @@ -75407,6 +82462,10 @@ final class Configuration } return $this->coverageXml; } + public function failOnDeprecation() : bool + { + return $this->failOnDeprecation; + } public function failOnEmptyTestSuite() : bool { return $this->failOnEmptyTestSuite; @@ -75415,6 +82474,10 @@ final class Configuration { return $this->failOnIncomplete; } + public function failOnNotice() : bool + { + return $this->failOnNotice; + } public function failOnRisky() : bool { return $this->failOnRisky; @@ -75427,6 +82490,42 @@ final class Configuration { return $this->failOnWarning; } + public function stopOnDefect() : bool + { + return $this->stopOnDefect; + } + public function stopOnDeprecation() : bool + { + return $this->stopOnDeprecation; + } + public function stopOnError() : bool + { + return $this->stopOnError; + } + public function stopOnFailure() : bool + { + return $this->stopOnFailure; + } + public function stopOnIncomplete() : bool + { + return $this->stopOnIncomplete; + } + public function stopOnNotice() : bool + { + return $this->stopOnNotice; + } + public function stopOnRisky() : bool + { + return $this->stopOnRisky; + } + public function stopOnSkipped() : bool + { + return $this->stopOnSkipped; + } + public function stopOnWarning() : bool + { + return $this->stopOnWarning; + } public function outputToStandardErrorStream() : bool { return $this->outputToStandardErrorStream; @@ -75454,6 +82553,8 @@ final class Configuration return $this->pharExtensionDirectory !== null; } /** + * @psalm-return non-empty-string + * * @throws NoPharExtensionDirectoryException */ public function pharExtensionDirectory() : string @@ -75490,34 +82591,6 @@ final class Configuration { return $this->processIsolation; } - public function stopOnDefect() : bool - { - return $this->stopOnDefect; - } - public function stopOnError() : bool - { - return $this->stopOnError; - } - public function stopOnFailure() : bool - { - return $this->stopOnFailure; - } - public function stopOnWarning() : bool - { - return $this->stopOnWarning; - } - public function stopOnIncomplete() : bool - { - return $this->stopOnIncomplete; - } - public function stopOnRisky() : bool - { - return $this->stopOnRisky; - } - public function stopOnSkipped() : bool - { - return $this->stopOnSkipped; - } public function enforceTimeLimit() : bool { return $this->enforceTimeLimit; @@ -75582,6 +82655,9 @@ final class Configuration { return $this->requireCoverageMetadata; } + /** + * @deprecated + */ public function registerMockObjectsFromTestArgumentsRecursively() : bool { return $this->registerMockObjectsFromTestArgumentsRecursively; @@ -75847,7 +82923,7 @@ final class Configuration return $this->defaultTestSuite; } /** - * @psalm-return non-empty-list + * @psalm-return non-empty-list */ public function testSuffixes() : array { @@ -75857,6 +82933,56 @@ final class Configuration { return $this->php; } + public function controlGarbageCollector() : bool + { + return $this->controlGarbageCollector; + } + public function numberOfTestsBeforeGarbageCollection() : int + { + return $this->numberOfTestsBeforeGarbageCollection; + } + /** + * @psalm-assert-if-true !null $this->generateBaseline + */ + public function hasGenerateBaseline() : bool + { + return $this->generateBaseline !== null; + } + /** + * @throws NoBaselineException + */ + public function generateBaseline() : string + { + if (!$this->hasGenerateBaseline()) { + throw new \PHPUnit\TextUI\Configuration\NoBaselineException(); + } + return $this->generateBaseline; + } + public function debug() : bool + { + return $this->debug; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +use PHPUnit\TextUI\Configuration\Exception; +use RuntimeException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class CannotFindSchemaException extends RuntimeException implements Exception +{ } + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\Configuration; + use RuntimeException; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit @@ -76163,8 +83309,8 @@ use PHPUnit\Runner\TestSuiteSorter; use PHPUnit\TextUI\CliArguments\Configuration as CliConfiguration; use PHPUnit\TextUI\XmlConfiguration\Configuration as XmlConfiguration; use PHPUnit\TextUI\XmlConfiguration\LoadedFromFileConfiguration; +use PHPUnit\TextUI\XmlConfiguration\SchemaDetector; use PHPUnit\Util\Filesystem; -use PHPUnit\Util\Xml\SchemaDetector; use PHPUnit\SebastianBergmann\CodeCoverage\Report\Html\Colors; use PHPUnit\SebastianBergmann\CodeCoverage\Report\Thresholds; use PHPUnit\SebastianBergmann\Environment\Console; @@ -76181,10 +83327,6 @@ final class Merger */ public function merge(CliConfiguration $cliConfiguration, XmlConfiguration $xmlConfiguration) : \PHPUnit\TextUI\Configuration\Configuration { - $cliArgument = null; - if ($cliConfiguration->hasArgument()) { - $cliArgument = $cliConfiguration->argument(); - } $configurationFile = null; if ($xmlConfiguration->wasLoadedFromFile()) { assert($xmlConfiguration instanceof LoadedFromFileConfiguration); @@ -76240,6 +83382,11 @@ final class Merger } else { $disableCodeCoverageIgnore = $xmlConfiguration->codeCoverage()->disableCodeCoverageIgnore(); } + if ($cliConfiguration->hasFailOnDeprecation()) { + $failOnDeprecation = $cliConfiguration->failOnDeprecation(); + } else { + $failOnDeprecation = $xmlConfiguration->phpunit()->failOnDeprecation(); + } if ($cliConfiguration->hasFailOnEmptyTestSuite()) { $failOnEmptyTestSuite = $cliConfiguration->failOnEmptyTestSuite(); } else { @@ -76250,6 +83397,11 @@ final class Merger } else { $failOnIncomplete = $xmlConfiguration->phpunit()->failOnIncomplete(); } + if ($cliConfiguration->hasFailOnNotice()) { + $failOnNotice = $cliConfiguration->failOnNotice(); + } else { + $failOnNotice = $xmlConfiguration->phpunit()->failOnNotice(); + } if ($cliConfiguration->hasFailOnRisky()) { $failOnRisky = $cliConfiguration->failOnRisky(); } else { @@ -76265,27 +83417,68 @@ final class Merger } else { $failOnWarning = $xmlConfiguration->phpunit()->failOnWarning(); } + if ($cliConfiguration->hasStopOnDefect()) { + $stopOnDefect = $cliConfiguration->stopOnDefect(); + } else { + $stopOnDefect = $xmlConfiguration->phpunit()->stopOnDefect(); + } + if ($cliConfiguration->hasStopOnDeprecation()) { + $stopOnDeprecation = $cliConfiguration->stopOnDeprecation(); + } else { + $stopOnDeprecation = $xmlConfiguration->phpunit()->stopOnDeprecation(); + } + if ($cliConfiguration->hasStopOnError()) { + $stopOnError = $cliConfiguration->stopOnError(); + } else { + $stopOnError = $xmlConfiguration->phpunit()->stopOnError(); + } + if ($cliConfiguration->hasStopOnFailure()) { + $stopOnFailure = $cliConfiguration->stopOnFailure(); + } else { + $stopOnFailure = $xmlConfiguration->phpunit()->stopOnFailure(); + } + if ($cliConfiguration->hasStopOnIncomplete()) { + $stopOnIncomplete = $cliConfiguration->stopOnIncomplete(); + } else { + $stopOnIncomplete = $xmlConfiguration->phpunit()->stopOnIncomplete(); + } + if ($cliConfiguration->hasStopOnNotice()) { + $stopOnNotice = $cliConfiguration->stopOnNotice(); + } else { + $stopOnNotice = $xmlConfiguration->phpunit()->stopOnNotice(); + } + if ($cliConfiguration->hasStopOnRisky()) { + $stopOnRisky = $cliConfiguration->stopOnRisky(); + } else { + $stopOnRisky = $xmlConfiguration->phpunit()->stopOnRisky(); + } + if ($cliConfiguration->hasStopOnSkipped()) { + $stopOnSkipped = $cliConfiguration->stopOnSkipped(); + } else { + $stopOnSkipped = $xmlConfiguration->phpunit()->stopOnSkipped(); + } + if ($cliConfiguration->hasStopOnWarning()) { + $stopOnWarning = $cliConfiguration->stopOnWarning(); + } else { + $stopOnWarning = $xmlConfiguration->phpunit()->stopOnWarning(); + } if ($cliConfiguration->hasStderr() && $cliConfiguration->stderr()) { $outputToStandardErrorStream = \true; } else { $outputToStandardErrorStream = $xmlConfiguration->phpunit()->stderr(); } - $maxNumberOfColumns = (new Console())->getNumberOfColumns(); if ($cliConfiguration->hasColumns()) { $columns = $cliConfiguration->columns(); } else { $columns = $xmlConfiguration->phpunit()->columns(); } if ($columns === 'max') { - $columns = $maxNumberOfColumns; + $columns = (new Console())->getNumberOfColumns(); } if ($columns < 16) { $columns = 16; EventFacade::emitter()->testRunnerTriggeredWarning('Less than 16 columns requested, number of columns set to 16'); } - if ($columns > $maxNumberOfColumns) { - $columns = $maxNumberOfColumns; - } assert(is_int($columns)); $noExtensions = \false; if ($cliConfiguration->hasNoExtensions() && $cliConfiguration->noExtensions()) { @@ -76406,41 +83599,6 @@ final class Merger } else { $processIsolation = $xmlConfiguration->phpunit()->processIsolation(); } - if ($cliConfiguration->hasStopOnDefect()) { - $stopOnDefect = $cliConfiguration->stopOnDefect(); - } else { - $stopOnDefect = $xmlConfiguration->phpunit()->stopOnDefect(); - } - if ($cliConfiguration->hasStopOnError()) { - $stopOnError = $cliConfiguration->stopOnError(); - } else { - $stopOnError = $xmlConfiguration->phpunit()->stopOnError(); - } - if ($cliConfiguration->hasStopOnFailure()) { - $stopOnFailure = $cliConfiguration->stopOnFailure(); - } else { - $stopOnFailure = $xmlConfiguration->phpunit()->stopOnFailure(); - } - if ($cliConfiguration->hasStopOnWarning()) { - $stopOnWarning = $cliConfiguration->stopOnWarning(); - } else { - $stopOnWarning = $xmlConfiguration->phpunit()->stopOnWarning(); - } - if ($cliConfiguration->hasStopOnIncomplete()) { - $stopOnIncomplete = $cliConfiguration->stopOnIncomplete(); - } else { - $stopOnIncomplete = $xmlConfiguration->phpunit()->stopOnIncomplete(); - } - if ($cliConfiguration->hasStopOnRisky()) { - $stopOnRisky = $cliConfiguration->stopOnRisky(); - } else { - $stopOnRisky = $xmlConfiguration->phpunit()->stopOnRisky(); - } - if ($cliConfiguration->hasStopOnSkipped()) { - $stopOnSkipped = $cliConfiguration->stopOnSkipped(); - } else { - $stopOnSkipped = $xmlConfiguration->phpunit()->stopOnSkipped(); - } if ($cliConfiguration->hasEnforceTimeLimit()) { $enforceTimeLimit = $cliConfiguration->enforceTimeLimit(); } else { @@ -76625,7 +83783,7 @@ final class Merger } if ($xmlConfiguration->wasLoadedFromFile() && $xmlConfiguration->hasValidationErrors()) { if ((new SchemaDetector())->detect($xmlConfiguration->filename())->detected()) { - EventFacade::emitter()->testRunnerTriggeredWarning('Your XML configuration validates against a deprecated schema. Migrate your XML configuration using "--migrate-configuration"!'); + EventFacade::emitter()->testRunnerTriggeredDeprecation('Your XML configuration validates against a deprecated schema. Migrate your XML configuration using "--migrate-configuration"!'); } else { EventFacade::emitter()->testRunnerTriggeredWarning("Test results may not be as expected because the XML configuration file did not pass validation:\n" . $xmlConfiguration->validationErrors()); } @@ -76663,16 +83821,41 @@ final class Merger if ($cliConfiguration->hasTestSuffixes()) { $testSuffixes = $cliConfiguration->testSuffixes(); } - $coverageIncludeDirectories = []; + $sourceIncludeDirectories = []; if ($cliConfiguration->hasCoverageFilter()) { foreach ($cliConfiguration->coverageFilter() as $directory) { - $coverageIncludeDirectories[] = new \PHPUnit\TextUI\Configuration\FilterDirectory($directory, '', '.php'); + $sourceIncludeDirectories[] = new \PHPUnit\TextUI\Configuration\FilterDirectory($directory, '', '.php'); + } + } + if ($xmlConfiguration->codeCoverage()->hasNonEmptyListOfFilesToBeIncludedInCodeCoverageReport()) { + foreach ($xmlConfiguration->codeCoverage()->directories() as $directory) { + $sourceIncludeDirectories[] = $directory; + } + $sourceIncludeFiles = $xmlConfiguration->codeCoverage()->files(); + $sourceExcludeDirectories = $xmlConfiguration->codeCoverage()->excludeDirectories(); + $sourceExcludeFiles = $xmlConfiguration->codeCoverage()->excludeFiles(); + } else { + foreach ($xmlConfiguration->source()->includeDirectories() as $directory) { + $sourceIncludeDirectories[] = $directory; } + $sourceIncludeFiles = $xmlConfiguration->source()->includeFiles(); + $sourceExcludeDirectories = $xmlConfiguration->source()->excludeDirectories(); + $sourceExcludeFiles = $xmlConfiguration->source()->excludeFiles(); } - foreach ($xmlConfiguration->codeCoverage()->directories() as $directory) { - $coverageIncludeDirectories[] = $directory; + $useBaseline = null; + $generateBaseline = null; + if (!$cliConfiguration->hasGenerateBaseline()) { + if ($cliConfiguration->hasUseBaseline()) { + $useBaseline = $cliConfiguration->useBaseline(); + } elseif ($xmlConfiguration->source()->hasBaseline()) { + $useBaseline = $xmlConfiguration->source()->baseline(); + } + } else { + $generateBaseline = $cliConfiguration->generateBaseline(); } - return new \PHPUnit\TextUI\Configuration\Configuration($cliArgument, $configurationFile, $bootstrap, $cacheResult, $cacheDirectory, $coverageCacheDirectory, \PHPUnit\TextUI\Configuration\FilterDirectoryCollection::fromArray($coverageIncludeDirectories), $xmlConfiguration->codeCoverage()->files(), $xmlConfiguration->codeCoverage()->excludeDirectories(), $xmlConfiguration->codeCoverage()->excludeFiles(), $testResultCacheFile, $coverageClover, $coverageCobertura, $coverageCrap4j, $coverageCrap4jThreshold, $coverageHtml, $coverageHtmlLowUpperBound, $coverageHtmlHighLowerBound, $coverageHtmlColorSuccessLow, $coverageHtmlColorSuccessMedium, $coverageHtmlColorSuccessHigh, $coverageHtmlColorWarning, $coverageHtmlColorDanger, $coverageHtmlCustomCssFile, $coveragePhp, $coverageText, $coverageTextShowUncoveredFiles, $coverageTextShowOnlySummary, $coverageXml, $pathCoverage, $xmlConfiguration->codeCoverage()->ignoreDeprecatedCodeUnits(), $disableCodeCoverageIgnore, $failOnEmptyTestSuite, $failOnIncomplete, $failOnRisky, $failOnSkipped, $failOnWarning, $outputToStandardErrorStream, $columns, $noExtensions, $pharExtensionDirectory, $extensionBootstrappers, $backupGlobals, $backupStaticProperties, $beStrictAboutChangesToGlobalState, $colors, $processIsolation, $stopOnDefect, $stopOnError, $stopOnFailure, $stopOnWarning, $stopOnIncomplete, $stopOnRisky, $stopOnSkipped, $enforceTimeLimit, $defaultTimeLimit, $timeoutForSmallTests, $timeoutForMediumTests, $timeoutForLargeTests, $reportUselessTests, $strictCoverage, $disallowTestOutput, $displayDetailsOnIncompleteTests, $displayDetailsOnSkippedTests, $displayDetailsOnTestsThatTriggerDeprecations, $displayDetailsOnTestsThatTriggerErrors, $displayDetailsOnTestsThatTriggerNotices, $displayDetailsOnTestsThatTriggerWarnings, $reverseDefectList, $requireCoverageMetadata, $registerMockObjectsFromTestArgumentsRecursively, $noProgress, $noResults, $noOutput, $executionOrder, $executionOrderDefects, $resolveDependencies, $logfileTeamcity, $logfileJunit, $logfileTestdoxHtml, $logfileTestdoxText, $logEventsText, $logEventsVerboseText, $teamCityOutput, $testDoxOutput, $testsCovering, $testsUsing, $filter, $groups, $excludeGroups, $randomOrderSeed, $includeUncoveredFiles, $xmlConfiguration->testSuite(), $includeTestSuite, $excludeTestSuite, $xmlConfiguration->phpunit()->hasDefaultTestSuite() ? $xmlConfiguration->phpunit()->defaultTestSuite() : null, $testSuffixes, new \PHPUnit\TextUI\Configuration\Php(\PHPUnit\TextUI\Configuration\DirectoryCollection::fromArray($includePaths), \PHPUnit\TextUI\Configuration\IniSettingCollection::fromArray($iniSettings), $xmlConfiguration->php()->constants(), $xmlConfiguration->php()->globalVariables(), $xmlConfiguration->php()->envVariables(), $xmlConfiguration->php()->postVariables(), $xmlConfiguration->php()->getVariables(), $xmlConfiguration->php()->cookieVariables(), $xmlConfiguration->php()->serverVariables(), $xmlConfiguration->php()->filesVariables(), $xmlConfiguration->php()->requestVariables())); + assert($useBaseline !== ''); + assert($generateBaseline !== ''); + return new \PHPUnit\TextUI\Configuration\Configuration($cliConfiguration->arguments(), $configurationFile, $bootstrap, $cacheResult, $cacheDirectory, $coverageCacheDirectory, new \PHPUnit\TextUI\Configuration\Source($useBaseline, $cliConfiguration->ignoreBaseline(), \PHPUnit\TextUI\Configuration\FilterDirectoryCollection::fromArray($sourceIncludeDirectories), $sourceIncludeFiles, $sourceExcludeDirectories, $sourceExcludeFiles, $xmlConfiguration->source()->restrictDeprecations(), $xmlConfiguration->source()->restrictNotices(), $xmlConfiguration->source()->restrictWarnings(), $xmlConfiguration->source()->ignoreSuppressionOfDeprecations(), $xmlConfiguration->source()->ignoreSuppressionOfPhpDeprecations(), $xmlConfiguration->source()->ignoreSuppressionOfErrors(), $xmlConfiguration->source()->ignoreSuppressionOfNotices(), $xmlConfiguration->source()->ignoreSuppressionOfPhpNotices(), $xmlConfiguration->source()->ignoreSuppressionOfWarnings(), $xmlConfiguration->source()->ignoreSuppressionOfPhpWarnings()), $testResultCacheFile, $coverageClover, $coverageCobertura, $coverageCrap4j, $coverageCrap4jThreshold, $coverageHtml, $coverageHtmlLowUpperBound, $coverageHtmlHighLowerBound, $coverageHtmlColorSuccessLow, $coverageHtmlColorSuccessMedium, $coverageHtmlColorSuccessHigh, $coverageHtmlColorWarning, $coverageHtmlColorDanger, $coverageHtmlCustomCssFile, $coveragePhp, $coverageText, $coverageTextShowUncoveredFiles, $coverageTextShowOnlySummary, $coverageXml, $pathCoverage, $xmlConfiguration->codeCoverage()->ignoreDeprecatedCodeUnits(), $disableCodeCoverageIgnore, $failOnDeprecation, $failOnEmptyTestSuite, $failOnIncomplete, $failOnNotice, $failOnRisky, $failOnSkipped, $failOnWarning, $stopOnDefect, $stopOnDeprecation, $stopOnError, $stopOnFailure, $stopOnIncomplete, $stopOnNotice, $stopOnRisky, $stopOnSkipped, $stopOnWarning, $outputToStandardErrorStream, $columns, $noExtensions, $pharExtensionDirectory, $extensionBootstrappers, $backupGlobals, $backupStaticProperties, $beStrictAboutChangesToGlobalState, $colors, $processIsolation, $enforceTimeLimit, $defaultTimeLimit, $timeoutForSmallTests, $timeoutForMediumTests, $timeoutForLargeTests, $reportUselessTests, $strictCoverage, $disallowTestOutput, $displayDetailsOnIncompleteTests, $displayDetailsOnSkippedTests, $displayDetailsOnTestsThatTriggerDeprecations, $displayDetailsOnTestsThatTriggerErrors, $displayDetailsOnTestsThatTriggerNotices, $displayDetailsOnTestsThatTriggerWarnings, $reverseDefectList, $requireCoverageMetadata, $registerMockObjectsFromTestArgumentsRecursively, $noProgress, $noResults, $noOutput, $executionOrder, $executionOrderDefects, $resolveDependencies, $logfileTeamcity, $logfileJunit, $logfileTestdoxHtml, $logfileTestdoxText, $logEventsText, $logEventsVerboseText, $teamCityOutput, $testDoxOutput, $testsCovering, $testsUsing, $filter, $groups, $excludeGroups, $randomOrderSeed, $includeUncoveredFiles, $xmlConfiguration->testSuite(), $includeTestSuite, $excludeTestSuite, $xmlConfiguration->phpunit()->hasDefaultTestSuite() ? $xmlConfiguration->phpunit()->defaultTestSuite() : null, $testSuffixes, new \PHPUnit\TextUI\Configuration\Php(\PHPUnit\TextUI\Configuration\DirectoryCollection::fromArray($includePaths), \PHPUnit\TextUI\Configuration\IniSettingCollection::fromArray($iniSettings), $xmlConfiguration->php()->constants(), $xmlConfiguration->php()->globalVariables(), $xmlConfiguration->php()->envVariables(), $xmlConfiguration->php()->postVariables(), $xmlConfiguration->php()->getVariables(), $xmlConfiguration->php()->cookieVariables(), $xmlConfiguration->php()->serverVariables(), $xmlConfiguration->php()->filesVariables(), $xmlConfiguration->php()->requestVariables()), $xmlConfiguration->phpunit()->controlGarbageCollector(), $xmlConfiguration->phpunit()->numberOfTestsBeforeGarbageCollection(), $generateBaseline, $cliConfiguration->debug()); } } [\PHPUnit\TextUI\Configuration\Configuration::class, \PHPUnit\TextUI\Configuration\Php::class, \PHPUnit\TextUI\Configuration\ConstantCollection::class, \PHPUnit\TextUI\Configuration\Constant::class, \PHPUnit\TextUI\Configuration\IniSettingCollection::class, \PHPUnit\TextUI\Configuration\IniSetting::class, \PHPUnit\TextUI\Configuration\VariableCollection::class, \PHPUnit\TextUI\Configuration\Variable::class, \PHPUnit\TextUI\Configuration\DirectoryCollection::class, \PHPUnit\TextUI\Configuration\Directory::class, \PHPUnit\TextUI\Configuration\FileCollection::class, \PHPUnit\TextUI\Configuration\File::class, \PHPUnit\TextUI\Configuration\FilterDirectoryCollection::class, \PHPUnit\TextUI\Configuration\FilterDirectory::class, \PHPUnit\TextUI\Configuration\TestDirectoryCollection::class, \PHPUnit\TextUI\Configuration\TestDirectory::class, \PHPUnit\TextUI\Configuration\TestFileCollection::class, \PHPUnit\TextUI\Configuration\TestFile::class, \PHPUnit\TextUI\Configuration\TestSuiteCollection::class, \PHPUnit\TextUI\Configuration\TestSuite::class, VersionComparisonOperator::class]]); + self::$instance = unserialize(file_get_contents($path), ['allowed_classes' => [\PHPUnit\TextUI\Configuration\Configuration::class, \PHPUnit\TextUI\Configuration\Php::class, \PHPUnit\TextUI\Configuration\ConstantCollection::class, \PHPUnit\TextUI\Configuration\Constant::class, \PHPUnit\TextUI\Configuration\IniSettingCollection::class, \PHPUnit\TextUI\Configuration\IniSetting::class, \PHPUnit\TextUI\Configuration\VariableCollection::class, \PHPUnit\TextUI\Configuration\Variable::class, \PHPUnit\TextUI\Configuration\DirectoryCollection::class, \PHPUnit\TextUI\Configuration\Directory::class, \PHPUnit\TextUI\Configuration\FileCollection::class, \PHPUnit\TextUI\Configuration\File::class, \PHPUnit\TextUI\Configuration\FilterDirectoryCollection::class, \PHPUnit\TextUI\Configuration\FilterDirectory::class, \PHPUnit\TextUI\Configuration\TestDirectoryCollection::class, \PHPUnit\TextUI\Configuration\TestDirectory::class, \PHPUnit\TextUI\Configuration\TestFileCollection::class, \PHPUnit\TextUI\Configuration\TestFile::class, \PHPUnit\TextUI\Configuration\TestSuiteCollection::class, \PHPUnit\TextUI\Configuration\TestSuite::class, VersionComparisonOperator::class, \PHPUnit\TextUI\Configuration\Source::class]]); } public static function get() : \PHPUnit\TextUI\Configuration\Configuration { @@ -76856,6 +84039,111 @@ declare (strict_types=1); */ namespace PHPUnit\TextUI\Configuration; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class SourceFilter +{ + public function includes(\PHPUnit\TextUI\Configuration\Source $source, string $path) : bool + { + $files = (new \PHPUnit\TextUI\Configuration\SourceMapper())->map($source); + return isset($files[$path]); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\Configuration; + +use function realpath; +use PHPUnit\SebastianBergmann\FileIterator\Facade as FileIteratorFacade; +use SplObjectStorage; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class SourceMapper +{ + /** + * @psalm-var SplObjectStorage> + */ + private static ?SplObjectStorage $files = null; + /** + * @psalm-return array + */ + public function map(\PHPUnit\TextUI\Configuration\Source $source) : array + { + if (self::$files === null) { + self::$files = new SplObjectStorage(); + } + if (isset(self::$files[$source])) { + return self::$files[$source]; + } + $files = []; + foreach ($source->includeDirectories() as $directory) { + foreach ((new FileIteratorFacade())->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix()) as $file) { + $file = realpath($file); + if (!$file) { + continue; + } + $files[$file] = \true; + } + } + foreach ($source->includeFiles() as $file) { + $file = realpath($file->path()); + if (!$file) { + continue; + } + $files[$file] = \true; + } + foreach ($source->excludeDirectories() as $directory) { + foreach ((new FileIteratorFacade())->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix()) as $file) { + $file = realpath($file); + if (!$file) { + continue; + } + if (!isset($files[$file])) { + continue; + } + unset($files[$file]); + } + } + foreach ($source->excludeFiles() as $file) { + $file = realpath($file->path()); + if (!$file) { + continue; + } + if (!isset($files[$file])) { + continue; + } + unset($files[$file]); + } + self::$files[$source] = $files; + return $files; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\Configuration; + +use function assert; +use function count; use function is_dir; use function is_file; use function realpath; @@ -76882,34 +84170,46 @@ final class TestSuiteBuilder */ public function build(\PHPUnit\TextUI\Configuration\Configuration $configuration) : TestSuite { - if ($configuration->hasCliArgument()) { - $argument = realpath($configuration->cliArgument()); - if (!$argument) { - throw new TestFileNotFoundException($configuration->cliArgument()); + if ($configuration->hasCliArguments()) { + $arguments = []; + foreach ($configuration->cliArguments() as $cliArgument) { + $argument = realpath($cliArgument); + if (!$argument) { + throw new TestFileNotFoundException($cliArgument); + } + $arguments[] = $argument; + } + if (count($arguments) === 1) { + $testSuite = $this->testSuiteFromPath($arguments[0], $configuration->testSuffixes()); + } else { + $testSuite = $this->testSuiteFromPathList($arguments, $configuration->testSuffixes()); } - $testSuite = $this->testSuiteFromPath($argument, $configuration->testSuffixes()); } if (!isset($testSuite)) { - $testSuite = (new TestSuiteMapper())->map($configuration->testSuite(), $configuration->includeTestSuite(), $configuration->excludeTestSuite()); + $xmlConfigurationFile = $configuration->hasConfigurationFile() ? $configuration->configurationFile() : 'Root Test Suite'; + assert(!empty($xmlConfigurationFile)); + $testSuite = (new TestSuiteMapper())->map($xmlConfigurationFile, $configuration->testSuite(), $configuration->includeTestSuite(), $configuration->excludeTestSuite()); } EventFacade::emitter()->testSuiteLoaded(\PHPUnit\Event\TestSuite\TestSuiteBuilder::from($testSuite)); return $testSuite; } /** - * @psalm-param list $suffixes + * @psalm-param non-empty-string $path + * @psalm-param list $suffixes + * @psalm-param ?TestSuite $suite * * @throws \PHPUnit\Framework\Exception */ - private function testSuiteFromPath(string $path, array $suffixes) : TestSuite + private function testSuiteFromPath(string $path, array $suffixes, ?TestSuite $suite = null) : TestSuite { if (is_dir($path)) { $files = (new FileIteratorFacade())->getFilesAsArray($path, $suffixes); - $suite = TestSuite::empty($path); + $suite = $suite ?: TestSuite::empty('CLI Arguments'); $suite->addTestFiles($files); return $suite; } if (is_file($path) && str_ends_with($path, '.phpt')) { - $suite = TestSuite::empty(); + $suite = $suite ?: TestSuite::empty($path); $suite->addTestFile($path); return $suite; } @@ -76919,7 +84219,25 @@ final class TestSuiteBuilder print $e->getMessage() . \PHP_EOL; exit(1); } - return TestSuite::fromClassReflector($testClass); + if (!$suite) { + return TestSuite::fromClassReflector($testClass); + } + $suite->addTestSuite($testClass); + return $suite; + } + /** + * @psalm-param list $paths + * @psalm-param list $suffixes + * + * @throws \PHPUnit\Framework\Exception + */ + private function testSuiteFromPathList(array $paths, array $suffixes) : TestSuite + { + $suite = TestSuite::empty('CLI Arguments'); + foreach ($paths as $path) { + $this->testSuiteFromPath($path, $suffixes, $suite); + } + return $suite; } } name; } - public function value() : mixed + public function value() : bool|string { return $this->value; } @@ -77400,11 +84718,20 @@ namespace PHPUnit\TextUI\Configuration; */ final class File { + /** + * @psalm-var non-empty-string + */ private readonly string $path; + /** + * @psalm-param non-empty-string $path + */ public function __construct(string $path) { $this->path = $path; } + /** + * @psalm-return non-empty-string + */ public function path() : string { return $this->path; @@ -77548,15 +84875,24 @@ namespace PHPUnit\TextUI\Configuration; */ final class FilterDirectory { + /** + * @psalm-var non-empty-string + */ private readonly string $path; private readonly string $prefix; private readonly string $suffix; + /** + * @psalm-param non-empty-string $path + */ public function __construct(string $path, string $prefix, string $suffix) { $this->path = $path; $this->prefix = $prefix; $this->suffix = $suffix; } + /** + * @psalm-return non-empty-string + */ public function path() : string { return $this->path; @@ -78094,6 +85430,154 @@ declare (strict_types=1); */ namespace PHPUnit\TextUI\Configuration; +/** + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + * + * @psalm-immutable + */ +final class Source +{ + /** + * @psalm-var non-empty-string + */ + private readonly ?string $baseline; + private readonly bool $ignoreBaseline; + private readonly \PHPUnit\TextUI\Configuration\FilterDirectoryCollection $includeDirectories; + private readonly \PHPUnit\TextUI\Configuration\FileCollection $includeFiles; + private readonly \PHPUnit\TextUI\Configuration\FilterDirectoryCollection $excludeDirectories; + private readonly \PHPUnit\TextUI\Configuration\FileCollection $excludeFiles; + private readonly bool $restrictDeprecations; + private readonly bool $restrictNotices; + private readonly bool $restrictWarnings; + private readonly bool $ignoreSuppressionOfDeprecations; + private readonly bool $ignoreSuppressionOfPhpDeprecations; + private readonly bool $ignoreSuppressionOfErrors; + private readonly bool $ignoreSuppressionOfNotices; + private readonly bool $ignoreSuppressionOfPhpNotices; + private readonly bool $ignoreSuppressionOfWarnings; + private readonly bool $ignoreSuppressionOfPhpWarnings; + /** + * @psalm-param non-empty-string $baseline + */ + public function __construct(?string $baseline, bool $ignoreBaseline, \PHPUnit\TextUI\Configuration\FilterDirectoryCollection $includeDirectories, \PHPUnit\TextUI\Configuration\FileCollection $includeFiles, \PHPUnit\TextUI\Configuration\FilterDirectoryCollection $excludeDirectories, \PHPUnit\TextUI\Configuration\FileCollection $excludeFiles, bool $restrictDeprecations, bool $restrictNotices, bool $restrictWarnings, bool $ignoreSuppressionOfDeprecations, bool $ignoreSuppressionOfPhpDeprecations, bool $ignoreSuppressionOfErrors, bool $ignoreSuppressionOfNotices, bool $ignoreSuppressionOfPhpNotices, bool $ignoreSuppressionOfWarnings, bool $ignoreSuppressionOfPhpWarnings) + { + $this->baseline = $baseline; + $this->ignoreBaseline = $ignoreBaseline; + $this->includeDirectories = $includeDirectories; + $this->includeFiles = $includeFiles; + $this->excludeDirectories = $excludeDirectories; + $this->excludeFiles = $excludeFiles; + $this->restrictDeprecations = $restrictDeprecations; + $this->restrictNotices = $restrictNotices; + $this->restrictWarnings = $restrictWarnings; + $this->ignoreSuppressionOfDeprecations = $ignoreSuppressionOfDeprecations; + $this->ignoreSuppressionOfPhpDeprecations = $ignoreSuppressionOfPhpDeprecations; + $this->ignoreSuppressionOfErrors = $ignoreSuppressionOfErrors; + $this->ignoreSuppressionOfNotices = $ignoreSuppressionOfNotices; + $this->ignoreSuppressionOfPhpNotices = $ignoreSuppressionOfPhpNotices; + $this->ignoreSuppressionOfWarnings = $ignoreSuppressionOfWarnings; + $this->ignoreSuppressionOfPhpWarnings = $ignoreSuppressionOfPhpWarnings; + } + /** + * @psalm-assert-if-true !null $this->baseline + */ + public function useBaseline() : bool + { + return $this->hasBaseline() && !$this->ignoreBaseline; + } + /** + * @psalm-assert-if-true !null $this->baseline + */ + public function hasBaseline() : bool + { + return $this->baseline !== null; + } + /** + * @psalm-return non-empty-string + * + * @throws NoBaselineException + */ + public function baseline() : string + { + if (!$this->hasBaseline()) { + throw new \PHPUnit\TextUI\Configuration\NoBaselineException(); + } + return $this->baseline; + } + public function includeDirectories() : \PHPUnit\TextUI\Configuration\FilterDirectoryCollection + { + return $this->includeDirectories; + } + public function includeFiles() : \PHPUnit\TextUI\Configuration\FileCollection + { + return $this->includeFiles; + } + public function excludeDirectories() : \PHPUnit\TextUI\Configuration\FilterDirectoryCollection + { + return $this->excludeDirectories; + } + public function excludeFiles() : \PHPUnit\TextUI\Configuration\FileCollection + { + return $this->excludeFiles; + } + public function notEmpty() : bool + { + return $this->includeDirectories->notEmpty() || $this->includeFiles->notEmpty(); + } + public function restrictDeprecations() : bool + { + return $this->restrictDeprecations; + } + public function restrictNotices() : bool + { + return $this->restrictNotices; + } + public function restrictWarnings() : bool + { + return $this->restrictWarnings; + } + public function ignoreSuppressionOfDeprecations() : bool + { + return $this->ignoreSuppressionOfDeprecations; + } + public function ignoreSuppressionOfPhpDeprecations() : bool + { + return $this->ignoreSuppressionOfPhpDeprecations; + } + public function ignoreSuppressionOfErrors() : bool + { + return $this->ignoreSuppressionOfErrors; + } + public function ignoreSuppressionOfNotices() : bool + { + return $this->ignoreSuppressionOfNotices; + } + public function ignoreSuppressionOfPhpNotices() : bool + { + return $this->ignoreSuppressionOfPhpNotices; + } + public function ignoreSuppressionOfWarnings() : bool + { + return $this->ignoreSuppressionOfWarnings; + } + public function ignoreSuppressionOfPhpWarnings() : bool + { + return $this->ignoreSuppressionOfPhpWarnings; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\Configuration; + use PHPUnit\Util\VersionComparisonOperator; /** * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit @@ -78102,11 +85586,17 @@ use PHPUnit\Util\VersionComparisonOperator; */ final class TestDirectory { + /** + * @psalm-var non-empty-string + */ private readonly string $path; private readonly string $prefix; private readonly string $suffix; private readonly string $phpVersion; private readonly VersionComparisonOperator $phpVersionOperator; + /** + * @psalm-param non-empty-string $path + */ public function __construct(string $path, string $prefix, string $suffix, string $phpVersion, VersionComparisonOperator $phpVersionOperator) { $this->path = $path; @@ -78115,6 +85605,9 @@ final class TestDirectory $this->phpVersion = $phpVersion; $this->phpVersionOperator = $phpVersionOperator; } + /** + * @psalm-return non-empty-string + */ public function path() : string { return $this->path; @@ -78435,10 +85928,16 @@ namespace PHPUnit\TextUI\Configuration; */ final class TestSuite { + /** + * @psalm-var non-empty-string + */ private readonly string $name; private readonly \PHPUnit\TextUI\Configuration\TestDirectoryCollection $directories; private readonly \PHPUnit\TextUI\Configuration\TestFileCollection $files; private readonly \PHPUnit\TextUI\Configuration\FileCollection $exclude; + /** + * @psalm-param non-empty-string $name + */ public function __construct(string $name, \PHPUnit\TextUI\Configuration\TestDirectoryCollection $directories, \PHPUnit\TextUI\Configuration\TestFileCollection $files, \PHPUnit\TextUI\Configuration\FileCollection $exclude) { $this->name = $name; @@ -78446,6 +85945,9 @@ final class TestSuite $this->files = $files; $this->exclude = $exclude; } + /** + * @psalm-return non-empty-string + */ public function name() : string { return $this->name; @@ -79293,6 +86795,7 @@ namespace PHPUnit\TextUI\XmlConfiguration; use PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection; use PHPUnit\TextUI\Configuration\Php; +use PHPUnit\TextUI\Configuration\Source; use PHPUnit\TextUI\Configuration\TestSuiteCollection; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage; use PHPUnit\TextUI\XmlConfiguration\Logging\Logging; @@ -79304,15 +86807,17 @@ use PHPUnit\TextUI\XmlConfiguration\Logging\Logging; abstract class Configuration { private readonly ExtensionBootstrapCollection $extensions; + private readonly Source $source; private readonly CodeCoverage $codeCoverage; private readonly \PHPUnit\TextUI\XmlConfiguration\Groups $groups; private readonly Logging $logging; private readonly Php $php; private readonly \PHPUnit\TextUI\XmlConfiguration\PHPUnit $phpunit; private readonly TestSuiteCollection $testSuite; - public function __construct(ExtensionBootstrapCollection $extensions, CodeCoverage $codeCoverage, \PHPUnit\TextUI\XmlConfiguration\Groups $groups, Logging $logging, Php $php, \PHPUnit\TextUI\XmlConfiguration\PHPUnit $phpunit, TestSuiteCollection $testSuite) + public function __construct(ExtensionBootstrapCollection $extensions, Source $source, CodeCoverage $codeCoverage, \PHPUnit\TextUI\XmlConfiguration\Groups $groups, Logging $logging, Php $php, \PHPUnit\TextUI\XmlConfiguration\PHPUnit $phpunit, TestSuiteCollection $testSuite) { $this->extensions = $extensions; + $this->source = $source; $this->codeCoverage = $codeCoverage; $this->groups = $groups; $this->logging = $logging; @@ -79324,6 +86829,10 @@ abstract class Configuration { return $this->extensions; } + public function source() : Source + { + return $this->source; + } public function codeCoverage() : CodeCoverage { return $this->codeCoverage; @@ -79385,6 +86894,7 @@ use PHPUnit\TextUI\Configuration\FilterDirectoryCollection as CodeCoverageFilter use PHPUnit\TextUI\Configuration\GroupCollection; use PHPUnit\TextUI\Configuration\IniSettingCollection; use PHPUnit\TextUI\Configuration\Php; +use PHPUnit\TextUI\Configuration\Source; use PHPUnit\TextUI\Configuration\TestSuiteCollection; use PHPUnit\TextUI\Configuration\VariableCollection; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage; @@ -79398,7 +86908,7 @@ final class DefaultConfiguration extends \PHPUnit\TextUI\XmlConfiguration\Config { public static function create() : self { - return new self(ExtensionBootstrapCollection::fromArray([]), new CodeCoverage(null, CodeCoverageFilterDirectoryCollection::fromArray([]), FileCollection::fromArray([]), CodeCoverageFilterDirectoryCollection::fromArray([]), FileCollection::fromArray([]), \false, \true, \false, \false, null, null, null, null, null, null, null), new \PHPUnit\TextUI\XmlConfiguration\Groups(GroupCollection::fromArray([]), GroupCollection::fromArray([])), new Logging(null, null, null, null), new Php(DirectoryCollection::fromArray([]), IniSettingCollection::fromArray([]), ConstantCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([])), new \PHPUnit\TextUI\XmlConfiguration\PHPUnit(null, \true, null, 80, \PHPUnit\TextUI\Configuration\Configuration::COLOR_DEFAULT, \false, \false, \false, \false, \false, \false, \false, \false, \false, null, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, null, \false, \false, \true, \false, \false, 1, 1, 10, 60, null, TestSuiteSorter::ORDER_DEFAULT, \true, \false, \false, \false, \false, \false), TestSuiteCollection::fromArray([])); + return new self(ExtensionBootstrapCollection::fromArray([]), new Source(null, \false, CodeCoverageFilterDirectoryCollection::fromArray([]), FileCollection::fromArray([]), CodeCoverageFilterDirectoryCollection::fromArray([]), FileCollection::fromArray([]), \false, \false, \false, \false, \false, \false, \false, \false, \false, \false), new CodeCoverage(null, CodeCoverageFilterDirectoryCollection::fromArray([]), FileCollection::fromArray([]), CodeCoverageFilterDirectoryCollection::fromArray([]), FileCollection::fromArray([]), \false, \true, \false, \false, null, null, null, null, null, null, null), new \PHPUnit\TextUI\XmlConfiguration\Groups(GroupCollection::fromArray([]), GroupCollection::fromArray([])), new Logging(null, null, null, null), new Php(DirectoryCollection::fromArray([]), IniSettingCollection::fromArray([]), ConstantCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([]), VariableCollection::fromArray([])), new \PHPUnit\TextUI\XmlConfiguration\PHPUnit(null, \true, null, 80, \PHPUnit\TextUI\Configuration\Configuration::COLOR_DEFAULT, \false, \false, \false, \false, \false, \false, \false, \false, \false, null, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, null, \false, \false, \true, \false, \false, 1, 1, 10, 60, null, TestSuiteSorter::ORDER_DEFAULT, \true, \false, \false, \false, \false, \false, \false, 100), TestSuiteCollection::fromArray([])); } public function isDefault() : bool { @@ -79465,11 +86975,11 @@ final class Generator - + - {src_directory} + {src_directory} - + EOT; @@ -79538,10 +87048,10 @@ namespace PHPUnit\TextUI\XmlConfiguration; use PHPUnit\TextUI\Configuration\ExtensionBootstrapCollection; use PHPUnit\TextUI\Configuration\Php; +use PHPUnit\TextUI\Configuration\Source; use PHPUnit\TextUI\Configuration\TestSuiteCollection; use PHPUnit\TextUI\XmlConfiguration\CodeCoverage\CodeCoverage; use PHPUnit\TextUI\XmlConfiguration\Logging\Logging; -use PHPUnit\Util\Xml\ValidationResult; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit * @@ -79550,12 +87060,12 @@ use PHPUnit\Util\Xml\ValidationResult; final class LoadedFromFileConfiguration extends \PHPUnit\TextUI\XmlConfiguration\Configuration { private readonly string $filename; - private readonly ValidationResult $validationResult; - public function __construct(string $filename, ValidationResult $validationResult, ExtensionBootstrapCollection $extensions, CodeCoverage $codeCoverage, \PHPUnit\TextUI\XmlConfiguration\Groups $groups, Logging $logging, Php $php, \PHPUnit\TextUI\XmlConfiguration\PHPUnit $phpunit, TestSuiteCollection $testSuite) + private readonly \PHPUnit\TextUI\XmlConfiguration\ValidationResult $validationResult; + public function __construct(string $filename, \PHPUnit\TextUI\XmlConfiguration\ValidationResult $validationResult, ExtensionBootstrapCollection $extensions, Source $source, CodeCoverage $codeCoverage, \PHPUnit\TextUI\XmlConfiguration\Groups $groups, Logging $logging, Php $php, \PHPUnit\TextUI\XmlConfiguration\PHPUnit $phpunit, TestSuiteCollection $testSuite) { $this->filename = $filename; $this->validationResult = $validationResult; - parent::__construct($extensions, $codeCoverage, $groups, $logging, $php, $phpunit, $testSuite); + parent::__construct($extensions, $source, $codeCoverage, $groups, $logging, $php, $phpunit, $testSuite); } public function filename() : string { @@ -79593,18 +87103,18 @@ use function assert; use function defined; use function dirname; use function explode; -use function is_file; use function is_numeric; use function preg_match; +use function realpath; use function str_contains; use function str_starts_with; -use function stream_resolve_include_path; use function strlen; use function strtolower; use function substr; use function trim; use DOMDocument; use DOMElement; +use DOMNode; use DOMXPath; use PHPUnit\Runner\TestSuiteSorter; use PHPUnit\Runner\Version; @@ -79623,6 +87133,7 @@ use PHPUnit\TextUI\Configuration\GroupCollection; use PHPUnit\TextUI\Configuration\IniSetting; use PHPUnit\TextUI\Configuration\IniSettingCollection; use PHPUnit\TextUI\Configuration\Php; +use PHPUnit\TextUI\Configuration\Source; use PHPUnit\TextUI\Configuration\TestDirectory; use PHPUnit\TextUI\Configuration\TestDirectoryCollection; use PHPUnit\TextUI\Configuration\TestFile; @@ -79646,8 +87157,6 @@ use PHPUnit\TextUI\XmlConfiguration\Logging\TestDox\Html as TestDoxHtml; use PHPUnit\TextUI\XmlConfiguration\Logging\TestDox\Text as TestDoxText; use PHPUnit\Util\VersionComparisonOperator; use PHPUnit\Util\Xml\Loader as XmlLoader; -use PHPUnit\Util\Xml\SchemaFinder; -use PHPUnit\Util\Xml\Validator; use PHPUnit\Util\Xml\XmlException; use PHPUnit\SebastianBergmann\CodeCoverage\Report\Html\Colors; use PHPUnit\SebastianBergmann\CodeCoverage\Report\Thresholds; @@ -79662,17 +87171,18 @@ final class Loader public function load(string $filename) : \PHPUnit\TextUI\XmlConfiguration\LoadedFromFileConfiguration { try { - $document = (new XmlLoader())->loadFile($filename, \false, \true, \true); + $document = (new XmlLoader())->loadFile($filename); } catch (XmlException $e) { throw new \PHPUnit\TextUI\XmlConfiguration\Exception($e->getMessage(), $e->getCode(), $e); } $xpath = new DOMXPath($document); try { - $xsdFilename = (new SchemaFinder())->find(Version::series()); - } catch (XmlException $e) { + $xsdFilename = (new \PHPUnit\TextUI\XmlConfiguration\SchemaFinder())->find(Version::series()); + } catch (\PHPUnit\TextUI\XmlConfiguration\CannotFindSchemaException $e) { throw new \PHPUnit\TextUI\XmlConfiguration\Exception($e->getMessage(), $e->getCode(), $e); } - return new \PHPUnit\TextUI\XmlConfiguration\LoadedFromFileConfiguration($filename, (new Validator())->validate($document, $xsdFilename), $this->extensions($xpath), $this->codeCoverage($filename, $xpath), $this->groups($xpath), $this->logging($filename, $xpath), $this->php($filename, $xpath), $this->phpunit($filename, $document), $this->testSuite($filename, $xpath)); + $configurationFileRealpath = realpath($filename); + return new \PHPUnit\TextUI\XmlConfiguration\LoadedFromFileConfiguration($configurationFileRealpath, (new \PHPUnit\TextUI\XmlConfiguration\Validator())->validate($document, $xsdFilename), $this->extensions($xpath), $this->source($configurationFileRealpath, $xpath), $this->codeCoverage($configurationFileRealpath, $xpath), $this->groups($xpath), $this->logging($configurationFileRealpath, $xpath), $this->php($configurationFileRealpath, $xpath), $this->phpunit($configurationFileRealpath, $document), $this->testSuite($configurationFileRealpath, $xpath)); } private function logging(string $filename, DOMXPath $xpath) : Logging { @@ -79712,7 +87222,10 @@ final class Loader } return ExtensionBootstrapCollection::fromArray($extensionBootstrappers); } - private function toAbsolutePath(string $filename, string $path, bool $useIncludePath = \false) : string + /** + * @psalm-return non-empty-string + */ + private function toAbsolutePath(string $filename, string $path) : string { $path = trim($path); if (str_starts_with($path, '/')) { @@ -79726,20 +87239,45 @@ final class Loader // - C:\windows // - C:/windows // - c:/windows - if (defined('PHP_WINDOWS_VERSION_BUILD') && ($path[0] === '\\' || strlen($path) >= 3 && preg_match('#^[A-Z]:[/\\\\]#i', substr($path, 0, 3)))) { + if (defined('PHP_WINDOWS_VERSION_BUILD') && !empty($path) && ($path[0] === '\\' || strlen($path) >= 3 && preg_match('#^[A-Z]:[/\\\\]#i', substr($path, 0, 3)))) { return $path; } if (str_contains($path, '://')) { return $path; } - $file = dirname($filename) . DIRECTORY_SEPARATOR . $path; - if ($useIncludePath && !is_file($file)) { - $includePathFile = stream_resolve_include_path($path); - if ($includePathFile) { - $file = $includePathFile; - } - } - return $file; + return dirname($filename) . DIRECTORY_SEPARATOR . $path; + } + private function source(string $filename, DOMXPath $xpath) : Source + { + $baseline = null; + $restrictDeprecations = \false; + $restrictNotices = \false; + $restrictWarnings = \false; + $ignoreSuppressionOfDeprecations = \false; + $ignoreSuppressionOfPhpDeprecations = \false; + $ignoreSuppressionOfErrors = \false; + $ignoreSuppressionOfNotices = \false; + $ignoreSuppressionOfPhpNotices = \false; + $ignoreSuppressionOfWarnings = \false; + $ignoreSuppressionOfPhpWarnings = \false; + $element = $this->element($xpath, 'source'); + if ($element) { + $baseline = $this->getStringAttribute($element, 'baseline'); + if ($baseline !== null) { + $baseline = $this->toAbsolutePath($filename, $baseline); + } + $restrictDeprecations = $this->getBooleanAttribute($element, 'restrictDeprecations', \false); + $restrictNotices = $this->getBooleanAttribute($element, 'restrictNotices', \false); + $restrictWarnings = $this->getBooleanAttribute($element, 'restrictWarnings', \false); + $ignoreSuppressionOfDeprecations = $this->getBooleanAttribute($element, 'ignoreSuppressionOfDeprecations', \false); + $ignoreSuppressionOfPhpDeprecations = $this->getBooleanAttribute($element, 'ignoreSuppressionOfPhpDeprecations', \false); + $ignoreSuppressionOfErrors = $this->getBooleanAttribute($element, 'ignoreSuppressionOfErrors', \false); + $ignoreSuppressionOfNotices = $this->getBooleanAttribute($element, 'ignoreSuppressionOfNotices', \false); + $ignoreSuppressionOfPhpNotices = $this->getBooleanAttribute($element, 'ignoreSuppressionOfPhpNotices', \false); + $ignoreSuppressionOfWarnings = $this->getBooleanAttribute($element, 'ignoreSuppressionOfWarnings', \false); + $ignoreSuppressionOfPhpWarnings = $this->getBooleanAttribute($element, 'ignoreSuppressionOfPhpWarnings', \false); + } + return new Source($baseline, \false, $this->readFilterDirectories($filename, $xpath, 'source/include/directory'), $this->readFilterFiles($filename, $xpath, 'source/include/file'), $this->readFilterDirectories($filename, $xpath, 'source/exclude/directory'), $this->readFilterFiles($filename, $xpath, 'source/exclude/file'), $restrictDeprecations, $restrictNotices, $restrictWarnings, $ignoreSuppressionOfDeprecations, $ignoreSuppressionOfPhpDeprecations, $ignoreSuppressionOfErrors, $ignoreSuppressionOfNotices, $ignoreSuppressionOfPhpNotices, $ignoreSuppressionOfWarnings, $ignoreSuppressionOfPhpWarnings); } private function codeCoverage(string $filename, DOMXPath $xpath) : CodeCoverage { @@ -79825,6 +87363,7 @@ final class Loader { $files = []; foreach ($xpath->query($query) as $file) { + assert($file instanceof DOMNode); $filePath = $file->textContent; if ($filePath) { $files[] = new File($this->toAbsolutePath($filename, $filePath)); @@ -79836,10 +87375,12 @@ final class Loader { $include = []; $exclude = []; - foreach ($xpath->query('groups' . '/include/group') as $group) { + foreach ($xpath->query('groups/include/group') as $group) { + assert($group instanceof DOMNode); $include[] = new Group($group->textContent); } - foreach ($xpath->query('groups' . '/exclude/group') as $group) { + foreach ($xpath->query('groups/exclude/group') as $group) { + assert($group instanceof DOMNode); $exclude[] = new Group($group->textContent); } return new \PHPUnit\TextUI\XmlConfiguration\Groups(GroupCollection::fromArray($include), GroupCollection::fromArray($exclude)); @@ -79883,6 +87424,7 @@ final class Loader { $includePaths = []; foreach ($xpath->query('php/includePath') as $includePath) { + assert($includePath instanceof DOMNode); $path = $includePath->textContent; if ($path) { $includePaths[] = new Directory($this->toAbsolutePath($filename, $path)); @@ -79992,7 +87534,7 @@ final class Loader } elseif ($document->documentElement->hasAttribute('forceCoversAnnotation')) { $beStrictAboutCoverageMetadata = $this->getBooleanAttribute($document->documentElement, 'beStrictAboutCoversAnnotation', \false); } - return new \PHPUnit\TextUI\XmlConfiguration\PHPUnit($cacheDirectory, $this->getBooleanAttribute($document->documentElement, 'cacheResult', \true), $cacheResultFile, $this->getColumns($document), $this->getColors($document), $this->getBooleanAttribute($document->documentElement, 'stderr', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnIncompleteTests', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnSkippedTests', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerDeprecations', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerErrors', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerNotices', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerWarnings', \false), $this->getBooleanAttribute($document->documentElement, 'reverseDefectList', \false), $requireCoverageMetadata, $bootstrap, $this->getBooleanAttribute($document->documentElement, 'processIsolation', \false), $this->getBooleanAttribute($document->documentElement, 'failOnEmptyTestSuite', \false), $this->getBooleanAttribute($document->documentElement, 'failOnIncomplete', \false), $this->getBooleanAttribute($document->documentElement, 'failOnRisky', \false), $this->getBooleanAttribute($document->documentElement, 'failOnSkipped', \false), $this->getBooleanAttribute($document->documentElement, 'failOnWarning', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnDefect', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnError', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnFailure', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnWarning', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnIncomplete', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnRisky', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnSkipped', \false), $extensionsDirectory, $this->getBooleanAttribute($document->documentElement, 'beStrictAboutChangesToGlobalState', \false), $this->getBooleanAttribute($document->documentElement, 'beStrictAboutOutputDuringTests', \false), $this->getBooleanAttribute($document->documentElement, 'beStrictAboutTestsThatDoNotTestAnything', \true), $beStrictAboutCoverageMetadata, $this->getBooleanAttribute($document->documentElement, 'enforceTimeLimit', \false), $this->getIntegerAttribute($document->documentElement, 'defaultTimeLimit', 1), $this->getIntegerAttribute($document->documentElement, 'timeoutForSmallTests', 1), $this->getIntegerAttribute($document->documentElement, 'timeoutForMediumTests', 10), $this->getIntegerAttribute($document->documentElement, 'timeoutForLargeTests', 60), $this->getStringAttribute($document->documentElement, 'defaultTestSuite'), $executionOrder, $resolveDependencies, $defectsFirst, $this->getBooleanAttribute($document->documentElement, 'backupGlobals', \false), $backupStaticProperties, $this->getBooleanAttribute($document->documentElement, 'registerMockObjectsFromTestArgumentsRecursively', \false), $this->getBooleanAttribute($document->documentElement, 'testdox', \false)); + return new \PHPUnit\TextUI\XmlConfiguration\PHPUnit($cacheDirectory, $this->getBooleanAttribute($document->documentElement, 'cacheResult', \true), $cacheResultFile, $this->getColumns($document), $this->getColors($document), $this->getBooleanAttribute($document->documentElement, 'stderr', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnIncompleteTests', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnSkippedTests', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerDeprecations', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerErrors', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerNotices', \false), $this->getBooleanAttribute($document->documentElement, 'displayDetailsOnTestsThatTriggerWarnings', \false), $this->getBooleanAttribute($document->documentElement, 'reverseDefectList', \false), $requireCoverageMetadata, $bootstrap, $this->getBooleanAttribute($document->documentElement, 'processIsolation', \false), $this->getBooleanAttribute($document->documentElement, 'failOnDeprecation', \false), $this->getBooleanAttribute($document->documentElement, 'failOnEmptyTestSuite', \false), $this->getBooleanAttribute($document->documentElement, 'failOnIncomplete', \false), $this->getBooleanAttribute($document->documentElement, 'failOnNotice', \false), $this->getBooleanAttribute($document->documentElement, 'failOnRisky', \false), $this->getBooleanAttribute($document->documentElement, 'failOnSkipped', \false), $this->getBooleanAttribute($document->documentElement, 'failOnWarning', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnDefect', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnDeprecation', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnError', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnFailure', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnIncomplete', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnNotice', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnRisky', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnSkipped', \false), $this->getBooleanAttribute($document->documentElement, 'stopOnWarning', \false), $extensionsDirectory, $this->getBooleanAttribute($document->documentElement, 'beStrictAboutChangesToGlobalState', \false), $this->getBooleanAttribute($document->documentElement, 'beStrictAboutOutputDuringTests', \false), $this->getBooleanAttribute($document->documentElement, 'beStrictAboutTestsThatDoNotTestAnything', \true), $beStrictAboutCoverageMetadata, $this->getBooleanAttribute($document->documentElement, 'enforceTimeLimit', \false), $this->getIntegerAttribute($document->documentElement, 'defaultTimeLimit', 1), $this->getIntegerAttribute($document->documentElement, 'timeoutForSmallTests', 1), $this->getIntegerAttribute($document->documentElement, 'timeoutForMediumTests', 10), $this->getIntegerAttribute($document->documentElement, 'timeoutForLargeTests', 60), $this->getStringAttribute($document->documentElement, 'defaultTestSuite'), $executionOrder, $resolveDependencies, $defectsFirst, $this->getBooleanAttribute($document->documentElement, 'backupGlobals', \false), $backupStaticProperties, $this->getBooleanAttribute($document->documentElement, 'registerMockObjectsFromTestArgumentsRecursively', \false), $this->getBooleanAttribute($document->documentElement, 'testdox', \false), $this->getBooleanAttribute($document->documentElement, 'controlGarbageCollector', \false), $this->getIntegerAttribute($document->documentElement, 'numberOfTestsBeforeGarbageCollection', 100)); } private function getColors(DOMDocument $document) : string { @@ -80072,7 +87614,9 @@ final class Loader } $files[] = new TestFile($this->toAbsolutePath($filename, $file), $phpVersion, $phpVersionOperator); } - $testSuites[] = new TestSuiteConfiguration($element->getAttribute('name'), TestDirectoryCollection::fromArray($directories), TestFileCollection::fromArray($files), FileCollection::fromArray($exclude)); + $name = $element->getAttribute('name'); + assert(!empty($name)); + $testSuites[] = new TestSuiteConfiguration($name, TestDirectoryCollection::fromArray($directories), TestFileCollection::fromArray($files), FileCollection::fromArray($exclude)); } return TestSuiteCollection::fromArray($testSuites); } @@ -80337,23 +87881,18 @@ declare (strict_types=1); */ namespace PHPUnit\TextUI\XmlConfiguration; -use function array_key_exists; -use function sprintf; use function version_compare; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class MigrationBuilder { - private const AVAILABLE_MIGRATIONS = ['8.5' => [\PHPUnit\TextUI\XmlConfiguration\RemoveLogTypes::class], '9.2' => [\PHPUnit\TextUI\XmlConfiguration\RemoveCacheTokensAttribute::class, \PHPUnit\TextUI\XmlConfiguration\IntroduceCoverageElement::class, \PHPUnit\TextUI\XmlConfiguration\MoveAttributesFromRootToCoverage::class, \PHPUnit\TextUI\XmlConfiguration\MoveAttributesFromFilterWhitelistToCoverage::class, \PHPUnit\TextUI\XmlConfiguration\MoveWhitelistDirectoriesToCoverage::class, \PHPUnit\TextUI\XmlConfiguration\MoveWhitelistExcludesToCoverage::class, \PHPUnit\TextUI\XmlConfiguration\RemoveEmptyFilter::class, \PHPUnit\TextUI\XmlConfiguration\CoverageCloverToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoverageCrap4jToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoverageHtmlToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoveragePhpToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoverageTextToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoverageXmlToReport::class, \PHPUnit\TextUI\XmlConfiguration\ConvertLogTypes::class], '9.5' => [\PHPUnit\TextUI\XmlConfiguration\RemoveListeners::class, \PHPUnit\TextUI\XmlConfiguration\RemoveTestSuiteLoaderAttributes::class, \PHPUnit\TextUI\XmlConfiguration\RemoveCacheResultFileAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveCoverageElementCacheDirectoryAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveCoverageElementProcessUncoveredFilesAttribute::class, \PHPUnit\TextUI\XmlConfiguration\IntroduceCacheDirectoryAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RenameBackupStaticAttributesAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveBeStrictAboutTodoAnnotatedTestsAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemovePrinterAttributes::class, \PHPUnit\TextUI\XmlConfiguration\RemoveVerboseAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RenameForceCoversAnnotationAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RenameBeStrictAboutCoversAnnotationAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveConversionToExceptionsAttributes::class, \PHPUnit\TextUI\XmlConfiguration\RemoveNoInteractionAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveLoggingElements::class, \PHPUnit\TextUI\XmlConfiguration\RemoveTestDoxGroupsElement::class]]; + private const AVAILABLE_MIGRATIONS = ['8.5' => [\PHPUnit\TextUI\XmlConfiguration\RemoveLogTypes::class], '9.2' => [\PHPUnit\TextUI\XmlConfiguration\RemoveCacheTokensAttribute::class, \PHPUnit\TextUI\XmlConfiguration\IntroduceCoverageElement::class, \PHPUnit\TextUI\XmlConfiguration\MoveAttributesFromRootToCoverage::class, \PHPUnit\TextUI\XmlConfiguration\MoveAttributesFromFilterWhitelistToCoverage::class, \PHPUnit\TextUI\XmlConfiguration\MoveWhitelistIncludesToCoverage::class, \PHPUnit\TextUI\XmlConfiguration\MoveWhitelistExcludesToCoverage::class, \PHPUnit\TextUI\XmlConfiguration\RemoveEmptyFilter::class, \PHPUnit\TextUI\XmlConfiguration\CoverageCloverToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoverageCrap4jToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoverageHtmlToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoveragePhpToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoverageTextToReport::class, \PHPUnit\TextUI\XmlConfiguration\CoverageXmlToReport::class, \PHPUnit\TextUI\XmlConfiguration\ConvertLogTypes::class], '9.5' => [\PHPUnit\TextUI\XmlConfiguration\RemoveListeners::class, \PHPUnit\TextUI\XmlConfiguration\RemoveTestSuiteLoaderAttributes::class, \PHPUnit\TextUI\XmlConfiguration\RemoveCacheResultFileAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveCoverageElementCacheDirectoryAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveCoverageElementProcessUncoveredFilesAttribute::class, \PHPUnit\TextUI\XmlConfiguration\IntroduceCacheDirectoryAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RenameBackupStaticAttributesAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveBeStrictAboutTodoAnnotatedTestsAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemovePrinterAttributes::class, \PHPUnit\TextUI\XmlConfiguration\RemoveVerboseAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RenameForceCoversAnnotationAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RenameBeStrictAboutCoversAnnotationAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveConversionToExceptionsAttributes::class, \PHPUnit\TextUI\XmlConfiguration\RemoveNoInteractionAttribute::class, \PHPUnit\TextUI\XmlConfiguration\RemoveLoggingElements::class, \PHPUnit\TextUI\XmlConfiguration\RemoveTestDoxGroupsElement::class], '10.0' => [\PHPUnit\TextUI\XmlConfiguration\MoveCoverageDirectoriesToSource::class]]; /** * @throws MigrationBuilderException */ public function build(string $fromVersion) : array { - if (!array_key_exists($fromVersion, self::AVAILABLE_MIGRATIONS)) { - throw new \PHPUnit\TextUI\XmlConfiguration\MigrationBuilderException(sprintf('Migration from schema version %s is not supported', $fromVersion)); - } $stack = [new \PHPUnit\TextUI\XmlConfiguration\UpdateSchemaLocation()]; foreach (self::AVAILABLE_MIGRATIONS as $version => $migrations) { if (version_compare($version, $fromVersion, '<')) { @@ -80869,35 +88408,43 @@ declare (strict_types=1); */ namespace PHPUnit\TextUI\XmlConfiguration; +use function assert; use DOMDocument; use DOMElement; -use PHPUnit\Util\Xml\SnapshotNodeList; +use DOMXPath; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ -final class MoveWhitelistDirectoriesToCoverage implements \PHPUnit\TextUI\XmlConfiguration\Migration +final class MoveCoverageDirectoriesToSource implements \PHPUnit\TextUI\XmlConfiguration\Migration { /** * @throws MigrationException */ public function migrate(DOMDocument $document) : void { - $whitelist = $document->getElementsByTagName('whitelist')->item(0); - if ($whitelist === null) { + $source = $document->getElementsByTagName('source')->item(0); + if ($source !== null) { return; } $coverage = $document->getElementsByTagName('coverage')->item(0); - if (!$coverage instanceof DOMElement) { - throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException('Unexpected state - No coverage element'); + if ($coverage === null) { + return; } - $include = $document->createElement('include'); - $coverage->appendChild($include); - foreach (SnapshotNodeList::fromNodeList($whitelist->childNodes) as $child) { - if (!$child instanceof DOMElement || $child->nodeName !== 'directory') { - continue; + $root = $document->documentElement; + assert($root instanceof DOMElement); + $source = $document->createElement('source'); + $root->appendChild($source); + $xpath = new DOMXPath($document); + foreach (['include', 'exclude'] as $element) { + foreach (\PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($xpath->query('//coverage/' . $element)) as $node) { + $source->appendChild($node); } - $include->appendChild($child); } + if ($coverage->childElementCount !== 0) { + return; + } + assert($coverage->parentNode !== null); + $coverage->parentNode->removeChild($coverage); } } getElementsByTagName('exclude')); + $excludeNodes = \PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($whitelist->getElementsByTagName('exclude')); if ($excludeNodes->count() === 0) { return; } @@ -80946,7 +88492,7 @@ final class MoveWhitelistExcludesToCoverage implements \PHPUnit\TextUI\XmlConfig } foreach ($excludeNodes as $excludeNode) { assert($excludeNode instanceof DOMElement); - foreach (SnapshotNodeList::fromNodeList($excludeNode->childNodes) as $child) { + foreach (\PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($excludeNode->childNodes) as $child) { if (!$child instanceof DOMElement || !in_array($child->nodeName, ['directory', 'file'], \true)) { continue; } @@ -80972,234 +88518,12 @@ declare (strict_types=1); */ namespace PHPUnit\TextUI\XmlConfiguration; -use function assert; -use DOMDocument; -use DOMElement; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration -{ - public function migrate(DOMDocument $document) : void - { - $root = $document->documentElement; - assert($root instanceof DOMElement); - if ($root->hasAttribute('beStrictAboutResourceUsageDuringSmallTests')) { - $root->removeAttribute('beStrictAboutResourceUsageDuringSmallTests'); - } - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\TextUI\XmlConfiguration; - -use function assert; -use DOMDocument; -use DOMElement; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class RemoveBeStrictAboutTodoAnnotatedTestsAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration -{ - public function migrate(DOMDocument $document) : void - { - $root = $document->documentElement; - assert($root instanceof DOMElement); - if ($root->hasAttribute('beStrictAboutTodoAnnotatedTests')) { - $root->removeAttribute('beStrictAboutTodoAnnotatedTests'); - } - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\TextUI\XmlConfiguration; - -use function assert; -use DOMDocument; -use DOMElement; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class RemoveCacheResultFileAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration -{ - public function migrate(DOMDocument $document) : void - { - $root = $document->documentElement; - assert($root instanceof DOMElement); - if ($root->hasAttribute('cacheResultFile')) { - $root->removeAttribute('cacheResultFile'); - } - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\TextUI\XmlConfiguration; - -use function assert; -use DOMDocument; -use DOMElement; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class RemoveCacheTokensAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration -{ - public function migrate(DOMDocument $document) : void - { - $root = $document->documentElement; - assert($root instanceof DOMElement); - if ($root->hasAttribute('cacheTokens')) { - $root->removeAttribute('cacheTokens'); - } - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\TextUI\XmlConfiguration; - -use function assert; use DOMDocument; use DOMElement; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ -final class RemoveConversionToExceptionsAttributes implements \PHPUnit\TextUI\XmlConfiguration\Migration -{ - public function migrate(DOMDocument $document) : void - { - $root = $document->documentElement; - assert($root instanceof DOMElement); - if ($root->hasAttribute('convertDeprecationsToExceptions')) { - $root->removeAttribute('convertDeprecationsToExceptions'); - } - if ($root->hasAttribute('convertErrorsToExceptions')) { - $root->removeAttribute('convertErrorsToExceptions'); - } - if ($root->hasAttribute('convertNoticesToExceptions')) { - $root->removeAttribute('convertNoticesToExceptions'); - } - if ($root->hasAttribute('convertWarningsToExceptions')) { - $root->removeAttribute('convertWarningsToExceptions'); - } - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\TextUI\XmlConfiguration; - -use DOMDocument; -use DOMElement; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class RemoveCoverageElementCacheDirectoryAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration -{ - public function migrate(DOMDocument $document) : void - { - $node = $document->getElementsByTagName('coverage')->item(0); - if (!$node instanceof DOMElement || $node->parentNode === null) { - return; - } - if ($node->hasAttribute('cacheDirectory')) { - $node->removeAttribute('cacheDirectory'); - } - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\TextUI\XmlConfiguration; - -use DOMDocument; -use DOMElement; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class RemoveCoverageElementProcessUncoveredFilesAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration -{ - public function migrate(DOMDocument $document) : void - { - $node = $document->getElementsByTagName('coverage')->item(0); - if (!$node instanceof DOMElement || $node->parentNode === null) { - return; - } - if ($node->hasAttribute('processUncoveredFiles')) { - $node->removeAttribute('processUncoveredFiles'); - } - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\TextUI\XmlConfiguration; - -use function sprintf; -use DOMDocument; -use DOMElement; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class RemoveEmptyFilter implements \PHPUnit\TextUI\XmlConfiguration\Migration +final class MoveWhitelistIncludesToCoverage implements \PHPUnit\TextUI\XmlConfiguration\Migration { /** * @throws MigrationException @@ -81207,26 +88531,23 @@ final class RemoveEmptyFilter implements \PHPUnit\TextUI\XmlConfiguration\Migrat public function migrate(DOMDocument $document) : void { $whitelist = $document->getElementsByTagName('whitelist')->item(0); - if ($whitelist instanceof DOMElement) { - $this->ensureEmpty($whitelist); - $whitelist->parentNode->removeChild($whitelist); - } - $filter = $document->getElementsByTagName('filter')->item(0); - if ($filter instanceof DOMElement) { - $this->ensureEmpty($filter); - $filter->parentNode->removeChild($filter); + if ($whitelist === null) { + return; } - } - /** - * @throws MigrationException - */ - private function ensureEmpty(DOMElement $element) : void - { - if ($element->attributes->length > 0) { - throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException(sprintf('%s element has unexpected attributes', $element->nodeName)); + $coverage = $document->getElementsByTagName('coverage')->item(0); + if (!$coverage instanceof DOMElement) { + throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException('Unexpected state - No coverage element'); } - if ($element->getElementsByTagName('*')->length > 0) { - throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException(sprintf('%s element has unexpected children', $element->nodeName)); + $include = $document->createElement('include'); + $coverage->appendChild($include); + foreach (\PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($whitelist->childNodes) as $child) { + if (!$child instanceof DOMElement) { + continue; + } + if (!($child->nodeName === 'directory' || $child->nodeName === 'file')) { + continue; + } + $include->appendChild($child); } } } @@ -81243,20 +88564,21 @@ declare (strict_types=1); */ namespace PHPUnit\TextUI\XmlConfiguration; +use function assert; use DOMDocument; use DOMElement; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ -final class RemoveListeners implements \PHPUnit\TextUI\XmlConfiguration\Migration +final class RemoveBeStrictAboutResourceUsageDuringSmallTestsAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration { public function migrate(DOMDocument $document) : void { - $node = $document->getElementsByTagName('listeners')->item(0); - if (!$node instanceof DOMElement || $node->parentNode === null) { - return; + $root = $document->documentElement; + assert($root instanceof DOMElement); + if ($root->hasAttribute('beStrictAboutResourceUsageDuringSmallTests')) { + $root->removeAttribute('beStrictAboutResourceUsageDuringSmallTests'); } - $node->parentNode->removeChild($node); } } documentElement; + assert($root instanceof DOMElement); + if ($root->hasAttribute('beStrictAboutTodoAnnotatedTests')) { + $root->removeAttribute('beStrictAboutTodoAnnotatedTests'); + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +use function assert; +use DOMDocument; +use DOMElement; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class RemoveCacheResultFileAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration +{ + public function migrate(DOMDocument $document) : void + { + $root = $document->documentElement; + assert($root instanceof DOMElement); + if ($root->hasAttribute('cacheResultFile')) { + $root->removeAttribute('cacheResultFile'); + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +use function assert; +use DOMDocument; +use DOMElement; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class RemoveCacheTokensAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration +{ + public function migrate(DOMDocument $document) : void + { + $root = $document->documentElement; + assert($root instanceof DOMElement); + if ($root->hasAttribute('cacheTokens')) { + $root->removeAttribute('cacheTokens'); + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +use function assert; +use DOMDocument; +use DOMElement; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class RemoveConversionToExceptionsAttributes implements \PHPUnit\TextUI\XmlConfiguration\Migration +{ + public function migrate(DOMDocument $document) : void + { + $root = $document->documentElement; + assert($root instanceof DOMElement); + if ($root->hasAttribute('convertDeprecationsToExceptions')) { + $root->removeAttribute('convertDeprecationsToExceptions'); + } + if ($root->hasAttribute('convertErrorsToExceptions')) { + $root->removeAttribute('convertErrorsToExceptions'); + } + if ($root->hasAttribute('convertNoticesToExceptions')) { + $root->removeAttribute('convertNoticesToExceptions'); + } + if ($root->hasAttribute('convertWarningsToExceptions')) { + $root->removeAttribute('convertWarningsToExceptions'); + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +use DOMDocument; +use DOMElement; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class RemoveCoverageElementCacheDirectoryAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration +{ + public function migrate(DOMDocument $document) : void + { + $node = $document->getElementsByTagName('coverage')->item(0); + if (!$node instanceof DOMElement || $node->parentNode === null) { + return; + } + if ($node->hasAttribute('cacheDirectory')) { + $node->removeAttribute('cacheDirectory'); + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +use DOMDocument; +use DOMElement; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class RemoveCoverageElementProcessUncoveredFilesAttribute implements \PHPUnit\TextUI\XmlConfiguration\Migration +{ + public function migrate(DOMDocument $document) : void + { + $node = $document->getElementsByTagName('coverage')->item(0); + if (!$node instanceof DOMElement || $node->parentNode === null) { + return; + } + if ($node->hasAttribute('processUncoveredFiles')) { + $node->removeAttribute('processUncoveredFiles'); + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +use function sprintf; +use DOMDocument; +use DOMElement; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class RemoveEmptyFilter implements \PHPUnit\TextUI\XmlConfiguration\Migration +{ + /** + * @throws MigrationException + */ + public function migrate(DOMDocument $document) : void + { + $whitelist = $document->getElementsByTagName('whitelist')->item(0); + if ($whitelist instanceof DOMElement) { + $this->ensureEmpty($whitelist); + $whitelist->parentNode->removeChild($whitelist); + } + $filter = $document->getElementsByTagName('filter')->item(0); + if ($filter instanceof DOMElement) { + $this->ensureEmpty($filter); + $filter->parentNode->removeChild($filter); + } + } + /** + * @throws MigrationException + */ + private function ensureEmpty(DOMElement $element) : void + { + if ($element->attributes->length > 0) { + throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException(sprintf('%s element has unexpected attributes', $element->nodeName)); + } + if ($element->getElementsByTagName('*')->length > 0) { + throw new \PHPUnit\TextUI\XmlConfiguration\MigrationException(sprintf('%s element has unexpected children', $element->nodeName)); + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +use DOMDocument; +use DOMElement; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class RemoveListeners implements \PHPUnit\TextUI\XmlConfiguration\Migration +{ + public function migrate(DOMDocument $document) : void + { + $node = $document->getElementsByTagName('listeners')->item(0); + if (!$node instanceof DOMElement || $node->parentNode === null) { + return; + } + $node->parentNode->removeChild($node); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +use function assert; +use DOMDocument; +use DOMElement; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ @@ -81287,7 +88878,7 @@ final class RemoveLogTypes implements \PHPUnit\TextUI\XmlConfiguration\Migration if (!$logging instanceof DOMElement) { return; } - foreach (SnapshotNodeList::fromNodeList($logging->getElementsByTagName('log')) as $logNode) { + foreach (\PHPUnit\TextUI\XmlConfiguration\SnapshotNodeList::fromNodeList($logging->getElementsByTagName('log')) as $logNode) { assert($logNode instanceof DOMElement); switch ($logNode->getAttribute('type')) { case 'json': @@ -81642,9 +89233,8 @@ declare (strict_types=1); */ namespace PHPUnit\TextUI\XmlConfiguration; -use function sprintf; +use PHPUnit\Runner\Version; use PHPUnit\Util\Xml\Loader as XmlLoader; -use PHPUnit\Util\Xml\SchemaDetector; use PHPUnit\Util\Xml\XmlException; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit @@ -81659,11 +89249,14 @@ final class Migrator */ public function migrate(string $filename) : string { - $origin = (new SchemaDetector())->detect($filename); + $origin = (new \PHPUnit\TextUI\XmlConfiguration\SchemaDetector())->detect($filename); if (!$origin->detected()) { - throw new \PHPUnit\TextUI\XmlConfiguration\Exception(sprintf('"%s" is not a valid PHPUnit XML configuration file that can be migrated', $filename)); + throw new \PHPUnit\TextUI\XmlConfiguration\Exception('The file does not validate against any know schema'); + } + if ($origin->version() === Version::series()) { + throw new \PHPUnit\TextUI\XmlConfiguration\Exception('The file does not need to be migrated'); } - $configurationDocument = (new XmlLoader())->loadFile($filename, \false, \true, \true); + $configurationDocument = (new XmlLoader())->loadFile($filename); foreach ((new \PHPUnit\TextUI\XmlConfiguration\MigrationBuilder())->build($origin->version()) as $migration) { $migration->migrate($configurationDocument); } @@ -81685,6 +89278,53 @@ declare (strict_types=1); */ namespace PHPUnit\TextUI\XmlConfiguration; +use function count; +use ArrayIterator; +use Countable; +use DOMNode; +use DOMNodeList; +use IteratorAggregate; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + * + * @template-implements IteratorAggregate + */ +final class SnapshotNodeList implements Countable, IteratorAggregate +{ + /** + * @psalm-var list + */ + private array $nodes = []; + public static function fromNodeList(DOMNodeList $list) : self + { + $snapshot = new self(); + foreach ($list as $node) { + $snapshot->nodes[] = $node; + } + return $snapshot; + } + public function count() : int + { + return count($this->nodes); + } + public function getIterator() : ArrayIterator + { + return new ArrayIterator($this->nodes); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + /** * @internal This class is not covered by the backward compatibility promise for PHPUnit * @@ -81708,18 +89348,25 @@ final class PHPUnit private readonly bool $requireCoverageMetadata; private readonly ?string $bootstrap; private readonly bool $processIsolation; + private readonly bool $failOnDeprecation; private readonly bool $failOnEmptyTestSuite; private readonly bool $failOnIncomplete; + private readonly bool $failOnNotice; private readonly bool $failOnRisky; private readonly bool $failOnSkipped; private readonly bool $failOnWarning; private readonly bool $stopOnDefect; + private readonly bool $stopOnDeprecation; private readonly bool $stopOnError; private readonly bool $stopOnFailure; - private readonly bool $stopOnWarning; private readonly bool $stopOnIncomplete; + private readonly bool $stopOnNotice; private readonly bool $stopOnRisky; private readonly bool $stopOnSkipped; + private readonly bool $stopOnWarning; + /** + * @psalm-var ?non-empty-string + */ private readonly ?string $extensionsDirectory; private readonly bool $beStrictAboutChangesToGlobalState; private readonly bool $beStrictAboutOutputDuringTests; @@ -81738,7 +89385,12 @@ final class PHPUnit private readonly bool $backupStaticProperties; private readonly bool $registerMockObjectsFromTestArgumentsRecursively; private readonly bool $testdoxPrinter; - public function __construct(?string $cacheDirectory, bool $cacheResult, ?string $cacheResultFile, int|string $columns, string $colors, bool $stderr, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $reverseDefectList, bool $requireCoverageMetadata, ?string $bootstrap, bool $processIsolation, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $stopOnDefect, bool $stopOnError, bool $stopOnFailure, bool $stopOnWarning, bool $stopOnIncomplete, bool $stopOnRisky, bool $stopOnSkipped, ?string $extensionsDirectory, bool $beStrictAboutChangesToGlobalState, bool $beStrictAboutOutputDuringTests, bool $beStrictAboutTestsThatDoNotTestAnything, bool $beStrictAboutCoverageMetadata, bool $enforceTimeLimit, int $defaultTimeLimit, int $timeoutForSmallTests, int $timeoutForMediumTests, int $timeoutForLargeTests, ?string $defaultTestSuite, int $executionOrder, bool $resolveDependencies, bool $defectsFirst, bool $backupGlobals, bool $backupStaticProperties, bool $registerMockObjectsFromTestArgumentsRecursively, bool $testdoxPrinter) + private readonly bool $controlGarbageCollector; + private readonly int $numberOfTestsBeforeGarbageCollection; + /** + * @psalm-param ?non-empty-string $extensionsDirectory + */ + public function __construct(?string $cacheDirectory, bool $cacheResult, ?string $cacheResultFile, int|string $columns, string $colors, bool $stderr, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $reverseDefectList, bool $requireCoverageMetadata, ?string $bootstrap, bool $processIsolation, bool $failOnDeprecation, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnNotice, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $stopOnDefect, bool $stopOnDeprecation, bool $stopOnError, bool $stopOnFailure, bool $stopOnIncomplete, bool $stopOnNotice, bool $stopOnRisky, bool $stopOnSkipped, bool $stopOnWarning, ?string $extensionsDirectory, bool $beStrictAboutChangesToGlobalState, bool $beStrictAboutOutputDuringTests, bool $beStrictAboutTestsThatDoNotTestAnything, bool $beStrictAboutCoverageMetadata, bool $enforceTimeLimit, int $defaultTimeLimit, int $timeoutForSmallTests, int $timeoutForMediumTests, int $timeoutForLargeTests, ?string $defaultTestSuite, int $executionOrder, bool $resolveDependencies, bool $defectsFirst, bool $backupGlobals, bool $backupStaticProperties, bool $registerMockObjectsFromTestArgumentsRecursively, bool $testdoxPrinter, bool $controlGarbageCollector, int $numberOfTestsBeforeGarbageCollection) { $this->cacheDirectory = $cacheDirectory; $this->cacheResult = $cacheResult; @@ -81756,18 +89408,22 @@ final class PHPUnit $this->requireCoverageMetadata = $requireCoverageMetadata; $this->bootstrap = $bootstrap; $this->processIsolation = $processIsolation; + $this->failOnDeprecation = $failOnDeprecation; $this->failOnEmptyTestSuite = $failOnEmptyTestSuite; $this->failOnIncomplete = $failOnIncomplete; + $this->failOnNotice = $failOnNotice; $this->failOnRisky = $failOnRisky; $this->failOnSkipped = $failOnSkipped; $this->failOnWarning = $failOnWarning; $this->stopOnDefect = $stopOnDefect; + $this->stopOnDeprecation = $stopOnDeprecation; $this->stopOnError = $stopOnError; $this->stopOnFailure = $stopOnFailure; - $this->stopOnWarning = $stopOnWarning; $this->stopOnIncomplete = $stopOnIncomplete; + $this->stopOnNotice = $stopOnNotice; $this->stopOnRisky = $stopOnRisky; $this->stopOnSkipped = $stopOnSkipped; + $this->stopOnWarning = $stopOnWarning; $this->extensionsDirectory = $extensionsDirectory; $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState; $this->beStrictAboutOutputDuringTests = $beStrictAboutOutputDuringTests; @@ -81786,6 +89442,8 @@ final class PHPUnit $this->backupStaticProperties = $backupStaticProperties; $this->registerMockObjectsFromTestArgumentsRecursively = $registerMockObjectsFromTestArgumentsRecursively; $this->testdoxPrinter = $testdoxPrinter; + $this->controlGarbageCollector = $controlGarbageCollector; + $this->numberOfTestsBeforeGarbageCollection = $numberOfTestsBeforeGarbageCollection; } /** * @psalm-assert-if-true !null $this->cacheDirectory @@ -81894,6 +89552,10 @@ final class PHPUnit { return $this->processIsolation; } + public function failOnDeprecation() : bool + { + return $this->failOnDeprecation; + } public function failOnEmptyTestSuite() : bool { return $this->failOnEmptyTestSuite; @@ -81902,6 +89564,10 @@ final class PHPUnit { return $this->failOnIncomplete; } + public function failOnNotice() : bool + { + return $this->failOnNotice; + } public function failOnRisky() : bool { return $this->failOnRisky; @@ -81918,6 +89584,10 @@ final class PHPUnit { return $this->stopOnDefect; } + public function stopOnDeprecation() : bool + { + return $this->stopOnDeprecation; + } public function stopOnError() : bool { return $this->stopOnError; @@ -81926,14 +89596,14 @@ final class PHPUnit { return $this->stopOnFailure; } - public function stopOnWarning() : bool - { - return $this->stopOnWarning; - } public function stopOnIncomplete() : bool { return $this->stopOnIncomplete; } + public function stopOnNotice() : bool + { + return $this->stopOnNotice; + } public function stopOnRisky() : bool { return $this->stopOnRisky; @@ -81942,6 +89612,10 @@ final class PHPUnit { return $this->stopOnSkipped; } + public function stopOnWarning() : bool + { + return $this->stopOnWarning; + } /** * @psalm-assert-if-true !null $this->extensionsDirectory */ @@ -81950,6 +89624,8 @@ final class PHPUnit return $this->extensionsDirectory !== null; } /** + * @psalm-return non-empty-string + * * @throws Exception */ public function extensionsDirectory() : string @@ -82032,6 +89708,9 @@ final class PHPUnit { return $this->backupStaticProperties; } + /** + * @deprecated + */ public function registerMockObjectsFromTestArgumentsRecursively() : bool { return $this->registerMockObjectsFromTestArgumentsRecursively; @@ -82040,6 +89719,218 @@ final class PHPUnit { return $this->testdoxPrinter; } + public function controlGarbageCollector() : bool + { + return $this->controlGarbageCollector; + } + public function numberOfTestsBeforeGarbageCollection() : int + { + return $this->numberOfTestsBeforeGarbageCollection; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + * + * @psalm-immutable + */ +final class FailedSchemaDetectionResult extends \PHPUnit\TextUI\XmlConfiguration\SchemaDetectionResult +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +use PHPUnit\Util\Xml\XmlException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + * + * @psalm-immutable + */ +abstract class SchemaDetectionResult +{ + /** + * @psalm-assert-if-true SuccessfulSchemaDetectionResult $this + */ + public function detected() : bool + { + return \false; + } + /** + * @throws XmlException + */ + public function version() : string + { + throw new XmlException('No supported schema was detected'); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +use PHPUnit\Util\Xml\Loader; +use PHPUnit\Util\Xml\XmlException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class SchemaDetector +{ + /** + * @throws XmlException + */ + public function detect(string $filename) : \PHPUnit\TextUI\XmlConfiguration\SchemaDetectionResult + { + $document = (new Loader())->loadFile($filename); + $schemaFinder = new \PHPUnit\TextUI\XmlConfiguration\SchemaFinder(); + foreach ($schemaFinder->available() as $candidate) { + $schema = (new \PHPUnit\TextUI\XmlConfiguration\SchemaFinder())->find($candidate); + if (!(new \PHPUnit\TextUI\XmlConfiguration\Validator())->validate($document, $schema)->hasValidationErrors()) { + return new \PHPUnit\TextUI\XmlConfiguration\SuccessfulSchemaDetectionResult($candidate); + } + } + return new \PHPUnit\TextUI\XmlConfiguration\FailedSchemaDetectionResult(); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + * + * @psalm-immutable + */ +final class SuccessfulSchemaDetectionResult extends \PHPUnit\TextUI\XmlConfiguration\SchemaDetectionResult +{ + /** + * @psalm-var non-empty-string + */ + private readonly string $version; + /** + * @psalm-param non-empty-string $version + */ + public function __construct(string $version) + { + $this->version = $version; + } + /** + * @psalm-assert-if-true SuccessfulSchemaDetectionResult $this + */ + public function detected() : bool + { + return \true; + } + /** + * @psalm-return non-empty-string + */ + public function version() : string + { + return $this->version; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +use function assert; +use function defined; +use function is_file; +use function rsort; +use function sprintf; +use DirectoryIterator; +use PHPUnit\Runner\Version; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class SchemaFinder +{ + /** + * @psalm-return non-empty-list + */ + public function available() : array + { + $result = [Version::series()]; + foreach (new DirectoryIterator($this->path() . 'schema') as $file) { + if ($file->isDot()) { + continue; + } + $version = $file->getBasename('.xsd'); + assert(!empty($version)); + $result[] = $version; + } + rsort($result); + return $result; + } + /** + * @throws CannotFindSchemaException + */ + public function find(string $version) : string + { + if ($version === Version::series()) { + $filename = $this->path() . 'phpunit.xsd'; + } else { + $filename = $this->path() . 'schema/' . $version . '.xsd'; + } + if (!is_file($filename)) { + throw new \PHPUnit\TextUI\XmlConfiguration\CannotFindSchemaException(sprintf('Schema for PHPUnit %s is not available', $version)); + } + return $filename; + } + private function path() : string + { + if (defined('__PHPUNIT_PHAR_ROOT__')) { + return __PHPUNIT_PHAR_ROOT__ . '/'; + } + return __DIR__ . '/../../../../'; + } } name(), $filterAsArray, \true)) { continue; @@ -82091,23 +89986,19 @@ final class TestSuiteMapper if (!empty($excludedFilterAsArray) && in_array($testSuiteConfiguration->name(), $excludedFilterAsArray, \true)) { continue; } - $testSuite = TestSuiteObject::empty($testSuiteConfiguration->name()); - $testSuiteEmpty = \true; $exclude = []; foreach ($testSuiteConfiguration->exclude()->asArray() as $file) { $exclude[] = $file->path(); } + $files = []; foreach ($testSuiteConfiguration->directories() as $directory) { + if (!str_contains($directory->path(), '*') && !is_dir($directory->path())) { + throw new TestDirectoryNotFoundException($directory->path()); + } if (!version_compare(PHP_VERSION, $directory->phpVersion(), $directory->phpVersionOperator()->asString())) { continue; } - $files = (new Facade())->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix(), $exclude); - if (!empty($files)) { - $testSuite->addTestFiles($files); - $testSuiteEmpty = \false; - } elseif (!str_contains($directory->path(), '*') && !is_dir($directory->path())) { - throw new TestDirectoryNotFoundException($directory->path()); - } + $files = array_merge($files, (new Facade())->getFilesAsArray($directory->path(), $directory->suffix(), $directory->prefix(), $exclude)); } foreach ($testSuiteConfiguration->files() as $file) { if (!is_file($file->path())) { @@ -82116,10 +90007,11 @@ final class TestSuiteMapper if (!version_compare(PHP_VERSION, $file->phpVersion(), $file->phpVersionOperator()->asString())) { continue; } - $testSuite->addTestFile($file->path()); - $testSuiteEmpty = \false; + $files[] = $file->path(); } - if (!$testSuiteEmpty) { + if (!empty($files)) { + $testSuite = TestSuiteObject::empty($testSuiteConfiguration->name()); + $testSuite->addTestFiles(array_unique($files)); $result->addTest($testSuite); } } @@ -82131,6 +90023,125 @@ final class TestSuiteMapper } + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +use function sprintf; +use function trim; +use LibXMLError; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + * + * @psalm-immutable + */ +final class ValidationResult +{ + /** + * @psalm-var array> + */ + private readonly array $validationErrors; + /** + * @psalm-param array $errors + */ + public static function fromArray(array $errors) : self + { + $validationErrors = []; + foreach ($errors as $error) { + if (!isset($validationErrors[$error->line])) { + $validationErrors[$error->line] = []; + } + $validationErrors[$error->line][] = trim($error->message); + } + return new self($validationErrors); + } + private function __construct(array $validationErrors) + { + $this->validationErrors = $validationErrors; + } + public function hasValidationErrors() : bool + { + return !empty($this->validationErrors); + } + public function asString() : string + { + $buffer = ''; + foreach ($this->validationErrors as $line => $validationErrorsOnLine) { + $buffer .= sprintf(\PHP_EOL . ' Line %d:' . \PHP_EOL, $line); + foreach ($validationErrorsOnLine as $validationError) { + $buffer .= sprintf(' - %s' . \PHP_EOL, $validationError); + } + } + return $buffer; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\XmlConfiguration; + +use function file_get_contents; +use function libxml_clear_errors; +use function libxml_get_errors; +use function libxml_use_internal_errors; +use DOMDocument; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Validator +{ + public function validate(DOMDocument $document, string $xsdFilename) : \PHPUnit\TextUI\XmlConfiguration\ValidationResult + { + $originalErrorHandling = libxml_use_internal_errors(\true); + $document->schemaValidateSource(file_get_contents($xsdFilename)); + $errors = libxml_get_errors(); + libxml_clear_errors(); + libxml_use_internal_errors($originalErrorHandling); + return \PHPUnit\TextUI\XmlConfiguration\ValidationResult::fromArray($errors); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI; + +use function sprintf; +use RuntimeException; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class DirectoryDoesNotExistException extends RuntimeException implements \PHPUnit\TextUI\Exception +{ + public function __construct(string $directory) + { + parent::__construct(sprintf('Directory "%s" does not exist and could not be created', $directory)); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI; + use RuntimeException; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit @@ -82288,7 +90324,7 @@ use PHPUnit\SebastianBergmann\Environment\Console; final class Help { private const LEFT_MARGIN = ' '; - private const HELP_TEXT = ['Usage' => [['text' => 'phpunit [options] UnitTest.php'], ['text' => 'phpunit [options] ']], 'Configuration' => [['arg' => '--bootstrap ', 'desc' => 'A PHP script that is included before the tests run'], ['arg' => '-c|--configuration ', 'desc' => 'Read configuration from XML file'], ['arg' => '--no-configuration', 'desc' => 'Ignore default configuration file (phpunit.xml)'], ['arg' => '--no-extensions', 'desc' => 'Do not load PHPUnit extensions'], ['arg' => '--include-path ', 'desc' => 'Prepend PHP\'s include_path with given path(s)'], ['arg' => '-d ', 'desc' => 'Sets a php.ini value'], ['arg' => '--cache-directory ', 'desc' => 'Specify cache directory'], ['arg' => '--generate-configuration', 'desc' => 'Generate configuration file with suggested settings'], ['arg' => '--migrate-configuration', 'desc' => 'Migrate configuration file to current format']], 'Selection' => [['arg' => '--list-suites', 'desc' => 'List available test suites'], ['arg' => '--testsuite ', 'desc' => 'Only run tests from the specified test suite(s)'], ['arg' => '--exclude-testsuite ', 'desc' => 'Exclude tests from the specified test suite(s)'], ['arg' => '--list-groups', 'desc' => 'List available test groups'], ['arg' => '--group ', 'desc' => 'Only run tests from the specified group(s)'], ['arg' => '--exclude-group ', 'desc' => 'Exclude tests from the specified group(s)'], ['arg' => '--covers ', 'desc' => 'Only run tests that intend to cover '], ['arg' => '--uses ', 'desc' => 'Only run tests that intend to use '], ['arg' => '--list-tests', 'desc' => 'List available tests'], ['arg' => '--list-tests-xml ', 'desc' => 'List available tests in XML format'], ['arg' => '--filter ', 'desc' => 'Filter which tests to run'], ['arg' => '--test-suffix ', 'desc' => 'Only search for test in files with specified suffix(es). Default: Test.php,.phpt']], 'Execution' => [['arg' => '--process-isolation', 'desc' => 'Run each test in a separate PHP process'], ['arg' => '--globals-backup', 'desc' => 'Backup and restore $GLOBALS for each test'], ['arg' => '--static-backup', 'desc' => 'Backup and restore static properties for each test'], ['spacer' => ''], ['arg' => '--strict-coverage', 'desc' => 'Be strict about code coverage metadata'], ['arg' => '--strict-global-state', 'desc' => 'Be strict about changes to global state'], ['arg' => '--disallow-test-output', 'desc' => 'Be strict about output during tests'], ['arg' => '--enforce-time-limit', 'desc' => 'Enforce time limit based on test size'], ['arg' => '--default-time-limit ', 'desc' => 'Timeout in seconds for tests that have no declared size'], ['arg' => '--dont-report-useless-tests', 'desc' => 'Do not report tests that do not test anything'], ['spacer' => ''], ['arg' => '--stop-on-defect', 'desc' => 'Stop execution upon first not-passed test'], ['arg' => '--stop-on-error', 'desc' => 'Stop execution upon first error'], ['arg' => '--stop-on-failure', 'desc' => 'Stop execution upon first error or failure'], ['arg' => '--stop-on-warning', 'desc' => 'Stop execution upon first warning'], ['arg' => '--stop-on-risky', 'desc' => 'Stop execution upon first risky test'], ['arg' => '--stop-on-skipped', 'desc' => 'Stop execution upon first skipped test'], ['arg' => '--stop-on-incomplete', 'desc' => 'Stop execution upon first incomplete test'], ['spacer' => ''], ['arg' => '--fail-on-incomplete', 'desc' => 'Treat incomplete tests as failures'], ['arg' => '--fail-on-risky', 'desc' => 'Treat risky tests as failures'], ['arg' => '--fail-on-skipped', 'desc' => 'Treat skipped tests as failures'], ['arg' => '--fail-on-warning', 'desc' => 'Treat tests with warnings as failures'], ['spacer' => ''], ['arg' => '--cache-result', 'desc' => 'Write test results to cache file'], ['arg' => '--do-not-cache-result', 'desc' => 'Do not write test results to cache file'], ['spacer' => ''], ['arg' => '--order-by ', 'desc' => 'Run tests in order: default|defects|depends|duration|no-depends|random|reverse|size'], ['arg' => '--random-order-seed ', 'desc' => 'Use the specified random seed when running tests in random order']], 'Reporting' => [['arg' => '--colors ', 'desc' => 'Use colors in output ("never", "auto" or "always")'], ['arg' => '--columns ', 'desc' => 'Number of columns to use for progress output'], ['arg' => '--columns max', 'desc' => 'Use maximum number of columns for progress output'], ['arg' => '--stderr', 'desc' => 'Write to STDERR instead of STDOUT'], ['spacer' => ''], ['arg' => '--no-progress', 'desc' => 'Disable output of test execution progress'], ['arg' => '--no-results', 'desc' => 'Disable output of test results'], ['arg' => '--no-output', 'desc' => 'Disable all output'], ['spacer' => ''], ['arg' => '--display-incomplete', 'desc' => 'Display details for incomplete tests'], ['arg' => '--display-skipped', 'desc' => 'Display details for skipped tests'], ['arg' => '--display-deprecations', 'desc' => 'Display details for deprecations triggered by tests'], ['arg' => '--display-errors', 'desc' => 'Display details for errors triggered by tests'], ['arg' => '--display-notices', 'desc' => 'Display details for notices triggered by tests'], ['arg' => '--display-warnings', 'desc' => 'Display details for warnings triggered by tests'], ['arg' => '--reverse-list', 'desc' => 'Print defects in reverse order'], ['spacer' => ''], ['arg' => '--teamcity', 'desc' => 'Replace default progress and result output with TeamCity format'], ['arg' => '--testdox', 'desc' => 'Replace default result output with TestDox format']], 'Logging' => [['arg' => '--log-junit ', 'desc' => 'Write test results in JUnit XML format to file'], ['arg' => '--log-teamcity ', 'desc' => 'Write test results in TeamCity format to file'], ['arg' => '--testdox-html ', 'desc' => 'Write test results in TestDox format (HTML) to file'], ['arg' => '--testdox-text ', 'desc' => 'Write test results in TestDox format (plain text) to file'], ['arg' => '--log-events-text ', 'desc' => 'Stream events as plain text to file'], ['arg' => '--log-events-verbose-text ', 'desc' => 'Stream events as plain text (with telemetry information) to file'], ['arg' => '--no-logging', 'desc' => 'Ignore logging configured in the XML configuration file']], 'Code Coverage' => [['arg' => '--coverage-clover ', 'desc' => 'Write code coverage report in Clover XML format to file'], ['arg' => '--coverage-cobertura ', 'desc' => 'Write code coverage report in Cobertura XML format to file'], ['arg' => '--coverage-crap4j ', 'desc' => 'Write code coverage report in Crap4J XML format to file'], ['arg' => '--coverage-html ', 'desc' => 'Write code coverage report in HTML format to directory'], ['arg' => '--coverage-php ', 'desc' => 'Write serialized code coverage data to file'], ['arg' => '--coverage-text=', 'desc' => 'Write code coverage report in text format to file [default: standard output]'], ['arg' => '--coverage-xml ', 'desc' => 'Write code coverage report in XML format to directory'], ['arg' => '--warm-coverage-cache', 'desc' => 'Warm static analysis cache'], ['arg' => '--coverage-filter ', 'desc' => 'Include in code coverage reporting'], ['arg' => '--path-coverage', 'desc' => 'Report path coverage in addition to line coverage'], ['arg' => '--disable-coverage-ignore', 'desc' => 'Disable metadata for ignoring code coverage'], ['arg' => '--no-coverage', 'desc' => 'Ignore code coverage reporting configured in the XML configuration file']], 'Miscellaneous' => [['arg' => '-h|--help', 'desc' => 'Prints this usage information'], ['arg' => '--version', 'desc' => 'Prints the version and exits'], ['arg' => '--atleast-version ', 'desc' => 'Checks that version is greater than and exits'], ['arg' => '--check-version', 'desc' => 'Check whether PHPUnit is the latest version and exits']]]; + private const HELP_TEXT = ['Usage' => [['text' => 'phpunit [options] ...']], 'Configuration' => [['arg' => '--bootstrap ', 'desc' => 'A PHP script that is included before the tests run'], ['arg' => '-c|--configuration ', 'desc' => 'Read configuration from XML file'], ['arg' => '--no-configuration', 'desc' => 'Ignore default configuration file (phpunit.xml)'], ['arg' => '--no-extensions', 'desc' => 'Do not load PHPUnit extensions'], ['arg' => '--include-path ', 'desc' => 'Prepend PHP\'s include_path with given path(s)'], ['arg' => '-d ', 'desc' => 'Sets a php.ini value'], ['arg' => '--cache-directory ', 'desc' => 'Specify cache directory'], ['arg' => '--generate-configuration', 'desc' => 'Generate configuration file with suggested settings'], ['arg' => '--migrate-configuration', 'desc' => 'Migrate configuration file to current format'], ['arg' => '--generate-baseline ', 'desc' => 'Generate baseline for issues'], ['arg' => '--use-baseline ', 'desc' => 'Use baseline to ignore issues'], ['arg' => '--ignore-baseline', 'desc' => 'Do not use baseline to ignore issues']], 'Selection' => [['arg' => '--list-suites', 'desc' => 'List available test suites'], ['arg' => '--testsuite ', 'desc' => 'Only run tests from the specified test suite(s)'], ['arg' => '--exclude-testsuite ', 'desc' => 'Exclude tests from the specified test suite(s)'], ['arg' => '--list-groups', 'desc' => 'List available test groups'], ['arg' => '--group ', 'desc' => 'Only run tests from the specified group(s)'], ['arg' => '--exclude-group ', 'desc' => 'Exclude tests from the specified group(s)'], ['arg' => '--covers ', 'desc' => 'Only run tests that intend to cover '], ['arg' => '--uses ', 'desc' => 'Only run tests that intend to use '], ['arg' => '--list-tests', 'desc' => 'List available tests'], ['arg' => '--list-tests-xml ', 'desc' => 'List available tests in XML format'], ['arg' => '--filter ', 'desc' => 'Filter which tests to run'], ['arg' => '--test-suffix ', 'desc' => 'Only search for test in files with specified suffix(es). Default: Test.php,.phpt']], 'Execution' => [['arg' => '--process-isolation', 'desc' => 'Run each test in a separate PHP process'], ['arg' => '--globals-backup', 'desc' => 'Backup and restore $GLOBALS for each test'], ['arg' => '--static-backup', 'desc' => 'Backup and restore static properties for each test'], ['spacer' => ''], ['arg' => '--strict-coverage', 'desc' => 'Be strict about code coverage metadata'], ['arg' => '--strict-global-state', 'desc' => 'Be strict about changes to global state'], ['arg' => '--disallow-test-output', 'desc' => 'Be strict about output during tests'], ['arg' => '--enforce-time-limit', 'desc' => 'Enforce time limit based on test size'], ['arg' => '--default-time-limit ', 'desc' => 'Timeout in seconds for tests that have no declared size'], ['arg' => '--dont-report-useless-tests', 'desc' => 'Do not report tests that do not test anything'], ['spacer' => ''], ['arg' => '--stop-on-defect', 'desc' => 'Stop after first error, failure, warning, or risky test'], ['arg' => '--stop-on-error', 'desc' => 'Stop after first error'], ['arg' => '--stop-on-failure', 'desc' => 'Stop after first failure'], ['arg' => '--stop-on-warning', 'desc' => 'Stop after first warning'], ['arg' => '--stop-on-risky', 'desc' => 'Stop after first risky test'], ['arg' => '--stop-on-deprecation', 'desc' => 'Stop after first test that triggered a deprecation'], ['arg' => '--stop-on-notice', 'desc' => 'Stop after first test that triggered a notice'], ['arg' => '--stop-on-skipped', 'desc' => 'Stop after first skipped test'], ['arg' => '--stop-on-incomplete', 'desc' => 'Stop after first incomplete test'], ['spacer' => ''], ['arg' => '--fail-on-warning', 'desc' => 'Signal failure using shell exit code when a warning was triggered'], ['arg' => '--fail-on-risky', 'desc' => 'Signal failure using shell exit code when a test was considered risky'], ['arg' => '--fail-on-deprecation', 'desc' => 'Signal failure using shell exit code when a deprecation was triggered'], ['arg' => '--fail-on-notice', 'desc' => 'Signal failure using shell exit code when a notice was triggered'], ['arg' => '--fail-on-skipped', 'desc' => 'Signal failure using shell exit code when a test was skipped'], ['arg' => '--fail-on-incomplete', 'desc' => 'Signal failure using shell exit code when a test was marked incomplete'], ['spacer' => ''], ['arg' => '--cache-result', 'desc' => 'Write test results to cache file'], ['arg' => '--do-not-cache-result', 'desc' => 'Do not write test results to cache file'], ['spacer' => ''], ['arg' => '--order-by ', 'desc' => 'Run tests in order: default|defects|depends|duration|no-depends|random|reverse|size'], ['arg' => '--random-order-seed ', 'desc' => 'Use the specified random seed when running tests in random order']], 'Reporting' => [['arg' => '--colors ', 'desc' => 'Use colors in output ("never", "auto" or "always")'], ['arg' => '--columns ', 'desc' => 'Number of columns to use for progress output'], ['arg' => '--columns max', 'desc' => 'Use maximum number of columns for progress output'], ['arg' => '--stderr', 'desc' => 'Write to STDERR instead of STDOUT'], ['spacer' => ''], ['arg' => '--no-progress', 'desc' => 'Disable output of test execution progress'], ['arg' => '--no-results', 'desc' => 'Disable output of test results'], ['arg' => '--no-output', 'desc' => 'Disable all output'], ['spacer' => ''], ['arg' => '--display-incomplete', 'desc' => 'Display details for incomplete tests'], ['arg' => '--display-skipped', 'desc' => 'Display details for skipped tests'], ['arg' => '--display-deprecations', 'desc' => 'Display details for deprecations triggered by tests'], ['arg' => '--display-errors', 'desc' => 'Display details for errors triggered by tests'], ['arg' => '--display-notices', 'desc' => 'Display details for notices triggered by tests'], ['arg' => '--display-warnings', 'desc' => 'Display details for warnings triggered by tests'], ['arg' => '--reverse-list', 'desc' => 'Print defects in reverse order'], ['spacer' => ''], ['arg' => '--teamcity', 'desc' => 'Replace default progress and result output with TeamCity format'], ['arg' => '--testdox', 'desc' => 'Replace default result output with TestDox format'], ['spacer' => ''], ['arg' => '--debug', 'desc' => 'Replace default progress and result output with debugging information']], 'Logging' => [['arg' => '--log-junit ', 'desc' => 'Write test results in JUnit XML format to file'], ['arg' => '--log-teamcity ', 'desc' => 'Write test results in TeamCity format to file'], ['arg' => '--testdox-html ', 'desc' => 'Write test results in TestDox format (HTML) to file'], ['arg' => '--testdox-text ', 'desc' => 'Write test results in TestDox format (plain text) to file'], ['arg' => '--log-events-text ', 'desc' => 'Stream events as plain text to file'], ['arg' => '--log-events-verbose-text ', 'desc' => 'Stream events as plain text with extended information to file'], ['arg' => '--no-logging', 'desc' => 'Ignore logging configured in the XML configuration file']], 'Code Coverage' => [['arg' => '--coverage-clover ', 'desc' => 'Write code coverage report in Clover XML format to file'], ['arg' => '--coverage-cobertura ', 'desc' => 'Write code coverage report in Cobertura XML format to file'], ['arg' => '--coverage-crap4j ', 'desc' => 'Write code coverage report in Crap4J XML format to file'], ['arg' => '--coverage-html ', 'desc' => 'Write code coverage report in HTML format to directory'], ['arg' => '--coverage-php ', 'desc' => 'Write serialized code coverage data to file'], ['arg' => '--coverage-text=', 'desc' => 'Write code coverage report in text format to file [default: standard output]'], ['arg' => '--coverage-xml ', 'desc' => 'Write code coverage report in XML format to directory'], ['arg' => '--warm-coverage-cache', 'desc' => 'Warm static analysis cache'], ['arg' => '--coverage-filter ', 'desc' => 'Include in code coverage reporting'], ['arg' => '--path-coverage', 'desc' => 'Report path coverage in addition to line coverage'], ['arg' => '--disable-coverage-ignore', 'desc' => 'Disable metadata for ignoring code coverage'], ['arg' => '--no-coverage', 'desc' => 'Ignore code coverage reporting configured in the XML configuration file']], 'Miscellaneous' => [['arg' => '-h|--help', 'desc' => 'Prints this usage information'], ['arg' => '--version', 'desc' => 'Prints the version and exits'], ['arg' => '--atleast-version ', 'desc' => 'Checks that version is greater than and exits'], ['arg' => '--check-version', 'desc' => 'Check whether PHPUnit is the latest version and exits']]]; private int $lengthOfLongestOptionName = 0; private readonly int $columnsAvailableForDescription; private ?bool $hasColor; @@ -82392,11 +90428,19 @@ use function str_repeat; use function strlen; use PHPUnit\Event\EventFacadeIsSealedException; use PHPUnit\Event\Facade; +use PHPUnit\Event\Test\DeprecationTriggered; use PHPUnit\Event\Test\Errored; -use PHPUnit\Event\Test\PrintedUnexpectedOutput; +use PHPUnit\Event\Test\ErrorTriggered; +use PHPUnit\Event\Test\NoticeTriggered; +use PHPUnit\Event\Test\PhpDeprecationTriggered; +use PHPUnit\Event\Test\PhpNoticeTriggered; +use PHPUnit\Event\Test\PhpWarningTriggered; +use PHPUnit\Event\Test\WarningTriggered; use PHPUnit\Event\TestRunner\ExecutionStarted; use PHPUnit\Event\UnknownSubscriberTypeException; use PHPUnit\Framework\TestStatus\TestStatus; +use PHPUnit\TextUI\Configuration\Source; +use PHPUnit\TextUI\Configuration\SourceFilter; use PHPUnit\TextUI\Output\Printer; use PHPUnit\Util\Color; /** @@ -82407,6 +90451,7 @@ final class ProgressPrinter private readonly Printer $printer; private readonly bool $colors; private readonly int $numberOfColumns; + private readonly Source $source; private int $column = 0; private int $numberOfTests = 0; private int $numberOfTestsWidth = 0; @@ -82418,12 +90463,13 @@ final class ProgressPrinter * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ - public function __construct(Printer $printer, bool $colors, int $numberOfColumns) + public function __construct(Printer $printer, Facade $facade, bool $colors, int $numberOfColumns, Source $source) { $this->printer = $printer; $this->colors = $colors; $this->numberOfColumns = $numberOfColumns; - $this->registerSubscribers(); + $this->source = $source; + $this->registerSubscribers($facade); } public function testRunnerExecutionStarted(ExecutionStarted $event) : void { @@ -82454,11 +90500,59 @@ final class ProgressPrinter { $this->updateTestStatus(TestStatus::incomplete()); } - public function testTriggeredNotice() : void + public function testTriggeredNotice(NoticeTriggered $event) : void + { + if ($event->ignoredByBaseline()) { + return; + } + if ($this->source->restrictNotices() && !(new SourceFilter())->includes($this->source, $event->file())) { + return; + } + if (!$this->source->ignoreSuppressionOfNotices() && $event->wasSuppressed()) { + return; + } + $this->updateTestStatus(TestStatus::notice()); + } + public function testTriggeredPhpNotice(PhpNoticeTriggered $event) : void { + if ($event->ignoredByBaseline()) { + return; + } + if ($this->source->restrictNotices() && !(new SourceFilter())->includes($this->source, $event->file())) { + return; + } + if (!$this->source->ignoreSuppressionOfPhpNotices() && $event->wasSuppressed()) { + return; + } $this->updateTestStatus(TestStatus::notice()); } - public function testTriggeredDeprecation() : void + public function testTriggeredDeprecation(DeprecationTriggered $event) : void + { + if ($event->ignoredByBaseline() || $event->ignoredByTest()) { + return; + } + if ($this->source->restrictDeprecations() && !(new SourceFilter())->includes($this->source, $event->file())) { + return; + } + if (!$this->source->ignoreSuppressionOfDeprecations() && $event->wasSuppressed()) { + return; + } + $this->updateTestStatus(TestStatus::deprecation()); + } + public function testTriggeredPhpDeprecation(PhpDeprecationTriggered $event) : void + { + if ($event->ignoredByBaseline() || $event->ignoredByTest()) { + return; + } + if ($this->source->restrictDeprecations() && !(new SourceFilter())->includes($this->source, $event->file())) { + return; + } + if (!$this->source->ignoreSuppressionOfPhpDeprecations() && $event->wasSuppressed()) { + return; + } + $this->updateTestStatus(TestStatus::deprecation()); + } + public function testTriggeredPhpunitDeprecation() : void { $this->updateTestStatus(TestStatus::deprecation()); } @@ -82466,10 +90560,43 @@ final class ProgressPrinter { $this->updateTestStatus(TestStatus::risky()); } - public function testTriggeredWarning() : void + public function testTriggeredWarning(WarningTriggered $event) : void { + if ($event->ignoredByBaseline()) { + return; + } + if ($this->source->restrictWarnings() && !(new SourceFilter())->includes($this->source, $event->file())) { + return; + } + if (!$this->source->ignoreSuppressionOfWarnings() && $event->wasSuppressed()) { + return; + } $this->updateTestStatus(TestStatus::warning()); } + public function testTriggeredPhpWarning(PhpWarningTriggered $event) : void + { + if ($event->ignoredByBaseline()) { + return; + } + if ($this->source->restrictWarnings() && !(new SourceFilter())->includes($this->source, $event->file())) { + return; + } + if (!$this->source->ignoreSuppressionOfPhpWarnings() && $event->wasSuppressed()) { + return; + } + $this->updateTestStatus(TestStatus::warning()); + } + public function testTriggeredPhpunitWarning() : void + { + $this->updateTestStatus(TestStatus::warning()); + } + public function testTriggeredError(ErrorTriggered $event) : void + { + if (!$this->source->ignoreSuppressionOfErrors() && $event->wasSuppressed()) { + return; + } + $this->updateTestStatus(TestStatus::error()); + } public function testFailed() : void { $this->updateTestStatus(TestStatus::failure()); @@ -82489,10 +90616,6 @@ final class ProgressPrinter $this->updateTestStatus(TestStatus::error()); } } - public function testPrintedOutput(PrintedUnexpectedOutput $event) : void - { - $this->printer->print($event->output()); - } public function testFinished() : void { if ($this->status === null) { @@ -82521,9 +90644,9 @@ final class ProgressPrinter * @throws EventFacadeIsSealedException * @throws UnknownSubscriberTypeException */ - private function registerSubscribers() : void + private function registerSubscribers(Facade $facade) : void { - Facade::registerSubscribers(new \PHPUnit\TextUI\Output\Default\ProgressPrinter\BeforeTestClassMethodErroredSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestConsideredRiskySubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestErroredSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestFailedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestFinishedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestMarkedIncompleteSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestPreparedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestRunnerExecutionStartedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestSkippedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredDeprecationSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredNoticeSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpDeprecationSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpNoticeSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpunitDeprecationSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpunitWarningSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpWarningSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredWarningSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestPrintedUnexpectedOutputSubscriber($this)); + $facade->registerSubscribers(new \PHPUnit\TextUI\Output\Default\ProgressPrinter\BeforeTestClassMethodErroredSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestConsideredRiskySubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestErroredSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestFailedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestFinishedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestMarkedIncompleteSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestPreparedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestRunnerExecutionStartedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestSkippedSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredDeprecationSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredNoticeSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpDeprecationSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpNoticeSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpunitDeprecationSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpunitWarningSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredPhpWarningSubscriber($this), new \PHPUnit\TextUI\Output\Default\ProgressPrinter\TestTriggeredWarningSubscriber($this)); } private function updateTestStatus(TestStatus $status) : void { @@ -82808,16 +90931,16 @@ declare (strict_types=1); */ namespace PHPUnit\TextUI\Output\Default\ProgressPrinter; -use PHPUnit\Event\Test\PrintedUnexpectedOutput; -use PHPUnit\Event\Test\PrintedUnexpectedOutputSubscriber; +use PHPUnit\Event\TestRunner\ExecutionStarted; +use PHPUnit\Event\TestRunner\ExecutionStartedSubscriber; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ -final class TestPrintedUnexpectedOutputSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements PrintedUnexpectedOutputSubscriber +final class TestRunnerExecutionStartedSubscriber extends \PHPUnit\TextUI\Output\Default\ProgressPrinter\Subscriber implements ExecutionStartedSubscriber { - public function notify(PrintedUnexpectedOutput $event) : void + public function notify(ExecutionStarted $event) : void { - $this->printer()->testPrintedOutput($event); + $this->printer()->testRunnerExecutionStarted($event); } } printer()->testRunnerExecutionStarted($event); + $this->printer()->testSkipped(); } } printer()->testSkipped(); + $this->printer()->testTriggeredDeprecation($event); } } printer()->testTriggeredDeprecation(); + $this->printer()->testTriggeredError($event); } } printer()->testTriggeredNotice(); + $this->printer()->testTriggeredNotice($event); } } printer()->testTriggeredDeprecation(); + $this->printer()->testTriggeredPhpDeprecation($event); } } printer()->testTriggeredNotice(); + $this->printer()->testTriggeredPhpNotice($event); } } printer()->testTriggeredWarning(); + $this->printer()->testTriggeredPhpWarning($event); } } printer()->testTriggeredDeprecation(); + $this->printer()->testTriggeredPhpunitDeprecation(); } } printer()->testTriggeredWarning(); + $this->printer()->testTriggeredPhpunitWarning(); } } printer()->testTriggeredWarning(); + $this->printer()->testTriggeredWarning($event); } } printer = $printer; $this->displayPhpunitErrors = $displayPhpunitErrors; $this->displayPhpunitWarnings = $displayPhpunitWarnings; + $this->displayPhpunitDeprecations = $displayPhpunitDeprecations; $this->displayTestsWithErrors = $displayTestsWithErrors; $this->displayTestsWithFailedAssertions = $displayTestsWithFailedAssertions; $this->displayRiskyTests = $displayRiskyTests; - $this->displayDetailsOnTestsThatTriggeredPhpunitDeprecations = $displayDetailsOnTestsThatTriggeredPhpunitDeprecations; $this->displayDetailsOnIncompleteTests = $displayDetailsOnIncompleteTests; $this->displayDetailsOnSkippedTests = $displayDetailsOnSkippedTests; $this->displayDetailsOnTestsThatTriggerDeprecations = $displayDetailsOnTestsThatTriggerDeprecations; @@ -83155,7 +91281,10 @@ final class ResultPrinter $this->printPhpunitErrors($result); } if ($this->displayPhpunitWarnings) { - $this->printPhpunitWarnings($result); + $this->printTestRunnerWarnings($result); + } + if ($this->displayPhpunitDeprecations) { + $this->printTestRunnerDeprecations($result); } if ($this->displayTestsWithErrors) { $this->printTestsWithErrors($result); @@ -83163,12 +91292,15 @@ final class ResultPrinter if ($this->displayTestsWithFailedAssertions) { $this->printTestsWithFailedAssertions($result); } - if ($this->displayRiskyTests) { - $this->printRiskyTests($result); + if ($this->displayPhpunitWarnings) { + $this->printDetailsOnTestsThatTriggeredPhpunitWarnings($result); } - if ($this->displayDetailsOnTestsThatTriggeredPhpunitDeprecations) { + if ($this->displayPhpunitDeprecations) { $this->printDetailsOnTestsThatTriggeredPhpunitDeprecations($result); } + if ($this->displayRiskyTests) { + $this->printRiskyTests($result); + } if ($this->displayDetailsOnIncompleteTests) { $this->printIncompleteTests($result); } @@ -83176,20 +91308,20 @@ final class ResultPrinter $this->printSkippedTestSuites($result); $this->printSkippedTests($result); } - if ($this->displayDetailsOnTestsThatTriggerDeprecations) { - $this->printDetailsOnTestsThatTriggerPhpDeprecations($result); - $this->printDetailsOnTestsThatTriggerDeprecations($result); - } if ($this->displayDetailsOnTestsThatTriggerErrors) { - $this->printDetailsOnTestsThatTriggerErrors($result); + $this->printIssueList('error', $result->errors()); + } + if ($this->displayDetailsOnTestsThatTriggerWarnings) { + $this->printIssueList('PHP warning', $result->phpWarnings()); + $this->printIssueList('warning', $result->warnings()); } if ($this->displayDetailsOnTestsThatTriggerNotices) { - $this->printDetailsOnTestsThatTriggerPhpNotices($result); - $this->printDetailsOnTestsThatTriggerNotices($result); + $this->printIssueList('PHP notice', $result->phpNotices()); + $this->printIssueList('notice', $result->notices()); } - if ($this->displayDetailsOnTestsThatTriggerWarnings) { - $this->printDetailsOnTestsThatTriggerPhpWarnings($result); - $this->printDetailsOnTestsThatTriggerWarnings($result); + if ($this->displayDetailsOnTestsThatTriggerDeprecations) { + $this->printIssueList('PHP deprecation', $result->phpDeprecations()); + $this->printIssueList('deprecation', $result->deprecations()); } } public function flush() : void @@ -83201,26 +91333,51 @@ final class ResultPrinter if (!$result->hasTestTriggeredPhpunitErrorEvents()) { return; } - $this->printList($result->numberOfTestsWithTestTriggeredPhpunitErrorEvents(), $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitErrorEvents()), 'PHPUnit error'); + $elements = $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitErrorEvents()); + $this->printListHeaderWithNumber($elements['numberOfTestsWithIssues'], 'PHPUnit error'); + $this->printList($elements['elements']); + } + private function printDetailsOnTestsThatTriggeredPhpunitDeprecations(TestResult $result) : void + { + if (!$result->hasTestTriggeredPhpunitDeprecationEvents()) { + return; + } + $elements = $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitDeprecationEvents()); + $this->printListHeaderWithNumberOfTestsAndNumberOfIssues($elements['numberOfTestsWithIssues'], $elements['numberOfIssues'], 'PHPUnit deprecation'); + $this->printList($elements['elements']); } - private function printPhpunitWarnings(TestResult $result) : void + private function printTestRunnerWarnings(TestResult $result) : void { - if (!$result->hasTestRunnerTriggeredWarningEvents() && !$result->hasTestTriggeredPhpunitWarningEvents()) { + if (!$result->hasTestRunnerTriggeredWarningEvents()) { return; } $elements = []; foreach ($result->testRunnerTriggeredWarningEvents() as $event) { $elements[] = ['title' => $event->message(), 'body' => '']; } - $elements = array_merge($elements, $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitWarningEvents())); - $this->printList($result->numberOfTestRunnerTriggeredWarningEvents() + $result->numberOfTestsWithTestTriggeredPhpunitWarningEvents(), $elements, 'PHPUnit warning'); + $this->printListHeaderWithNumber(count($elements), 'PHPUnit test runner warning'); + $this->printList($elements); } - private function printDetailsOnTestsThatTriggeredPhpunitDeprecations(TestResult $result) : void + private function printTestRunnerDeprecations(TestResult $result) : void { - if (!$result->hasTestTriggeredPhpunitDeprecationEvents()) { + if (!$result->hasTestRunnerTriggeredDeprecationEvents()) { return; } - $this->printList($result->numberOfTestsWithTestTriggeredPhpunitDeprecationEvents(), $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitDeprecationEvents()), 'PHPUnit deprecation'); + $elements = []; + foreach ($result->testRunnerTriggeredDeprecationEvents() as $event) { + $elements[] = ['title' => $event->message(), 'body' => '']; + } + $this->printListHeaderWithNumber(count($elements), 'PHPUnit test runner deprecation'); + $this->printList($elements); + } + private function printDetailsOnTestsThatTriggeredPhpunitWarnings(TestResult $result) : void + { + if (!$result->hasTestTriggeredPhpunitWarningEvents()) { + return; + } + $elements = $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpunitWarningEvents()); + $this->printListHeaderWithNumberOfTestsAndNumberOfIssues($elements['numberOfTestsWithIssues'], $elements['numberOfIssues'], 'PHPUnit warning'); + $this->printList($elements['elements']); } private function printTestsWithErrors(TestResult $result) : void { @@ -83236,7 +91393,8 @@ final class ResultPrinter } $elements[] = ['title' => $title, 'body' => $event->throwable()->asString()]; } - $this->printList(count($elements), $elements, 'error'); + $this->printListHeaderWithNumber(count($elements), 'error'); + $this->printList($elements); } private function printTestsWithFailedAssertions(TestResult $result) : void { @@ -83251,14 +91409,17 @@ final class ResultPrinter } $elements[] = ['title' => $this->name($event->test()), 'body' => $body]; } - $this->printList(count($elements), $elements, 'failure'); + $this->printListHeaderWithNumber(count($elements), 'failure'); + $this->printList($elements); } private function printRiskyTests(TestResult $result) : void { if (!$result->hasTestConsideredRiskyEvents()) { return; } - $this->printList($result->numberOfTestsWithTestConsideredRiskyEvents(), $this->mapTestsWithIssuesEventsToElements($result->testConsideredRiskyEvents()), 'risky test'); + $elements = $this->mapTestsWithIssuesEventsToElements($result->testConsideredRiskyEvents()); + $this->printListHeaderWithNumber($elements['numberOfTestsWithIssues'], 'risky test'); + $this->printList($elements['elements']); } private function printIncompleteTests(TestResult $result) : void { @@ -83269,7 +91430,8 @@ final class ResultPrinter foreach ($result->testMarkedIncompleteEvents() as $event) { $elements[] = ['title' => $this->name($event->test()), 'body' => $event->throwable()->asString()]; } - $this->printList(count($elements), $elements, 'incomplete test'); + $this->printListHeaderWithNumber(count($elements), 'incomplete test'); + $this->printList($elements); } private function printSkippedTestSuites(TestResult $result) : void { @@ -83280,7 +91442,8 @@ final class ResultPrinter foreach ($result->testSuiteSkippedEvents() as $event) { $elements[] = ['title' => $event->testSuite()->name(), 'body' => $event->message()]; } - $this->printList(count($elements), $elements, 'skipped test suite'); + $this->printListHeaderWithNumber(count($elements), 'skipped test suite'); + $this->printList($elements); } private function printSkippedTests(TestResult $result) : void { @@ -83291,67 +91454,66 @@ final class ResultPrinter foreach ($result->testSkippedEvents() as $event) { $elements[] = ['title' => $this->name($event->test()), 'body' => $event->message()]; } - $this->printList(count($elements), $elements, 'skipped test'); + $this->printListHeaderWithNumber(count($elements), 'skipped test'); + $this->printList($elements); } - private function printDetailsOnTestsThatTriggerPhpDeprecations(TestResult $result) : void + /** + * @psalm-param non-empty-string $type + * @psalm-param list $issues + */ + private function printIssueList(string $type, array $issues) : void { - if (!$result->hasTestTriggeredPhpDeprecationEvents()) { + if (empty($issues)) { return; } - $this->printList($result->numberOfTestsWithTestTriggeredPhpDeprecationEvents(), $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpDeprecationEvents()), 'PHP deprecation'); - } - private function printDetailsOnTestsThatTriggerDeprecations(TestResult $result) : void - { - if (!$result->hasTestTriggeredDeprecationEvents()) { - return; + $numberOfUniqueIssues = count($issues); + $triggeringTests = []; + foreach ($issues as $issue) { + $triggeringTests = array_merge($triggeringTests, array_keys($issue->triggeringTests())); } - $this->printList($result->numberOfTestsWithTestTriggeredDeprecationEvents(), $this->mapTestsWithIssuesEventsToElements($result->testTriggeredDeprecationEvents()), 'deprecation'); - } - private function printDetailsOnTestsThatTriggerErrors(TestResult $result) : void - { - if (!$result->hasTestTriggeredErrorEvents()) { - return; - } - $this->printList($result->numberOfTestsWithTestTriggeredErrorEvents(), $this->mapTestsWithIssuesEventsToElements($result->testTriggeredErrorEvents()), 'error'); - } - private function printDetailsOnTestsThatTriggerPhpNotices(TestResult $result) : void - { - if (!$result->hasTestTriggeredPhpNoticeEvents()) { - return; + $numberOfTests = count(array_unique($triggeringTests)); + unset($triggeringTests); + $this->printListHeader(sprintf('%d test%s triggered %d %s%s:' . PHP_EOL . PHP_EOL, $numberOfTests, $numberOfTests !== 1 ? 's' : '', $numberOfUniqueIssues, $type, $numberOfUniqueIssues !== 1 ? 's' : '')); + $i = 1; + foreach ($issues as $issue) { + $title = sprintf('%s:%d', $issue->file(), $issue->line()); + $body = trim($issue->description()) . PHP_EOL . PHP_EOL . 'Triggered by:'; + $triggeringTests = $issue->triggeringTests(); + ksort($triggeringTests); + foreach ($triggeringTests as $triggeringTest) { + $body .= PHP_EOL . PHP_EOL . '* ' . $triggeringTest['test']->id(); + if ($triggeringTest['count'] > 1) { + $body .= sprintf(' (%d times)', $triggeringTest['count']); + } + if ($triggeringTest['test']->isTestMethod()) { + $body .= PHP_EOL . ' ' . $triggeringTest['test']->file() . ':' . $triggeringTest['test']->line(); + } + } + $this->printIssueListElement($i++, $title, $body); + $this->printer->print(PHP_EOL); } - $this->printList($result->numberOfTestsWithTestTriggeredPhpNoticeEvents(), $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpNoticeEvents()), 'PHP notice'); } - private function printDetailsOnTestsThatTriggerNotices(TestResult $result) : void + private function printListHeaderWithNumberOfTestsAndNumberOfIssues(int $numberOfTestsWithIssues, int $numberOfIssues, string $type) : void { - if (!$result->hasTestTriggeredNoticeEvents()) { - return; - } - $this->printList($result->numberOfTestsWithTestTriggeredNoticeEvents(), $this->mapTestsWithIssuesEventsToElements($result->testTriggeredNoticeEvents()), 'notice'); + $this->printListHeader(sprintf("%d test%s triggered %d %s%s:\n\n", $numberOfTestsWithIssues, $numberOfTestsWithIssues !== 1 ? 's' : '', $numberOfIssues, $type, $numberOfIssues !== 1 ? 's' : '')); } - private function printDetailsOnTestsThatTriggerPhpWarnings(TestResult $result) : void + private function printListHeaderWithNumber(int $number, string $type) : void { - if (!$result->hasTestTriggeredPhpWarningEvents()) { - return; - } - $this->printList($result->numberOfTestsWithTestTriggeredPhpWarningEvents(), $this->mapTestsWithIssuesEventsToElements($result->testTriggeredPhpWarningEvents()), 'PHP warning'); + $this->printListHeader(sprintf("There %s %d %s%s:\n\n", $number === 1 ? 'was' : 'were', $number, $type, $number === 1 ? '' : 's')); } - private function printDetailsOnTestsThatTriggerWarnings(TestResult $result) : void + private function printListHeader(string $header) : void { - if (!$result->hasTestTriggeredWarningEvents()) { - return; + if ($this->listPrinted) { + $this->printer->print("--\n\n"); } - $this->printList($result->numberOfTestsWithTestTriggeredWarningEvents(), $this->mapTestsWithIssuesEventsToElements($result->testTriggeredWarningEvents()), 'warning'); + $this->listPrinted = \true; + $this->printer->print($header); } /** * @psalm-param list $elements */ - private function printList(int $count, array $elements, string $type) : void + private function printList(array $elements) : void { - if ($this->listPrinted) { - $this->printer->print("--\n\n"); - } - $this->listPrinted = \true; - $this->printer->print(sprintf("There %s %d %s%s:\n\n", $count === 1 ? 'was' : 'were', $count, $type, $count === 1 ? '' : 's')); $i = 1; if ($this->displayDefectsInReverseOrder) { $elements = array_reverse($elements); @@ -83366,63 +91528,120 @@ final class ResultPrinter $body = trim($body); $this->printer->print(sprintf("%s%d) %s\n%s%s", $number > 1 ? "\n" : '', $number, $title, $body, !empty($body) ? "\n" : '')); } - /** - * @throws NoDataSetFromDataProviderException - */ + private function printIssueListElement(int $number, string $title, string $body) : void + { + $body = trim($body); + $this->printer->print(sprintf("%d) %s\n%s%s", $number, $title, $body, !empty($body) ? "\n" : '')); + } private function name(Test $test) : string { if ($test->isTestMethod()) { assert($test instanceof TestMethod); - return $test->nameWithClass(); + if (!$test->testData()->hasDataFromDataProvider()) { + return $test->nameWithClass(); + } + return $test->className() . '::' . $test->methodName() . $test->testData()->dataFromDataProvider()->dataAsStringForResultOutput(); } return $test->name(); } - private function location(Test $test) : string - { - if (!$test->isTestMethod()) { - return ''; - } - assert($test instanceof TestMethod); - return sprintf('%s%s:%d%s', PHP_EOL, $test->file(), $test->line(), PHP_EOL); - } /** * @psalm-param array> $events * - * @psalm-return list + * @psalm-return array{numberOfTestsWithIssues: int, numberOfIssues: int, elements: list} */ private function mapTestsWithIssuesEventsToElements(array $events) : array { $elements = []; + $issues = 0; foreach ($events as $reasons) { $test = $reasons[0]->test(); + $testLocation = $this->testLocation($test); $title = $this->name($test); - $location = $this->location($test); - if (count($reasons) === 1) { - $body = trim($reasons[0]->message()) . PHP_EOL; - } else { - $body = ''; - $first = \true; - foreach ($reasons as $reason) { - if ($first) { - $first = \false; - } else { - $body .= PHP_EOL; - } - $lines = explode(PHP_EOL, trim($reason->message())); - $body .= '* ' . $lines[0] . PHP_EOL; - if (count($lines) > 1) { - foreach (range(1, count($lines) - 1) as $line) { - $body .= ' ' . $lines[$line] . PHP_EOL; - } - } + $body = ''; + $first = \true; + $single = count($reasons) === 1; + foreach ($reasons as $reason) { + if ($first) { + $first = \false; + } else { + $body .= PHP_EOL; } + $body .= $this->reasonMessage($reason, $single); + $body .= $this->reasonLocation($reason, $single); + $issues++; } - if (!empty($location)) { - $body .= $location; + if (!empty($testLocation)) { + $body .= $testLocation; } $elements[] = ['title' => $title, 'body' => $body]; } - return $elements; + return ['numberOfTestsWithIssues' => count($events), 'numberOfIssues' => $issues, 'elements' => $elements]; + } + private function testLocation(Test $test) : string + { + if (!$test->isTestMethod()) { + return ''; + } + assert($test instanceof TestMethod); + return sprintf('%s%s:%d%s', PHP_EOL, $test->file(), $test->line(), PHP_EOL); + } + private function reasonMessage(ConsideredRisky|DeprecationTriggered|ErrorTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpunitDeprecationTriggered|PhpunitErrorTriggered|PhpunitWarningTriggered|PhpWarningTriggered|WarningTriggered $reason, bool $single) : string + { + $message = trim($reason->message()); + if ($single) { + return $message . PHP_EOL; + } + $lines = explode(PHP_EOL, $message); + $buffer = '* ' . $lines[0] . PHP_EOL; + if (count($lines) > 1) { + foreach (range(1, count($lines) - 1) as $line) { + $buffer .= ' ' . $lines[$line] . PHP_EOL; + } + } + return $buffer; + } + private function reasonLocation(ConsideredRisky|DeprecationTriggered|ErrorTriggered|NoticeTriggered|PhpDeprecationTriggered|PhpNoticeTriggered|PhpunitDeprecationTriggered|PhpunitErrorTriggered|PhpunitWarningTriggered|PhpWarningTriggered|WarningTriggered $reason, bool $single) : string + { + if (!$reason instanceof DeprecationTriggered && !$reason instanceof PhpDeprecationTriggered && !$reason instanceof ErrorTriggered && !$reason instanceof NoticeTriggered && !$reason instanceof PhpNoticeTriggered && !$reason instanceof WarningTriggered && !$reason instanceof PhpWarningTriggered) { + return ''; + } + return sprintf('%s%s:%d%s', $single ? '' : ' ', $reason->file(), $reason->line(), PHP_EOL); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\Output\Default; + +use PHPUnit\Event\EventFacadeIsSealedException; +use PHPUnit\Event\Facade; +use PHPUnit\Event\Test\PrintedUnexpectedOutput; +use PHPUnit\Event\Test\PrintedUnexpectedOutputSubscriber; +use PHPUnit\Event\UnknownSubscriberTypeException; +use PHPUnit\TextUI\Output\Printer; +final class UnexpectedOutputPrinter implements PrintedUnexpectedOutputSubscriber +{ + private readonly Printer $printer; + /** + * @throws EventFacadeIsSealedException + * @throws UnknownSubscriberTypeException + */ + public function __construct(Printer $printer, Facade $facade) + { + $this->printer = $printer; + $facade->registerSubscriber($this); + } + public function notify(PrintedUnexpectedOutput $event) : void + { + $this->printer->print($event->output()); } } debug()) { + return self::$printer; + } + self::createUnexpectedOutputPrinter(); + if (!$extensionReplacesProgressOutput) { + self::createProgressPrinter($configuration); + } + if (!$extensionReplacesResultOutput) { + self::createResultPrinter($configuration); + self::createSummaryPrinter($configuration); + } if ($configuration->outputIsTeamCity()) { - new TeamCityLogger(\PHPUnit\TextUI\Output\DefaultPrinter::standardOutput()); + new TeamCityLogger(\PHPUnit\TextUI\Output\DefaultPrinter::standardOutput(), EventFacade::instance()); } - self::$colors = $configuration->colors(); return self::$printer; } /** @@ -83513,6 +91746,9 @@ final class Facade private static function createPrinter(Configuration $configuration) : void { $printerNeeded = \false; + if ($configuration->debug()) { + $printerNeeded = \true; + } if ($configuration->outputIsTeamCity()) { $printerNeeded = \true; } @@ -83541,7 +91777,7 @@ final class Facade if (!self::useDefaultProgressPrinter($configuration)) { return; } - new DefaultProgressPrinter(self::$printer, $configuration->colors(), $configuration->columns()); + new DefaultProgressPrinter(self::$printer, EventFacade::instance(), $configuration->colors(), $configuration->columns(), $configuration->source()); self::$defaultProgressPrinter = \true; } private static function useDefaultProgressPrinter(Configuration $configuration) : bool @@ -83560,8 +91796,8 @@ final class Facade private static function createResultPrinter(Configuration $configuration) : void { assert(self::$printer !== null); - if ($configuration->outputIsTeamCity() || $configuration->outputIsTestDox()) { - self::$defaultResultPrinter = new DefaultResultPrinter(self::$printer, \true, \true, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false, \false); + if ($configuration->outputIsTestDox()) { + self::$defaultResultPrinter = new DefaultResultPrinter(self::$printer, \true, \true, \true, \false, \false, \true, \false, \false, $configuration->displayDetailsOnTestsThatTriggerDeprecations(), $configuration->displayDetailsOnTestsThatTriggerErrors(), $configuration->displayDetailsOnTestsThatTriggerNotices(), $configuration->displayDetailsOnTestsThatTriggerWarnings(), $configuration->reverseDefectList()); } if ($configuration->outputIsTestDox()) { self::$testDoxResultPrinter = new TestDoxResultPrinter(self::$printer, $configuration->colors()); @@ -83582,6 +91818,15 @@ final class Facade } self::$summaryPrinter = new \PHPUnit\TextUI\Output\SummaryPrinter(self::$printer, $configuration->colors()); } + /** + * @throws EventFacadeIsSealedException + * @throws UnknownSubscriberTypeException + */ + private static function createUnexpectedOutputPrinter() : void + { + assert(self::$printer !== null); + new UnexpectedOutputPrinter(self::$printer, EventFacade::instance()); + } } wasSuccessfulAndNoTestHasIssues() && !$result->hasTestSuiteSkippedEvents() && !$result->hasTestSkippedEvents()) { $this->printWithColor('fg-black, bg-green', sprintf('OK (%d test%s, %d assertion%s)', $result->numberOfTestsRun(), $result->numberOfTestsRun() === 1 ? '' : 's', $result->numberOfAssertions(), $result->numberOfAssertions() === 1 ? '' : 's')); + $this->printNumberOfIssuesIgnoredByBaseline($result); return; } $color = 'fg-black, bg-yellow'; @@ -83770,34 +92016,35 @@ final class SummaryPrinter if (!$result->hasTestsWithIssues()) { $this->printWithColor($color, 'OK, but some tests were skipped!'); } else { - $this->printWithColor($color, 'OK, but some tests have issues!'); + $this->printWithColor($color, 'OK, but there were issues!'); } } else { - if ($result->hasTestErroredEvents()) { + if ($result->hasTestErroredEvents() || $result->hasTestTriggeredPhpunitErrorEvents()) { $color = 'fg-white, bg-red'; $this->printWithColor($color, 'ERRORS!'); } elseif ($result->hasTestFailedEvents()) { $color = 'fg-white, bg-red'; $this->printWithColor($color, 'FAILURES!'); - } elseif ($result->hasWarningEvents()) { + } elseif ($result->hasWarnings()) { $this->printWithColor($color, 'WARNINGS!'); - } elseif ($result->hasDeprecationEvents()) { + } elseif ($result->hasDeprecations()) { $this->printWithColor($color, 'DEPRECATIONS!'); - } elseif ($result->hasNoticeEvents()) { + } elseif ($result->hasNotices()) { $this->printWithColor($color, 'NOTICES!'); } } $this->printCountString($result->numberOfTestsRun(), 'Tests', $color, \true); $this->printCountString($result->numberOfAssertions(), 'Assertions', $color, \true); - $this->printCountString($result->numberOfTestErroredEvents() + $result->numberOfTestsWithTestTriggeredErrorEvents(), 'Errors', $color); + $this->printCountString($result->numberOfErrors(), 'Errors', $color); $this->printCountString($result->numberOfTestFailedEvents(), 'Failures', $color); - $this->printCountString($result->numberOfWarningEvents(), 'Warnings', $color); - $this->printCountString($result->numberOfDeprecationEvents(), 'Deprecations', $color); - $this->printCountString($result->numberOfNoticeEvents(), 'Notices', $color); + $this->printCountString($result->numberOfWarnings(), 'Warnings', $color); + $this->printCountString($result->numberOfDeprecations(), 'Deprecations', $color); + $this->printCountString($result->numberOfNotices(), 'Notices', $color); $this->printCountString($result->numberOfTestSuiteSkippedEvents() + $result->numberOfTestSkippedEvents(), 'Skipped', $color); $this->printCountString($result->numberOfTestMarkedIncompleteEvents(), 'Incomplete', $color); $this->printCountString($result->numberOfTestsWithTestConsideredRiskyEvents(), 'Risky', $color); $this->printWithColor($color, '.'); + $this->printNumberOfIssuesIgnoredByBaseline($result); } private function printCountString(int $count, string $name, string $color, bool $always = \false) : void { @@ -83816,6 +92063,12 @@ final class SummaryPrinter $this->printer->print(\PHP_EOL); } } + private function printNumberOfIssuesIgnoredByBaseline(TestResult $result) : void + { + if ($result->hasIssuesIgnoredByBaseline()) { + $this->printer->print(sprintf('%s%d issue%s %s ignored by baseline.%s', \PHP_EOL, $result->numberOfIssuesIgnoredByBaseline(), $result->numberOfIssuesIgnoredByBaseline() > 1 ? 's' : '', $result->numberOfIssuesIgnoredByBaseline() > 1 ? 'were' : 'was', \PHP_EOL)); + } + } } printer->print($buffer . PHP_EOL); } - /** - * @throws NoDataSetFromDataProviderException - */ private function printTestResult(TestDoxTestResult $test) : void { $this->printTestResultHeader($test); $this->printTestResultBody($test); } - /** - * @throws NoDataSetFromDataProviderException - */ private function printTestResultHeader(TestDoxTestResult $test) : void { $buffer = ' ' . $this->symbolFor($test->status()) . ' '; @@ -84044,7 +92290,7 @@ final class ResultPrinter if ($status->isSkipped()) { return 'fg-cyan'; } - if ($status->isRisky() || $status->isIncomplete() || $status->isWarning()) { + if ($status->isIncomplete() || $status->isDeprecation() || $status->isNotice() || $status->isRisky() || $status->isWarning()) { return 'fg-yellow'; } return 'fg-blue'; @@ -84063,7 +92309,7 @@ final class ResultPrinter if ($status->isSkipped()) { return 'fg-cyan'; } - if ($status->isRisky() || $status->isIncomplete() || $status->isWarning()) { + if ($status->isIncomplete() || $status->isDeprecation() || $status->isNotice() || $status->isRisky() || $status->isWarning()) { return 'fg-yellow'; } return 'fg-white,bg-blue'; @@ -84079,15 +92325,12 @@ final class ResultPrinter if ($status->isSkipped()) { return '↩'; } - if ($status->isRisky()) { - return '☢'; + if ($status->isDeprecation() || $status->isNotice() || $status->isRisky() || $status->isWarning()) { + return '⚠'; } if ($status->isIncomplete()) { return '∅'; } - if ($status->isWarning()) { - return '⚠'; - } return '?'; } } @@ -84113,30 +92356,36 @@ final class ShellExitCodeCalculator private const SUCCESS_EXIT = 0; private const FAILURE_EXIT = 1; private const EXCEPTION_EXIT = 2; - public function calculate(bool $failOnEmptyTestSuite, bool $failOnRisky, bool $failOnWarning, bool $failOnIncomplete, bool $failOnSkipped, TestResult $result) : int + public function calculate(bool $failOnDeprecation, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnNotice, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, TestResult $result) : int { $returnCode = self::FAILURE_EXIT; if ($result->wasSuccessful()) { $returnCode = self::SUCCESS_EXIT; } - if ($failOnEmptyTestSuite && $result->numberOfTests() === 0) { + if ($failOnEmptyTestSuite && !$result->hasTests()) { $returnCode = self::FAILURE_EXIT; } if ($result->wasSuccessfulIgnoringPhpunitWarnings()) { - if ($failOnRisky && $result->hasTestConsideredRiskyEvents()) { + if ($failOnDeprecation && $result->hasDeprecations()) { + $returnCode = self::FAILURE_EXIT; + } + if ($failOnIncomplete && $result->hasIncompleteTests()) { $returnCode = self::FAILURE_EXIT; } - if ($failOnWarning && $result->hasWarningEvents()) { + if ($failOnNotice && $result->hasNotices()) { $returnCode = self::FAILURE_EXIT; } - if ($failOnIncomplete && $result->hasTestMarkedIncompleteEvents()) { + if ($failOnRisky && $result->hasRiskyTests()) { $returnCode = self::FAILURE_EXIT; } - if ($failOnSkipped && $result->hasTestSkippedEvents()) { + if ($failOnSkipped && $result->hasSkippedTests()) { + $returnCode = self::FAILURE_EXIT; + } + if ($failOnWarning && $result->hasWarnings()) { $returnCode = self::FAILURE_EXIT; } } - if ($result->hasTestErroredEvents()) { + if ($result->hasErrors()) { $returnCode = self::EXCEPTION_EXIT; } return $returnCode; @@ -84405,148 +92654,6 @@ declare (strict_types=1); */ namespace PHPUnit\Util; -use const E_DEPRECATED; -use const E_NOTICE; -use const E_STRICT; -use const E_USER_DEPRECATED; -use const E_USER_NOTICE; -use const E_USER_WARNING; -use const E_WARNING; -use function debug_backtrace; -use function error_reporting; -use function in_array; -use function restore_error_handler; -use function set_error_handler; -use PHPUnit\Event; -use PHPUnit\Framework\TestCase; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class ErrorHandler -{ - private static ?self $instance = null; - private bool $enabled = \false; - public static function instance() : self - { - return self::$instance ?? (self::$instance = new self()); - } - /** - * @throws Exception - */ - public function __invoke(int $errorNumber, string $errorString, string $errorFile, int $errorLine) : bool - { - $suppressed = !($errorNumber & error_reporting()); - if ($suppressed && in_array($errorNumber, [E_DEPRECATED, E_NOTICE, E_STRICT, E_WARNING], \true)) { - return \false; - } - switch ($errorNumber) { - case E_NOTICE: - case E_STRICT: - Event\Facade::emitter()->testTriggeredPhpNotice($this->testValueObjectForEvents(), $errorString, $errorFile, $errorLine); - return \true; - case E_USER_NOTICE: - Event\Facade::emitter()->testTriggeredNotice($this->testValueObjectForEvents(), $errorString, $errorFile, $errorLine); - break; - case E_WARNING: - Event\Facade::emitter()->testTriggeredPhpWarning($this->testValueObjectForEvents(), $errorString, $errorFile, $errorLine); - break; - case E_USER_WARNING: - Event\Facade::emitter()->testTriggeredWarning($this->testValueObjectForEvents(), $errorString, $errorFile, $errorLine); - break; - case E_DEPRECATED: - Event\Facade::emitter()->testTriggeredPhpDeprecation($this->testValueObjectForEvents(), $errorString, $errorFile, $errorLine); - break; - case E_USER_DEPRECATED: - Event\Facade::emitter()->testTriggeredDeprecation($this->testValueObjectForEvents(), $errorString, $errorFile, $errorLine); - break; - case \E_USER_ERROR: - Event\Facade::emitter()->testTriggeredError($this->testValueObjectForEvents(), $errorString, $errorFile, $errorLine); - break; - default: - // @codeCoverageIgnoreStart - return \false; - } - return \true; - } - public function enable() : void - { - if ($this->enabled) { - // @codeCoverageIgnoreStart - return; - // @codeCoverageIgnoreEnd - } - $oldErrorHandler = set_error_handler($this); - if ($oldErrorHandler !== null) { - // @codeCoverageIgnoreStart - restore_error_handler(); - return; - // @codeCoverageIgnoreEnd - } - $this->enabled = \true; - } - public function disable() : void - { - if (!$this->enabled) { - // @codeCoverageIgnoreStart - return; - // @codeCoverageIgnoreEnd - } - restore_error_handler(); - $this->enabled = \false; - } - /** - * @throws NoTestCaseObjectOnCallStackException - */ - private function testValueObjectForEvents() : Event\Code\Test - { - foreach (debug_backtrace() as $frame) { - if (isset($frame['object']) && $frame['object'] instanceof TestCase) { - return $frame['object']->valueObjectForEvents(); - } - } - // @codeCoverageIgnoreStart - throw new \PHPUnit\Util\NoTestCaseObjectOnCallStackException(); - // @codeCoverageIgnoreEnd - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Util; - -use function sprintf; -use RuntimeException; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class DirectoryDoesNotExistException extends RuntimeException implements \PHPUnit\Util\Exception -{ - public function __construct(string $directory) - { - parent::__construct(sprintf('Directory "%s" does not exist and could not be created', $directory)); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Util; - use Throwable; /** * @internal This interface is not covered by the backward compatibility promise for PHPUnit @@ -84612,31 +92719,6 @@ declare (strict_types=1); */ namespace PHPUnit\Util; -use function sprintf; -use RuntimeException; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class InvalidSocketException extends RuntimeException implements \PHPUnit\Util\Exception -{ - public function __construct(string $socket) - { - parent::__construct(sprintf('"%s" does not match "socket://hostname:port" format', $socket)); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Util; - use function sprintf; use RuntimeException; /** @@ -84651,30 +92733,6 @@ final class InvalidVersionOperatorException extends RuntimeException implements } - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Util; - -use RuntimeException; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class NoTestCaseObjectOnCallStackException extends RuntimeException implements \PHPUnit\Util\Exception -{ - public function __construct() - { - parent::__construct('Cannot find TestCase object on call stack'); - } -} -enabled = $enabled; + } /** * @psalm-return list */ @@ -84852,7 +92917,7 @@ final class ExcludeList } public function isExcluded(string $file) : bool { - if (defined('PHPUNIT_TESTSUITE')) { + if (!$this->enabled) { return \false; } self::initialize(); @@ -84879,7 +92944,7 @@ final class ExcludeList self::$directories[] = $directory; } // Hide process isolation workaround on Windows. - if (DIRECTORY_SEPARATOR === '\\') { + if (\PHP_OS_FAMILY === 'Windows') { // tempnam() prefix is limited to first 3 chars. // @see https://php.net/manual/en/function.tempnam.php self::$directories[] = sys_get_temp_dir() . '\\PHP'; @@ -84900,8 +92965,65 @@ declare (strict_types=1); */ namespace PHPUnit\Util; +use function is_array; +use function is_scalar; +use PHPUnit\SebastianBergmann\RecursionContext\Context; +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + * + * @deprecated + */ +final class Exporter +{ + public static function export(mixed $value, bool $exportObjects = \false) : string + { + if (self::isExportable($value) || $exportObjects) { + return (new \PHPUnit\SebastianBergmann\Exporter\Exporter())->export($value); + } + return '{enable export of objects to see this value}'; + } + private static function isExportable(mixed &$value, Context $context = null) : bool + { + if (is_scalar($value) || $value === null) { + return \true; + } + if (!is_array($value)) { + return \false; + } + if (!$context) { + $context = new Context(); + } + if ($context->contains($value) !== \false) { + return \true; + } + $array = $value; + $context->add($value); + foreach ($array as &$_value) { + if (!self::isExportable($_value, $context)) { + return \false; + } + } + return \true; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + use function is_dir; +use function is_string; use function mkdir; +use function realpath; +use function str_starts_with; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ @@ -84911,6 +93033,22 @@ final class Filesystem { return !(!is_dir($directory) && !@mkdir($directory, 0777, \true) && !is_dir($directory)); } + /** + * @psalm-param non-empty-string $path + * + * @return false|non-empty-string + */ + public static function resolvePathOrStream(string $path) : false|string + { + if (str_starts_with($path, 'php://') || str_starts_with($path, 'socket://')) { + return $path; + } + $path = realpath($path); + if (is_string($path) && !empty($path)) { + return $path; + } + return \false; + } } getFile(); $eLine = $t->getLine(); } else { - if ($t->getPrevious()) { + if ($unwrap && $t->getPrevious()) { $t = $t->getPrevious(); } $eTrace = $t->getTrace(); @@ -84974,7 +93112,7 @@ final class Filter } return $filteredStacktrace; } - private static function shouldPrintFrame(array $frame, string|false $prefix, \PHPUnit\Util\ExcludeList $excludeList) : bool + private static function shouldPrintFrame(array $frame, false|string $prefix, \PHPUnit\Util\ExcludeList $excludeList) : bool { if (!isset($frame['file'])) { return \false; @@ -85016,6 +93154,8 @@ declare (strict_types=1); */ namespace PHPUnit\Util; +use const PHP_MAJOR_VERSION; +use const PHP_MINOR_VERSION; use function array_keys; use function array_reverse; use function array_shift; @@ -85044,6 +93184,10 @@ final class GlobalState * @psalm-var list */ private const SUPER_GLOBAL_ARRAYS = ['_ENV', '_POST', '_GET', '_COOKIE', '_SERVER', '_FILES', '_REQUEST']; + /** + * @psalm-var array> + */ + private const DEPRECATED_INI_SETTINGS = ['7.3' => ['iconv.input_encoding' => \true, 'iconv.output_encoding' => \true, 'iconv.internal_encoding' => \true, 'mbstring.func_overload' => \true, 'mbstring.http_input' => \true, 'mbstring.http_output' => \true, 'mbstring.internal_encoding' => \true, 'string.strip_tags' => \true], '7.4' => ['iconv.input_encoding' => \true, 'iconv.output_encoding' => \true, 'iconv.internal_encoding' => \true, 'mbstring.func_overload' => \true, 'mbstring.http_input' => \true, 'mbstring.http_output' => \true, 'mbstring.internal_encoding' => \true, 'pdo_odbc.db2_instance_name' => \true, 'string.strip_tags' => \true], '8.0' => ['iconv.input_encoding' => \true, 'iconv.output_encoding' => \true, 'iconv.internal_encoding' => \true, 'mbstring.http_input' => \true, 'mbstring.http_output' => \true, 'mbstring.internal_encoding' => \true], '8.1' => ['auto_detect_line_endings' => \true, 'filter.default' => \true, 'iconv.input_encoding' => \true, 'iconv.output_encoding' => \true, 'iconv.internal_encoding' => \true, 'mbstring.http_input' => \true, 'mbstring.http_output' => \true, 'mbstring.internal_encoding' => \true, 'oci8.old_oci_close_semantics' => \true], '8.2' => ['auto_detect_line_endings' => \true, 'filter.default' => \true, 'iconv.input_encoding' => \true, 'iconv.output_encoding' => \true, 'iconv.internal_encoding' => \true, 'mbstring.http_input' => \true, 'mbstring.http_output' => \true, 'mbstring.internal_encoding' => \true, 'oci8.old_oci_close_semantics' => \true], '8.3' => ['auto_detect_line_endings' => \true, 'filter.default' => \true, 'iconv.input_encoding' => \true, 'iconv.output_encoding' => \true, 'iconv.internal_encoding' => \true, 'mbstring.http_input' => \true, 'mbstring.http_output' => \true, 'mbstring.internal_encoding' => \true, 'oci8.old_oci_close_semantics' => \true]]; /** * @throws Exception */ @@ -85091,6 +93235,9 @@ final class GlobalState { $result = ''; foreach (ini_get_all(null, \false) as $key => $value) { + if (self::isIniSettingDeprecated($key)) { + continue; + } $result .= sprintf('@ini_set(%s, %s);' . "\n", self::exportVariable($key), self::exportVariable((string) $value)); } return $result; @@ -85150,6 +93297,10 @@ final class GlobalState } return $result; } + private static function isIniSettingDeprecated(string $iniSetting) : bool + { + return isset(self::DEPRECATED_INI_SETTINGS[PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION][$iniSetting]); + } } */ protected array $env = []; - protected int $timeout = 0; public static function factory() : self { - if (DIRECTORY_SEPARATOR === '\\') { + if (\PHP_OS_FAMILY === 'Windows') { return new \PHPUnit\Util\PHP\WindowsPhpProcess(); } return new \PHPUnit\Util\PHP\DefaultPhpProcess(); } - public function __construct() - { - $this->runtime = new Runtime(); - } /** * Defines if should use STDERR redirection or not. * @@ -85360,20 +93504,6 @@ abstract class AbstractPhpProcess { return $this->env; } - /** - * Sets the amount of seconds to wait before timing out. - */ - public function setTimeout(int $timeout) : void - { - $this->timeout = $timeout; - } - /** - * Returns the amount of seconds to wait before timing out. - */ - public function getTimeout() : int - { - return $this->timeout; - } /** * Runs a single test in a separate PHP process. * @@ -85382,21 +93512,27 @@ abstract class AbstractPhpProcess * @throws MoreThanOneDataSetFromDataProviderException * @throws NoPreviousThrowableException */ - public function runTestJob(string $job, Test $test) : void + public function runTestJob(string $job, Test $test, string $processResultFile) : void { $_result = $this->runJob($job); - $this->processChildResult($test, $_result['stdout'], $_result['stderr']); + $processResult = ''; + if (file_exists($processResultFile)) { + $processResult = file_get_contents($processResultFile); + @unlink($processResultFile); + } + $this->processChildResult($test, $processResult, $_result['stderr']); } /** * Returns the command based into the configurations. */ public function getCommand(array $settings, string $file = null) : string { - $command = $this->runtime->getBinary(); - if ($this->runtime->hasPCOV()) { - $settings = array_merge($settings, $this->runtime->getCurrentSettings(array_keys(ini_get_all('pcov')))); - } elseif ($this->runtime->hasXdebug()) { - $settings = array_merge($settings, $this->runtime->getCurrentSettings(array_keys(ini_get_all('xdebug')))); + $runtime = new Runtime(); + $command = $runtime->getBinary(); + if ($runtime->hasPCOV()) { + $settings = array_merge($settings, $runtime->getCurrentSettings(array_keys(ini_get_all('pcov')))); + } elseif ($runtime->hasXdebug()) { + $settings = array_merge($settings, $runtime->getCurrentSettings(array_keys(ini_get_all('xdebug')))); } $command .= $this->settingsToParameters($settings); if (PHP_SAPI === 'phpdbg') { @@ -85454,10 +93590,7 @@ abstract class AbstractPhpProcess } ); try { - if (str_starts_with($stdout, "#!/usr/bin/env php\n")) { - $stdout = substr($stdout, 19); - } - $childResult = unserialize(str_replace("#!/usr/bin/env php\n", '', $stdout)); + $childResult = unserialize($stdout); restore_error_handler(); if ($childResult === \false) { $exception = new AssertionFailedError('Test was run in child process and ended unexpectedly'); @@ -85476,7 +93609,7 @@ abstract class AbstractPhpProcess if (!empty($childResult['output'])) { $output = $childResult['output']; } - Facade::forward($childResult['events']); + Facade::instance()->forward($childResult['events']); PassedTests::instance()->import($childResult['passedTests']); assert($test instanceof TestCase); $test->setResult($childResult['testResult']); @@ -85506,17 +93639,13 @@ namespace PHPUnit\Util\PHP; use function array_merge; use function fclose; use function file_put_contents; -use function fread; use function fwrite; use function is_array; use function is_resource; use function proc_close; use function proc_open; -use function proc_terminate; use function rewind; -use function sprintf; use function stream_get_contents; -use function stream_select; use function sys_get_temp_dir; use function tempnam; use function unlink; @@ -85530,13 +93659,15 @@ class DefaultPhpProcess extends \PHPUnit\Util\PHP\AbstractPhpProcess /** * Runs a single job (PHP code) using a separate PHP process. * + * @psalm-return array{stdout: string, stderr: string} + * * @throws Exception * @throws PhpProcessException */ public function runJob(string $job, array $settings = []) : array { if ($this->stdin || $this->useTemporaryFile()) { - if (!($this->tempFile = tempnam(sys_get_temp_dir(), 'PHPUnit')) || file_put_contents($this->tempFile, $job) === \false) { + if (!($this->tempFile = tempnam(sys_get_temp_dir(), 'phpunit_')) || file_put_contents($this->tempFile, $job) === \false) { throw new \PHPUnit\Util\PHP\PhpProcessException('Unable to write temporary file'); } $job = $this->stdin; @@ -85553,6 +93684,8 @@ class DefaultPhpProcess extends \PHPUnit\Util\PHP\AbstractPhpProcess /** * Handles creating the child process and returning the STDOUT and STDERR. * + * @psalm-return array{stdout: string, stderr: string} + * * @throws Exception * @throws PhpProcessException */ @@ -85580,56 +93713,13 @@ class DefaultPhpProcess extends \PHPUnit\Util\PHP\AbstractPhpProcess } fclose($pipes[0]); $stderr = $stdout = ''; - if ($this->timeout) { - unset($pipes[0]); - while (\true) { - $r = $pipes; - $w = null; - $e = null; - $n = @stream_select($r, $w, $e, $this->timeout); - if ($n === \false) { - break; - } - if ($n === 0) { - proc_terminate($process, 9); - throw new \PHPUnit\Util\PHP\PhpProcessException(sprintf('Job execution aborted after %d seconds', $this->timeout)); - } - if ($n > 0) { - foreach ($r as $pipe) { - $pipeOffset = 0; - foreach ($pipes as $i => $origPipe) { - if ($pipe === $origPipe) { - $pipeOffset = $i; - break; - } - } - if (!$pipeOffset) { - break; - } - $line = fread($pipe, 8192); - if ($line === '' || $line === \false) { - fclose($pipes[$pipeOffset]); - unset($pipes[$pipeOffset]); - } elseif ($pipeOffset === 1) { - $stdout .= $line; - } else { - $stderr .= $line; - } - } - if (empty($pipes)) { - break; - } - } - } - } else { - if (isset($pipes[1])) { - $stdout = stream_get_contents($pipes[1]); - fclose($pipes[1]); - } - if (isset($pipes[2])) { - $stderr = stream_get_contents($pipes[2]); - fclose($pipes[2]); - } + if (isset($pipes[1])) { + $stdout = stream_get_contents($pipes[1]); + fclose($pipes[1]); + } + if (isset($pipes[2])) { + $stderr = stream_get_contents($pipes[2]); + fclose($pipes[2]); } if (isset($handles[1])) { rewind($handles[1]); @@ -85698,131 +93788,22 @@ if ($composerAutoload) { function __phpunit_run_isolated_test() { - $dispatcher = Facade::initForIsolation( + $dispatcher = Facade::instance()->initForIsolation( PHPUnit\Event\Telemetry\HRTime::fromSecondsAndNanoseconds( {offsetSeconds}, {offsetNanoseconds} - ) + ), + {exportObjects}, ); require_once '{filename}'; if ({collectCodeCoverageInformation}) { - CodeCoverage::instance()->init(ConfigurationRegistry::get(), CodeCoverageFilterRegistry::instance()); + CodeCoverage::instance()->init(ConfigurationRegistry::get(), CodeCoverageFilterRegistry::instance(), true); + CodeCoverage::instance()->ignoreLines({linesToBeIgnored}); } $test = new {className}('{name}'); - $test->setData('{dataName}', unserialize('{data}')); - $test->setDependencyInput(unserialize('{dependencyInput}')); - $test->setInIsolation(true); - - ob_end_clean(); - - $test->run(); - - $output = ''; - - if (!$test->hasExpectationOnOutput()) { - $output = $test->output(); - } - - ini_set('xdebug.scream', '0'); - - // Not every STDOUT target stream is rewindable - @rewind(STDOUT); - - if ($stdout = @stream_get_contents(STDOUT)) { - $output = $stdout . $output; - $streamMetaData = stream_get_meta_data(STDOUT); - - if (!empty($streamMetaData['stream_type']) && 'STDIO' === $streamMetaData['stream_type']) { - @ftruncate(STDOUT, 0); - @rewind(STDOUT); - } - } - - print serialize( - [ - 'testResult' => $test->result(), - 'codeCoverage' => {collectCodeCoverageInformation} ? CodeCoverage::instance()->codeCoverage() : null, - 'numAssertions' => $test->numberOfAssertionsPerformed(), - 'output' => $output, - 'events' => $dispatcher->flush(), - 'passedTests' => PassedTests::instance() - ] - ); -} - -function __phpunit_error_handler($errno, $errstr, $errfile, $errline) -{ - return true; -} - -set_error_handler('__phpunit_error_handler'); - -{constants} -{included_files} -{globals} - -restore_error_handler(); - -ConfigurationRegistry::loadFrom('{serializedConfiguration}'); -(new PhpHandler)->handle(ConfigurationRegistry::get()->php()); - -if ('{bootstrap}' !== '') { - require_once '{bootstrap}'; -} - -__phpunit_run_isolated_test(); -init(ConfigurationRegistry::get(), CodeCoverageFilterRegistry::instance()); - } - - $test = new {className}('{methodName}'); $test->setData('{dataName}', unserialize('{data}')); $test->setDependencyInput(unserialize('{dependencyInput}')); @@ -85834,7 +93815,7 @@ function __phpunit_run_isolated_test() $output = ''; - if (!$test->hasExpectationOnOutput()) { + if (!$test->expectsOutput()) { $output = $test->output(); } @@ -85853,15 +93834,135 @@ function __phpunit_run_isolated_test() } } - print serialize( - [ - 'testResult' => $test->result(), - 'codeCoverage' => {collectCodeCoverageInformation} ? CodeCoverage::instance()->codeCoverage() : null, - 'numAssertions' => $test->numberOfAssertionsPerformed(), - 'output' => $output, - 'events' => $dispatcher->flush(), - 'passedTests' => PassedTests::instance() - ] + file_put_contents( + '{processResultFile}', + serialize( + [ + 'testResult' => $test->result(), + 'codeCoverage' => {collectCodeCoverageInformation} ? CodeCoverage::instance()->codeCoverage() : null, + 'numAssertions' => $test->numberOfAssertionsPerformed(), + 'output' => $output, + 'events' => $dispatcher->flush(), + 'passedTests' => PassedTests::instance() + ] + ) + ); +} + +function __phpunit_error_handler($errno, $errstr, $errfile, $errline) +{ + return true; +} + +set_error_handler('__phpunit_error_handler'); + +{constants} +{included_files} +{globals} + +restore_error_handler(); + +ConfigurationRegistry::loadFrom('{serializedConfiguration}'); +(new PhpHandler)->handle(ConfigurationRegistry::get()->php()); + +if ('{bootstrap}' !== '') { + require_once '{bootstrap}'; +} + +__phpunit_run_isolated_test(); +initForIsolation( + PHPUnit\Event\Telemetry\HRTime::fromSecondsAndNanoseconds( + {offsetSeconds}, + {offsetNanoseconds} + ), + {exportObjects}, + ); + + require_once '{filename}'; + + if ({collectCodeCoverageInformation}) { + CodeCoverage::instance()->init(ConfigurationRegistry::get(), CodeCoverageFilterRegistry::instance(), true); + CodeCoverage::instance()->ignoreLines({linesToBeIgnored}); + } + + $test = new {className}('{methodName}'); + + $test->setData('{dataName}', unserialize('{data}')); + $test->setDependencyInput(unserialize('{dependencyInput}')); + $test->setInIsolation(true); + + ob_end_clean(); + + $test->run(); + + $output = ''; + + if (!$test->expectsOutput()) { + $output = $test->output(); + } + + ini_set('xdebug.scream', '0'); + + // Not every STDOUT target stream is rewindable + @rewind(STDOUT); + + if ($stdout = @stream_get_contents(STDOUT)) { + $output = $stdout . $output; + $streamMetaData = stream_get_meta_data(STDOUT); + + if (!empty($streamMetaData['stream_type']) && 'STDIO' === $streamMetaData['stream_type']) { + @ftruncate(STDOUT, 0); + @rewind(STDOUT); + } + } + + file_put_contents( + '{processResultFile}', + serialize( + [ + 'testResult' => $test->result(), + 'codeCoverage' => {collectCodeCoverageInformation} ? CodeCoverage::instance()->codeCoverage() : null, + 'numAssertions' => $test->numberOfAssertionsPerformed(), + 'output' => $output, + 'events' => $dispatcher->flush(), + 'passedTests' => PassedTests::instance() + ] + ) ); } @@ -85993,6 +94094,9 @@ declare (strict_types=1); */ namespace PHPUnit\Util; +use function array_keys; +use function array_merge; +use function array_reverse; use PHPUnit\Framework\Assert; use PHPUnit\Framework\TestCase; use ReflectionClass; @@ -86007,7 +94111,7 @@ final class Reflection * @psalm-param class-string $className * @psalm-param non-empty-string $methodName * - * @psalm-return array{file: string, line: int} + * @psalm-return array{file: non-empty-string, line: non-negative-int} */ public static function sourceLocationFor(string $className, string $methodName) : array { @@ -86024,31 +94128,43 @@ final class Reflection /** * @psalm-return list */ - public function publicMethodsInTestClass(ReflectionClass $class) : array + public static function publicMethodsInTestClass(ReflectionClass $class) : array { - return $this->filterMethods($class, ReflectionMethod::IS_PUBLIC); + return self::filterAndSortMethods($class, ReflectionMethod::IS_PUBLIC, \true); } /** * @psalm-return list */ - public function methodsInTestClass(ReflectionClass $class) : array + public static function methodsInTestClass(ReflectionClass $class) : array { - return $this->filterMethods($class, null); + return self::filterAndSortMethods($class, null, \false); } /** * @psalm-return list */ - private function filterMethods(ReflectionClass $class, ?int $filter) : array + private static function filterAndSortMethods(ReflectionClass $class, ?int $filter, bool $sortHighestToLowest) : array { - $methods = []; + $methodsByClass = []; foreach ($class->getMethods($filter) as $method) { - if ($method->getDeclaringClass()->getName() === TestCase::class) { + $declaringClassName = $method->getDeclaringClass()->getName(); + if ($declaringClassName === TestCase::class) { continue; } - if ($method->getDeclaringClass()->getName() === Assert::class) { + if ($declaringClassName === Assert::class) { continue; } - $methods[] = $method; + if (!isset($methodsByClass[$declaringClassName])) { + $methodsByClass[$declaringClassName] = []; + } + $methodsByClass[$declaringClassName][] = $method; + } + $classNames = array_keys($methodsByClass); + if ($sortHighestToLowest) { + $classNames = array_reverse($classNames); + } + $methods = []; + foreach ($classNames as $className) { + $methods = array_merge($methods, $methodsByClass[$className]); } return $methods; } @@ -86103,6 +94219,7 @@ use function trim; use PHPUnit\Framework\ExpectationFailedException; use PHPUnit\Framework\PhptAssertionFailedError; use PHPUnit\Framework\SelfDescribing; +use PHPUnit\Runner\ErrorException; use Throwable; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit @@ -86111,6 +94228,9 @@ final class ThrowableToStringMapper { public static function map(Throwable $t) : string { + if ($t instanceof ErrorException) { + return $t->getMessage(); + } if ($t instanceof SelfDescribing) { $buffer = $t->toString(); if ($t instanceof ExpectationFailedException && $t->getComparisonFailure()) { @@ -86183,114 +94303,6 @@ final class VersionComparisonOperator } - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Util; - -use const ENT_QUOTES; -use function htmlspecialchars; -use function mb_convert_encoding; -use function ord; -use function preg_replace; -use function strlen; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class Xml -{ - /** - * Escapes a string for the use in XML documents. - * - * Any Unicode character is allowed, excluding the surrogate blocks, FFFE, - * and FFFF (not even as character reference). - * - * @see https://www.w3.org/TR/xml/#charsets - */ - public static function prepareString(string $string) : string - { - return preg_replace('/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]/', '', htmlspecialchars(self::convertToUtf8($string), ENT_QUOTES)); - } - private static function convertToUtf8(string $string) : string - { - if (!self::isUtf8($string)) { - $string = mb_convert_encoding($string, 'UTF-8'); - } - return $string; - } - private static function isUtf8(string $string) : bool - { - $length = strlen($string); - for ($i = 0; $i < $length; $i++) { - if (ord($string[$i]) < 0x80) { - $n = 0; - } elseif ((ord($string[$i]) & 0xe0) === 0xc0) { - $n = 1; - } elseif ((ord($string[$i]) & 0xf0) === 0xe0) { - $n = 2; - } elseif ((ord($string[$i]) & 0xf0) === 0xf0) { - $n = 3; - } else { - return \false; - } - for ($j = 0; $j < $n; $j++) { - if (++$i === $length || (ord($string[$i]) & 0xc0) !== 0x80) { - return \false; - } - } - } - return \true; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Util\Xml; - -use RuntimeException; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class Exception extends RuntimeException implements \PHPUnit\Exception -{ -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Util\Xml; - -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - * - * @psalm-immutable - */ -final class FailedSchemaDetectionResult extends \PHPUnit\Util\Xml\SchemaDetectionResult -{ -} -load($contents, $isHtml, $filename, $xinclude, $strict); + return $this->load($contents, $filename); } /** * @throws XmlException */ - public function load(string $actual, bool $isHtml = \false, string $filename = '', bool $xinclude = \false, bool $strict = \false) : DOMDocument + public function load(string $actual, ?string $filename = null) : DOMDocument { if ($actual === '') { - throw new \PHPUnit\Util\Xml\XmlException('Could not load XML from empty string'); - } - // Required for XInclude on Windows. - if ($xinclude) { - $cwd = getcwd(); - @chdir(dirname($filename)); + if ($filename === null) { + throw new \PHPUnit\Util\Xml\XmlException('Could not parse XML from empty string'); + } + throw new \PHPUnit\Util\Xml\XmlException(sprintf('Could not parse XML from empty file "%s"', $filename)); } $document = new DOMDocument(); $document->preserveWhiteSpace = \false; $internal = libxml_use_internal_errors(\true); $message = ''; $reporting = error_reporting(0); - if ($filename !== '') { - // Required for XInclude + // Required for XInclude + if ($filename !== null) { + // Required for XInclude on Windows + if (\PHP_OS_FAMILY === 'Windows') { + $cwd = getcwd(); + @chdir(dirname($filename)); + } $document->documentURI = $filename; } - if ($isHtml) { - $loaded = $document->loadHTML($actual); - } else { - $loaded = $document->loadXML($actual); - } - if (!$isHtml && $xinclude) { + $loaded = $document->loadXML($actual); + if ($filename !== null) { $document->xinclude(); } foreach (libxml_get_errors() as $error) { @@ -86367,9 +94378,9 @@ final class Loader if (isset($cwd)) { @chdir($cwd); } - if ($loaded === \false || $strict && $message !== '') { - if ($filename !== '') { - throw new \PHPUnit\Util\Xml\XmlException(sprintf('Could not load "%s".%s', $filename, $message !== '' ? "\n" . $message : '')); + if ($loaded === \false || $message !== '') { + if ($filename !== null) { + throw new \PHPUnit\Util\Xml\XmlException(sprintf('Could not load "%s"%s', $filename, $message !== '' ? ":\n" . $message : '')); } if ($message === '') { $message = 'Could not load XML for unknown reason'; @@ -86390,277 +94401,60 @@ declare (strict_types=1); * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -namespace PHPUnit\Util\Xml; - -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - * - * @psalm-immutable - */ -abstract class SchemaDetectionResult -{ - public function detected() : bool - { - return \false; - } - /** - * @throws XmlException - */ - public function version() : string - { - throw new \PHPUnit\Util\Xml\XmlException('No supported schema was detected'); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Util\Xml; - -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class SchemaDetector -{ - /** - * @throws XmlException - */ - public function detect(string $filename) : \PHPUnit\Util\Xml\SchemaDetectionResult - { - $document = (new \PHPUnit\Util\Xml\Loader())->loadFile($filename, \false, \true, \true); - foreach (['9.5', '9.2', '8.5'] as $candidate) { - $schema = (new \PHPUnit\Util\Xml\SchemaFinder())->find($candidate); - if (!(new \PHPUnit\Util\Xml\Validator())->validate($document, $schema)->hasValidationErrors()) { - return new \PHPUnit\Util\Xml\SuccessfulSchemaDetectionResult($candidate); - } - } - return new \PHPUnit\Util\Xml\FailedSchemaDetectionResult(); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Util\Xml; +namespace PHPUnit\Util; -use function defined; -use function is_file; -use function sprintf; -use PHPUnit\Runner\Version; +use const ENT_QUOTES; +use function htmlspecialchars; +use function mb_convert_encoding; +use function ord; +use function preg_replace; +use function strlen; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ -final class SchemaFinder +final class Xml { /** - * @throws XmlException + * Escapes a string for the use in XML documents. + * + * Any Unicode character is allowed, excluding the surrogate blocks, FFFE, + * and FFFF (not even as character reference). + * + * @see https://www.w3.org/TR/xml/#charsets */ - public function find(string $version) : string - { - if ($version === Version::series()) { - $filename = $this->path() . 'phpunit.xsd'; - } else { - $filename = $this->path() . 'schema/' . $version . '.xsd'; - } - if (!is_file($filename)) { - throw new \PHPUnit\Util\Xml\XmlException(sprintf('Schema for PHPUnit %s is not available', $version)); - } - return $filename; - } - private function path() : string + public static function prepareString(string $string) : string { - if (defined('__PHPUNIT_PHAR_ROOT__')) { - return __PHPUNIT_PHAR_ROOT__ . '/'; - } - return __DIR__ . '/../../../'; + return preg_replace('/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]/', '', htmlspecialchars(self::convertToUtf8($string), ENT_QUOTES)); } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Util\Xml; - -use function count; -use ArrayIterator; -use Countable; -use DOMNode; -use DOMNodeList; -use IteratorAggregate; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - * - * @template-implements IteratorAggregate - */ -final class SnapshotNodeList implements Countable, IteratorAggregate -{ - /** - * @psalm-var list - */ - private array $nodes = []; - public static function fromNodeList(DOMNodeList $list) : self + private static function convertToUtf8(string $string) : string { - $snapshot = new self(); - foreach ($list as $node) { - $snapshot->nodes[] = $node; + if (!self::isUtf8($string)) { + $string = mb_convert_encoding($string, 'UTF-8'); } - return $snapshot; - } - public function count() : int - { - return count($this->nodes); - } - public function getIterator() : ArrayIterator - { - return new ArrayIterator($this->nodes); - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Util\Xml; - -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - * - * @psalm-immutable - */ -final class SuccessfulSchemaDetectionResult extends \PHPUnit\Util\Xml\SchemaDetectionResult -{ - private readonly string $version; - public function __construct(string $version) - { - $this->version = $version; - } - public function detected() : bool - { - return \true; - } - public function version() : string - { - return $this->version; + return $string; } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Util\Xml; - -use function sprintf; -use function trim; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - * - * @psalm-immutable - */ -final class ValidationResult -{ - /** - * @psalm-var array> - */ - private readonly array $validationErrors; - /** - * @psalm-param array $errors - */ - public static function fromArray(array $errors) : self + private static function isUtf8(string $string) : bool { - $validationErrors = []; - foreach ($errors as $error) { - if (!isset($validationErrors[$error->line])) { - $validationErrors[$error->line] = []; + $length = strlen($string); + for ($i = 0; $i < $length; $i++) { + if (ord($string[$i]) < 0x80) { + $n = 0; + } elseif ((ord($string[$i]) & 0xe0) === 0xc0) { + $n = 1; + } elseif ((ord($string[$i]) & 0xf0) === 0xe0) { + $n = 2; + } elseif ((ord($string[$i]) & 0xf0) === 0xf0) { + $n = 3; + } else { + return \false; } - $validationErrors[$error->line][] = trim($error->message); - } - return new self($validationErrors); - } - private function __construct(array $validationErrors) - { - $this->validationErrors = $validationErrors; - } - public function hasValidationErrors() : bool - { - return !empty($this->validationErrors); - } - public function asString() : string - { - $buffer = ''; - foreach ($this->validationErrors as $line => $validationErrorsOnLine) { - $buffer .= sprintf(\PHP_EOL . ' Line %d:' . \PHP_EOL, $line); - foreach ($validationErrorsOnLine as $validationError) { - $buffer .= sprintf(' - %s' . \PHP_EOL, $validationError); + for ($j = 0; $j < $n; $j++) { + if (++$i === $length || (ord($string[$i]) & 0xc0) !== 0x80) { + return \false; + } } } - return $buffer; - } -} - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace PHPUnit\Util\Xml; - -use function file_get_contents; -use function libxml_clear_errors; -use function libxml_get_errors; -use function libxml_use_internal_errors; -use DOMDocument; -/** - * @internal This class is not covered by the backward compatibility promise for PHPUnit - */ -final class Validator -{ - public function validate(DOMDocument $document, string $xsdFilename) : \PHPUnit\Util\Xml\ValidationResult - { - $originalErrorHandling = libxml_use_internal_errors(\true); - $document->schemaValidateSource(file_get_contents($xsdFilename)); - $errors = libxml_get_errors(); - libxml_clear_errors(); - libxml_use_internal_errors($originalErrorHandling); - return \PHPUnit\Util\Xml\ValidationResult::fromArray($errors); + return \true; } } @@ -86669,14 +94463,14 @@ final class Validator phpunit phpunit - 10.0.16 + 10.5.8 The PHP Unit Testing framework. BSD-3-Clause - pkg:composer/phpunit/phpunit@10.0.16 + pkg:composer/phpunit/phpunit@10.5.8 myclabs @@ -86693,14 +94487,14 @@ final class Validator nikic php-parser - v4.15.4 + v5.0.0 A PHP parser written in PHP BSD-3-Clause - pkg:composer/nikic/php-parser@v4.15.4 + pkg:composer/nikic/php-parser@v5.0.0 phar-io @@ -86729,26 +94523,26 @@ final class Validator phpunit php-code-coverage - 10.0.2 + 10.1.11 Library that provides collection, processing, and rendering functionality for PHP code coverage information. BSD-3-Clause - pkg:composer/phpunit/php-code-coverage@10.0.2 + pkg:composer/phpunit/php-code-coverage@10.1.11 phpunit php-file-iterator - 4.0.1 + 4.1.0 FilterIterator implementation that filters files based on a list of suffixes. BSD-3-Clause - pkg:composer/phpunit/php-file-iterator@4.0.1 + pkg:composer/phpunit/php-file-iterator@4.1.0 phpunit @@ -86765,14 +94559,14 @@ final class Validator phpunit php-text-template - 3.0.0 + 3.0.1 Simple template engine. BSD-3-Clause - pkg:composer/phpunit/php-text-template@3.0.0 + pkg:composer/phpunit/php-text-template@3.0.1 phpunit @@ -86825,86 +94619,86 @@ final class Validator sebastian comparator - 5.0.0 + 5.0.1 Provides the functionality to compare PHP values for equality BSD-3-Clause - pkg:composer/sebastian/comparator@5.0.0 + pkg:composer/sebastian/comparator@5.0.1 sebastian complexity - 3.0.0 + 3.2.0 Library for calculating the complexity of PHP code units BSD-3-Clause - pkg:composer/sebastian/complexity@3.0.0 + pkg:composer/sebastian/complexity@3.2.0 sebastian diff - 5.0.0 + 5.1.0 Diff implementation BSD-3-Clause - pkg:composer/sebastian/diff@5.0.0 + pkg:composer/sebastian/diff@5.1.0 sebastian environment - 6.0.0 + 6.0.1 Provides functionality to handle HHVM/PHP environments BSD-3-Clause - pkg:composer/sebastian/environment@6.0.0 + pkg:composer/sebastian/environment@6.0.1 sebastian exporter - 5.0.0 + 5.1.1 Provides the functionality to export PHP variables for visualization BSD-3-Clause - pkg:composer/sebastian/exporter@5.0.0 + pkg:composer/sebastian/exporter@5.1.1 sebastian global-state - 6.0.0 + 6.0.1 Snapshotting of global state BSD-3-Clause - pkg:composer/sebastian/global-state@6.0.0 + pkg:composer/sebastian/global-state@6.0.1 sebastian lines-of-code - 2.0.0 + 2.0.2 Library for counting the lines of code in PHP source code BSD-3-Clause - pkg:composer/sebastian/lines-of-code@2.0.0 + pkg:composer/sebastian/lines-of-code@2.0.2 sebastian @@ -86969,14 +94763,14 @@ final class Validator theseer tokenizer - 1.2.1 + 1.2.2 A small library for converting tokenized PHP source code into XML and potentially other formats BSD-3-Clause - pkg:composer/theseer/tokenizer@1.2.1 + pkg:composer/theseer/tokenizer@1.2.2 @@ -86984,7 +94778,2516 @@ final class Validator - This Schema file defines the rules by which the XML configuration file of PHPUnit 8.5 may be structured. + This Schema file defines the rules by which the XML configuration file of PHPUnit 10.0 may be structured. + + + + + + Root Element + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The main type specifying the document structure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This Schema file defines the rules by which the XML configuration file of PHPUnit 10.1 may be structured. + + + + + + Root Element + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The main type specifying the document structure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This Schema file defines the rules by which the XML configuration file of PHPUnit 10.2 may be structured. + + + + + + Root Element + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The main type specifying the document structure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This Schema file defines the rules by which the XML configuration file of PHPUnit 10.3 may be structured. + + + + + + Root Element + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The main type specifying the document structure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This Schema file defines the rules by which the XML configuration file of PHPUnit 10.4 may be structured. + + + + + + Root Element + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The main type specifying the document structure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This Schema file defines the rules by which the XML configuration file of PHPUnit 8.5 may be structured. + + + + + + Root Element + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The main type specifying the document structure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This Schema file defines the rules by which the XML configuration file of PHPUnit 9.0 may be structured. + + + + + + Root Element + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The main type specifying the document structure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This Schema file defines the rules by which the XML configuration file of PHPUnit 9.0 may be structured. + + + + + + Root Element + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The main type specifying the document structure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This Schema file defines the rules by which the XML configuration file of PHPUnit 9.2 may be structured. @@ -87119,9 +97422,7 @@ final class Validator - - @@ -87147,7 +97448,7 @@ final class Validator - + @@ -87232,7 +97533,7 @@ final class Validator - + @@ -87242,7 +97543,9 @@ final class Validator + + @@ -87264,7 +97567,7 @@ final class Validator - + @@ -87292,7 +97595,7 @@ final class Validator - + @@ -87301,7 +97604,7 @@ final class Validator - This Schema file defines the rules by which the XML configuration file of PHPUnit 9.2 may be structured. + This Schema file defines the rules by which the XML configuration file of PHPUnit 9.3 may be structured. @@ -87310,30 +97613,33 @@ final class Validator Root Element - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + @@ -87421,37 +97727,333 @@ final class Validator - + - + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The main type specifying the document structure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This Schema file defines the rules by which the XML configuration file of PHPUnit 9.4 may be structured. + + + + + + Root Element + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + - - - - - - - - + + @@ -87462,7 +98064,7 @@ final class Validator - + @@ -87538,16 +98140,14 @@ final class Validator - - - + @@ -87557,6 +98157,7 @@ final class Validator + @@ -87569,7 +98170,6 @@ final class Validator - @@ -87581,7 +98181,7 @@ final class Validator - + @@ -87591,8 +98191,8 @@ final class Validator - - + + @@ -87609,10 +98209,51 @@ final class Validator - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -87829,7 +98470,7 @@ final class Validator - + @@ -87895,8 +98536,10 @@ final class Validator - - + + + + @@ -89586,12 +100229,6 @@ use Exception; */ final class ExceptionComparator extends ObjectComparator { - /** - * Returns whether the comparator can compare two values. - * - * @param mixed $expected The first value to compare - * @param mixed $actual The second value to compare - */ public function accepts(mixed $expected, mixed $actual) : bool { return $expected instanceof Exception && $actual instanceof Exception; @@ -89747,28 +100384,29 @@ declare (strict_types=1); */ namespace PHPUnit\SebastianBergmann\Comparator; +use function array_keys; use function assert; -use PHPUnit\Framework\MockObject\MockObject; +use function str_starts_with; +use PHPUnit\Framework\MockObject\Stub; /** * Compares PHPUnit\Framework\MockObject\MockObject instances for equality. */ final class MockObjectComparator extends ObjectComparator { - /** - * Returns whether the comparator can compare two values. - * - * @param mixed $expected The first value to compare - * @param mixed $actual The second value to compare - */ public function accepts(mixed $expected, mixed $actual) : bool { - return $expected instanceof MockObject && $actual instanceof MockObject; + return $expected instanceof Stub && $actual instanceof Stub; } protected function toArray(object $object) : array { - assert($object instanceof MockObject); + assert($object instanceof Stub); $array = parent::toArray($object); - unset($array['__phpunit_invocationMocker']); + foreach (array_keys($array) as $key) { + if (!str_starts_with($key, '__phpunit_')) { + continue; + } + unset($array[$key]); + } return $array; } } @@ -90114,12 +100752,10 @@ namespace PHPUnit\SebastianBergmann\Complexity; use function assert; use function file_get_contents; use PHPUnit\PhpParser\Error; -use PHPUnit\PhpParser\Lexer; use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\NodeTraverser; use PHPUnit\PhpParser\NodeVisitor\NameResolver; use PHPUnit\PhpParser\NodeVisitor\ParentConnectingVisitor; -use PHPUnit\PhpParser\Parser; use PHPUnit\PhpParser\ParserFactory; final class Calculator { @@ -90136,7 +100772,7 @@ final class Calculator public function calculateForSourceString(string $source) : ComplexityCollection { try { - $nodes = $this->parser()->parse($source); + $nodes = (new ParserFactory())->createForHostVersion()->parse($source); assert($nodes !== null); return $this->calculateForAbstractSyntaxTree($nodes); // @codeCoverageIgnoreStart @@ -90167,10 +100803,6 @@ final class Calculator // @codeCoverageIgnoreEnd return $complexityCalculatingVisitor->result(); } - private function parser() : Parser - { - return (new ParserFactory())->create(ParserFactory::PREFER_PHP7, new Lexer()); - } } name = $name; $this->cyclomaticComplexity = $cyclomaticComplexity; } + /** + * @psalm-return non-empty-string + */ public function name() : string { return $this->name; } + /** + * @psalm-return positive-int + */ public function cyclomaticComplexity() : int { return $this->cyclomaticComplexity; } + public function isFunction() : bool + { + return !$this->isMethod(); + } + public function isMethod() : bool + { + return str_contains($this->name, '::'); + } } */ - private array $items; + private readonly array $items; public static function fromList(Complexity ...$items) : self { return new self($items); @@ -90253,6 +100915,9 @@ final class ComplexityCollection implements Countable, IteratorAggregate { return new ComplexityCollectionIterator($this); } + /** + * @psalm-return non-negative-int + */ public function count() : int { return count($this->items); @@ -90261,6 +100926,9 @@ final class ComplexityCollection implements Countable, IteratorAggregate { return empty($this->items); } + /** + * @psalm-return non-negative-int + */ public function cyclomaticComplexity() : int { $cyclomaticComplexity = 0; @@ -90269,6 +100937,26 @@ final class ComplexityCollection implements Countable, IteratorAggregate } return $cyclomaticComplexity; } + public function isFunction() : self + { + return new self(array_values(array_filter($this->items, static fn(Complexity $complexity): bool => $complexity->isFunction()))); + } + public function isMethod() : self + { + return new self(array_values(array_filter($this->items, static fn(Complexity $complexity): bool => $complexity->isMethod()))); + } + public function mergeWith(self $other) : self + { + return new self(array_merge($this->asArray(), $other->asArray())); + } + public function sortByDescendingCyclomaticComplexity() : self + { + $items = $this->items; + usort($items, static function (Complexity $a, Complexity $b) : int { + return $a->cyclomaticComplexity() <=> $b->cyclomaticComplexity(); + }); + return new self(array_reverse($items)); + } } */ - private array $items; + private readonly array $items; private int $position = 0; public function __construct(ComplexityCollection $items) { @@ -90394,11 +101082,13 @@ namespace PHPUnit\SebastianBergmann\Complexity; use function assert; use function is_array; use PHPUnit\PhpParser\Node; +use PHPUnit\PhpParser\Node\Expr\New_; use PHPUnit\PhpParser\Node\Name; use PHPUnit\PhpParser\Node\Stmt; use PHPUnit\PhpParser\Node\Stmt\Class_; use PHPUnit\PhpParser\Node\Stmt\ClassMethod; use PHPUnit\PhpParser\Node\Stmt\Function_; +use PHPUnit\PhpParser\Node\Stmt\Interface_; use PHPUnit\PhpParser\Node\Stmt\Trait_; use PHPUnit\PhpParser\NodeTraverser; use PHPUnit\PhpParser\NodeVisitorAbstract; @@ -90419,6 +101109,12 @@ final class ComplexityCalculatingVisitor extends NodeVisitorAbstract return null; } if ($node instanceof ClassMethod) { + if ($node->getAttribute('parent') instanceof Interface_) { + return null; + } + if ($node->isAbstract()) { + return null; + } $name = $this->classMethodName($node); } else { $name = $this->functionName($node); @@ -90437,6 +101133,8 @@ final class ComplexityCalculatingVisitor extends NodeVisitorAbstract } /** * @param Stmt[] $statements + * + * @psalm-return positive-int */ private function cyclomaticComplexity(array $statements) : int { @@ -90447,19 +101145,30 @@ final class ComplexityCalculatingVisitor extends NodeVisitorAbstract $traverser->traverse($statements); return $cyclomaticComplexityCalculatingVisitor->cyclomaticComplexity(); } + /** + * @psalm-return non-empty-string + */ private function classMethodName(ClassMethod $node) : string { $parent = $node->getAttribute('parent'); assert($parent instanceof Class_ || $parent instanceof Trait_); + if ($parent->getAttribute('parent') instanceof New_) { + return 'anonymous class'; + } assert(isset($parent->namespacedName)); assert($parent->namespacedName instanceof Name); return $parent->namespacedName->toString() . '::' . $node->name->toString(); } + /** + * @psalm-return non-empty-string + */ private function functionName(Function_ $node) : string { assert(isset($node->namespacedName)); assert($node->namespacedName instanceof Name); - return $node->namespacedName->toString(); + $functionName = $node->namespacedName->toString(); + assert($functionName !== ''); + return $functionName; } } cyclomaticComplexity++; } } + /** + * @psalm-return positive-int + */ public function cyclomaticComplexity() : int { return $this->cyclomaticComplexity; @@ -90528,7 +101243,13 @@ declare (strict_types=1); */ namespace PHPUnit\SebastianBergmann\Diff; -final class Chunk +use ArrayIterator; +use IteratorAggregate; +use Traversable; +/** + * @template-implements IteratorAggregate + */ +final class Chunk implements IteratorAggregate { private int $start; private int $startRange; @@ -90543,26 +101264,26 @@ final class Chunk $this->endRange = $endRange; $this->lines = $lines; } - public function getStart() : int + public function start() : int { return $this->start; } - public function getStartRange() : int + public function startRange() : int { return $this->startRange; } - public function getEnd() : int + public function end() : int { return $this->end; } - public function getEndRange() : int + public function endRange() : int { return $this->endRange; } /** * @psalm-return list */ - public function getLines() : array + public function lines() : array { return $this->lines; } @@ -90578,6 +101299,47 @@ final class Chunk } $this->lines = $lines; } + /** + * @deprecated Use start() instead + */ + public function getStart() : int + { + return $this->start; + } + /** + * @deprecated Use startRange() instead + */ + public function getStartRange() : int + { + return $this->startRange; + } + /** + * @deprecated Use end() instead + */ + public function getEnd() : int + { + return $this->end; + } + /** + * @deprecated Use endRange() instead + */ + public function getEndRange() : int + { + return $this->endRange; + } + /** + * @psalm-return list + * + * @deprecated Use lines() instead + */ + public function getLines() : array + { + return $this->lines; + } + public function getIterator() : Traversable + { + return new ArrayIterator($this->lines); + } } + */ +final class Diff implements IteratorAggregate { + /** + * @psalm-var non-empty-string + */ private string $from; + /** + * @psalm-var non-empty-string + */ private string $to; /** * @psalm-var list */ private array $chunks; /** + * @psalm-param non-empty-string $from + * @psalm-param non-empty-string $to * @psalm-param list $chunks */ public function __construct(string $from, string $to, array $chunks = []) @@ -90609,18 +101385,24 @@ final class Diff $this->to = $to; $this->chunks = $chunks; } - public function getFrom() : string + /** + * @psalm-return non-empty-string + */ + public function from() : string { return $this->from; } - public function getTo() : string + /** + * @psalm-return non-empty-string + */ + public function to() : string { return $this->to; } /** * @psalm-return list */ - public function getChunks() : array + public function chunks() : array { return $this->chunks; } @@ -90631,6 +101413,37 @@ final class Diff { $this->chunks = $chunks; } + /** + * @psalm-return non-empty-string + * + * @deprecated + */ + public function getFrom() : string + { + return $this->from; + } + /** + * @psalm-return non-empty-string + * + * @deprecated + */ + public function getTo() : string + { + return $this->to; + } + /** + * @psalm-return list + * + * @deprecated + */ + public function getChunks() : array + { + return $this->chunks; + } + public function getIterator() : Traversable + { + return new ArrayIterator($this->chunks); + } } type = $type; $this->content = $content; } + public function content() : string + { + return $this->content; + } + public function type() : int + { + return $this->type; + } + public function isAdded() : bool + { + return $this->type === self::ADDED; + } + public function isRemoved() : bool + { + return $this->type === self::REMOVED; + } + public function isUnchanged() : bool + { + return $this->type === self::UNCHANGED; + } + /** + * @deprecated + */ public function getContent() : string { return $this->content; } + /** + * @deprecated + */ public function getType() : int { return $this->type; @@ -91031,7 +101870,12 @@ final class MemoryEfficientLongestCommonSubsequenceCalculator implements Longest if ($from[$i] === $to[$j]) { $current[$j + 1] = $prev[$j] + 1; } else { - $current[$j + 1] = max($current[$j], $prev[$j + 1]); + // don't use max() to avoid function call overhead + if ($current[$j] > $prev[$j + 1]) { + $current[$j + 1] = $current[$j]; + } else { + $current[$j + 1] = $prev[$j + 1]; + } } } } @@ -91610,6 +102454,7 @@ declare (strict_types=1); namespace PHPUnit\SebastianBergmann\Diff; use function array_pop; +use function assert; use function count; use function max; use function preg_match; @@ -91639,6 +102484,8 @@ final class Parser $diffs[] = $diff; $collected = []; } + assert(!empty($fromMatch['file'])); + assert(!empty($toMatch['file'])); $diff = new Diff($fromMatch['file'], $toMatch['file']); $i++; } else { @@ -91660,8 +102507,8 @@ final class Parser $chunk = null; $diffLines = []; foreach ($lines as $line) { - if (preg_match('/^@@\\s+-(?P\\d+)(?:,\\s*(?P\\d+))?\\s+\\+(?P\\d+)(?:,\\s*(?P\\d+))?\\s+@@/', $line, $match)) { - $chunk = new Chunk((int) $match['start'], isset($match['startrange']) ? max(1, (int) $match['startrange']) : 1, (int) $match['end'], isset($match['endrange']) ? max(1, (int) $match['endrange']) : 1); + if (preg_match('/^@@\\s+-(?P\\d+)(?:,\\s*(?P\\d+))?\\s+\\+(?P\\d+)(?:,\\s*(?P\\d+))?\\s+@@/', $line, $match, \PREG_UNMATCHED_AS_NULL)) { + $chunk = new Chunk((int) $match['start'], isset($match['startrange']) ? max(0, (int) $match['startrange']) : 1, (int) $match['end'], isset($match['endrange']) ? max(0, (int) $match['endrange']) : 1); $chunks[] = $chunk; $diffLines = []; continue; @@ -91718,7 +102565,21 @@ final class TimeEfficientLongestCommonSubsequenceCalculator implements LongestCo for ($i = 1; $i <= $fromLength; $i++) { for ($j = 1; $j <= $toLength; $j++) { $o = $j * $width + $i; - $matrix[$o] = max($matrix[$o - 1], $matrix[$o - $width], $from[$i - 1] === $to[$j - 1] ? $matrix[$o - $width - 1] + 1 : 0); + // don't use max() to avoid function call overhead + $firstOrLast = $from[$i - 1] === $to[$j - 1] ? $matrix[$o - $width - 1] + 1 : 0; + if ($matrix[$o - 1] > $matrix[$o - $width]) { + if ($firstOrLast > $matrix[$o - 1]) { + $matrix[$o] = $firstOrLast; + } else { + $matrix[$o] = $matrix[$o - 1]; + } + } else { + if ($firstOrLast > $matrix[$o - $width]) { + $matrix[$o] = $firstOrLast; + } else { + $matrix[$o] = $matrix[$o - $width]; + } + } } } $i = $fromLength; @@ -91950,7 +102811,7 @@ use function php_ini_loaded_file; use function php_ini_scanned_files; use function phpversion; use function sprintf; -use function strpos; +use function strrpos; final class Runtime { private static string $binary; @@ -91989,7 +102850,14 @@ final class Runtime if (!$this->isOpcacheActive()) { return \false; } - if (strpos(ini_get('opcache.jit'), '0') === 0) { + if (ini_get('opcache.jit_buffer_size') === '0') { + return \false; + } + $jit = ini_get('opcache.jit'); + if ($jit === 'disable' || $jit === 'off') { + return \false; + } + if (strrpos($jit, '0') === 3) { return \false; } return \true; @@ -92176,17 +103044,6 @@ use BackedEnum; use PHPUnit\SebastianBergmann\RecursionContext\Context; use SplObjectStorage; use UnitEnum; -/** - * A nifty utility for visualizing PHP variables. - * - * - * export(new Exception); - * - */ final class Exporter { /** @@ -92221,7 +103078,7 @@ final class Exporter if ($context->contains($data[$key]) !== \false) { $result[] = '*RECURSION*'; } else { - $result[] = sprintf('array(%s)', $this->shortenedRecursiveExport($data[$key], $context)); + $result[] = sprintf('[%s]', $this->shortenedRecursiveExport($data[$key], $context)); } } else { $result[] = $exporter->shortenedExport($value); @@ -92257,7 +103114,7 @@ final class Exporter return sprintf('%s Object (%s)', $value::class, count($this->toArray($value)) > 0 ? '...' : ''); } if (is_array($value)) { - return sprintf('Array (%s)', count($value) > 0 ? '...' : ''); + return sprintf('[%s]', count($value) > 0 ? '...' : ''); } return $this->export($value); } @@ -92279,9 +103136,9 @@ final class Exporter continue; } // properties are transformed to keys in the following way: - // private $property => "\0Classname\0property" - // protected $property => "\0*\0property" - // public $property => "property" + // private $propertyName => "\0ClassName\0propertyName" + // protected $propertyName => "\0*\0propertyName" + // public $propertyName => "propertyName" if (preg_match('/^\\0.+\\0(.+)$/', (string) $key, $matches)) { $key = $matches[1]; } @@ -92291,19 +103148,17 @@ final class Exporter } $array[$key] = $val; } - // Some internal classes like SplObjectStorage don't work with the + // Some internal classes like SplObjectStorage do not work with the // above (fast) mechanism nor with reflection in Zend. // Format the output similarly to print_r() in this case if ($value instanceof SplObjectStorage) { foreach ($value as $_value) { $array['Object #' . spl_object_id($_value)] = ['obj' => $_value, 'inf' => $value->getInfo()]; } + $value->rewind(); } return $array; } - /** - * Recursive implementation of export. - */ private function recursiveExport(mixed &$value, int $indentation, ?Context $processed = null) : string { if ($value === null) { @@ -92341,7 +103196,7 @@ final class Exporter return sprintf('%s Enum #%d (%s)', $value::class, spl_object_id($value), $value->name); } if (is_string($value)) { - // Match for most non printable chars somewhat taking multibyte chars into account + // Match for most non-printable chars somewhat taking multibyte chars into account if (preg_match('/[^\\x09-\\x0d\\x1b\\x20-\\xff]/', $value)) { return 'Binary String: 0x' . bin2hex($value); } @@ -92360,27 +103215,27 @@ final class Exporter $values = ''; if (count($array) > 0) { foreach ($array as $k => $v) { - $values .= sprintf('%s %s => %s' . "\n", $whitespace, $this->recursiveExport($k, $indentation), $this->recursiveExport($value[$k], $indentation + 1, $processed)); + $values .= $whitespace . ' ' . $this->recursiveExport($k, $indentation) . ' => ' . $this->recursiveExport($value[$k], $indentation + 1, $processed) . ",\n"; } $values = "\n" . $values . $whitespace; } - return sprintf('Array &%s (%s)', $key, $values); + return 'Array &' . (string) $key . ' [' . $values . ']'; } if (is_object($value)) { $class = $value::class; if ($processed->contains($value)) { - return sprintf('%s Object #%d', $class, spl_object_id($value)); + return $class . ' Object #' . spl_object_id($value); } $processed->add($value); $values = ''; $array = $this->toArray($value); if (count($array) > 0) { foreach ($array as $k => $v) { - $values .= sprintf('%s %s => %s' . "\n", $whitespace, $this->recursiveExport($k, $indentation), $this->recursiveExport($v, $indentation + 1, $processed)); + $values .= $whitespace . ' ' . $this->recursiveExport($k, $indentation) . ' => ' . $this->recursiveExport($v, $indentation + 1, $processed) . ",\n"; } $values = "\n" . $values . $whitespace; } - return sprintf('%s Object #%d (%s)', $class, spl_object_id($value), $values); + return $class . ' Object #' . spl_object_id($value) . ' (' . $values . ')'; } return var_export($value, \true); } @@ -92652,8 +103507,7 @@ final class Restorer foreach ($snapshot->staticProperties() as $className => $staticProperties) { foreach ($staticProperties as $name => $value) { $reflector = new ReflectionProperty($className, $name); - $reflector->setAccessible(\true); - $reflector->setValue($value); + $reflector->setValue(null, $value); } } foreach ($newClasses as $className) { @@ -92670,8 +103524,7 @@ final class Restorer if (!isset($defaults[$name])) { continue; } - $property->setAccessible(\true); - $property->setValue($defaults[$name]); + $property->setValue(null, $defaults[$name]); } } } @@ -92891,7 +103744,6 @@ class Snapshot if ($this->excludeList->isStaticPropertyExcluded($className, $name)) { continue; } - $property->setAccessible(\true); if (!$property->isInitialized()) { continue; } @@ -93031,10 +103883,8 @@ use function assert; use function file_get_contents; use function substr_count; use PHPUnit\PhpParser\Error; -use PHPUnit\PhpParser\Lexer; use PHPUnit\PhpParser\Node; use PHPUnit\PhpParser\NodeTraverser; -use PHPUnit\PhpParser\Parser; use PHPUnit\PhpParser\ParserFactory; final class Counter { @@ -93054,8 +103904,9 @@ final class Counter if ($linesOfCode === 0 && !empty($source)) { $linesOfCode = 1; } + assert($linesOfCode >= 0); try { - $nodes = $this->parser()->parse($source); + $nodes = (new ParserFactory())->createForHostVersion()->parse($source); assert($nodes !== null); return $this->countInAbstractSyntaxTree($linesOfCode, $nodes); // @codeCoverageIgnoreStart @@ -93065,6 +103916,8 @@ final class Counter // @codeCoverageIgnoreEnd } /** + * @psalm-param non-negative-int $linesOfCode + * * @param Node[] $nodes * * @throws RuntimeException @@ -93084,10 +103937,6 @@ final class Counter // @codeCoverageIgnoreEnd return $visitor->result(); } - private function parser() : Parser - { - return (new ParserFactory())->create(ParserFactory::PREFER_PHP7, new Lexer()); - } } linesOfCode = $linesOfCode; @@ -93234,7 +104090,12 @@ final class LineCountingVisitor extends NodeVisitorAbstract foreach ($this->comments() as $comment) { $commentLinesOfCode += $comment->getEndLine() - $comment->getStartLine() + 1; } - return new LinesOfCode($this->linesOfCode, $commentLinesOfCode, $this->linesOfCode - $commentLinesOfCode, count(array_unique($this->linesWithStatements))); + $nonCommentLinesOfCode = $this->linesOfCode - $commentLinesOfCode; + $logicalLinesOfCode = count(array_unique($this->linesWithStatements)); + assert($commentLinesOfCode >= 0); + assert($nonCommentLinesOfCode >= 0); + assert($logicalLinesOfCode >= 0); + return new LinesOfCode($this->linesOfCode, $commentLinesOfCode, $nonCommentLinesOfCode, $logicalLinesOfCode); } /** * @return Comment[] @@ -93266,25 +104127,46 @@ namespace PHPUnit\SebastianBergmann\LinesOfCode; */ final class LinesOfCode { - private int $linesOfCode; - private int $commentLinesOfCode; - private int $nonCommentLinesOfCode; - private int $logicalLinesOfCode; /** + * @psalm-var non-negative-int + */ + private readonly int $linesOfCode; + /** + * @psalm-var non-negative-int + */ + private readonly int $commentLinesOfCode; + /** + * @psalm-var non-negative-int + */ + private readonly int $nonCommentLinesOfCode; + /** + * @psalm-var non-negative-int + */ + private readonly int $logicalLinesOfCode; + /** + * @psalm-param non-negative-int $linesOfCode + * @psalm-param non-negative-int $commentLinesOfCode + * @psalm-param non-negative-int $nonCommentLinesOfCode + * @psalm-param non-negative-int $logicalLinesOfCode + * * @throws IllogicalValuesException * @throws NegativeValueException */ public function __construct(int $linesOfCode, int $commentLinesOfCode, int $nonCommentLinesOfCode, int $logicalLinesOfCode) { + /** @psalm-suppress DocblockTypeContradiction */ if ($linesOfCode < 0) { throw new NegativeValueException('$linesOfCode must not be negative'); } + /** @psalm-suppress DocblockTypeContradiction */ if ($commentLinesOfCode < 0) { throw new NegativeValueException('$commentLinesOfCode must not be negative'); } + /** @psalm-suppress DocblockTypeContradiction */ if ($nonCommentLinesOfCode < 0) { throw new NegativeValueException('$nonCommentLinesOfCode must not be negative'); } + /** @psalm-suppress DocblockTypeContradiction */ if ($logicalLinesOfCode < 0) { throw new NegativeValueException('$logicalLinesOfCode must not be negative'); } @@ -93296,18 +104178,30 @@ final class LinesOfCode $this->nonCommentLinesOfCode = $nonCommentLinesOfCode; $this->logicalLinesOfCode = $logicalLinesOfCode; } + /** + * @psalm-return non-negative-int + */ public function linesOfCode() : int { return $this->linesOfCode; } + /** + * @psalm-return non-negative-int + */ public function commentLinesOfCode() : int { return $this->commentLinesOfCode; } + /** + * @psalm-return non-negative-int + */ public function nonCommentLinesOfCode() : int { return $this->nonCommentLinesOfCode; } + /** + * @psalm-return non-negative-int + */ public function logicalLinesOfCode() : int { return $this->logicalLinesOfCode; @@ -95222,6 +106116,7 @@ class TokenCollectionException extends Exception declare (strict_types=1); namespace PHPUnit\TheSeer\Tokenizer; +use function var_dump; class Tokenizer { /** @@ -95247,6 +106142,10 @@ class Tokenizer } $line = $tok[2]; $values = \preg_split('/\\R+/Uu', $tok[1]); + if (!$values) { + $result->addToken(new Token($line, \token_name($tok[0]), '{binary data}')); + continue; + } foreach ($values as $v) { $token = new Token($line, \token_name($tok[0]), $v); $lastToken = $token; @@ -95264,11 +106163,6 @@ class Tokenizer $prev = new Token(0, 'Placeholder', ''); $final = new TokenCollection(); foreach ($tokens as $token) { - if ($prev === null) { - $final->addToken($token); - $prev = $token; - continue; - } $gap = $token->getLine() - $prev->getLine(); while ($gap > 1) { $linebreak = new Token($prev->getLine() + 1, 'T_WHITESPACE', ''); @@ -95363,12 +106257,17 @@ class XMLSerializer namespace PHPSTORM_META { override( - \PHPUnit\Framework\TestCase::createMock(0), + \PHPUnit\Framework\TestCase::createStub(0), map([""=>"$0"]) ); override( - \PHPUnit\Framework\TestCase::createStub(0), + \PHPUnit\Framework\TestCase::createConfiguredStub(0), + map([""=>"$0"]) + ); + + override( + \PHPUnit\Framework\TestCase::createMock(0), map([""=>"$0"]) ); @@ -95392,4 +106291,4 @@ namespace PHPSTORM_META { map([""=>"$0"]) ); } -]qLr3=R}}}W䌋Xp p&K;ӯxQ6GBMB \ No newline at end of file +ȸd@N].Ku4 |)BYz` pw6`m*P ؟pGBMB \ No newline at end of file